[med-svn] [python-bx] 01/04: Imported Upstream version 0.7.2+20150623

Afif Elghraoui afif at moszumanska.debian.org
Thu Jun 30 08:38:04 UTC 2016


This is an automated email from the git hooks/post-receive script.

afif pushed a commit to branch master
in repository python-bx.

commit 1a5adf5c63d5d543a8f5cedbad2038012a417480
Author: Afif Elghraoui <afif at ghraoui.name>
Date:   Sat Apr 23 21:09:16 2016 -0700

    Imported Upstream version 0.7.2+20150623
---
 .hg_archival.txt                                   |     6 +
 .hgignore                                          |    23 +
 .hgtags                                            |     1 +
 LICENSE                                            |    20 +
 MANIFEST.in                                        |     7 +
 distribute_setup.py                                |   546 +
 doc/Makefile                                       |    83 +
 doc/source/conf.py                                 |   202 +
 doc/source/contents.rst                            |    18 +
 doc/source/index.rst                               |    28 +
 doc/source/static/base.css                         |   152 +
 doc/source/static/tripoli.base.css                 |   509 +
 doc/source/templates/index.html                    |    34 +
 doc/source/templates/indexsidebar.html             |     9 +
 doc/source/templates/layout.html                   |    51 +
 lib/bx/__init__.py                                 |    14 +
 lib/bx/_seqmapping.c                               |  5344 ++++++
 lib/bx/_seqmapping.pyx                             |   241 +
 lib/bx/align/__init__.py                           |     7 +
 lib/bx/align/_core.c                               |  1673 ++
 lib/bx/align/_core.pyx                             |    13 +
 lib/bx/align/_epo.c                                | 10839 ++++++++++++
 lib/bx/align/_epo.pyx                              |   184 +
 lib/bx/align/axt.py                                |   193 +
 lib/bx/align/core.py                               |   426 +
 lib/bx/align/epo.py                                |   278 +
 lib/bx/align/epo_tests.py                          |   234 +
 lib/bx/align/lav.py                                |   571 +
 lib/bx/align/lav_tests.py                          |    45 +
 lib/bx/align/maf.py                                |   231 +
 lib/bx/align/maf_tests.py                          |   190 +
 lib/bx/align/score.py                              |   291 +
 lib/bx/align/score_tests.py                        |    94 +
 lib/bx/align/sitemask/__init__.py                  |     6 +
 lib/bx/align/sitemask/_cpg.c                       |  3042 ++++
 lib/bx/align/sitemask/_cpg.pyx                     |    90 +
 lib/bx/align/sitemask/core.py                      |    35 +
 lib/bx/align/sitemask/cpg.py                       |    91 +
 lib/bx/align/sitemask/find_cpg.c                   |    66 +
 lib/bx/align/sitemask/find_cpg.h                   |     7 +
 lib/bx/align/sitemask/quality.py                   |   130 +
 lib/bx/align/sitemask/sitemask_tests.py            |    82 +
 lib/bx/align/tools/__init__.py                     |     8 +
 lib/bx/align/tools/chop.py                         |    29 +
 lib/bx/align/tools/fuse.py                         |    88 +
 lib/bx/align/tools/thread.py                       |    98 +
 lib/bx/align/tools/tile.py                         |    81 +
 lib/bx/arrays/__init__.py                          |     3 +
 lib/bx/arrays/array_tree.c                         | 16912 +++++++++++++++++++
 lib/bx/arrays/array_tree.pyx                       |   514 +
 lib/bx/arrays/array_tree_tests.py                  |   117 +
 lib/bx/arrays/bed.c                                |  2584 +++
 lib/bx/arrays/bed.pyx                              |    46 +
 lib/bx/arrays/wiggle.c                             |  3684 ++++
 lib/bx/arrays/wiggle.pxd                           |    13 +
 lib/bx/arrays/wiggle.pyx                           |    98 +
 lib/bx/bbi/__init__.py                             |     3 +
 lib/bx/bbi/bbi_file.c                              | 15626 +++++++++++++++++
 lib/bx/bbi/bbi_file.pxd                            |    91 +
 lib/bx/bbi/bbi_file.pyx                            |   393 +
 lib/bx/bbi/bigbed_file.c                           |  8876 ++++++++++
 lib/bx/bbi/bigbed_file.pyx                         |   142 +
 lib/bx/bbi/bigwig_file.c                           | 10167 +++++++++++
 lib/bx/bbi/bigwig_file.pyx                         |   165 +
 lib/bx/bbi/bigwig_tests.py                         |    83 +
 lib/bx/bbi/bpt_file.c                              |  2868 ++++
 lib/bx/bbi/bpt_file.pxd                            |    16 +
 lib/bx/bbi/bpt_file.pyx                            |    76 +
 lib/bx/bbi/cirtree_file.c                          |  3901 +++++
 lib/bx/bbi/cirtree_file.pxd                        |    15 +
 lib/bx/bbi/cirtree_file.pyx                        |   105 +
 lib/bx/bbi/types.pxd                               |    12 +
 lib/bx/binned_array.py                             |   345 +
 lib/bx/binned_array_tests.py                       |    93 +
 lib/bx/bitset.c                                    |  5871 +++++++
 lib/bx/bitset.pyx                                  |   240 +
 lib/bx/bitset_builders.py                          |   155 +
 lib/bx/bitset_tests.py                             |   112 +
 lib/bx/bitset_utils.py                             |    74 +
 lib/bx/cookbook/__init__.py                        |    98 +
 lib/bx/cookbook/argparse.py                        |  2362 +++
 lib/bx/cookbook/attribute.py                       |   121 +
 lib/bx/cookbook/doc_optparse.py                    |    86 +
 lib/bx/cookbook/progress_bar.py                    |    80 +
 lib/bx/filter.py                                   |    54 +
 lib/bx/gene_reader.py                              |   283 +
 lib/bx/interval_index_file.py                      |   503 +
 lib/bx/interval_index_file_tests.py                |    50 +
 lib/bx/intervals/__init__.py                       |     7 +
 lib/bx/intervals/cluster.c                         |  2615 +++
 lib/bx/intervals/cluster.pyx                       |   122 +
 lib/bx/intervals/cluster_tests.py                  |   103 +
 lib/bx/intervals/intersection.c                    |  8477 ++++++++++
 lib/bx/intervals/intersection.pyx                  |   488 +
 lib/bx/intervals/intersection_tests.py             |   219 +
 lib/bx/intervals/io.py                             |   224 +
 lib/bx/intervals/operations/__init__.py            |    39 +
 lib/bx/intervals/operations/base_coverage.py       |    29 +
 lib/bx/intervals/operations/complement.py          |    55 +
 lib/bx/intervals/operations/concat.py              |    61 +
 lib/bx/intervals/operations/coverage.py            |    72 +
 lib/bx/intervals/operations/find_clusters.py       |   162 +
 lib/bx/intervals/operations/intersect.py           |    77 +
 lib/bx/intervals/operations/join.py                |   137 +
 lib/bx/intervals/operations/merge.py               |    40 +
 lib/bx/intervals/operations/quicksect.py           |   155 +
 lib/bx/intervals/operations/subtract.py            |    72 +
 lib/bx/intervals/random_intervals.py               |   212 +
 lib/bx/intseq/__init__.py                          |     3 +
 lib/bx/intseq/ngramcount.c                         |  2711 +++
 lib/bx/intseq/ngramcount.pyx                       |    82 +
 lib/bx/misc/__init__.py                            |    13 +
 lib/bx/misc/_seekbzip2.c                           |  3194 ++++
 lib/bx/misc/_seekbzip2.pyx                         |   191 +
 lib/bx/misc/bgzf.c                                 |  2331 +++
 lib/bx/misc/bgzf.pyx                               |    36 +
 lib/bx/misc/bgzf_tests.py                          |     7 +
 lib/bx/misc/binary_file.py                         |   169 +
 lib/bx/misc/cdb.py                                 |   109 +
 lib/bx/misc/cdb_tests.py                           |    34 +
 lib/bx/misc/filecache.py                           |   105 +
 lib/bx/misc/filecache_tests.py                     |    30 +
 lib/bx/misc/readlengths.py                         |    29 +
 lib/bx/misc/seekbzip2.py                           |   148 +
 lib/bx/misc/seekbzip2_tests.py                     |    86 +
 lib/bx/misc/seeklzop.py                            |   167 +
 lib/bx/misc/seeklzop_tests.py                      |    30 +
 lib/bx/motif/__init__.py                           |     0
 lib/bx/motif/_pwm.c                                |  2250 +++
 lib/bx/motif/_pwm.pyx                              |    91 +
 lib/bx/motif/io/__init__.py                        |     0
 lib/bx/motif/io/transfac.py                        |   221 +
 lib/bx/motif/io/transfac_tests.py                  |    94 +
 lib/bx/motif/logo/__init__.py                      |    71 +
 lib/bx/motif/logo/template.ps                      |    62 +
 lib/bx/motif/pwm.py                                |   149 +
 lib/bx/motif/pwm_tests.py                          |    81 +
 lib/bx/phylo/__init__.py                           |     3 +
 lib/bx/phylo/newick.py                             |    98 +
 lib/bx/phylo/newick_tests.py                       |    33 +
 lib/bx/phylo/phast.py                              |    42 +
 lib/bx/phylo/phast_tests.py                        |    36 +
 lib/bx/pwm/__init__.py                             |     7 +
 lib/bx/pwm/_position_weight_matrix.c               |  1620 ++
 lib/bx/pwm/_position_weight_matrix.pyx             |     5 +
 lib/bx/pwm/bed_score_aligned_pwm.py                |    87 +
 lib/bx/pwm/bed_score_aligned_string.py             |    86 +
 lib/bx/pwm/maf_select_motifs.py                    |    69 +
 lib/bx/pwm/position_weight_matrix.py               |   849 +
 lib/bx/pwm/pwm_score_maf.py                        |   218 +
 lib/bx/pwm/pwm_score_motifs.py                     |    59 +
 lib/bx/pwm/pwm_score_positions.py                  |    63 +
 lib/bx/pwm/pwm_tests.py                            |    97 +
 lib/bx/seq/__init__.py                             |     7 +
 lib/bx/seq/_nib.c                                  |  1922 +++
 lib/bx/seq/_nib.pyx                                |    46 +
 lib/bx/seq/_twobit.c                               |  3010 ++++
 lib/bx/seq/_twobit.pyx                             |   123 +
 lib/bx/seq/core.py                                 |    64 +
 lib/bx/seq/fasta.py                                |   105 +
 lib/bx/seq/fasta_tests.py                          |    37 +
 lib/bx/seq/nib.py                                  |    84 +
 lib/bx/seq/nib_tests.py                            |    51 +
 lib/bx/seq/qdna.py                                 |   283 +
 lib/bx/seq/qdna_tests.py                           |    37 +
 lib/bx/seq/seq.py                                  |   135 +
 lib/bx/seq/seq_tests.py                            |    54 +
 lib/bx/seq/twobit.py                               |   126 +
 lib/bx/seq/twobit_tests.py                         |    48 +
 lib/bx/seqmapping.py                               |    94 +
 lib/bx/seqmapping_tests.py                         |    86 +
 lib/bx/tabular/__init__.py                         |     3 +
 lib/bx/tabular/io.py                               |   146 +
 lib/bx/wiggle.py                                   |    78 +
 lib/bx/wiggle_tests.py                             |    90 +
 lib/bx_extras/__init__.py                          |     0
 lib/bx_extras/fpconst.py                           |   163 +
 lib/bx_extras/lrucache.py                          |   230 +
 lib/bx_extras/pstat.py                             |  1062 ++
 lib/bx_extras/pyparsing.py                         |  3601 ++++
 lib/bx_extras/stats.py                             |  4344 +++++
 lib/psyco_full.py                                  |    14 +
 script_tests/base/__init__.py                      |   102 +
 script_tests/bnMapper_tests.py                     |    34 +
 script_tests/line_select_tests.py                  |    20 +
 script_tests/maf_extract_ranges_indexed_tests.py   |     7 +
 script_tests/out_to_chain_tests.py                 |     8 +
 scripts/aggregate_scores_in_intervals.py           |   126 +
 scripts/align_print_template.py                    |    47 +
 scripts/axt_extract_ranges.py                      |    68 +
 scripts/axt_to_fasta.py                            |    53 +
 scripts/axt_to_lav.py                              |   158 +
 scripts/axt_to_maf.py                              |   161 +
 scripts/bed_bigwig_profile.py                      |    33 +
 scripts/bed_build_windows.py                       |    54 +
 scripts/bed_complement.py                          |    50 +
 scripts/bed_count_by_interval.py                   |    29 +
 scripts/bed_count_overlapping.py                   |    29 +
 scripts/bed_coverage.py                            |    29 +
 scripts/bed_coverage_by_interval.py                |    55 +
 scripts/bed_diff_basewise_summary.py               |    44 +
 scripts/bed_extend_to.py                           |    36 +
 scripts/bed_intersect.py                           |    68 +
 scripts/bed_intersect_basewise.py                  |    40 +
 scripts/bed_merge_overlapping.py                   |    33 +
 scripts/bed_rand_intersect.py                      |   160 +
 scripts/bed_subtract_basewise.py                   |    43 +
 scripts/bnMapper.py                                |   262 +
 scripts/div_snp_table_chr.py                       |   146 +
 scripts/find_in_sorted_file.py                     |    77 +
 scripts/gene_fourfold_sites.py                     |   236 +
 scripts/get_scores_in_intervals.py                 |    59 +
 scripts/int_seqs_to_char_strings.py                |    24 +
 scripts/interval_count_intersections.py            |    50 +
 scripts/interval_join.py                           |    39 +
 scripts/lav_to_axt.py                              |    55 +
 scripts/lav_to_maf.py                              |    53 +
 scripts/line_select.py                             |    31 +
 scripts/lzop_build_offset_table.py                 |    90 +
 scripts/mMK_bitset.py                              |   150 +
 scripts/maf_build_index.py                         |    83 +
 scripts/maf_chop.py                                |    55 +
 scripts/maf_chunk.py                               |    80 +
 scripts/maf_col_counts.py                          |    38 +
 scripts/maf_col_counts_all.py                      |    64 +
 scripts/maf_count.py                               |    58 +
 scripts/maf_covered_ranges.py                      |    53 +
 scripts/maf_covered_regions.py                     |    56 +
 scripts/maf_div_sites.py                           |    55 +
 scripts/maf_drop_overlapping.py                    |    56 +
 scripts/maf_extract_chrom_ranges.py                |    91 +
 scripts/maf_extract_ranges.py                      |    73 +
 scripts/maf_extract_ranges_indexed.py              |   114 +
 scripts/maf_filter.py                              |    52 +
 scripts/maf_filter_max_wc.py                       |    40 +
 scripts/maf_gap_frequency.py                       |    23 +
 scripts/maf_gc_content.py                          |    32 +
 scripts/maf_interval_alignibility.py               |   111 +
 scripts/maf_limit_to_species.py                    |    40 +
 scripts/maf_mapping_word_frequency.py              |    58 +
 scripts/maf_mask_cpg.py                            |    40 +
 scripts/maf_mean_length_ungapped_piece.py          |    34 +
 scripts/maf_percent_columns_matching.py            |    38 +
 scripts/maf_percent_identity.py                    |    41 +
 scripts/maf_print_chroms.py                        |    37 +
 scripts/maf_print_scores.py                        |    57 +
 scripts/maf_randomize.py                           |    35 +
 scripts/maf_region_coverage_by_src.py              |    68 +
 scripts/maf_select.py                              |    35 +
 scripts/maf_shuffle_columns.py                     |    29 +
 scripts/maf_species_in_all_files.py                |    26 +
 scripts/maf_split_by_src.py                        |    60 +
 scripts/maf_thread_for_species.py                  |    55 +
 scripts/maf_tile.py                                |   138 +
 scripts/maf_tile_2.py                              |   274 +
 scripts/maf_tile_2bit.py                           |   268 +
 scripts/maf_to_axt.py                              |   110 +
 scripts/maf_to_concat_fasta.py                     |    61 +
 scripts/maf_to_fasta.py                            |    42 +
 scripts/maf_to_int_seqs.py                         |    40 +
 scripts/maf_translate_chars.py                     |    39 +
 scripts/maf_truncate.py                            |    40 +
 scripts/maf_word_frequency.py                      |    47 +
 scripts/mask_quality.py                            |    98 +
 scripts/nib_chrom_intervals_to_fasta.py            |    47 +
 scripts/nib_intervals_to_fasta.py                  |    41 +
 scripts/nib_length.py                              |    13 +
 scripts/one_field_per_line.py                      |    14 +
 scripts/out_to_chain.py                            |    70 +
 scripts/prefix_lines.py                            |     9 +
 scripts/pretty_table.py                            |    44 +
 scripts/qv_to_bqv.py                               |    69 +
 scripts/random_lines.py                            |    16 +
 scripts/table_add_column.py                        |    46 +
 scripts/table_filter.py                            |    72 +
 scripts/tfloc_summary.py                           |    27 +
 scripts/ucsc_gene_table_to_intervals.py            |    76 +
 scripts/wiggle_to_array_tree.py                    |    37 +
 scripts/wiggle_to_binned_array.py                  |    54 +
 scripts/wiggle_to_chr_binned_array.py              |    42 +
 scripts/wiggle_to_simple.py                        |    24 +
 setup.cfg                                          |    17 +
 setup.py                                           |   231 +
 src/binBits.c                                      |   317 +
 src/binBits.h                                      |    28 +
 src/bunzip/micro-bunzip.c                          |   705 +
 src/bunzip/micro-bunzip.h                          |    77 +
 src/cluster.c                                      |   267 +
 src/cluster.h                                      |    39 +
 src/kent/bits.c                                    |   279 +
 src/kent/bits.h                                    |    72 +
 src/kent/common.c                                  |    62 +
 src/kent/common.h                                  |    32 +
 src/pwm_utils.c                                    |    63 +
 src/pwm_utils.h                                    |     3 +
 src/samtools/bgzf.c                                |   693 +
 src/samtools/bgzf.h                                |   142 +
 src/samtools/khash.h                               |   486 +
 test_data/bbi_tests/make_expectation.sh            |    11 +
 test_data/bbi_tests/test.bw                        |   Bin 0 -> 74982 bytes
 test_data/bbi_tests/test.expectation               |    24 +
 test_data/bbi_tests/test.regions                   |     6 +
 test_data/bbi_tests/test.wig                       |  9992 +++++++++++
 test_data/bgzf_tests/test.txt                      |    20 +
 test_data/bgzf_tests/test.txt.gz                   |   Bin 0 -> 991 bytes
 .../epo_tests/epo_547_hs_mm_12way_mammals_65.chain |  1705 ++
 .../epo_tests/epo_547_hs_mm_12way_mammals_65.out   |    10 +
 test_data/epo_tests/hg19.chrom.sizes               |    93 +
 test_data/epo_tests/hg19.mm9.rBest.chain.gz        |   Bin 0 -> 1212215 bytes
 test_data/epo_tests/hg19_one_peak.bed              |     1 +
 test_data/epo_tests/hg19_one_peak.mapped.bed       |     1 +
 test_data/epo_tests/hpeaks.bed                     |     5 +
 test_data/epo_tests/hpeaks.mapped.bed12            |     3 +
 test_data/epo_tests/hpeaks.mapped.bed4             |     5 +
 test_data/epo_tests/hpeaks.mapped.nopeak2.bed4     |     2 +
 test_data/epo_tests/mm9.chrom.sizes                |    35 +
 test_data/lav_tests/apple.fa                       |    10 +
 test_data/lav_tests/apple_orange.lav               |    55 +
 test_data/lav_tests/orange.fa                      |     9 +
 test_data/lav_tests/orange.nib                     |   Bin 0 -> 189 bytes
 test_data/maf_tests/dcking_ghp074.bed              |     1 +
 test_data/maf_tests/dcking_ghp074.maf              |    64 +
 test_data/maf_tests/mm8_chr7_tiny.maf              |    76 +
 test_data/maf_tests/mm8_chr7_tiny.maf.index        |   Bin 0 -> 82841 bytes
 test_data/seq_tests/test.2bit                      |   Bin 0 -> 144 bytes
 test_data/seq_tests/test.fa                        |    11 +
 test_data/seq_tests/test.nib                       |   Bin 0 -> 198 bytes
 test_data/seq_tests/test.qdna                      |   Bin 0 -> 411 bytes
 test_data/seq_tests/test2.fa                       |     9 +
 test_data/seq_tests/testMask.2bit                  |   Bin 0 -> 236 bytes
 test_data/seq_tests/testMask.fa                    |    10 +
 test_data/seq_tests/testN.2bit                     |   Bin 0 -> 127 bytes
 test_data/seq_tests/testN.fa                       |     4 +
 333 files changed, 170801 insertions(+)

diff --git a/.hg_archival.txt b/.hg_archival.txt
new file mode 100644
index 0000000..b52ef42
--- /dev/null
+++ b/.hg_archival.txt
@@ -0,0 +1,6 @@
+repo: 075807ec108016807156d50f8618799cb107c128
+node: da37e3aa45dc610ab4fc2f60949de90f93f84401
+branch: default
+latesttag: bnMapper freeze
+latesttagdistance: 9
+changessincelatesttag: 11
diff --git a/.hgignore b/.hgignore
new file mode 100644
index 0000000..b619417
--- /dev/null
+++ b/.hgignore
@@ -0,0 +1,23 @@
+syntax: glob
+
+# Build directory
+build
+
+# Python bytecode
+*.pyc
+
+# Object files
+*.so
+*.pyd
+
+# egg-info for inplace builds
+bx_python.egg-info
+
+# IDE project files
+*.kpf
+
+# windows shortcuts
+*.lnk
+
+# nose egg
+nose*.egg
diff --git a/.hgtags b/.hgtags
new file mode 100644
index 0000000..a02cc1b
--- /dev/null
+++ b/.hgtags
@@ -0,0 +1 @@
+83b6d153f88995ad6e223391281b4442e1f38f5a bnMapper freeze
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..3014db2
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,20 @@
+Copyright (c) 2005-2015 The Pennsylvania State University
+Copyright (c) 2013-2015 The Johns Hopkins University
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/MANIFEST.in b/MANIFEST.in
new file mode 100644
index 0000000..15100ca
--- /dev/null
+++ b/MANIFEST.in
@@ -0,0 +1,7 @@
+include distribute_setup.py
+include LICENSE
+recursive-include src *.h
+recursive-include src *.c
+recursive-include lib *.h
+recursive-include lib *.c
+recursive-include lib *.pyx
diff --git a/distribute_setup.py b/distribute_setup.py
new file mode 100644
index 0000000..a447f7e
--- /dev/null
+++ b/distribute_setup.py
@@ -0,0 +1,546 @@
+#!python
+"""Bootstrap distribute installation
+
+If you want to use setuptools in your package's setup.py, just include this
+file in the same directory with it, and add this to the top of your setup.py::
+
+    from distribute_setup import use_setuptools
+    use_setuptools()
+
+If you want to require a specific version of setuptools, set a download
+mirror, or use an alternate download directory, you can do so by supplying
+the appropriate options to ``use_setuptools()``.
+
+This file can also be run as a script to install or upgrade setuptools.
+"""
+import os
+import shutil
+import sys
+import time
+import fnmatch
+import tempfile
+import tarfile
+import optparse
+
+from distutils import log
+
+try:
+    from site import USER_SITE
+except ImportError:
+    USER_SITE = None
+
+try:
+    import subprocess
+
+    def _python_cmd(*args):
+        args = (sys.executable,) + args
+        return subprocess.call(args) == 0
+
+except ImportError:
+    # will be used for python 2.3
+    def _python_cmd(*args):
+        args = (sys.executable,) + args
+        # quoting arguments if windows
+        if sys.platform == 'win32':
+            def quote(arg):
+                if ' ' in arg:
+                    return '"%s"' % arg
+                return arg
+            args = [quote(arg) for arg in args]
+        return os.spawnl(os.P_WAIT, sys.executable, *args) == 0
+
+DEFAULT_VERSION = "0.6.35"
+DEFAULT_URL = "http://pypi.python.org/packages/source/d/distribute/"
+SETUPTOOLS_FAKED_VERSION = "0.6c11"
+
+SETUPTOOLS_PKG_INFO = """\
+Metadata-Version: 1.0
+Name: setuptools
+Version: %s
+Summary: xxxx
+Home-page: xxx
+Author: xxx
+Author-email: xxx
+License: xxx
+Description: xxx
+""" % SETUPTOOLS_FAKED_VERSION
+
+
+def _install(tarball, install_args=()):
+    # extracting the tarball
+    tmpdir = tempfile.mkdtemp()
+    log.warn('Extracting in %s', tmpdir)
+    old_wd = os.getcwd()
+    try:
+        os.chdir(tmpdir)
+        tar = tarfile.open(tarball)
+        _extractall(tar)
+        tar.close()
+
+        # going in the directory
+        subdir = os.path.join(tmpdir, os.listdir(tmpdir)[0])
+        os.chdir(subdir)
+        log.warn('Now working in %s', subdir)
+
+        # installing
+        log.warn('Installing Distribute')
+        if not _python_cmd('setup.py', 'install', *install_args):
+            log.warn('Something went wrong during the installation.')
+            log.warn('See the error message above.')
+            # exitcode will be 2
+            return 2
+    finally:
+        os.chdir(old_wd)
+        shutil.rmtree(tmpdir)
+
+
+def _build_egg(egg, tarball, to_dir):
+    # extracting the tarball
+    tmpdir = tempfile.mkdtemp()
+    log.warn('Extracting in %s', tmpdir)
+    old_wd = os.getcwd()
+    try:
+        os.chdir(tmpdir)
+        tar = tarfile.open(tarball)
+        _extractall(tar)
+        tar.close()
+
+        # going in the directory
+        subdir = os.path.join(tmpdir, os.listdir(tmpdir)[0])
+        os.chdir(subdir)
+        log.warn('Now working in %s', subdir)
+
+        # building an egg
+        log.warn('Building a Distribute egg in %s', to_dir)
+        _python_cmd('setup.py', '-q', 'bdist_egg', '--dist-dir', to_dir)
+
+    finally:
+        os.chdir(old_wd)
+        shutil.rmtree(tmpdir)
+    # returning the result
+    log.warn(egg)
+    if not os.path.exists(egg):
+        raise IOError('Could not build the egg.')
+
+
+def _do_download(version, download_base, to_dir, download_delay):
+    egg = os.path.join(to_dir, 'distribute-%s-py%d.%d.egg'
+                       % (version, sys.version_info[0], sys.version_info[1]))
+    if not os.path.exists(egg):
+        tarball = download_setuptools(version, download_base,
+                                      to_dir, download_delay)
+        _build_egg(egg, tarball, to_dir)
+    sys.path.insert(0, egg)
+    import setuptools
+    setuptools.bootstrap_install_from = egg
+
+
+def use_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL,
+                   to_dir=os.curdir, download_delay=15, no_fake=True):
+    # making sure we use the absolute path
+    to_dir = os.path.abspath(to_dir)
+    was_imported = 'pkg_resources' in sys.modules or \
+        'setuptools' in sys.modules
+    try:
+        try:
+            import pkg_resources
+            if not hasattr(pkg_resources, '_distribute'):
+                if not no_fake:
+                    _fake_setuptools()
+                raise ImportError
+        except ImportError:
+            return _do_download(version, download_base, to_dir, download_delay)
+        try:
+            pkg_resources.require("distribute>=" + version)
+            return
+        except pkg_resources.VersionConflict:
+            e = sys.exc_info()[1]
+            if was_imported:
+                sys.stderr.write(
+                "The required version of distribute (>=%s) is not available,\n"
+                "and can't be installed while this script is running. Please\n"
+                "install a more recent version first, using\n"
+                "'easy_install -U distribute'."
+                "\n\n(Currently using %r)\n" % (version, e.args[0]))
+                sys.exit(2)
+            else:
+                del pkg_resources, sys.modules['pkg_resources']    # reload ok
+                return _do_download(version, download_base, to_dir,
+                                    download_delay)
+        except pkg_resources.DistributionNotFound:
+            return _do_download(version, download_base, to_dir,
+                                download_delay)
+    finally:
+        if not no_fake:
+            _create_fake_setuptools_pkg_info(to_dir)
+
+
+def download_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL,
+                        to_dir=os.curdir, delay=15):
+    """Download distribute from a specified location and return its filename
+
+    `version` should be a valid distribute version number that is available
+    as an egg for download under the `download_base` URL (which should end
+    with a '/'). `to_dir` is the directory where the egg will be downloaded.
+    `delay` is the number of seconds to pause before an actual download
+    attempt.
+    """
+    # making sure we use the absolute path
+    to_dir = os.path.abspath(to_dir)
+    try:
+        from urllib.request import urlopen
+    except ImportError:
+        from urllib2 import urlopen
+    tgz_name = "distribute-%s.tar.gz" % version
+    url = download_base + tgz_name
+    saveto = os.path.join(to_dir, tgz_name)
+    src = dst = None
+    if not os.path.exists(saveto):  # Avoid repeated downloads
+        try:
+            log.warn("Downloading %s", url)
+            src = urlopen(url)
+            # Read/write all in one block, so we don't create a corrupt file
+            # if the download is interrupted.
+            data = src.read()
+            dst = open(saveto, "wb")
+            dst.write(data)
+        finally:
+            if src:
+                src.close()
+            if dst:
+                dst.close()
+    return os.path.realpath(saveto)
+
+
+def _no_sandbox(function):
+    def __no_sandbox(*args, **kw):
+        try:
+            from setuptools.sandbox import DirectorySandbox
+            if not hasattr(DirectorySandbox, '_old'):
+                def violation(*args):
+                    pass
+                DirectorySandbox._old = DirectorySandbox._violation
+                DirectorySandbox._violation = violation
+                patched = True
+            else:
+                patched = False
+        except ImportError:
+            patched = False
+
+        try:
+            return function(*args, **kw)
+        finally:
+            if patched:
+                DirectorySandbox._violation = DirectorySandbox._old
+                del DirectorySandbox._old
+
+    return __no_sandbox
+
+
+def _patch_file(path, content):
+    """Will backup the file then patch it"""
+    f = open(path)
+    existing_content = f.read()
+    f.close()
+    if existing_content == content:
+        # already patched
+        log.warn('Already patched.')
+        return False
+    log.warn('Patching...')
+    _rename_path(path)
+    f = open(path, 'w')
+    try:
+        f.write(content)
+    finally:
+        f.close()
+    return True
+
+_patch_file = _no_sandbox(_patch_file)
+
+
+def _same_content(path, content):
+    f = open(path)
+    existing_content = f.read()
+    f.close()
+    return existing_content == content
+
+
+def _rename_path(path):
+    new_name = path + '.OLD.%s' % time.time()
+    log.warn('Renaming %s to %s', path, new_name)
+    os.rename(path, new_name)
+    return new_name
+
+
+def _remove_flat_installation(placeholder):
+    if not os.path.isdir(placeholder):
+        log.warn('Unkown installation at %s', placeholder)
+        return False
+    found = False
+    for file in os.listdir(placeholder):
+        if fnmatch.fnmatch(file, 'setuptools*.egg-info'):
+            found = True
+            break
+    if not found:
+        log.warn('Could not locate setuptools*.egg-info')
+        return
+
+    log.warn('Moving elements out of the way...')
+    pkg_info = os.path.join(placeholder, file)
+    if os.path.isdir(pkg_info):
+        patched = _patch_egg_dir(pkg_info)
+    else:
+        patched = _patch_file(pkg_info, SETUPTOOLS_PKG_INFO)
+
+    if not patched:
+        log.warn('%s already patched.', pkg_info)
+        return False
+    # now let's move the files out of the way
+    for element in ('setuptools', 'pkg_resources.py', 'site.py'):
+        element = os.path.join(placeholder, element)
+        if os.path.exists(element):
+            _rename_path(element)
+        else:
+            log.warn('Could not find the %s element of the '
+                     'Setuptools distribution', element)
+    return True
+
+_remove_flat_installation = _no_sandbox(_remove_flat_installation)
+
+
+def _after_install(dist):
+    log.warn('After install bootstrap.')
+    placeholder = dist.get_command_obj('install').install_purelib
+    _create_fake_setuptools_pkg_info(placeholder)
+
+
+def _create_fake_setuptools_pkg_info(placeholder):
+    if not placeholder or not os.path.exists(placeholder):
+        log.warn('Could not find the install location')
+        return
+    pyver = '%s.%s' % (sys.version_info[0], sys.version_info[1])
+    setuptools_file = 'setuptools-%s-py%s.egg-info' % \
+            (SETUPTOOLS_FAKED_VERSION, pyver)
+    pkg_info = os.path.join(placeholder, setuptools_file)
+    if os.path.exists(pkg_info):
+        log.warn('%s already exists', pkg_info)
+        return
+
+    log.warn('Creating %s', pkg_info)
+    try:
+        f = open(pkg_info, 'w')
+    except EnvironmentError:
+        log.warn("Don't have permissions to write %s, skipping", pkg_info)
+        return
+    try:
+        f.write(SETUPTOOLS_PKG_INFO)
+    finally:
+        f.close()
+
+    pth_file = os.path.join(placeholder, 'setuptools.pth')
+    log.warn('Creating %s', pth_file)
+    f = open(pth_file, 'w')
+    try:
+        f.write(os.path.join(os.curdir, setuptools_file))
+    finally:
+        f.close()
+
+_create_fake_setuptools_pkg_info = _no_sandbox(
+    _create_fake_setuptools_pkg_info
+)
+
+
+def _patch_egg_dir(path):
+    # let's check if it's already patched
+    pkg_info = os.path.join(path, 'EGG-INFO', 'PKG-INFO')
+    if os.path.exists(pkg_info):
+        if _same_content(pkg_info, SETUPTOOLS_PKG_INFO):
+            log.warn('%s already patched.', pkg_info)
+            return False
+    _rename_path(path)
+    os.mkdir(path)
+    os.mkdir(os.path.join(path, 'EGG-INFO'))
+    pkg_info = os.path.join(path, 'EGG-INFO', 'PKG-INFO')
+    f = open(pkg_info, 'w')
+    try:
+        f.write(SETUPTOOLS_PKG_INFO)
+    finally:
+        f.close()
+    return True
+
+_patch_egg_dir = _no_sandbox(_patch_egg_dir)
+
+
+def _before_install():
+    log.warn('Before install bootstrap.')
+    _fake_setuptools()
+
+
+def _under_prefix(location):
+    if 'install' not in sys.argv:
+        return True
+    args = sys.argv[sys.argv.index('install') + 1:]
+    for index, arg in enumerate(args):
+        for option in ('--root', '--prefix'):
+            if arg.startswith('%s=' % option):
+                top_dir = arg.split('root=')[-1]
+                return location.startswith(top_dir)
+            elif arg == option:
+                if len(args) > index:
+                    top_dir = args[index + 1]
+                    return location.startswith(top_dir)
+        if arg == '--user' and USER_SITE is not None:
+            return location.startswith(USER_SITE)
+    return True
+
+
+def _fake_setuptools():
+    log.warn('Scanning installed packages')
+    try:
+        import pkg_resources
+    except ImportError:
+        # we're cool
+        log.warn('Setuptools or Distribute does not seem to be installed.')
+        return
+    ws = pkg_resources.working_set
+    try:
+        setuptools_dist = ws.find(
+            pkg_resources.Requirement.parse('setuptools', replacement=False)
+            )
+    except TypeError:
+        # old distribute API
+        setuptools_dist = ws.find(
+            pkg_resources.Requirement.parse('setuptools')
+        )
+
+    if setuptools_dist is None:
+        log.warn('No setuptools distribution found')
+        return
+    # detecting if it was already faked
+    setuptools_location = setuptools_dist.location
+    log.warn('Setuptools installation detected at %s', setuptools_location)
+
+    # if --root or --preix was provided, and if
+    # setuptools is not located in them, we don't patch it
+    if not _under_prefix(setuptools_location):
+        log.warn('Not patching, --root or --prefix is installing Distribute'
+                 ' in another location')
+        return
+
+    # let's see if its an egg
+    if not setuptools_location.endswith('.egg'):
+        log.warn('Non-egg installation')
+        res = _remove_flat_installation(setuptools_location)
+        if not res:
+            return
+    else:
+        log.warn('Egg installation')
+        pkg_info = os.path.join(setuptools_location, 'EGG-INFO', 'PKG-INFO')
+        if (os.path.exists(pkg_info) and
+            _same_content(pkg_info, SETUPTOOLS_PKG_INFO)):
+            log.warn('Already patched.')
+            return
+        log.warn('Patching...')
+        # let's create a fake egg replacing setuptools one
+        res = _patch_egg_dir(setuptools_location)
+        if not res:
+            return
+    log.warn('Patching complete.')
+    _relaunch()
+
+
+def _relaunch():
+    log.warn('Relaunching...')
+    # we have to relaunch the process
+    # pip marker to avoid a relaunch bug
+    _cmd1 = ['-c', 'install', '--single-version-externally-managed']
+    _cmd2 = ['-c', 'install', '--record']
+    if sys.argv[:3] == _cmd1 or sys.argv[:3] == _cmd2:
+        sys.argv[0] = 'setup.py'
+    args = [sys.executable] + sys.argv
+    sys.exit(subprocess.call(args))
+
+
+def _extractall(self, path=".", members=None):
+    """Extract all members from the archive to the current working
+       directory and set owner, modification time and permissions on
+       directories afterwards. `path' specifies a different directory
+       to extract to. `members' is optional and must be a subset of the
+       list returned by getmembers().
+    """
+    import copy
+    import operator
+    from tarfile import ExtractError
+    directories = []
+
+    if members is None:
+        members = self
+
+    for tarinfo in members:
+        if tarinfo.isdir():
+            # Extract directories with a safe mode.
+            directories.append(tarinfo)
+            tarinfo = copy.copy(tarinfo)
+            tarinfo.mode = 448  # decimal for oct 0700
+        self.extract(tarinfo, path)
+
+    # Reverse sort directories.
+    if sys.version_info < (2, 4):
+        def sorter(dir1, dir2):
+            return cmp(dir1.name, dir2.name)
+        directories.sort(sorter)
+        directories.reverse()
+    else:
+        directories.sort(key=operator.attrgetter('name'), reverse=True)
+
+    # Set correct owner, mtime and filemode on directories.
+    for tarinfo in directories:
+        dirpath = os.path.join(path, tarinfo.name)
+        try:
+            self.chown(tarinfo, dirpath)
+            self.utime(tarinfo, dirpath)
+            self.chmod(tarinfo, dirpath)
+        except ExtractError:
+            e = sys.exc_info()[1]
+            if self.errorlevel > 1:
+                raise
+            else:
+                self._dbg(1, "tarfile: %s" % e)
+
+
+def _build_install_args(options):
+    """
+    Build the arguments to 'python setup.py install' on the distribute package
+    """
+    install_args = []
+    if options.user_install:
+        if sys.version_info < (2, 6):
+            log.warn("--user requires Python 2.6 or later")
+            raise SystemExit(1)
+        install_args.append('--user')
+    return install_args
+
+def _parse_args():
+    """
+    Parse the command line for options
+    """
+    parser = optparse.OptionParser()
+    parser.add_option(
+        '--user', dest='user_install', action='store_true', default=False,
+        help='install in user site package (requires Python 2.6 or later)')
+    parser.add_option(
+        '--download-base', dest='download_base', metavar="URL",
+        default=DEFAULT_URL,
+        help='alternative URL from where to download the distribute package')
+    options, args = parser.parse_args()
+    # positional arguments are ignored
+    return options
+
+def main(version=DEFAULT_VERSION):
+    """Install or upgrade setuptools and EasyInstall"""
+    options = _parse_args()
+    tarball = download_setuptools(download_base=options.download_base)
+    return _install(tarball, _build_install_args(options))
+
+if __name__ == '__main__':
+    sys.exit(main())
diff --git a/doc/Makefile b/doc/Makefile
new file mode 100644
index 0000000..7abd1c5
--- /dev/null
+++ b/doc/Makefile
@@ -0,0 +1,83 @@
+# Makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line.
+SPHINXOPTS    =
+SPHINXBUILD   = sphinx-build
+PAPER         =
+
+# Internal variables.
+PAPEROPT_a4     = -D latex_paper_size=a4
+PAPEROPT_letter = -D latex_paper_size=letter
+ALLSPHINXOPTS   = -d build/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
+
+.PHONY: help clean html web pickle htmlhelp latex changes linkcheck
+
+help:
+	@echo "Please use \`make <target>' where <target> is one of"
+	@echo "  html      to make standalone HTML files"
+	@echo "  apidoc    to run epydoc" 
+	@echo "  pickle    to make pickle files"
+	@echo "  json      to make JSON files"
+	@echo "  htmlhelp  to make HTML files and a HTML help project"
+	@echo "  latex     to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
+	@echo "  changes   to make an overview over all changed/added/deprecated items"
+	@echo "  linkcheck to check all external links for integrity"
+
+clean:
+	-rm -rf docbuild/*
+
+html:
+	mkdir -p build/html build/doctrees
+	$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) docbuild/html
+	@echo
+	@echo "Build finished. The HTML pages are in docbuild/html."
+
+apidoc:
+	mkdir -p build/html/apidoc
+	epydoc-2.6 --docformat restructuredtext ../lib/bx -o docbuild/html/apidoc
+	@echo
+	@echo "Epydoc finished. The pages are in docbuild/html/apidoc."
+
+
+pickle:
+	mkdir -p build/pickle build/doctrees
+	$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) docbuild/pickle
+	@echo
+	@echo "Build finished; now you can process the pickle files."
+
+web: pickle
+
+json:
+	mkdir -p build/json build/doctrees
+	$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) docbuild/json
+	@echo
+	@echo "Build finished; now you can process the JSON files."
+
+htmlhelp:
+	mkdir -p build/htmlhelp build/doctrees
+	$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) docbuild/htmlhelp
+	@echo
+	@echo "Build finished; now you can run HTML Help Workshop with the" \
+	      ".hhp project file in build/htmlhelp."
+
+latex:
+	mkdir -p build/latex build/doctrees
+	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) docbuild/latex
+	@echo
+	@echo "Build finished; the LaTeX files are in build/latex."
+	@echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \
+	      "run these through (pdf)latex."
+
+changes:
+	mkdir -p build/changes build/doctrees
+	$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) docbuild/changes
+	@echo
+	@echo "The overview file is in build/changes."
+
+linkcheck:
+	mkdir -p build/linkcheck build/doctrees
+	$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) docbuild/linkcheck
+	@echo
+	@echo "Link check complete; look for any errors in the above output " \
+	      "or in build/linkcheck/output.txt."
diff --git a/doc/source/conf.py b/doc/source/conf.py
new file mode 100644
index 0000000..a3b9595
--- /dev/null
+++ b/doc/source/conf.py
@@ -0,0 +1,202 @@
+# -*- coding: utf-8 -*-
+#
+# BxPython documentation build configuration file, created by
+# sphinx-quickstart on Fri May 08 10:18:22 2009.
+#
+# This file is execfile()d with the current directory set to its containing dir.
+#
+# The contents of this file are pickled, so don't put values in the namespace
+# that aren't pickleable (module imports are okay, they're removed automatically).
+#
+# Note that not all possible configuration values are present in this
+# autogenerated file.
+#
+# All configuration values have a default; values that are commented out
+# serve to show the default.
+
+import sys, os
+
+# If your extensions are in another directory, add it here. If the directory
+# is relative to the documentation root, use os.path.abspath to make it
+# absolute, like shown here.
+#sys.path.append(os.path.abspath('.'))
+curr_dir = os.path.dirname( __file__ )
+bx_dir = os.path.join( curr_dir, '..', '..', 'lib')
+sys.path.insert( 0, bx_dir )
+import bx
+
+# General configuration
+# ---------------------
+
+# Add any Sphinx extension module names here, as strings. They can be extensions
+# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
+extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.intersphinx']
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['templates']
+
+# The suffix of source filenames.
+source_suffix = '.rst'
+
+# The encoding of source files.
+#source_encoding = 'utf-8'
+
+# The master toctree document.
+master_doc = 'index'
+
+# General information about the project.
+project = u'bx-python'
+copyright = u'2009, James Taylor'
+
+# The version info for the project you're documenting, acts as replacement for
+# |version| and |release|, also used in various other places throughout the
+# built documents.
+#
+# The short X.Y version.
+version = bx.__version__
+
+# The full version, including alpha/beta/rc tags.
+release = version
+
+# The language for content autogenerated by Sphinx. Refer to documentation
+# for a list of supported languages.
+#language = None
+
+# There are two options for replacing |today|: either, you set today to some
+# non-false value, then it is used:
+#today = ''
+# Else, today_fmt is used as the format for a strftime call.
+#today_fmt = '%B %d, %Y'
+
+# List of documents that shouldn't be included in the build.
+#unused_docs = []
+
+# List of directories, relative to source directory, that shouldn't be searched
+# for source files.
+exclude_trees = []
+
+# The reST default role (used for this markup: `text`) to use for all documents.
+#default_role = None
+
+# If true, '()' will be appended to :func: etc. cross-reference text.
+#add_function_parentheses = True
+
+# If true, the current module name will be prepended to all description
+# unit titles (such as .. function::).
+#add_module_names = True
+
+# If true, sectionauthor and moduleauthor directives will be shown in the
+# output. They are ignored by default.
+#show_authors = False
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'sphinx'
+
+
+# Options for HTML output
+# -----------------------
+
+# The style sheet to use for HTML and HTML Help pages. A file of that name
+# must exist either in Sphinx' static/ path, or in one of the custom paths
+# given in html_static_path.
+html_style = 'base.css'
+
+# The name for this set of Sphinx documents.  If None, it defaults to
+# "<project> v<release> documentation".
+#html_title = None
+
+# A shorter title for the navigation bar.  Default is the same as html_title.
+#html_short_title = None
+
+# The name of an image file (relative to this directory) to place at the top
+# of the sidebar.
+#html_logo = None
+
+# The name of an image file (within the static path) to use as favicon of the
+# docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32
+# pixels large.
+#html_favicon = None
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+html_static_path = ['static']
+
+# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
+# using the given strftime format.
+#html_last_updated_fmt = '%b %d, %Y'
+
+# If true, SmartyPants will be used to convert quotes and dashes to
+# typographically correct entities.
+#html_use_smartypants = True
+
+# Custom sidebar templates, maps document names to template names.
+html_index = 'index.html'
+html_sidebars = { 'index': 'indexsidebar.html'}
+
+# Additional templates that should be rendered to pages, maps page names to
+# template names.
+##html_additional_pages = {
+##    'index': 'index.html',
+##}
+
+# If false, no module index is generated.
+#html_use_modindex = True
+
+# If false, no index is generated.
+#html_use_index = True
+
+# If true, the index is split into individual pages for each letter.
+#html_split_index = False
+
+# If true, the reST sources are included in the HTML build as _sources/<name>.
+#html_copy_source = True
+
+# If true, an OpenSearch description file will be output, and all pages will
+# contain a <link> tag referring to it.  The value of this option must be the
+# base URL from which the finished HTML is served.
+#html_use_opensearch = ''
+
+# If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml").
+#html_file_suffix = ''
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = 'bx-doc'
+
+
+# Options for LaTeX output
+# ------------------------
+
+# The paper size ('letter' or 'a4').
+#latex_paper_size = 'letter'
+
+# The font size ('10pt', '11pt' or '12pt').
+#latex_font_size = '10pt'
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title, author, document class [howto/manual]).
+latex_documents = [
+  ('index', 'bx-python.tex', ur'bx-python Documentation',
+   ur'James Taylor', 'manual'),
+]
+
+# The name of an image file (relative to this directory) to place at the top of
+# the title page.
+#latex_logo = None
+
+# For "manual" documents, if this is true, then toplevel headings are parts,
+# not chapters.
+#latex_use_parts = False
+
+# Additional stuff for the LaTeX preamble.
+#latex_preamble = ''
+
+# Documents to append as an appendix to all manuals.
+#latex_appendices = []
+
+# If false, no module index is generated.
+#latex_use_modindex = True
+
+
+# Example configuration for intersphinx: refer to the Python standard library.
+#intersphinx_mapping = {'http://docs.python.org/dev': None}
diff --git a/doc/source/contents.rst b/doc/source/contents.rst
new file mode 100644
index 0000000..c0d48d2
--- /dev/null
+++ b/doc/source/contents.rst
@@ -0,0 +1,18 @@
+
+
+bx-python documentation contents
+================================
+
+Browse the Python API `class documentation <apidoc/index.html>`_ 
+
+Contents:
+
+.. toctree::
+   :maxdepth: 2
+
+   modules/index.rst 
+
+* :ref:`genindex`
+* :ref:`modindex`
+* :ref:`search`
+
diff --git a/doc/source/index.rst b/doc/source/index.rst
new file mode 100644
index 0000000..01a1507
--- /dev/null
+++ b/doc/source/index.rst
@@ -0,0 +1,28 @@
+About bx-python
+===============
+
+The bx-python project is a python library and associated set of scripts to allow for rapid implementation of genome scale analyses. The library contains a variety of useful modules, but the particular strengths are:
+
+ * Classes for reading and working with genome-scale multiple local alignments (in MAF, AXT, and LAV formats)
+ * Generic data structure for indexing on disk files that contain blocks of data associated with intervals on various sequences (used, for example, to provide random access to individual alignments in huge files; optomized for use over network filesystems)
+ * Data structures for working with intervals on sequences
+ * "Binned bitsets" which act just like chromosome sized bit arrays, but lazily allocate regions and allow large blocks of all set or all unset bits to be stored compactly
+ * "Intersecter" for performing fast intersection tests that preserve both query and target intervals and associated annotation 
+
+These tools have been used in a variety of published research, and are a fundamental part of the ongoing Galaxy and ESPERR projects.
+
+Contents
+========
+
+.. toctree::
+   :maxdepth: 2
+
+   modules/index.rst
+
+Indices and tables
+==================
+
+* :ref:`genindex`
+* :ref:`modindex`
+* :ref:`search`
+
diff --git a/doc/source/static/base.css b/doc/source/static/base.css
new file mode 100644
index 0000000..e8dbe6a
--- /dev/null
+++ b/doc/source/static/base.css
@@ -0,0 +1,152 @@
+ at import url(tripoli.base.css);
+
+html {
+    font-family: 'Verdana', sans-serif;
+    color: #333333;
+}
+body {
+    padding: 3em 3em;
+}
+
+h1.pageheader {
+    font-variant: small-caps;
+    margin-top: 0;
+    border-top: solid 1px;
+    padding-top: 2px;
+    border-bottom: solid 1px;
+    border-color: #CCCCCC;
+    margin-bottom: 1em;
+}
+
+h1.pageheader a {
+    color: inherit;
+    text-decoration: inherit;
+    border: none;
+}
+
+.content h1, .content h2, .content h3, .content h4, .content h5, .content h6 {
+    font-family: 'Hoefler Text', 'Georgia', serif;
+    font-weight: normal;
+    color: #666666;
+    /* border-bottom: solid #666666 1px; */
+}
+
+.content h1.pagetitle {
+    color: #c33;
+}
+
+#main {
+}
+
+.colpad {
+    padding: 0 2em;
+}
+
+#main > .inner {
+    min-width: 70em;
+    max-width: 90em;
+    margin: auto;
+    height: 100%;
+}
+
+#left {
+    background: white;
+    margin-right: 36%; /* 31em; */
+    padding-right: 3%;
+    height: 100%;
+}
+
+#right {
+    float: right;
+    width: 33%; /* 28em; */
+    padding-left: 3%; 
+    border-left: solid #CCCCCC 1px;
+}
+
+.sidebar {
+    font-size: 1em;
+}
+
+.sidebar ul {
+    margin-left: 0;
+}
+
+.sidebar ul li {
+    list-style-type: none;
+    margin-bottom: 0.6em;
+}
+
+.sidebar ul.pages {
+    margin-left: 5px;
+    margin-top: 0.6em;
+}
+
+.sidebar ul.pages li {
+    background: url(hbullet.png) 0 0.4em no-repeat;
+    padding-left: 25px;
+    list-style-type: none;
+}
+
+.sidebar ul.pages li {
+}
+
+.sidebar h1 {
+    clear: both;
+}
+
+.sidebar .publications .info {
+    color: #666666;
+}
+
+.postinfo {
+    color: #666666;
+    font-size: 92%;
+    margin-top: -1em;
+}
+
+.postreadlink {
+    margin-top: -1em;
+}
+
+.sidebar .posts .info {
+    color: #666666;
+}
+
+.comments_title {
+    margin-top: 2em;
+}
+
+label {
+    display: block;
+}
+
+#footer {
+    clear: both;
+}
+
+a, a:link, a:visited {
+    text-decoration: none;
+    border-bottom: dotted #666666 1px;
+    color: black;
+}
+
+a:hover {
+ color: #CC3333;
+}
+
+li {
+    list-style: square;
+}
+
+table.layout td {
+    vertical-align: top;
+    padding-left: 2em;
+    padding-right: 2em;
+    border-left: solid #999999 1px
+}
+
+hr {
+    border: none;
+    height: 1px;
+    background: #999999; 
+}	
diff --git a/doc/source/static/tripoli.base.css b/doc/source/static/tripoli.base.css
new file mode 100644
index 0000000..da57842
--- /dev/null
+++ b/doc/source/static/tripoli.base.css
@@ -0,0 +1,509 @@
+/*
+ *   Tripoli is a generic CSS standard for HTML rendering. 
+ *   Copyright (C) 2007 David Hellsing
+ *   
+ *   http://devkick.com/lab/tripoli/
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+**/
+
+/*
+_______________________________
+RESET */
+
+*
+{
+	text-decoration:none;
+	font-size:1em;
+	outline:none;
+	margin:0;
+	padding:0;
+}
+
+code,kbd,samp,pre,tt,var,textarea,input,select,isindex,listing,xmp,plaintext
+{
+	font:inherit;
+	white-space:normal;
+}
+
+a,img,a img,iframe,form,abbr,acronym,object,applet,table,a abbr,a acronym
+{
+	border-width:0;
+}
+
+dfn,i,cite,var,address,em
+{
+	font-style:normal;
+}
+
+th,b,strong,h1,h2,h3,h4,h5,h6,dt
+{
+	font-weight:normal;
+}
+
+caption,th,td
+{
+	text-align:left;
+}
+
+html
+{
+	background:white;
+	color:black;
+	line-height:1;
+	font-family:arial, sans-serif;
+}
+
+/* \*/
+
+html
+{
+	font-family:sans-serif;
+}
+
+/* */
+
+q
+{
+	quotes:"\201C""\201D""\2018""\2019";
+}
+
+ul,ol,dir,menu
+{
+	list-style:none;
+}
+
+sub,sup
+{
+	vertical-align:baseline;
+}
+
+a
+{
+	color:inherit;
+}
+
+/*
+_______________________________
+DISABLE DEPRECATED HTML */
+
+font,basefont
+{
+	color:inherit;
+	font:inherit;
+	font-size:100%;
+}
+
+
+center,*[align]
+{
+	text-align:inherit;
+}
+
+s,strike,u
+{
+	text-decoration:inherit;
+}
+
+img
+{
+	border:none;
+	margin:0;
+}
+
+ol
+{
+	list-style-type:decimal;
+}
+
+body
+{
+	background-color:transparent;
+}
+
+tr,th,td
+{
+	width:auto;
+	height:auto;
+	background-color:transparent;
+	vertical-align:inherit;
+	border:none;
+}
+
+table[border],.content table[border]
+{
+	border-collapse:separate;
+	border-spacing:0;
+}
+
+nobr
+{
+	white-space:normal;
+}
+
+marquee
+{
+	overflow:visible;
+	-moz-binding:none;
+}
+
+blink
+{
+	text-decoration:none;
+}
+
+/*
+_______________________________
+GENERAL */
+
+html
+{
+	font-size:125%;
+}
+
+body
+{
+	font-size:50%;
+}
+
+a
+{
+	text-decoration:underline;
+}
+
+strong,th,thead td,h1,h2,h3,h4,h5,h6,dt
+{
+	font-weight:bold;
+}
+
+cite,em,dfn
+{
+	font-style:italic;
+}
+
+code,kbd,samp,pre,tt,var,input[type='text'],input[type='password'],textarea
+{
+	font-size:100%;
+	font-family:mono-space,monospace;
+}
+
+pre
+{
+	white-space:pre;
+}
+
+pre *
+{
+	font-size:100%;
+	white-space:pre;
+}
+
+del
+{
+	text-decoration:line-through;
+}
+
+ins,dfn
+{
+	border-bottom:1px solid black;
+}
+
+small,sup,sub
+{
+	font-size:85%;
+}
+
+big
+{
+	font-size:125%;
+	line-height:80%;
+}
+
+abbr,acronym
+{
+	text-transform:uppercase;
+	font-size:85%;
+	letter-spacing:.1em;
+}
+
+abbr[title],acronym[title],dfn[title]
+{
+	cursor:help;
+	border-bottom:1px dotted black;
+}
+
+sup
+{
+	vertical-align:super;
+}
+
+sub
+{
+	vertical-align:sub;
+}
+
+blockquote
+{
+	padding-left:2.2em;
+}
+
+hr
+{
+	display:none; /* We will re-reset it later for content */
+}
+
+:lang(af),:lang(nl),:lang(pl)
+{
+	quotes:'\201E' '\201D' '\201A' '\2019';
+}
+
+:lang(bg),:lang(cs),:lang(de),:lang(is),:lang(lt),:lang(sk),:lang(sr),:lang(ro)
+{
+	quotes:'\201E' '\201C' '\201A' '\2018';
+}
+
+:lang(da),:lang(hr)
+{
+	quotes:'\00BB' '\00AB' '\203A' '\2039';
+}
+
+:lang(el),:lang(es),:lang(sq),:lang(tr)
+{
+	quotes:'\00AB' '\00BB' '\2039' '\203A';
+}
+
+:lang(en-GB)
+{
+	quotes:'\2018' '\2019' '\201C' '\201D';
+}
+
+:lang(fi),:lang(sv)
+{
+	quotes:'\201D' '\201D' '\2019' '\2019';
+}
+
+:lang(fr)
+{
+	quotes:'\ab\2005' '\2005\bb' '\2039\2005' '\2005\203a';
+}
+
+*[lang|='en'] q:before
+{
+	content:'\201C';
+}
+
+*[lang|='en'] q:after
+{
+	content:'\201D';
+}
+
+*[lang|='en'] q q:before
+{
+	content:'\2018';
+}
+
+*[lang|='en'] q q:after
+{
+	content:'\2019';
+}
+
+input,select,button
+{
+	cursor:pointer;
+}
+
+input[type='text'],input[type='password']
+{
+	cursor:text;
+}
+
+input[type='hidden']
+{
+	display:none;
+}
+
+/*
+_______________________________
+CONTENT */
+
+.content
+{
+	font-size:1.2em;
+	line-height:1.6em;
+}
+
+.content h1
+{
+	font-size:1.6em;
+	line-height:1;
+	margin:1em 0 .5em;
+}
+
+.content h2
+{
+	font-size:1.5em;
+	line-height:1;
+	margin:1.07em 0 .535em;
+}
+
+.content h3
+{
+	font-size:1.4em;
+	line-height:1;
+	margin:1.14em 0 .57em;
+}
+
+.content h4
+{
+	font-size:1.3em;
+	line-height:1;
+	margin:1.23em 0 .615em;
+}
+
+.content h5
+{
+	font-size:1.2em;
+	line-height:1;
+	margin:1.33em 0 .67em;
+}
+
+.content h6
+{
+	font-size:1em;
+	line-height:1;
+	margin:1.6em 0 .8em;
+}
+
+.content hr
+{
+	display:block;
+	background:black;
+	color:black;
+	width:100%;
+	height:1px;
+	border:none;
+}
+
+.content ul
+{
+	list-style:disc outside;
+}
+
+.content ol
+{
+	list-style:decimal outside;
+}
+
+.content table
+{
+	border-collapse:collapse;
+}
+
+.content hr,.content p,.content ul,.content ol,.content dl,.content pre, .content address,.content table,.content form
+{
+	margin-bottom:1.6em;
+}
+
+.content p+p
+{
+	margin-top:-.8em;
+}
+
+.content fieldset
+{
+	margin:1.6em 0;
+	padding:1.6em;
+}
+
+/* \*/
+
+.content legend
+{
+	padding-left:.8em;
+	padding-right:.8em;
+}
+
+/* */
+
+ at media all and (min-width: 0px) /* for Opera 8 */
+{ 
+	.content legend
+	{
+		margin-bottom:1.6em;
+	}
+	.content fieldset
+	{
+		margin-top:0;
+	}
+	.content[class^='content'] fieldset
+	{
+		margin-top:1.6em;
+	}
+}
+
+.content fieldset>*:first-child
+{
+	margin-top:0;
+}
+
+.content textarea,.content input[type='text']
+{
+	padding:.1em .2em;
+}
+
+.content input
+{
+	padding:.2em .1em;
+}
+
+.content select
+{
+	padding:.2em .1em 0;
+}
+
+.content select[multiple]
+{
+	margin-bottom:.8em;
+}
+
+.content option
+{
+	padding:0 .4em .1em;
+}
+
+.content button
+{
+	padding:.3em .5em;
+}
+
+.content input[type='radio']
+{
+	position:relative;
+	bottom:-.2em;
+}
+
+.content dt
+{
+	margin-top:.8em;
+	margin-bottom:.4em;
+}
+
+.content ul,.content ol
+{
+	margin-left:2.2em;
+}
+
+.content caption,.content form div
+{
+	padding-bottom:.8em;
+}
+
+.content ul ul,content ol ul,.content ul ol,content ol ol
+{
+	margin-bottom:0;
+}
+
+/*
+_______________________________
+END */
diff --git a/doc/source/templates/index.html b/doc/source/templates/index.html
new file mode 100644
index 0000000..597f930
--- /dev/null
+++ b/doc/source/templates/index.html
@@ -0,0 +1,34 @@
+{% extends "layout.html" %}
+{% set title = 'bx python' %}
+{% block body %}
+  <h1>Welcome</h1>
+
+  <p>
+    
+    The <b>bx-python</b> project is a python library and associated set of scripts to allow for rapid implementation of genome scale analyses. The library contains a variety of useful modules, but the particular strengths are:
+
+    <ul>
+      <li>Classes for reading and working with genome-scale multiple local alignments (in MAF, AXT, and LAV formats)</li>
+     <li>Generic data structure for indexing on disk files that contain blocks of data associated with intervals on various sequences (used, for example, to provide random access to individual alignments in huge files; optomized for use over network filesystems)
+     </li>
+     <li>Data structures for working with intervals on sequences</li>
+     <li>"Binned bitsets" which act just like chromosome sized bit arrays, but lazily allocate regions and allow large blocks of all set or all unset bits to be stored compactly</li>
+     <li>"Intersecter" for performing fast intersection tests that preserve both query and target intervals and associated annotation </li>
+
+      These tools have been used in a variety of published research, and are a fundamental part of the ongoing Galaxy and ESPERR projects.
+      
+    </ul>
+    
+  </p>
+
+  <h1>Documentation</h1>
+
+  <ul>
+    <li><a href="{{ pathto("contents") }}">Contents</a></li>
+    <li><a href="{{ pathto("search") }}">Search</a></li>
+    <li><a href="{{ pathto("genindex") }}">General Index</a></li>
+    <li><a href="{{ pathto("modindex") }}">Module Index</a></li>
+    <li><a href="apidoc/index.html">API documentation</a></li>
+  </ul>
+
+{% endblock %}
diff --git a/doc/source/templates/indexsidebar.html b/doc/source/templates/indexsidebar.html
new file mode 100644
index 0000000..4247e03
--- /dev/null
+++ b/doc/source/templates/indexsidebar.html
@@ -0,0 +1,9 @@
+<h3>About bx-python</h3>
+
+<p>Current version: <b>{{ version }}</b></p>
+
+<h3>Download</h3>
+
+<p align="center">
+  <a href="http://bitbucket.org/james_taylor/bx-python">bx-python source</a>
+</p>
diff --git a/doc/source/templates/layout.html b/doc/source/templates/layout.html
new file mode 100644
index 0000000..48b1045
--- /dev/null
+++ b/doc/source/templates/layout.html
@@ -0,0 +1,51 @@
+{% extends "!layout.html" %}
+
+{%- block document %}
+    <div id="main">
+        <div class="inner">
+            <div id="title" class="content">
+                <h1 class="pageheader">
+                    <a href="{{pathto('index')}}">bx-python</a>
+                </h1>
+            </div>	
+            <div id="right">
+                <div class="content secondary sidebar">
+                    {{ relbar() }}
+                    {{ sidebar() }}
+                </div>
+            </div>
+            <div id="left" class="document">
+                <div class="documentwrapper">
+                    {%- if builder != 'htmlhelp' %}
+                      <div class="bodywrapper">
+                    {%- endif %}
+                    <div class="body content">
+                        {% block body %} {% endblock %}
+                    </div>
+                    {%- if builder != 'htmlhelp' %}
+                      </div>
+                    {%- endif %}
+                </div>
+            </div>
+        </div>
+    </div>
+{%- endblock %}
+
+{% block doctype %}
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+{% endblock %}
+
+{% block rootrellink %}
+        <li><a href="{{ pathto('index') }}">bx-python home</a></li>
+        <li><a href="{{ pathto('contents') }}">Table of contents</a></li>
+{% endblock %}
+
+{# Sidebar and already handled #}
+
+{% block relbar1 %}{% endblock %}
+{% block relbar2 %}{% endblock %}
+
+{% block sidebar1 %}{% endblock %}
+{% block sidebar2 %}{% endblock %}
+
+{% block footer %}{% endblock %}
\ No newline at end of file
diff --git a/lib/bx/__init__.py b/lib/bx/__init__.py
new file mode 100644
index 0000000..e1fcac0
--- /dev/null
+++ b/lib/bx/__init__.py
@@ -0,0 +1,14 @@
+import sys
+"""
+Shamelessly ripped off of py.std
+"""
+__version__ = '0.5.0'
+
+class Std( object ):
+    def __init__( self ):
+        self.__dict__ = sys.modules
+    def __getattr__( self, name ):
+        m = __import__(name)
+        return m
+
+std = Std()
diff --git a/lib/bx/_seqmapping.c b/lib/bx/_seqmapping.c
new file mode 100644
index 0000000..3dce174
--- /dev/null
+++ b/lib/bx/_seqmapping.c
@@ -0,0 +1,5344 @@
+/* Generated by Cython 0.18 on Mon Jul 15 13:25:44 2013 */
+
+#define PY_SSIZE_T_CLEAN
+#include "Python.h"
+#ifndef Py_PYTHON_H
+    #error Python headers needed to compile C extensions, please install development version of Python.
+#elif PY_VERSION_HEX < 0x02040000
+    #error Cython requires Python 2.4+.
+#else
+#include <stddef.h> /* For offsetof */
+#ifndef offsetof
+#define offsetof(type, member) ( (size_t) & ((type*)0) -> member )
+#endif
+#if !defined(WIN32) && !defined(MS_WINDOWS)
+  #ifndef __stdcall
+    #define __stdcall
+  #endif
+  #ifndef __cdecl
+    #define __cdecl
+  #endif
+  #ifndef __fastcall
+    #define __fastcall
+  #endif
+#endif
+#ifndef DL_IMPORT
+  #define DL_IMPORT(t) t
+#endif
+#ifndef DL_EXPORT
+  #define DL_EXPORT(t) t
+#endif
+#ifndef PY_LONG_LONG
+  #define PY_LONG_LONG LONG_LONG
+#endif
+#ifndef Py_HUGE_VAL
+  #define Py_HUGE_VAL HUGE_VAL
+#endif
+#ifdef PYPY_VERSION
+#define CYTHON_COMPILING_IN_PYPY 1
+#define CYTHON_COMPILING_IN_CPYTHON 0
+#else
+#define CYTHON_COMPILING_IN_PYPY 0
+#define CYTHON_COMPILING_IN_CPYTHON 1
+#endif
+#if PY_VERSION_HEX < 0x02050000
+  typedef int Py_ssize_t;
+  #define PY_SSIZE_T_MAX INT_MAX
+  #define PY_SSIZE_T_MIN INT_MIN
+  #define PY_FORMAT_SIZE_T ""
+  #define CYTHON_FORMAT_SSIZE_T ""
+  #define PyInt_FromSsize_t(z) PyInt_FromLong(z)
+  #define PyInt_AsSsize_t(o)   __Pyx_PyInt_AsInt(o)
+  #define PyNumber_Index(o)    ((PyNumber_Check(o) && !PyFloat_Check(o)) ? PyNumber_Int(o) : \
+                                (PyErr_Format(PyExc_TypeError, \
+                                              "expected index value, got %.200s", Py_TYPE(o)->tp_name), \
+                                 (PyObject*)0))
+  #define __Pyx_PyIndex_Check(o) (PyNumber_Check(o) && !PyFloat_Check(o) && \
+                                  !PyComplex_Check(o))
+  #define PyIndex_Check __Pyx_PyIndex_Check
+  #define PyErr_WarnEx(category, message, stacklevel) PyErr_Warn(category, message)
+  #define __PYX_BUILD_PY_SSIZE_T "i"
+#else
+  #define __PYX_BUILD_PY_SSIZE_T "n"
+  #define CYTHON_FORMAT_SSIZE_T "z"
+  #define __Pyx_PyIndex_Check PyIndex_Check
+#endif
+#if PY_VERSION_HEX < 0x02060000
+  #define Py_REFCNT(ob) (((PyObject*)(ob))->ob_refcnt)
+  #define Py_TYPE(ob)   (((PyObject*)(ob))->ob_type)
+  #define Py_SIZE(ob)   (((PyVarObject*)(ob))->ob_size)
+  #define PyVarObject_HEAD_INIT(type, size) \
+          PyObject_HEAD_INIT(type) size,
+  #define PyType_Modified(t)
+  typedef struct {
+     void *buf;
+     PyObject *obj;
+     Py_ssize_t len;
+     Py_ssize_t itemsize;
+     int readonly;
+     int ndim;
+     char *format;
+     Py_ssize_t *shape;
+     Py_ssize_t *strides;
+     Py_ssize_t *suboffsets;
+     void *internal;
+  } Py_buffer;
+  #define PyBUF_SIMPLE 0
+  #define PyBUF_WRITABLE 0x0001
+  #define PyBUF_FORMAT 0x0004
+  #define PyBUF_ND 0x0008
+  #define PyBUF_STRIDES (0x0010 | PyBUF_ND)
+  #define PyBUF_C_CONTIGUOUS (0x0020 | PyBUF_STRIDES)
+  #define PyBUF_F_CONTIGUOUS (0x0040 | PyBUF_STRIDES)
+  #define PyBUF_ANY_CONTIGUOUS (0x0080 | PyBUF_STRIDES)
+  #define PyBUF_INDIRECT (0x0100 | PyBUF_STRIDES)
+  #define PyBUF_RECORDS (PyBUF_STRIDES | PyBUF_FORMAT | PyBUF_WRITABLE)
+  #define PyBUF_FULL (PyBUF_INDIRECT | PyBUF_FORMAT | PyBUF_WRITABLE)
+  typedef int (*getbufferproc)(PyObject *, Py_buffer *, int);
+  typedef void (*releasebufferproc)(PyObject *, Py_buffer *);
+#endif
+#if PY_MAJOR_VERSION < 3
+  #define __Pyx_BUILTIN_MODULE_NAME "__builtin__"
+  #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \
+          PyCode_New(a, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
+#else
+  #define __Pyx_BUILTIN_MODULE_NAME "builtins"
+  #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \
+          PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
+#endif
+#if PY_MAJOR_VERSION < 3 && PY_MINOR_VERSION < 6
+  #define PyUnicode_FromString(s) PyUnicode_Decode(s, strlen(s), "UTF-8", "strict")
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define Py_TPFLAGS_CHECKTYPES 0
+  #define Py_TPFLAGS_HAVE_INDEX 0
+#endif
+#if (PY_VERSION_HEX < 0x02060000) || (PY_MAJOR_VERSION >= 3)
+  #define Py_TPFLAGS_HAVE_NEWBUFFER 0
+#endif
+#if PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND)
+  #define CYTHON_PEP393_ENABLED 1
+  #define __Pyx_PyUnicode_READY(op)       (likely(PyUnicode_IS_READY(op)) ? \
+                                              0 : _PyUnicode_Ready((PyObject *)(op)))
+  #define __Pyx_PyUnicode_GET_LENGTH(u)   PyUnicode_GET_LENGTH(u)
+  #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_READ_CHAR(u, i)
+  #define __Pyx_PyUnicode_READ(k, d, i)   PyUnicode_READ(k, d, i)
+#else
+  #define CYTHON_PEP393_ENABLED 0
+  #define __Pyx_PyUnicode_READY(op)       (0)
+  #define __Pyx_PyUnicode_GET_LENGTH(u)   PyUnicode_GET_SIZE(u)
+  #define __Pyx_PyUnicode_READ_CHAR(u, i) ((Py_UCS4)(PyUnicode_AS_UNICODE(u)[i]))
+  #define __Pyx_PyUnicode_READ(k, d, i)   ((k=k), (Py_UCS4)(((Py_UNICODE*)d)[i]))
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define PyBaseString_Type            PyUnicode_Type
+  #define PyStringObject               PyUnicodeObject
+  #define PyString_Type                PyUnicode_Type
+  #define PyString_Check               PyUnicode_Check
+  #define PyString_CheckExact          PyUnicode_CheckExact
+#endif
+#if PY_VERSION_HEX < 0x02060000
+  #define PyBytesObject                PyStringObject
+  #define PyBytes_Type                 PyString_Type
+  #define PyBytes_Check                PyString_Check
+  #define PyBytes_CheckExact           PyString_CheckExact
+  #define PyBytes_FromString           PyString_FromString
+  #define PyBytes_FromStringAndSize    PyString_FromStringAndSize
+  #define PyBytes_FromFormat           PyString_FromFormat
+  #define PyBytes_DecodeEscape         PyString_DecodeEscape
+  #define PyBytes_AsString             PyString_AsString
+  #define PyBytes_AsStringAndSize      PyString_AsStringAndSize
+  #define PyBytes_Size                 PyString_Size
+  #define PyBytes_AS_STRING            PyString_AS_STRING
+  #define PyBytes_GET_SIZE             PyString_GET_SIZE
+  #define PyBytes_Repr                 PyString_Repr
+  #define PyBytes_Concat               PyString_Concat
+  #define PyBytes_ConcatAndDel         PyString_ConcatAndDel
+#endif
+#if PY_VERSION_HEX < 0x02060000
+  #define PySet_Check(obj)             PyObject_TypeCheck(obj, &PySet_Type)
+  #define PyFrozenSet_Check(obj)       PyObject_TypeCheck(obj, &PyFrozenSet_Type)
+#endif
+#ifndef PySet_CheckExact
+  #define PySet_CheckExact(obj)        (Py_TYPE(obj) == &PySet_Type)
+#endif
+#define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type)
+#if PY_MAJOR_VERSION >= 3
+  #define PyIntObject                  PyLongObject
+  #define PyInt_Type                   PyLong_Type
+  #define PyInt_Check(op)              PyLong_Check(op)
+  #define PyInt_CheckExact(op)         PyLong_CheckExact(op)
+  #define PyInt_FromString             PyLong_FromString
+  #define PyInt_FromUnicode            PyLong_FromUnicode
+  #define PyInt_FromLong               PyLong_FromLong
+  #define PyInt_FromSize_t             PyLong_FromSize_t
+  #define PyInt_FromSsize_t            PyLong_FromSsize_t
+  #define PyInt_AsLong                 PyLong_AsLong
+  #define PyInt_AS_LONG                PyLong_AS_LONG
+  #define PyInt_AsSsize_t              PyLong_AsSsize_t
+  #define PyInt_AsUnsignedLongMask     PyLong_AsUnsignedLongMask
+  #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define PyBoolObject                 PyLongObject
+#endif
+#if PY_VERSION_HEX < 0x03020000
+  typedef long Py_hash_t;
+  #define __Pyx_PyInt_FromHash_t PyInt_FromLong
+  #define __Pyx_PyInt_AsHash_t   PyInt_AsLong
+#else
+  #define __Pyx_PyInt_FromHash_t PyInt_FromSsize_t
+  #define __Pyx_PyInt_AsHash_t   PyInt_AsSsize_t
+#endif
+#if (PY_MAJOR_VERSION < 3) || (PY_VERSION_HEX >= 0x03010300)
+  #define __Pyx_PySequence_GetSlice(obj, a, b) PySequence_GetSlice(obj, a, b)
+  #define __Pyx_PySequence_SetSlice(obj, a, b, value) PySequence_SetSlice(obj, a, b, value)
+  #define __Pyx_PySequence_DelSlice(obj, a, b) PySequence_DelSlice(obj, a, b)
+#else
+  #define __Pyx_PySequence_GetSlice(obj, a, b) (unlikely(!(obj)) ? \
+        (PyErr_SetString(PyExc_SystemError, "null argument to internal routine"), (PyObject*)0) : \
+        (likely((obj)->ob_type->tp_as_mapping) ? (PySequence_GetSlice(obj, a, b)) : \
+            (PyErr_Format(PyExc_TypeError, "'%.200s' object is unsliceable", (obj)->ob_type->tp_name), (PyObject*)0)))
+  #define __Pyx_PySequence_SetSlice(obj, a, b, value) (unlikely(!(obj)) ? \
+        (PyErr_SetString(PyExc_SystemError, "null argument to internal routine"), -1) : \
+        (likely((obj)->ob_type->tp_as_mapping) ? (PySequence_SetSlice(obj, a, b, value)) : \
+            (PyErr_Format(PyExc_TypeError, "'%.200s' object doesn't support slice assignment", (obj)->ob_type->tp_name), -1)))
+  #define __Pyx_PySequence_DelSlice(obj, a, b) (unlikely(!(obj)) ? \
+        (PyErr_SetString(PyExc_SystemError, "null argument to internal routine"), -1) : \
+        (likely((obj)->ob_type->tp_as_mapping) ? (PySequence_DelSlice(obj, a, b)) : \
+            (PyErr_Format(PyExc_TypeError, "'%.200s' object doesn't support slice deletion", (obj)->ob_type->tp_name), -1)))
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define PyMethod_New(func, self, klass) ((self) ? PyMethod_New(func, self) : PyInstanceMethod_New(func))
+#endif
+#if PY_VERSION_HEX < 0x02050000
+  #define __Pyx_GetAttrString(o,n)   PyObject_GetAttrString((o),((char *)(n)))
+  #define __Pyx_SetAttrString(o,n,a) PyObject_SetAttrString((o),((char *)(n)),(a))
+  #define __Pyx_DelAttrString(o,n)   PyObject_DelAttrString((o),((char *)(n)))
+#else
+  #define __Pyx_GetAttrString(o,n)   PyObject_GetAttrString((o),(n))
+  #define __Pyx_SetAttrString(o,n,a) PyObject_SetAttrString((o),(n),(a))
+  #define __Pyx_DelAttrString(o,n)   PyObject_DelAttrString((o),(n))
+#endif
+#if PY_VERSION_HEX < 0x02050000
+  #define __Pyx_NAMESTR(n) ((char *)(n))
+  #define __Pyx_DOCSTR(n)  ((char *)(n))
+#else
+  #define __Pyx_NAMESTR(n) (n)
+  #define __Pyx_DOCSTR(n)  (n)
+#endif
+
+
+#if PY_MAJOR_VERSION >= 3
+  #define __Pyx_PyNumber_Divide(x,y)         PyNumber_TrueDivide(x,y)
+  #define __Pyx_PyNumber_InPlaceDivide(x,y)  PyNumber_InPlaceTrueDivide(x,y)
+#else
+  #define __Pyx_PyNumber_Divide(x,y)         PyNumber_Divide(x,y)
+  #define __Pyx_PyNumber_InPlaceDivide(x,y)  PyNumber_InPlaceDivide(x,y)
+#endif
+
+#ifndef __PYX_EXTERN_C
+  #ifdef __cplusplus
+    #define __PYX_EXTERN_C extern "C"
+  #else
+    #define __PYX_EXTERN_C extern
+  #endif
+#endif
+
+#if defined(WIN32) || defined(MS_WINDOWS)
+#define _USE_MATH_DEFINES
+#endif
+#include <math.h>
+#define __PYX_HAVE__bx___seqmapping
+#define __PYX_HAVE_API__bx___seqmapping
+#include "stdlib.h"
+#ifdef _OPENMP
+#include <omp.h>
+#endif /* _OPENMP */
+
+#ifdef PYREX_WITHOUT_ASSERTIONS
+#define CYTHON_WITHOUT_ASSERTIONS
+#endif
+
+#ifndef CYTHON_INLINE
+  #if defined(__GNUC__)
+    #define CYTHON_INLINE __inline__
+  #elif defined(_MSC_VER)
+    #define CYTHON_INLINE __inline
+  #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+    #define CYTHON_INLINE inline
+  #else
+    #define CYTHON_INLINE
+  #endif
+#endif
+#ifndef CYTHON_UNUSED
+# if defined(__GNUC__)
+#   if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
+#     define CYTHON_UNUSED __attribute__ ((__unused__))
+#   else
+#     define CYTHON_UNUSED
+#   endif
+# elif defined(__ICC) || (defined(__INTEL_COMPILER) && !defined(_MSC_VER))
+#   define CYTHON_UNUSED __attribute__ ((__unused__))
+# else
+#   define CYTHON_UNUSED
+# endif
+#endif
+typedef struct {PyObject **p; char *s; const long n; const char* encoding; const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry; /*proto*/
+
+#define __Pyx_PyBytes_FromUString(s) PyBytes_FromString((char*)s)
+#define __Pyx_PyBytes_AsUString(s)   ((unsigned char*) PyBytes_AsString(s))
+#define __Pyx_Owned_Py_None(b) (Py_INCREF(Py_None), Py_None)
+#define __Pyx_PyBool_FromLong(b) ((b) ? (Py_INCREF(Py_True), Py_True) : (Py_INCREF(Py_False), Py_False))
+static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*);
+static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x);
+static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*);
+static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t);
+static CYTHON_INLINE size_t __Pyx_PyInt_AsSize_t(PyObject*);
+#if CYTHON_COMPILING_IN_CPYTHON
+#define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x))
+#else
+#define __pyx_PyFloat_AsDouble(x) PyFloat_AsDouble(x)
+#endif
+#define __pyx_PyFloat_AsFloat(x) ((float) __pyx_PyFloat_AsDouble(x))
+
+
+#ifdef __GNUC__
+  /* Test for GCC > 2.95 */
+  #if __GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))
+    #define likely(x)   __builtin_expect(!!(x), 1)
+    #define unlikely(x) __builtin_expect(!!(x), 0)
+  #else /* __GNUC__ > 2 ... */
+    #define likely(x)   (x)
+    #define unlikely(x) (x)
+  #endif /* __GNUC__ > 2 ... */
+#else /* __GNUC__ */
+  #define likely(x)   (x)
+  #define unlikely(x) (x)
+#endif /* __GNUC__ */
+    
+static PyObject *__pyx_m;
+static PyObject *__pyx_b;
+static PyObject *__pyx_empty_tuple;
+static PyObject *__pyx_empty_bytes;
+static int __pyx_lineno;
+static int __pyx_clineno = 0;
+static const char * __pyx_cfilenm= __FILE__;
+static const char *__pyx_filename;
+
+
+static const char *__pyx_f[] = {
+  "_seqmapping.pyx",
+};
+
+/*--- Type declarations ---*/
+struct __pyx_obj_2bx_11_seqmapping_CharToIntArrayMapping;
+struct __pyx_obj_2bx_11_seqmapping_IntToIntMapping;
+
+/* "bx/_seqmapping.pyx":19
+ * import sys
+ * 
+ * cdef class CharToIntArrayMapping:             # <<<<<<<<<<<<<<
+ *     """Mapping for converting strings to int arrays"""
+ * 
+ */
+struct __pyx_obj_2bx_11_seqmapping_CharToIntArrayMapping {
+  PyObject_HEAD
+  int table[256];
+  int out_size;
+  PyObject *reverse_table;
+};
+
+
+/* "bx/_seqmapping.pyx":102
+ *         return self.out_size
+ * 
+ * cdef class IntToIntMapping:             # <<<<<<<<<<<<<<
+ * 
+ *     cdef int* table
+ */
+struct __pyx_obj_2bx_11_seqmapping_IntToIntMapping {
+  PyObject_HEAD
+  int *table;
+  int in_size;
+  int out_size;
+};
+
+#ifndef CYTHON_REFNANNY
+  #define CYTHON_REFNANNY 0
+#endif
+#if CYTHON_REFNANNY
+  typedef struct {
+    void (*INCREF)(void*, PyObject*, int);
+    void (*DECREF)(void*, PyObject*, int);
+    void (*GOTREF)(void*, PyObject*, int);
+    void (*GIVEREF)(void*, PyObject*, int);
+    void* (*SetupContext)(const char*, int, const char*);
+    void (*FinishContext)(void**);
+  } __Pyx_RefNannyAPIStruct;
+  static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL;
+  static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname); /*proto*/
+  #define __Pyx_RefNannyDeclarations void *__pyx_refnanny = NULL;
+#ifdef WITH_THREAD
+  #define __Pyx_RefNannySetupContext(name, acquire_gil) \
+          if (acquire_gil) { \
+              PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure(); \
+              __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__); \
+              PyGILState_Release(__pyx_gilstate_save); \
+          } else { \
+              __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__); \
+          }
+#else
+  #define __Pyx_RefNannySetupContext(name, acquire_gil) \
+          __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__)
+#endif
+  #define __Pyx_RefNannyFinishContext() \
+          __Pyx_RefNanny->FinishContext(&__pyx_refnanny)
+  #define __Pyx_INCREF(r)  __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_DECREF(r)  __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_GOTREF(r)  __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_XINCREF(r)  do { if((r) != NULL) {__Pyx_INCREF(r); }} while(0)
+  #define __Pyx_XDECREF(r)  do { if((r) != NULL) {__Pyx_DECREF(r); }} while(0)
+  #define __Pyx_XGOTREF(r)  do { if((r) != NULL) {__Pyx_GOTREF(r); }} while(0)
+  #define __Pyx_XGIVEREF(r) do { if((r) != NULL) {__Pyx_GIVEREF(r);}} while(0)
+#else
+  #define __Pyx_RefNannyDeclarations
+  #define __Pyx_RefNannySetupContext(name, acquire_gil)
+  #define __Pyx_RefNannyFinishContext()
+  #define __Pyx_INCREF(r) Py_INCREF(r)
+  #define __Pyx_DECREF(r) Py_DECREF(r)
+  #define __Pyx_GOTREF(r)
+  #define __Pyx_GIVEREF(r)
+  #define __Pyx_XINCREF(r) Py_XINCREF(r)
+  #define __Pyx_XDECREF(r) Py_XDECREF(r)
+  #define __Pyx_XGOTREF(r)
+  #define __Pyx_XGIVEREF(r)
+#endif /* CYTHON_REFNANNY */
+#define __Pyx_CLEAR(r)    do { PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);} while(0)
+#define __Pyx_XCLEAR(r)   do { if((r) != NULL) {PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);}} while(0)
+
+static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/
+
+static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
+    Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/
+
+static CYTHON_INLINE int __Pyx_CheckKeywordStrings(PyObject *kwdict, const char* function_name, int kw_allowed); /*proto*/
+
+static void __Pyx_RaiseDoubleKeywordsError(const char* func_name, PyObject* kw_name); /*proto*/
+
+static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
+    PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
+    const char* function_name); /*proto*/
+
+#define __Pyx_SetItemInt(o, i, v, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \
+                                                    __Pyx_SetItemInt_Fast(o, i, v) : \
+                                                    __Pyx_SetItemInt_Generic(o, to_py_func(i), v))
+static CYTHON_INLINE int __Pyx_SetItemInt_Generic(PyObject *o, PyObject *j, PyObject *v) {
+    int r;
+    if (!j) return -1;
+    r = PyObject_SetItem(o, j, v);
+    Py_DECREF(j);
+    return r;
+}
+static CYTHON_INLINE int __Pyx_SetItemInt_Fast(PyObject *o, Py_ssize_t i, PyObject *v) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    if (PyList_CheckExact(o)) {
+        Py_ssize_t n = (likely(i >= 0)) ? i : i + PyList_GET_SIZE(o);
+        if (likely((n >= 0) & (n < PyList_GET_SIZE(o)))) {
+            PyObject* old = PyList_GET_ITEM(o, n);
+            Py_INCREF(v);
+            PyList_SET_ITEM(o, n, v);
+            Py_DECREF(old);
+            return 1;
+        }
+    } else {  /* inlined PySequence_SetItem() */
+        PySequenceMethods *m = Py_TYPE(o)->tp_as_sequence;
+        if (likely(m && m->sq_ass_item)) {
+            if (unlikely(i < 0) && likely(m->sq_length)) {
+                Py_ssize_t l = m->sq_length(o);
+                if (unlikely(l < 0)) return -1;
+                i += l;
+            }
+            return m->sq_ass_item(o, i, v);
+        }
+    }
+#else
+#if CYTHON_COMPILING_IN_PYPY
+    if (PySequence_Check(o) && !PyDict_Check(o)) {
+#else
+    if (PySequence_Check(o)) {
+#endif
+        return PySequence_SetItem(o, i, v);
+    }
+#endif
+    return __Pyx_SetItemInt_Generic(o, PyInt_FromSsize_t(i), v);
+}
+
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j) {
+    PyObject *r;
+    if (!j) return NULL;
+    r = PyObject_GetItem(o, j);
+    Py_DECREF(j);
+    return r;
+}
+#define __Pyx_GetItemInt_List(o, i, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \
+                                                    __Pyx_GetItemInt_List_Fast(o, i) : \
+                                                    __Pyx_GetItemInt_Generic(o, to_py_func(i)))
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    if (likely((0 <= i) & (i < PyList_GET_SIZE(o)))) {
+        PyObject *r = PyList_GET_ITEM(o, i);
+        Py_INCREF(r);
+        return r;
+    }
+    else if ((-PyList_GET_SIZE(o) <= i) & (i < 0)) {
+        PyObject *r = PyList_GET_ITEM(o, PyList_GET_SIZE(o) + i);
+        Py_INCREF(r);
+        return r;
+    }
+    return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
+#else
+    return PySequence_GetItem(o, i);
+#endif
+}
+#define __Pyx_GetItemInt_Tuple(o, i, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \
+                                                    __Pyx_GetItemInt_Tuple_Fast(o, i) : \
+                                                    __Pyx_GetItemInt_Generic(o, to_py_func(i)))
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    if (likely((0 <= i) & (i < PyTuple_GET_SIZE(o)))) {
+        PyObject *r = PyTuple_GET_ITEM(o, i);
+        Py_INCREF(r);
+        return r;
+    }
+    else if ((-PyTuple_GET_SIZE(o) <= i) & (i < 0)) {
+        PyObject *r = PyTuple_GET_ITEM(o, PyTuple_GET_SIZE(o) + i);
+        Py_INCREF(r);
+        return r;
+    }
+    return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
+#else
+    return PySequence_GetItem(o, i);
+#endif
+}
+#define __Pyx_GetItemInt(o, i, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \
+                                                    __Pyx_GetItemInt_Fast(o, i) : \
+                                                    __Pyx_GetItemInt_Generic(o, to_py_func(i)))
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    if (PyList_CheckExact(o)) {
+        Py_ssize_t n = (likely(i >= 0)) ? i : i + PyList_GET_SIZE(o);
+        if (likely((n >= 0) & (n < PyList_GET_SIZE(o)))) {
+            PyObject *r = PyList_GET_ITEM(o, n);
+            Py_INCREF(r);
+            return r;
+        }
+    }
+    else if (PyTuple_CheckExact(o)) {
+        Py_ssize_t n = (likely(i >= 0)) ? i : i + PyTuple_GET_SIZE(o);
+        if (likely((n >= 0) & (n < PyTuple_GET_SIZE(o)))) {
+            PyObject *r = PyTuple_GET_ITEM(o, n);
+            Py_INCREF(r);
+            return r;
+        }
+    } else {  /* inlined PySequence_GetItem() */
+        PySequenceMethods *m = Py_TYPE(o)->tp_as_sequence;
+        if (likely(m && m->sq_item)) {
+            if (unlikely(i < 0) && likely(m->sq_length)) {
+                Py_ssize_t l = m->sq_length(o);
+                if (unlikely(l < 0)) return NULL;
+                i += l;
+            }
+            return m->sq_item(o, i);
+        }
+    }
+#else
+    if (PySequence_Check(o)) {
+        return PySequence_GetItem(o, i);
+    }
+#endif
+    return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
+}
+
+static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
+static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
+
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause); /*proto*/
+
+static CYTHON_INLINE long __Pyx_div_long(long, long); /* proto */
+
+static CYTHON_INLINE int __Pyx_PySequence_Contains(PyObject* item, PyObject* seq, int eq) {
+    int result = PySequence_Contains(seq, item);
+    return unlikely(result < 0) ? result : (result == (eq == Py_EQ));
+}
+
+static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level); /*proto*/
+
+static CYTHON_INLINE void __Pyx_RaiseImportError(PyObject *name);
+
+static CYTHON_INLINE unsigned char __Pyx_PyInt_AsUnsignedChar(PyObject *);
+
+static CYTHON_INLINE unsigned short __Pyx_PyInt_AsUnsignedShort(PyObject *);
+
+static CYTHON_INLINE unsigned int __Pyx_PyInt_AsUnsignedInt(PyObject *);
+
+static CYTHON_INLINE char __Pyx_PyInt_AsChar(PyObject *);
+
+static CYTHON_INLINE short __Pyx_PyInt_AsShort(PyObject *);
+
+static CYTHON_INLINE int __Pyx_PyInt_AsInt(PyObject *);
+
+static CYTHON_INLINE signed char __Pyx_PyInt_AsSignedChar(PyObject *);
+
+static CYTHON_INLINE signed short __Pyx_PyInt_AsSignedShort(PyObject *);
+
+static CYTHON_INLINE signed int __Pyx_PyInt_AsSignedInt(PyObject *);
+
+static CYTHON_INLINE int __Pyx_PyInt_AsLongDouble(PyObject *);
+
+static CYTHON_INLINE unsigned long __Pyx_PyInt_AsUnsignedLong(PyObject *);
+
+static CYTHON_INLINE unsigned PY_LONG_LONG __Pyx_PyInt_AsUnsignedLongLong(PyObject *);
+
+static CYTHON_INLINE long __Pyx_PyInt_AsLong(PyObject *);
+
+static CYTHON_INLINE PY_LONG_LONG __Pyx_PyInt_AsLongLong(PyObject *);
+
+static CYTHON_INLINE signed long __Pyx_PyInt_AsSignedLong(PyObject *);
+
+static CYTHON_INLINE signed PY_LONG_LONG __Pyx_PyInt_AsSignedLongLong(PyObject *);
+
+static int __Pyx_check_binary_version(void);
+
+typedef struct {
+    int code_line;
+    PyCodeObject* code_object;
+} __Pyx_CodeObjectCacheEntry;
+struct __Pyx_CodeObjectCache {
+    int count;
+    int max_count;
+    __Pyx_CodeObjectCacheEntry* entries;
+};
+static struct __Pyx_CodeObjectCache __pyx_code_cache = {0,0,NULL};
+static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line);
+static PyCodeObject *__pyx_find_code_object(int code_line);
+static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object);
+
+static void __Pyx_AddTraceback(const char *funcname, int c_line,
+                               int py_line, const char *filename); /*proto*/
+
+static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
+
+
+/* Module declarations from 'bx._seqmapping' */
+static PyTypeObject *__pyx_ptype_2bx_11_seqmapping_CharToIntArrayMapping = 0;
+static PyTypeObject *__pyx_ptype_2bx_11_seqmapping_IntToIntMapping = 0;
+#define __Pyx_MODULE_NAME "bx._seqmapping"
+int __pyx_module_is_main_bx___seqmapping = 0;
+
+/* Implementation of 'bx._seqmapping' */
+static PyObject *__pyx_builtin_ord;
+static PyObject *__pyx_builtin_chr;
+static PyObject *__pyx_builtin_range;
+static int __pyx_pf_2bx_11_seqmapping_21CharToIntArrayMapping___cinit__(struct __pyx_obj_2bx_11_seqmapping_CharToIntArrayMapping *__pyx_v_self); /* proto */
+static int __pyx_pf_2bx_11_seqmapping_21CharToIntArrayMapping_2__init__(struct __pyx_obj_2bx_11_seqmapping_CharToIntArrayMapping *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_2bx_11_seqmapping_21CharToIntArrayMapping_4set_mapping(struct __pyx_obj_2bx_11_seqmapping_CharToIntArrayMapping *__pyx_v_self, PyObject *__pyx_v_c, int __pyx_v_symbol); /* proto */
+static PyObject *__pyx_pf_2bx_11_seqmapping_21CharToIntArrayMapping_6translate(struct __pyx_obj_2bx_11_seqmapping_CharToIntArrayMapping *__pyx_v_self, PyObject *__pyx_v_string); /* proto */
+static PyObject *__pyx_pf_2bx_11_seqmapping_21CharToIntArrayMapping_8translate_list(struct __pyx_obj_2bx_11_seqmapping_CharToIntArrayMapping *__pyx_v_self, PyObject *__pyx_v_strings); /* proto */
+static PyObject *__pyx_pf_2bx_11_seqmapping_21CharToIntArrayMapping_10reverse_map(struct __pyx_obj_2bx_11_seqmapping_CharToIntArrayMapping *__pyx_v_self, PyObject *__pyx_v_val, PyObject *__pyx_v_nseqs); /* proto */
+static PyObject *__pyx_pf_2bx_11_seqmapping_21CharToIntArrayMapping_12get_out_size(struct __pyx_obj_2bx_11_seqmapping_CharToIntArrayMapping *__pyx_v_self); /* proto */
+static int __pyx_pf_2bx_11_seqmapping_15IntToIntMapping___cinit__(struct __pyx_obj_2bx_11_seqmapping_IntToIntMapping *__pyx_v_self, int __pyx_v_in_size); /* proto */
+static void __pyx_pf_2bx_11_seqmapping_15IntToIntMapping_2__dealloc__(struct __pyx_obj_2bx_11_seqmapping_IntToIntMapping *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_2bx_11_seqmapping_15IntToIntMapping_4set_mapping(struct __pyx_obj_2bx_11_seqmapping_IntToIntMapping *__pyx_v_self, int __pyx_v_index, int __pyx_v_symbol); /* proto */
+static PyObject *__pyx_pf_2bx_11_seqmapping_15IntToIntMapping_6translate(struct __pyx_obj_2bx_11_seqmapping_IntToIntMapping *__pyx_v_self, PyObject *__pyx_v_src); /* proto */
+static PyObject *__pyx_pf_2bx_11_seqmapping_15IntToIntMapping_8__getitem__(struct __pyx_obj_2bx_11_seqmapping_IntToIntMapping *__pyx_v_self, int __pyx_v_x); /* proto */
+static PyObject *__pyx_pf_2bx_11_seqmapping_15IntToIntMapping_10collapse(struct __pyx_obj_2bx_11_seqmapping_IntToIntMapping *__pyx_v_self, int __pyx_v_a, int __pyx_v_b); /* proto */
+static PyObject *__pyx_pf_2bx_11_seqmapping_15IntToIntMapping_12expand(struct __pyx_obj_2bx_11_seqmapping_IntToIntMapping *__pyx_v_self, int __pyx_v_x); /* proto */
+static PyObject *__pyx_pf_2bx_11_seqmapping_15IntToIntMapping_14expand_out(struct __pyx_obj_2bx_11_seqmapping_IntToIntMapping *__pyx_v_self, int __pyx_v_a); /* proto */
+static PyObject *__pyx_pf_2bx_11_seqmapping_15IntToIntMapping_16expand_random_split(struct __pyx_obj_2bx_11_seqmapping_IntToIntMapping *__pyx_v_self, int __pyx_v_a); /* proto */
+static PyObject *__pyx_pf_2bx_11_seqmapping_15IntToIntMapping_18get_in_size(struct __pyx_obj_2bx_11_seqmapping_IntToIntMapping *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_2bx_11_seqmapping_15IntToIntMapping_20get_out_size(struct __pyx_obj_2bx_11_seqmapping_IntToIntMapping *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_2bx_11_seqmapping_15IntToIntMapping_22get_table(struct __pyx_obj_2bx_11_seqmapping_IntToIntMapping *__pyx_v_self); /* proto */
+static char __pyx_k_1[] = "Malloc Failed";
+static char __pyx_k_2[] = "%d not between 0 and %s";
+static char __pyx_k_3[] = "`src` argument must be a buffer of 32bit integers";
+static char __pyx_k_4[] = "\nPyrex extension classes used by `seqmapping.py`.\n";
+static char __pyx_k__a[] = "a";
+static char __pyx_k__b[] = "b";
+static char __pyx_k__c[] = "c";
+static char __pyx_k__i[] = "i";
+static char __pyx_k__chr[] = "chr";
+static char __pyx_k__ord[] = "ord";
+static char __pyx_k__sys[] = "sys";
+static char __pyx_k__val[] = "val";
+static char __pyx_k__math[] = "math";
+static char __pyx_k__floor[] = "floor";
+static char __pyx_k__index[] = "index";
+static char __pyx_k__nseqs[] = "nseqs";
+static char __pyx_k__numpy[] = "numpy";
+static char __pyx_k__range[] = "range";
+static char __pyx_k__zeros[] = "zeros";
+static char __pyx_k__random[] = "random";
+static char __pyx_k__sample[] = "sample";
+static char __pyx_k__symbol[] = "symbol";
+static char __pyx_k__in_size[] = "in_size";
+static char __pyx_k____main__[] = "__main__";
+static char __pyx_k____test__[] = "__test__";
+static char __pyx_k__randrange[] = "randrange";
+static PyObject *__pyx_kp_s_1;
+static PyObject *__pyx_kp_s_2;
+static PyObject *__pyx_kp_s_3;
+static PyObject *__pyx_n_s____main__;
+static PyObject *__pyx_n_s____test__;
+static PyObject *__pyx_n_s__a;
+static PyObject *__pyx_n_s__b;
+static PyObject *__pyx_n_s__c;
+static PyObject *__pyx_n_s__chr;
+static PyObject *__pyx_n_s__floor;
+static PyObject *__pyx_n_s__i;
+static PyObject *__pyx_n_s__in_size;
+static PyObject *__pyx_n_s__index;
+static PyObject *__pyx_n_s__math;
+static PyObject *__pyx_n_s__nseqs;
+static PyObject *__pyx_n_s__numpy;
+static PyObject *__pyx_n_s__ord;
+static PyObject *__pyx_n_s__random;
+static PyObject *__pyx_n_s__randrange;
+static PyObject *__pyx_n_s__range;
+static PyObject *__pyx_n_s__sample;
+static PyObject *__pyx_n_s__symbol;
+static PyObject *__pyx_n_s__sys;
+static PyObject *__pyx_n_s__val;
+static PyObject *__pyx_n_s__zeros;
+static PyObject *__pyx_int_0;
+static PyObject *__pyx_int_1;
+static PyObject *__pyx_int_neg_1;
+
+/* Python wrapper */
+static int __pyx_pw_2bx_11_seqmapping_21CharToIntArrayMapping_1__cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static int __pyx_pw_2bx_11_seqmapping_21CharToIntArrayMapping_1__cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__cinit__ (wrapper)", 0);
+  if (unlikely(PyTuple_GET_SIZE(__pyx_args) > 0)) {
+    __Pyx_RaiseArgtupleInvalid("__cinit__", 1, 0, 0, PyTuple_GET_SIZE(__pyx_args)); return -1;}
+  if (unlikely(__pyx_kwds) && unlikely(PyDict_Size(__pyx_kwds) > 0) && unlikely(!__Pyx_CheckKeywordStrings(__pyx_kwds, "__cinit__", 0))) return -1;
+  __pyx_r = __pyx_pf_2bx_11_seqmapping_21CharToIntArrayMapping___cinit__(((struct __pyx_obj_2bx_11_seqmapping_CharToIntArrayMapping *)__pyx_v_self));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/_seqmapping.pyx":26
+ *     cdef object reverse_table
+ * 
+ *     def __cinit__( self ):             # <<<<<<<<<<<<<<
+ *         """Init empty mapping (all characters map to -1)"""
+ *         cdef int i
+ */
+
+static int __pyx_pf_2bx_11_seqmapping_21CharToIntArrayMapping___cinit__(struct __pyx_obj_2bx_11_seqmapping_CharToIntArrayMapping *__pyx_v_self) {
+  int __pyx_v_i;
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__cinit__", 0);
+
+  /* "bx/_seqmapping.pyx":29
+ *         """Init empty mapping (all characters map to -1)"""
+ *         cdef int i
+ *         for i from 0 <= i < 256: self.table[i] = -1             # <<<<<<<<<<<<<<
+ *         self.out_size = 0
+ * 
+ */
+  for (__pyx_v_i = 0; __pyx_v_i < 256; __pyx_v_i++) {
+    (__pyx_v_self->table[__pyx_v_i]) = -1;
+  }
+
+  /* "bx/_seqmapping.pyx":30
+ *         cdef int i
+ *         for i from 0 <= i < 256: self.table[i] = -1
+ *         self.out_size = 0             # <<<<<<<<<<<<<<
+ * 
+ *     def __init__( self ):
+ */
+  __pyx_v_self->out_size = 0;
+
+  __pyx_r = 0;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_2bx_11_seqmapping_21CharToIntArrayMapping_3__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static int __pyx_pw_2bx_11_seqmapping_21CharToIntArrayMapping_3__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__init__ (wrapper)", 0);
+  if (unlikely(PyTuple_GET_SIZE(__pyx_args) > 0)) {
+    __Pyx_RaiseArgtupleInvalid("__init__", 1, 0, 0, PyTuple_GET_SIZE(__pyx_args)); return -1;}
+  if (unlikely(__pyx_kwds) && unlikely(PyDict_Size(__pyx_kwds) > 0) && unlikely(!__Pyx_CheckKeywordStrings(__pyx_kwds, "__init__", 0))) return -1;
+  __pyx_r = __pyx_pf_2bx_11_seqmapping_21CharToIntArrayMapping_2__init__(((struct __pyx_obj_2bx_11_seqmapping_CharToIntArrayMapping *)__pyx_v_self));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/_seqmapping.pyx":32
+ *         self.out_size = 0
+ * 
+ *     def __init__( self ):             # <<<<<<<<<<<<<<
+ *         self.reverse_table = dict()
+ * 
+ */
+
+static int __pyx_pf_2bx_11_seqmapping_21CharToIntArrayMapping_2__init__(struct __pyx_obj_2bx_11_seqmapping_CharToIntArrayMapping *__pyx_v_self) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__init__", 0);
+
+  /* "bx/_seqmapping.pyx":33
+ * 
+ *     def __init__( self ):
+ *         self.reverse_table = dict()             # <<<<<<<<<<<<<<
+ * 
+ *     def set_mapping( self, c, int symbol ):
+ */
+  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 33; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(((PyObject *)__pyx_t_1));
+  __Pyx_GIVEREF(((PyObject *)__pyx_t_1));
+  __Pyx_GOTREF(__pyx_v_self->reverse_table);
+  __Pyx_DECREF(__pyx_v_self->reverse_table);
+  __pyx_v_self->reverse_table = ((PyObject *)__pyx_t_1);
+  __pyx_t_1 = 0;
+
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("bx._seqmapping.CharToIntArrayMapping.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = -1;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_11_seqmapping_21CharToIntArrayMapping_5set_mapping(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_2bx_11_seqmapping_21CharToIntArrayMapping_4set_mapping[] = "Modify mapping so 'chars' map to 'symbol'";
+static PyObject *__pyx_pw_2bx_11_seqmapping_21CharToIntArrayMapping_5set_mapping(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_c = 0;
+  int __pyx_v_symbol;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("set_mapping (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__c,&__pyx_n_s__symbol,0};
+    PyObject* values[2] = {0,0};
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__c)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__symbol)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("set_mapping", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 35; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "set_mapping") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 35; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
+      goto __pyx_L5_argtuple_error;
+    } else {
+      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+    }
+    __pyx_v_c = values[0];
+    __pyx_v_symbol = __Pyx_PyInt_AsInt(values[1]); if (unlikely((__pyx_v_symbol == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 35; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("set_mapping", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 35; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx._seqmapping.CharToIntArrayMapping.set_mapping", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_11_seqmapping_21CharToIntArrayMapping_4set_mapping(((struct __pyx_obj_2bx_11_seqmapping_CharToIntArrayMapping *)__pyx_v_self), __pyx_v_c, __pyx_v_symbol);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/_seqmapping.pyx":35
+ *         self.reverse_table = dict()
+ * 
+ *     def set_mapping( self, c, int symbol ):             # <<<<<<<<<<<<<<
+ *         """Modify mapping so 'chars' map to 'symbol'"""
+ *         char = ord( c )
+ */
+
+static PyObject *__pyx_pf_2bx_11_seqmapping_21CharToIntArrayMapping_4set_mapping(struct __pyx_obj_2bx_11_seqmapping_CharToIntArrayMapping *__pyx_v_self, PyObject *__pyx_v_c, int __pyx_v_symbol) {
+  PyObject *__pyx_v_char = NULL;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  Py_ssize_t __pyx_t_3;
+  int __pyx_t_4;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("set_mapping", 0);
+
+  /* "bx/_seqmapping.pyx":37
+ *     def set_mapping( self, c, int symbol ):
+ *         """Modify mapping so 'chars' map to 'symbol'"""
+ *         char = ord( c )             # <<<<<<<<<<<<<<
+ *         self.table[ char ] = symbol
+ *         if self.out_size <= symbol:
+ */
+  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 37; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_INCREF(__pyx_v_c);
+  PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_c);
+  __Pyx_GIVEREF(__pyx_v_c);
+  __pyx_t_2 = PyObject_Call(__pyx_builtin_ord, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 37; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+  __pyx_v_char = __pyx_t_2;
+  __pyx_t_2 = 0;
+
+  /* "bx/_seqmapping.pyx":38
+ *         """Modify mapping so 'chars' map to 'symbol'"""
+ *         char = ord( c )
+ *         self.table[ char ] = symbol             # <<<<<<<<<<<<<<
+ *         if self.out_size <= symbol:
+ *             self.out_size = symbol + 1
+ */
+  __pyx_t_3 = __Pyx_PyIndex_AsSsize_t(__pyx_v_char); if (unlikely((__pyx_t_3 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 38; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  (__pyx_v_self->table[__pyx_t_3]) = __pyx_v_symbol;
+
+  /* "bx/_seqmapping.pyx":39
+ *         char = ord( c )
+ *         self.table[ char ] = symbol
+ *         if self.out_size <= symbol:             # <<<<<<<<<<<<<<
+ *             self.out_size = symbol + 1
+ *         self.reverse_table[ symbol ] = chr( char )
+ */
+  __pyx_t_4 = (__pyx_v_self->out_size <= __pyx_v_symbol);
+  if (__pyx_t_4) {
+
+    /* "bx/_seqmapping.pyx":40
+ *         self.table[ char ] = symbol
+ *         if self.out_size <= symbol:
+ *             self.out_size = symbol + 1             # <<<<<<<<<<<<<<
+ *         self.reverse_table[ symbol ] = chr( char )
+ * 
+ */
+    __pyx_v_self->out_size = (__pyx_v_symbol + 1);
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  /* "bx/_seqmapping.pyx":41
+ *         if self.out_size <= symbol:
+ *             self.out_size = symbol + 1
+ *         self.reverse_table[ symbol ] = chr( char )             # <<<<<<<<<<<<<<
+ * 
+ *     def translate( self, string ):
+ */
+  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 41; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_INCREF(__pyx_v_char);
+  PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_char);
+  __Pyx_GIVEREF(__pyx_v_char);
+  __pyx_t_1 = PyObject_Call(__pyx_builtin_chr, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 41; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
+  if (__Pyx_SetItemInt(__pyx_v_self->reverse_table, __pyx_v_symbol, __pyx_t_1, sizeof(int), PyInt_FromLong) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 41; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_AddTraceback("bx._seqmapping.CharToIntArrayMapping.set_mapping", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_char);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_11_seqmapping_21CharToIntArrayMapping_7translate(PyObject *__pyx_v_self, PyObject *__pyx_v_string); /*proto*/
+static char __pyx_doc_2bx_11_seqmapping_21CharToIntArrayMapping_6translate[] = "Translate 'string' and return as int array";
+static PyObject *__pyx_pw_2bx_11_seqmapping_21CharToIntArrayMapping_7translate(PyObject *__pyx_v_self, PyObject *__pyx_v_string) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("translate (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_11_seqmapping_21CharToIntArrayMapping_6translate(((struct __pyx_obj_2bx_11_seqmapping_CharToIntArrayMapping *)__pyx_v_self), ((PyObject *)__pyx_v_string));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/_seqmapping.pyx":43
+ *         self.reverse_table[ symbol ] = chr( char )
+ * 
+ *     def translate( self, string ):             # <<<<<<<<<<<<<<
+ *         """Translate 'string' and return as int array"""
+ *         cdef int s_len, t_len
+ */
+
+static PyObject *__pyx_pf_2bx_11_seqmapping_21CharToIntArrayMapping_6translate(struct __pyx_obj_2bx_11_seqmapping_CharToIntArrayMapping *__pyx_v_self, PyObject *__pyx_v_string) {
+  int __pyx_v_s_len;
+  int __pyx_v_t_len;
+  unsigned char *__pyx_v_s_buf;
+  int *__pyx_v_t_buf;
+  PyObject *__pyx_v_rval = NULL;
+  long __pyx_v_i;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("translate", 0);
+
+  /* "bx/_seqmapping.pyx":49
+ *         cdef int * t_buf
+ *         # Get direct access to string
+ *         PyString_AsStringAndSize( string, <char **> &s_buf, &s_len )             # <<<<<<<<<<<<<<
+ *         # Initialize empty array
+ *         rval = zeros( s_len, 'i' )
+ */
+  __pyx_t_1 = PyString_AsStringAndSize(__pyx_v_string, ((char **)(&__pyx_v_s_buf)), (&__pyx_v_s_len)); if (unlikely(__pyx_t_1 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 49; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "bx/_seqmapping.pyx":51
+ *         PyString_AsStringAndSize( string, <char **> &s_buf, &s_len )
+ *         # Initialize empty array
+ *         rval = zeros( s_len, 'i' )             # <<<<<<<<<<<<<<
+ *         PyObject_AsWriteBuffer( rval, <void **> &t_buf, &t_len )
+ *         # Translate
+ */
+  __pyx_t_2 = __Pyx_GetName(__pyx_m, __pyx_n_s__zeros); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 51; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = PyInt_FromLong(__pyx_v_s_len); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 51; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 51; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
+  __Pyx_GIVEREF(__pyx_t_3);
+  __Pyx_INCREF(((PyObject *)__pyx_n_s__i));
+  PyTuple_SET_ITEM(__pyx_t_4, 1, ((PyObject *)__pyx_n_s__i));
+  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__i));
+  __pyx_t_3 = 0;
+  __pyx_t_3 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_4), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 51; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
+  __pyx_v_rval = __pyx_t_3;
+  __pyx_t_3 = 0;
+
+  /* "bx/_seqmapping.pyx":52
+ *         # Initialize empty array
+ *         rval = zeros( s_len, 'i' )
+ *         PyObject_AsWriteBuffer( rval, <void **> &t_buf, &t_len )             # <<<<<<<<<<<<<<
+ *         # Translate
+ *         for i from 0 <= i < s_len:
+ */
+  __pyx_t_1 = PyObject_AsWriteBuffer(__pyx_v_rval, ((void **)(&__pyx_v_t_buf)), (&__pyx_v_t_len)); if (unlikely(__pyx_t_1 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 52; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "bx/_seqmapping.pyx":54
+ *         PyObject_AsWriteBuffer( rval, <void **> &t_buf, &t_len )
+ *         # Translate
+ *         for i from 0 <= i < s_len:             # <<<<<<<<<<<<<<
+ *             t_buf[i] = self.table[ s_buf[ i ] ]
+ *         # Done
+ */
+  __pyx_t_1 = __pyx_v_s_len;
+  for (__pyx_v_i = 0; __pyx_v_i < __pyx_t_1; __pyx_v_i++) {
+
+    /* "bx/_seqmapping.pyx":55
+ *         # Translate
+ *         for i from 0 <= i < s_len:
+ *             t_buf[i] = self.table[ s_buf[ i ] ]             # <<<<<<<<<<<<<<
+ *         # Done
+ *         return rval
+ */
+    (__pyx_v_t_buf[__pyx_v_i]) = (__pyx_v_self->table[(__pyx_v_s_buf[__pyx_v_i])]);
+  }
+
+  /* "bx/_seqmapping.pyx":57
+ *             t_buf[i] = self.table[ s_buf[ i ] ]
+ *         # Done
+ *         return rval             # <<<<<<<<<<<<<<
+ * 
+ *     def translate_list( self, strings ):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __Pyx_INCREF(__pyx_v_rval);
+  __pyx_r = __pyx_v_rval;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_AddTraceback("bx._seqmapping.CharToIntArrayMapping.translate", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_rval);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_11_seqmapping_21CharToIntArrayMapping_9translate_list(PyObject *__pyx_v_self, PyObject *__pyx_v_strings); /*proto*/
+static char __pyx_doc_2bx_11_seqmapping_21CharToIntArrayMapping_8translate_list[] = "Translate a list of strings into an int array";
+static PyObject *__pyx_pw_2bx_11_seqmapping_21CharToIntArrayMapping_9translate_list(PyObject *__pyx_v_self, PyObject *__pyx_v_strings) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("translate_list (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_11_seqmapping_21CharToIntArrayMapping_8translate_list(((struct __pyx_obj_2bx_11_seqmapping_CharToIntArrayMapping *)__pyx_v_self), ((PyObject *)__pyx_v_strings));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/_seqmapping.pyx":59
+ *         return rval
+ * 
+ *     def translate_list( self, strings ):             # <<<<<<<<<<<<<<
+ *         """Translate a list of strings into an int array"""
+ *         cdef int text_len, factor, i
+ */
+
+static PyObject *__pyx_pf_2bx_11_seqmapping_21CharToIntArrayMapping_8translate_list(struct __pyx_obj_2bx_11_seqmapping_CharToIntArrayMapping *__pyx_v_self, PyObject *__pyx_v_strings) {
+  int __pyx_v_text_len;
+  int __pyx_v_factor;
+  int __pyx_v_i;
+  int __pyx_v_s_len;
+  int __pyx_v_t_len;
+  unsigned char *__pyx_v_s_buf;
+  int *__pyx_v_t_buf;
+  PyObject *__pyx_v_rval = NULL;
+  PyObject *__pyx_v_string = NULL;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  Py_ssize_t __pyx_t_1;
+  int __pyx_t_2;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  PyObject *__pyx_t_5 = NULL;
+  int __pyx_t_6;
+  PyObject *(*__pyx_t_7)(PyObject *);
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("translate_list", 0);
+
+  /* "bx/_seqmapping.pyx":67
+ * 
+ *         # No input, no output
+ *         if len( strings ) < 1: return None             # <<<<<<<<<<<<<<
+ * 
+ *         # Length of result
+ */
+  __pyx_t_1 = PyObject_Length(__pyx_v_strings); if (unlikely(__pyx_t_1 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 67; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = (__pyx_t_1 < 1);
+  if (__pyx_t_2) {
+    __Pyx_XDECREF(__pyx_r);
+    __Pyx_INCREF(Py_None);
+    __pyx_r = Py_None;
+    goto __pyx_L0;
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  /* "bx/_seqmapping.pyx":70
+ * 
+ *         # Length of result
+ *         text_len = len( strings[0] )             # <<<<<<<<<<<<<<
+ * 
+ *         # Init result array
+ */
+  __pyx_t_3 = __Pyx_GetItemInt(__pyx_v_strings, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 70; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_1 = PyObject_Length(__pyx_t_3); if (unlikely(__pyx_t_1 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 70; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __pyx_v_text_len = __pyx_t_1;
+
+  /* "bx/_seqmapping.pyx":73
+ * 
+ *         # Init result array
+ *         rval = zeros( text_len, 'i' )             # <<<<<<<<<<<<<<
+ *         PyObject_AsWriteBuffer( rval, <void **> &t_buf, &t_len )
+ * 
+ */
+  __pyx_t_3 = __Pyx_GetName(__pyx_m, __pyx_n_s__zeros); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 73; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_4 = PyInt_FromLong(__pyx_v_text_len); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 73; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 73; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_4);
+  __Pyx_GIVEREF(__pyx_t_4);
+  __Pyx_INCREF(((PyObject *)__pyx_n_s__i));
+  PyTuple_SET_ITEM(__pyx_t_5, 1, ((PyObject *)__pyx_n_s__i));
+  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__i));
+  __pyx_t_4 = 0;
+  __pyx_t_4 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_t_5), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 73; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_5)); __pyx_t_5 = 0;
+  __pyx_v_rval = __pyx_t_4;
+  __pyx_t_4 = 0;
+
+  /* "bx/_seqmapping.pyx":74
+ *         # Init result array
+ *         rval = zeros( text_len, 'i' )
+ *         PyObject_AsWriteBuffer( rval, <void **> &t_buf, &t_len )             # <<<<<<<<<<<<<<
+ * 
+ *         # Loop over seqs and accumulate result values
+ */
+  __pyx_t_6 = PyObject_AsWriteBuffer(__pyx_v_rval, ((void **)(&__pyx_v_t_buf)), (&__pyx_v_t_len)); if (unlikely(__pyx_t_6 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 74; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "bx/_seqmapping.pyx":77
+ * 
+ *         # Loop over seqs and accumulate result values
+ *         factor = 1             # <<<<<<<<<<<<<<
+ *         for string in strings:
+ *             PyString_AsStringAndSize( string, <char **> &s_buf, &s_len )
+ */
+  __pyx_v_factor = 1;
+
+  /* "bx/_seqmapping.pyx":78
+ *         # Loop over seqs and accumulate result values
+ *         factor = 1
+ *         for string in strings:             # <<<<<<<<<<<<<<
+ *             PyString_AsStringAndSize( string, <char **> &s_buf, &s_len )
+ *             for i from 0 <= i < text_len:
+ */
+  if (PyList_CheckExact(__pyx_v_strings) || PyTuple_CheckExact(__pyx_v_strings)) {
+    __pyx_t_4 = __pyx_v_strings; __Pyx_INCREF(__pyx_t_4); __pyx_t_1 = 0;
+    __pyx_t_7 = NULL;
+  } else {
+    __pyx_t_1 = -1; __pyx_t_4 = PyObject_GetIter(__pyx_v_strings); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 78; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    __pyx_t_7 = Py_TYPE(__pyx_t_4)->tp_iternext;
+  }
+  for (;;) {
+    if (!__pyx_t_7 && PyList_CheckExact(__pyx_t_4)) {
+      if (__pyx_t_1 >= PyList_GET_SIZE(__pyx_t_4)) break;
+      #if CYTHON_COMPILING_IN_CPYTHON
+      __pyx_t_5 = PyList_GET_ITEM(__pyx_t_4, __pyx_t_1); __Pyx_INCREF(__pyx_t_5); __pyx_t_1++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 78; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      #else
+      __pyx_t_5 = PySequence_ITEM(__pyx_t_4, __pyx_t_1); __pyx_t_1++; if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 78; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      #endif
+    } else if (!__pyx_t_7 && PyTuple_CheckExact(__pyx_t_4)) {
+      if (__pyx_t_1 >= PyTuple_GET_SIZE(__pyx_t_4)) break;
+      #if CYTHON_COMPILING_IN_CPYTHON
+      __pyx_t_5 = PyTuple_GET_ITEM(__pyx_t_4, __pyx_t_1); __Pyx_INCREF(__pyx_t_5); __pyx_t_1++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 78; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      #else
+      __pyx_t_5 = PySequence_ITEM(__pyx_t_4, __pyx_t_1); __pyx_t_1++; if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 78; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      #endif
+    } else {
+      __pyx_t_5 = __pyx_t_7(__pyx_t_4);
+      if (unlikely(!__pyx_t_5)) {
+        if (PyErr_Occurred()) {
+          if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
+          else {__pyx_filename = __pyx_f[0]; __pyx_lineno = 78; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        }
+        break;
+      }
+      __Pyx_GOTREF(__pyx_t_5);
+    }
+    __Pyx_XDECREF(__pyx_v_string);
+    __pyx_v_string = __pyx_t_5;
+    __pyx_t_5 = 0;
+
+    /* "bx/_seqmapping.pyx":79
+ *         factor = 1
+ *         for string in strings:
+ *             PyString_AsStringAndSize( string, <char **> &s_buf, &s_len )             # <<<<<<<<<<<<<<
+ *             for i from 0 <= i < text_len:
+ *                 if t_buf[i] >= 0:
+ */
+    __pyx_t_6 = PyString_AsStringAndSize(__pyx_v_string, ((char **)(&__pyx_v_s_buf)), (&__pyx_v_s_len)); if (unlikely(__pyx_t_6 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 79; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+    /* "bx/_seqmapping.pyx":80
+ *         for string in strings:
+ *             PyString_AsStringAndSize( string, <char **> &s_buf, &s_len )
+ *             for i from 0 <= i < text_len:             # <<<<<<<<<<<<<<
+ *                 if t_buf[i] >= 0:
+ *                     if self.table[ s_buf[i] ] == -1:
+ */
+    __pyx_t_6 = __pyx_v_text_len;
+    for (__pyx_v_i = 0; __pyx_v_i < __pyx_t_6; __pyx_v_i++) {
+
+      /* "bx/_seqmapping.pyx":81
+ *             PyString_AsStringAndSize( string, <char **> &s_buf, &s_len )
+ *             for i from 0 <= i < text_len:
+ *                 if t_buf[i] >= 0:             # <<<<<<<<<<<<<<
+ *                     if self.table[ s_buf[i] ] == -1:
+ *                         t_buf[i] = -1
+ */
+      __pyx_t_2 = ((__pyx_v_t_buf[__pyx_v_i]) >= 0);
+      if (__pyx_t_2) {
+
+        /* "bx/_seqmapping.pyx":82
+ *             for i from 0 <= i < text_len:
+ *                 if t_buf[i] >= 0:
+ *                     if self.table[ s_buf[i] ] == -1:             # <<<<<<<<<<<<<<
+ *                         t_buf[i] = -1
+ *                     else:
+ */
+        __pyx_t_2 = ((__pyx_v_self->table[(__pyx_v_s_buf[__pyx_v_i])]) == -1);
+        if (__pyx_t_2) {
+
+          /* "bx/_seqmapping.pyx":83
+ *                 if t_buf[i] >= 0:
+ *                     if self.table[ s_buf[i] ] == -1:
+ *                         t_buf[i] = -1             # <<<<<<<<<<<<<<
+ *                     else:
+ *                         t_buf[i] = t_buf[i] + ( self.table[ s_buf[i] ] * factor )
+ */
+          (__pyx_v_t_buf[__pyx_v_i]) = -1;
+          goto __pyx_L9;
+        }
+        /*else*/ {
+
+          /* "bx/_seqmapping.pyx":85
+ *                         t_buf[i] = -1
+ *                     else:
+ *                         t_buf[i] = t_buf[i] + ( self.table[ s_buf[i] ] * factor )             # <<<<<<<<<<<<<<
+ *             factor = factor * self.out_size
+ *         return rval
+ */
+          (__pyx_v_t_buf[__pyx_v_i]) = ((__pyx_v_t_buf[__pyx_v_i]) + ((__pyx_v_self->table[(__pyx_v_s_buf[__pyx_v_i])]) * __pyx_v_factor));
+        }
+        __pyx_L9:;
+        goto __pyx_L8;
+      }
+      __pyx_L8:;
+    }
+
+    /* "bx/_seqmapping.pyx":86
+ *                     else:
+ *                         t_buf[i] = t_buf[i] + ( self.table[ s_buf[i] ] * factor )
+ *             factor = factor * self.out_size             # <<<<<<<<<<<<<<
+ *         return rval
+ * 
+ */
+    __pyx_v_factor = (__pyx_v_factor * __pyx_v_self->out_size);
+  }
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+
+  /* "bx/_seqmapping.pyx":87
+ *                         t_buf[i] = t_buf[i] + ( self.table[ s_buf[i] ] * factor )
+ *             factor = factor * self.out_size
+ *         return rval             # <<<<<<<<<<<<<<
+ * 
+ *     def reverse_map( self, val, nseqs ):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __Pyx_INCREF(__pyx_v_rval);
+  __pyx_r = __pyx_v_rval;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_XDECREF(__pyx_t_5);
+  __Pyx_AddTraceback("bx._seqmapping.CharToIntArrayMapping.translate_list", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_rval);
+  __Pyx_XDECREF(__pyx_v_string);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_11_seqmapping_21CharToIntArrayMapping_11reverse_map(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyObject *__pyx_pw_2bx_11_seqmapping_21CharToIntArrayMapping_11reverse_map(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_val = 0;
+  PyObject *__pyx_v_nseqs = 0;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("reverse_map (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__val,&__pyx_n_s__nseqs,0};
+    PyObject* values[2] = {0,0};
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__val)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__nseqs)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("reverse_map", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 89; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "reverse_map") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 89; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
+      goto __pyx_L5_argtuple_error;
+    } else {
+      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+    }
+    __pyx_v_val = values[0];
+    __pyx_v_nseqs = values[1];
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("reverse_map", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 89; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx._seqmapping.CharToIntArrayMapping.reverse_map", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_11_seqmapping_21CharToIntArrayMapping_10reverse_map(((struct __pyx_obj_2bx_11_seqmapping_CharToIntArrayMapping *)__pyx_v_self), __pyx_v_val, __pyx_v_nseqs);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/_seqmapping.pyx":89
+ *         return rval
+ * 
+ *     def reverse_map( self, val, nseqs ):             # <<<<<<<<<<<<<<
+ *         factor = self.out_size ** (nseqs-1)
+ *         rval = []
+ */
+
+static PyObject *__pyx_pf_2bx_11_seqmapping_21CharToIntArrayMapping_10reverse_map(struct __pyx_obj_2bx_11_seqmapping_CharToIntArrayMapping *__pyx_v_self, PyObject *__pyx_v_val, PyObject *__pyx_v_nseqs) {
+  PyObject *__pyx_v_factor = NULL;
+  PyObject *__pyx_v_rval = NULL;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  int __pyx_t_4;
+  int __pyx_t_5;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("reverse_map", 0);
+  __Pyx_INCREF(__pyx_v_val);
+
+  /* "bx/_seqmapping.pyx":90
+ * 
+ *     def reverse_map( self, val, nseqs ):
+ *         factor = self.out_size ** (nseqs-1)             # <<<<<<<<<<<<<<
+ *         rval = []
+ *         while factor > 0:
+ */
+  __pyx_t_1 = PyInt_FromLong(__pyx_v_self->out_size); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 90; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = PyNumber_Subtract(__pyx_v_nseqs, __pyx_int_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 90; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = PyNumber_Power(__pyx_t_1, __pyx_t_2, Py_None); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 90; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_v_factor = __pyx_t_3;
+  __pyx_t_3 = 0;
+
+  /* "bx/_seqmapping.pyx":91
+ *     def reverse_map( self, val, nseqs ):
+ *         factor = self.out_size ** (nseqs-1)
+ *         rval = []             # <<<<<<<<<<<<<<
+ *         while factor > 0:
+ *             rval.append( self.reverse_table[ int( floor( val / factor ) ) ] )
+ */
+  __pyx_t_3 = PyList_New(0); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 91; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_v_rval = ((PyObject*)__pyx_t_3);
+  __pyx_t_3 = 0;
+
+  /* "bx/_seqmapping.pyx":92
+ *         factor = self.out_size ** (nseqs-1)
+ *         rval = []
+ *         while factor > 0:             # <<<<<<<<<<<<<<
+ *             rval.append( self.reverse_table[ int( floor( val / factor ) ) ] )
+ *             val = val - ( floor(val/factor) * factor )
+ */
+  while (1) {
+    __pyx_t_3 = PyObject_RichCompare(__pyx_v_factor, __pyx_int_0, Py_GT); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 92; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 92; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    if (!__pyx_t_4) break;
+
+    /* "bx/_seqmapping.pyx":93
+ *         rval = []
+ *         while factor > 0:
+ *             rval.append( self.reverse_table[ int( floor( val / factor ) ) ] )             # <<<<<<<<<<<<<<
+ *             val = val - ( floor(val/factor) * factor )
+ *             factor = floor( factor / self.out_size )
+ */
+    __pyx_t_3 = __Pyx_GetName(__pyx_m, __pyx_n_s__floor); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 93; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __pyx_t_2 = __Pyx_PyNumber_Divide(__pyx_v_val, __pyx_v_factor); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 93; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 93; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_2);
+    __Pyx_GIVEREF(__pyx_t_2);
+    __pyx_t_2 = 0;
+    __pyx_t_2 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 93; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+    __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 93; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_2);
+    __Pyx_GIVEREF(__pyx_t_2);
+    __pyx_t_2 = 0;
+    __pyx_t_2 = PyObject_Call(((PyObject *)((PyObject*)(&PyInt_Type))), ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 93; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+    __pyx_t_1 = PyObject_GetItem(__pyx_v_self->reverse_table, __pyx_t_2); if (!__pyx_t_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 93; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    __pyx_t_5 = PyList_Append(__pyx_v_rval, __pyx_t_1); if (unlikely(__pyx_t_5 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 93; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+    /* "bx/_seqmapping.pyx":94
+ *         while factor > 0:
+ *             rval.append( self.reverse_table[ int( floor( val / factor ) ) ] )
+ *             val = val - ( floor(val/factor) * factor )             # <<<<<<<<<<<<<<
+ *             factor = floor( factor / self.out_size )
+ *         rval.reverse()
+ */
+    __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__floor); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 94; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __pyx_t_2 = __Pyx_PyNumber_Divide(__pyx_v_val, __pyx_v_factor); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 94; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 94; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_2);
+    __Pyx_GIVEREF(__pyx_t_2);
+    __pyx_t_2 = 0;
+    __pyx_t_2 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 94; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
+    __pyx_t_3 = PyNumber_Multiply(__pyx_t_2, __pyx_v_factor); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 94; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    __pyx_t_2 = PyNumber_Subtract(__pyx_v_val, __pyx_t_3); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 94; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __Pyx_DECREF(__pyx_v_val);
+    __pyx_v_val = __pyx_t_2;
+    __pyx_t_2 = 0;
+
+    /* "bx/_seqmapping.pyx":95
+ *             rval.append( self.reverse_table[ int( floor( val / factor ) ) ] )
+ *             val = val - ( floor(val/factor) * factor )
+ *             factor = floor( factor / self.out_size )             # <<<<<<<<<<<<<<
+ *         rval.reverse()
+ *         return rval
+ */
+    __pyx_t_2 = __Pyx_GetName(__pyx_m, __pyx_n_s__floor); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 95; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_t_3 = PyInt_FromLong(__pyx_v_self->out_size); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 95; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __pyx_t_1 = __Pyx_PyNumber_Divide(__pyx_v_factor, __pyx_t_3); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 95; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 95; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1);
+    __Pyx_GIVEREF(__pyx_t_1);
+    __pyx_t_1 = 0;
+    __pyx_t_1 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 95; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
+    __Pyx_DECREF(__pyx_v_factor);
+    __pyx_v_factor = __pyx_t_1;
+    __pyx_t_1 = 0;
+  }
+
+  /* "bx/_seqmapping.pyx":96
+ *             val = val - ( floor(val/factor) * factor )
+ *             factor = floor( factor / self.out_size )
+ *         rval.reverse()             # <<<<<<<<<<<<<<
+ *         return rval
+ * 
+ */
+  __pyx_t_5 = PyList_Reverse(__pyx_v_rval); if (unlikely(__pyx_t_5 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 96; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "bx/_seqmapping.pyx":97
+ *             factor = floor( factor / self.out_size )
+ *         rval.reverse()
+ *         return rval             # <<<<<<<<<<<<<<
+ * 
+ *     def get_out_size( self ):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __Pyx_INCREF(((PyObject *)__pyx_v_rval));
+  __pyx_r = ((PyObject *)__pyx_v_rval);
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_AddTraceback("bx._seqmapping.CharToIntArrayMapping.reverse_map", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_factor);
+  __Pyx_XDECREF(__pyx_v_rval);
+  __Pyx_XDECREF(__pyx_v_val);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_11_seqmapping_21CharToIntArrayMapping_13get_out_size(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static PyObject *__pyx_pw_2bx_11_seqmapping_21CharToIntArrayMapping_13get_out_size(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("get_out_size (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_11_seqmapping_21CharToIntArrayMapping_12get_out_size(((struct __pyx_obj_2bx_11_seqmapping_CharToIntArrayMapping *)__pyx_v_self));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/_seqmapping.pyx":99
+ *         return rval
+ * 
+ *     def get_out_size( self ):             # <<<<<<<<<<<<<<
+ *         return self.out_size
+ * 
+ */
+
+static PyObject *__pyx_pf_2bx_11_seqmapping_21CharToIntArrayMapping_12get_out_size(struct __pyx_obj_2bx_11_seqmapping_CharToIntArrayMapping *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("get_out_size", 0);
+
+  /* "bx/_seqmapping.pyx":100
+ * 
+ *     def get_out_size( self ):
+ *         return self.out_size             # <<<<<<<<<<<<<<
+ * 
+ * cdef class IntToIntMapping:
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = PyInt_FromLong(__pyx_v_self->out_size); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 100; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("bx._seqmapping.CharToIntArrayMapping.get_out_size", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_2bx_11_seqmapping_15IntToIntMapping_1__cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static int __pyx_pw_2bx_11_seqmapping_15IntToIntMapping_1__cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  int __pyx_v_in_size;
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__cinit__ (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__in_size,0};
+    PyObject* values[1] = {0};
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__in_size)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__cinit__") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 108; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else if (PyTuple_GET_SIZE(__pyx_args) != 1) {
+      goto __pyx_L5_argtuple_error;
+    } else {
+      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+    }
+    __pyx_v_in_size = __Pyx_PyInt_AsInt(values[0]); if (unlikely((__pyx_v_in_size == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 108; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("__cinit__", 1, 1, 1, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 108; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx._seqmapping.IntToIntMapping.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return -1;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_11_seqmapping_15IntToIntMapping___cinit__(((struct __pyx_obj_2bx_11_seqmapping_IntToIntMapping *)__pyx_v_self), __pyx_v_in_size);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/_seqmapping.pyx":108
+ *     cdef int out_size
+ * 
+ *     def __cinit__( self, int in_size ):             # <<<<<<<<<<<<<<
+ *         self.in_size = in_size
+ *         self.table = <int *> malloc( in_size * sizeof( int ) )
+ */
+
+static int __pyx_pf_2bx_11_seqmapping_15IntToIntMapping___cinit__(struct __pyx_obj_2bx_11_seqmapping_IntToIntMapping *__pyx_v_self, int __pyx_v_in_size) {
+  long __pyx_v_i;
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  int __pyx_t_2;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__cinit__", 0);
+
+  /* "bx/_seqmapping.pyx":109
+ * 
+ *     def __cinit__( self, int in_size ):
+ *         self.in_size = in_size             # <<<<<<<<<<<<<<
+ *         self.table = <int *> malloc( in_size * sizeof( int ) )
+ *         if self.table == NULL: raise "Malloc Failed"
+ */
+  __pyx_v_self->in_size = __pyx_v_in_size;
+
+  /* "bx/_seqmapping.pyx":110
+ *     def __cinit__( self, int in_size ):
+ *         self.in_size = in_size
+ *         self.table = <int *> malloc( in_size * sizeof( int ) )             # <<<<<<<<<<<<<<
+ *         if self.table == NULL: raise "Malloc Failed"
+ *         for i from 0 <= i < in_size: self.table[i] = -1
+ */
+  __pyx_v_self->table = ((int *)malloc((__pyx_v_in_size * (sizeof(int)))));
+
+  /* "bx/_seqmapping.pyx":111
+ *         self.in_size = in_size
+ *         self.table = <int *> malloc( in_size * sizeof( int ) )
+ *         if self.table == NULL: raise "Malloc Failed"             # <<<<<<<<<<<<<<
+ *         for i from 0 <= i < in_size: self.table[i] = -1
+ *         self.out_size = 0
+ */
+  __pyx_t_1 = (__pyx_v_self->table == NULL);
+  if (__pyx_t_1) {
+    __Pyx_Raise(((PyObject *)__pyx_kp_s_1), 0, 0, 0);
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 111; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  /* "bx/_seqmapping.pyx":112
+ *         self.table = <int *> malloc( in_size * sizeof( int ) )
+ *         if self.table == NULL: raise "Malloc Failed"
+ *         for i from 0 <= i < in_size: self.table[i] = -1             # <<<<<<<<<<<<<<
+ *         self.out_size = 0
+ * 
+ */
+  __pyx_t_2 = __pyx_v_in_size;
+  for (__pyx_v_i = 0; __pyx_v_i < __pyx_t_2; __pyx_v_i++) {
+    (__pyx_v_self->table[__pyx_v_i]) = -1;
+  }
+
+  /* "bx/_seqmapping.pyx":113
+ *         if self.table == NULL: raise "Malloc Failed"
+ *         for i from 0 <= i < in_size: self.table[i] = -1
+ *         self.out_size = 0             # <<<<<<<<<<<<<<
+ * 
+ *     def __dealloc__( self ):
+ */
+  __pyx_v_self->out_size = 0;
+
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_AddTraceback("bx._seqmapping.IntToIntMapping.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = -1;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static void __pyx_pw_2bx_11_seqmapping_15IntToIntMapping_3__dealloc__(PyObject *__pyx_v_self); /*proto*/
+static void __pyx_pw_2bx_11_seqmapping_15IntToIntMapping_3__dealloc__(PyObject *__pyx_v_self) {
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__dealloc__ (wrapper)", 0);
+  __pyx_pf_2bx_11_seqmapping_15IntToIntMapping_2__dealloc__(((struct __pyx_obj_2bx_11_seqmapping_IntToIntMapping *)__pyx_v_self));
+  __Pyx_RefNannyFinishContext();
+}
+
+/* "bx/_seqmapping.pyx":115
+ *         self.out_size = 0
+ * 
+ *     def __dealloc__( self ):             # <<<<<<<<<<<<<<
+ *         # sys.stderr.write( "freeing mapping_helper.IntToIntMapping\n" ); sys.stderr.flush()
+ *         free( self.table )
+ */
+
+static void __pyx_pf_2bx_11_seqmapping_15IntToIntMapping_2__dealloc__(struct __pyx_obj_2bx_11_seqmapping_IntToIntMapping *__pyx_v_self) {
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__dealloc__", 0);
+
+  /* "bx/_seqmapping.pyx":117
+ *     def __dealloc__( self ):
+ *         # sys.stderr.write( "freeing mapping_helper.IntToIntMapping\n" ); sys.stderr.flush()
+ *         free( self.table )             # <<<<<<<<<<<<<<
+ * 
+ *     def set_mapping( self, int index, int symbol ):
+ */
+  free(__pyx_v_self->table);
+
+  __Pyx_RefNannyFinishContext();
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_11_seqmapping_15IntToIntMapping_5set_mapping(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyObject *__pyx_pw_2bx_11_seqmapping_15IntToIntMapping_5set_mapping(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  int __pyx_v_index;
+  int __pyx_v_symbol;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("set_mapping (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__index,&__pyx_n_s__symbol,0};
+    PyObject* values[2] = {0,0};
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__index)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__symbol)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("set_mapping", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "set_mapping") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
+      goto __pyx_L5_argtuple_error;
+    } else {
+      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+    }
+    __pyx_v_index = __Pyx_PyInt_AsInt(values[0]); if (unlikely((__pyx_v_index == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_symbol = __Pyx_PyInt_AsInt(values[1]); if (unlikely((__pyx_v_symbol == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("set_mapping", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx._seqmapping.IntToIntMapping.set_mapping", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_11_seqmapping_15IntToIntMapping_4set_mapping(((struct __pyx_obj_2bx_11_seqmapping_IntToIntMapping *)__pyx_v_self), __pyx_v_index, __pyx_v_symbol);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/_seqmapping.pyx":119
+ *         free( self.table )
+ * 
+ *     def set_mapping( self, int index, int symbol ):             # <<<<<<<<<<<<<<
+ *         assert ( -1 <= index < self.in_size ), "%d not between 0 and %s" % ( index, self.in_size )
+ *         self.table[index] = symbol
+ */
+
+static PyObject *__pyx_pf_2bx_11_seqmapping_15IntToIntMapping_4set_mapping(struct __pyx_obj_2bx_11_seqmapping_IntToIntMapping *__pyx_v_self, int __pyx_v_index, int __pyx_v_symbol) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("set_mapping", 0);
+
+  /* "bx/_seqmapping.pyx":120
+ * 
+ *     def set_mapping( self, int index, int symbol ):
+ *         assert ( -1 <= index < self.in_size ), "%d not between 0 and %s" % ( index, self.in_size )             # <<<<<<<<<<<<<<
+ *         self.table[index] = symbol
+ *         if self.out_size <= symbol:
+ */
+  #ifndef CYTHON_WITHOUT_ASSERTIONS
+  __pyx_t_1 = (-1 <= __pyx_v_index);
+  if (__pyx_t_1) {
+    __pyx_t_1 = (__pyx_v_index < __pyx_v_self->in_size);
+  }
+  if (unlikely(!__pyx_t_1)) {
+    __pyx_t_2 = PyInt_FromLong(__pyx_v_index); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_t_3 = PyInt_FromLong(__pyx_v_self->in_size); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_2);
+    __Pyx_GIVEREF(__pyx_t_2);
+    PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_3);
+    __Pyx_GIVEREF(__pyx_t_3);
+    __pyx_t_2 = 0;
+    __pyx_t_3 = 0;
+    __pyx_t_3 = PyNumber_Remainder(((PyObject *)__pyx_kp_s_2), ((PyObject *)__pyx_t_4)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(((PyObject *)__pyx_t_3));
+    __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
+    PyErr_SetObject(PyExc_AssertionError, ((PyObject *)__pyx_t_3));
+    __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  #endif
+
+  /* "bx/_seqmapping.pyx":121
+ *     def set_mapping( self, int index, int symbol ):
+ *         assert ( -1 <= index < self.in_size ), "%d not between 0 and %s" % ( index, self.in_size )
+ *         self.table[index] = symbol             # <<<<<<<<<<<<<<
+ *         if self.out_size <= symbol:
+ *             self.out_size = symbol + 1
+ */
+  (__pyx_v_self->table[__pyx_v_index]) = __pyx_v_symbol;
+
+  /* "bx/_seqmapping.pyx":122
+ *         assert ( -1 <= index < self.in_size ), "%d not between 0 and %s" % ( index, self.in_size )
+ *         self.table[index] = symbol
+ *         if self.out_size <= symbol:             # <<<<<<<<<<<<<<
+ *             self.out_size = symbol + 1
+ * 
+ */
+  __pyx_t_1 = (__pyx_v_self->out_size <= __pyx_v_symbol);
+  if (__pyx_t_1) {
+
+    /* "bx/_seqmapping.pyx":123
+ *         self.table[index] = symbol
+ *         if self.out_size <= symbol:
+ *             self.out_size = symbol + 1             # <<<<<<<<<<<<<<
+ * 
+ *     def translate( self, src ):
+ */
+    __pyx_v_self->out_size = (__pyx_v_symbol + 1);
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_AddTraceback("bx._seqmapping.IntToIntMapping.set_mapping", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_11_seqmapping_15IntToIntMapping_7translate(PyObject *__pyx_v_self, PyObject *__pyx_v_src); /*proto*/
+static char __pyx_doc_2bx_11_seqmapping_15IntToIntMapping_6translate[] = "Translate `string` and return as int array";
+static PyObject *__pyx_pw_2bx_11_seqmapping_15IntToIntMapping_7translate(PyObject *__pyx_v_self, PyObject *__pyx_v_src) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("translate (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_11_seqmapping_15IntToIntMapping_6translate(((struct __pyx_obj_2bx_11_seqmapping_IntToIntMapping *)__pyx_v_self), ((PyObject *)__pyx_v_src));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/_seqmapping.pyx":125
+ *             self.out_size = symbol + 1
+ * 
+ *     def translate( self, src ):             # <<<<<<<<<<<<<<
+ *         """Translate `string` and return as int array"""
+ *         cdef int s_len, t_len
+ */
+
+static PyObject *__pyx_pf_2bx_11_seqmapping_15IntToIntMapping_6translate(struct __pyx_obj_2bx_11_seqmapping_IntToIntMapping *__pyx_v_self, PyObject *__pyx_v_src) {
+  int __pyx_v_s_len;
+  int __pyx_v_t_len;
+  int *__pyx_v_s_buf;
+  int *__pyx_v_t_buf;
+  PyObject *__pyx_v_rval = NULL;
+  long __pyx_v_i;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  size_t __pyx_t_2;
+  Py_ssize_t __pyx_t_3;
+  PyObject *__pyx_t_4 = NULL;
+  PyObject *__pyx_t_5 = NULL;
+  PyObject *__pyx_t_6 = NULL;
+  int __pyx_t_7;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("translate", 0);
+
+  /* "bx/_seqmapping.pyx":130
+ *         cdef int *s_buf, *t_buf
+ *         # Get direct access to string
+ *         PyObject_AsReadBuffer( src, <void **> &s_buf, &s_len )             # <<<<<<<<<<<<<<
+ *         s_len = s_len / sizeof( int )
+ *         assert s_len == len( src ), "`src` argument must be a buffer of 32bit integers"
+ */
+  __pyx_t_1 = PyObject_AsReadBuffer(__pyx_v_src, ((void **)(&__pyx_v_s_buf)), (&__pyx_v_s_len)); if (unlikely(__pyx_t_1 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "bx/_seqmapping.pyx":131
+ *         # Get direct access to string
+ *         PyObject_AsReadBuffer( src, <void **> &s_buf, &s_len )
+ *         s_len = s_len / sizeof( int )             # <<<<<<<<<<<<<<
+ *         assert s_len == len( src ), "`src` argument must be a buffer of 32bit integers"
+ *         # Initialize empty array
+ */
+  __pyx_t_2 = (sizeof(int));
+  if (unlikely(__pyx_t_2 == 0)) {
+    PyErr_Format(PyExc_ZeroDivisionError, "integer division or modulo by zero");
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 131; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  __pyx_v_s_len = (__pyx_v_s_len / __pyx_t_2);
+
+  /* "bx/_seqmapping.pyx":132
+ *         PyObject_AsReadBuffer( src, <void **> &s_buf, &s_len )
+ *         s_len = s_len / sizeof( int )
+ *         assert s_len == len( src ), "`src` argument must be a buffer of 32bit integers"             # <<<<<<<<<<<<<<
+ *         # Initialize empty array
+ *         rval = zeros( s_len, 'i' )
+ */
+  #ifndef CYTHON_WITHOUT_ASSERTIONS
+  __pyx_t_3 = PyObject_Length(__pyx_v_src); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (unlikely(!(__pyx_v_s_len == __pyx_t_3))) {
+    PyErr_SetObject(PyExc_AssertionError, ((PyObject *)__pyx_kp_s_3));
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  #endif
+
+  /* "bx/_seqmapping.pyx":134
+ *         assert s_len == len( src ), "`src` argument must be a buffer of 32bit integers"
+ *         # Initialize empty array
+ *         rval = zeros( s_len, 'i' )             # <<<<<<<<<<<<<<
+ *         PyObject_AsWriteBuffer( rval, <void **> &t_buf, &t_len )
+ *         # Translate
+ */
+  __pyx_t_4 = __Pyx_GetName(__pyx_m, __pyx_n_s__zeros); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 134; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __pyx_t_5 = PyInt_FromLong(__pyx_v_s_len); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 134; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __pyx_t_6 = PyTuple_New(2); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 134; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_6);
+  PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_5);
+  __Pyx_GIVEREF(__pyx_t_5);
+  __Pyx_INCREF(((PyObject *)__pyx_n_s__i));
+  PyTuple_SET_ITEM(__pyx_t_6, 1, ((PyObject *)__pyx_n_s__i));
+  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__i));
+  __pyx_t_5 = 0;
+  __pyx_t_5 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_t_6), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 134; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_6)); __pyx_t_6 = 0;
+  __pyx_v_rval = __pyx_t_5;
+  __pyx_t_5 = 0;
+
+  /* "bx/_seqmapping.pyx":135
+ *         # Initialize empty array
+ *         rval = zeros( s_len, 'i' )
+ *         PyObject_AsWriteBuffer( rval, <void **> &t_buf, &t_len )             # <<<<<<<<<<<<<<
+ *         # Translate
+ *         for i from 0 <= i < s_len:
+ */
+  __pyx_t_1 = PyObject_AsWriteBuffer(__pyx_v_rval, ((void **)(&__pyx_v_t_buf)), (&__pyx_v_t_len)); if (unlikely(__pyx_t_1 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 135; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "bx/_seqmapping.pyx":137
+ *         PyObject_AsWriteBuffer( rval, <void **> &t_buf, &t_len )
+ *         # Translate
+ *         for i from 0 <= i < s_len:             # <<<<<<<<<<<<<<
+ *             if s_buf[i] == -1:
+ *                 t_buf[i] = -1
+ */
+  __pyx_t_1 = __pyx_v_s_len;
+  for (__pyx_v_i = 0; __pyx_v_i < __pyx_t_1; __pyx_v_i++) {
+
+    /* "bx/_seqmapping.pyx":138
+ *         # Translate
+ *         for i from 0 <= i < s_len:
+ *             if s_buf[i] == -1:             # <<<<<<<<<<<<<<
+ *                 t_buf[i] = -1
+ *             elif s_buf[i] >= self.in_size:
+ */
+    __pyx_t_7 = ((__pyx_v_s_buf[__pyx_v_i]) == -1);
+    if (__pyx_t_7) {
+
+      /* "bx/_seqmapping.pyx":139
+ *         for i from 0 <= i < s_len:
+ *             if s_buf[i] == -1:
+ *                 t_buf[i] = -1             # <<<<<<<<<<<<<<
+ *             elif s_buf[i] >= self.in_size:
+ *                 t_buf[i] = -1
+ */
+      (__pyx_v_t_buf[__pyx_v_i]) = -1;
+      goto __pyx_L5;
+    }
+
+    /* "bx/_seqmapping.pyx":140
+ *             if s_buf[i] == -1:
+ *                 t_buf[i] = -1
+ *             elif s_buf[i] >= self.in_size:             # <<<<<<<<<<<<<<
+ *                 t_buf[i] = -1
+ *             else:
+ */
+    __pyx_t_7 = ((__pyx_v_s_buf[__pyx_v_i]) >= __pyx_v_self->in_size);
+    if (__pyx_t_7) {
+
+      /* "bx/_seqmapping.pyx":141
+ *                 t_buf[i] = -1
+ *             elif s_buf[i] >= self.in_size:
+ *                 t_buf[i] = -1             # <<<<<<<<<<<<<<
+ *             else:
+ *                 t_buf[i] = self.table[ s_buf[ i ] ]
+ */
+      (__pyx_v_t_buf[__pyx_v_i]) = -1;
+      goto __pyx_L5;
+    }
+    /*else*/ {
+
+      /* "bx/_seqmapping.pyx":143
+ *                 t_buf[i] = -1
+ *             else:
+ *                 t_buf[i] = self.table[ s_buf[ i ] ]             # <<<<<<<<<<<<<<
+ *         # Done
+ *         return rval
+ */
+      (__pyx_v_t_buf[__pyx_v_i]) = (__pyx_v_self->table[(__pyx_v_s_buf[__pyx_v_i])]);
+    }
+    __pyx_L5:;
+  }
+
+  /* "bx/_seqmapping.pyx":145
+ *                 t_buf[i] = self.table[ s_buf[ i ] ]
+ *         # Done
+ *         return rval             # <<<<<<<<<<<<<<
+ * 
+ *     def __getitem__( self, int x ):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __Pyx_INCREF(__pyx_v_rval);
+  __pyx_r = __pyx_v_rval;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_XDECREF(__pyx_t_5);
+  __Pyx_XDECREF(__pyx_t_6);
+  __Pyx_AddTraceback("bx._seqmapping.IntToIntMapping.translate", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_rval);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_11_seqmapping_15IntToIntMapping_9__getitem__(PyObject *__pyx_v_self, PyObject *__pyx_arg_x); /*proto*/
+static PyObject *__pyx_pw_2bx_11_seqmapping_15IntToIntMapping_9__getitem__(PyObject *__pyx_v_self, PyObject *__pyx_arg_x) {
+  int __pyx_v_x;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__getitem__ (wrapper)", 0);
+  assert(__pyx_arg_x); {
+    __pyx_v_x = __Pyx_PyInt_AsInt(__pyx_arg_x); if (unlikely((__pyx_v_x == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx._seqmapping.IntToIntMapping.__getitem__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_11_seqmapping_15IntToIntMapping_8__getitem__(((struct __pyx_obj_2bx_11_seqmapping_IntToIntMapping *)__pyx_v_self), ((int)__pyx_v_x));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/_seqmapping.pyx":147
+ *         return rval
+ * 
+ *     def __getitem__( self, int x ):             # <<<<<<<<<<<<<<
+ *         if x == -1: return -1
+ *         assert 0 <= x < self.in_size
+ */
+
+static PyObject *__pyx_pf_2bx_11_seqmapping_15IntToIntMapping_8__getitem__(struct __pyx_obj_2bx_11_seqmapping_IntToIntMapping *__pyx_v_self, int __pyx_v_x) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__getitem__", 0);
+
+  /* "bx/_seqmapping.pyx":148
+ * 
+ *     def __getitem__( self, int x ):
+ *         if x == -1: return -1             # <<<<<<<<<<<<<<
+ *         assert 0 <= x < self.in_size
+ *         return self.table[ x ]
+ */
+  __pyx_t_1 = (__pyx_v_x == -1);
+  if (__pyx_t_1) {
+    __Pyx_XDECREF(__pyx_r);
+    __Pyx_INCREF(__pyx_int_neg_1);
+    __pyx_r = __pyx_int_neg_1;
+    goto __pyx_L0;
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  /* "bx/_seqmapping.pyx":149
+ *     def __getitem__( self, int x ):
+ *         if x == -1: return -1
+ *         assert 0 <= x < self.in_size             # <<<<<<<<<<<<<<
+ *         return self.table[ x ]
+ * 
+ */
+  #ifndef CYTHON_WITHOUT_ASSERTIONS
+  __pyx_t_1 = (0 <= __pyx_v_x);
+  if (__pyx_t_1) {
+    __pyx_t_1 = (__pyx_v_x < __pyx_v_self->in_size);
+  }
+  if (unlikely(!__pyx_t_1)) {
+    PyErr_SetNone(PyExc_AssertionError);
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 149; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  #endif
+
+  /* "bx/_seqmapping.pyx":150
+ *         if x == -1: return -1
+ *         assert 0 <= x < self.in_size
+ *         return self.table[ x ]             # <<<<<<<<<<<<<<
+ * 
+ *     def collapse( self, int a, int b ):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_2 = PyInt_FromLong((__pyx_v_self->table[__pyx_v_x])); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 150; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_r = __pyx_t_2;
+  __pyx_t_2 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_AddTraceback("bx._seqmapping.IntToIntMapping.__getitem__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_11_seqmapping_15IntToIntMapping_11collapse(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyObject *__pyx_pw_2bx_11_seqmapping_15IntToIntMapping_11collapse(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  int __pyx_v_a;
+  int __pyx_v_b;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("collapse (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__a,&__pyx_n_s__b,0};
+    PyObject* values[2] = {0,0};
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__a)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__b)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("collapse", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 152; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "collapse") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 152; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
+      goto __pyx_L5_argtuple_error;
+    } else {
+      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+    }
+    __pyx_v_a = __Pyx_PyInt_AsInt(values[0]); if (unlikely((__pyx_v_a == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 152; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_b = __Pyx_PyInt_AsInt(values[1]); if (unlikely((__pyx_v_b == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 152; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("collapse", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 152; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx._seqmapping.IntToIntMapping.collapse", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_11_seqmapping_15IntToIntMapping_10collapse(((struct __pyx_obj_2bx_11_seqmapping_IntToIntMapping *)__pyx_v_self), __pyx_v_a, __pyx_v_b);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/_seqmapping.pyx":152
+ *         return self.table[ x ]
+ * 
+ *     def collapse( self, int a, int b ):             # <<<<<<<<<<<<<<
+ *         cdef int i
+ *         cdef IntToIntMapping copy
+ */
+
+static PyObject *__pyx_pf_2bx_11_seqmapping_15IntToIntMapping_10collapse(struct __pyx_obj_2bx_11_seqmapping_IntToIntMapping *__pyx_v_self, int __pyx_v_a, int __pyx_v_b) {
+  int __pyx_v_i;
+  struct __pyx_obj_2bx_11_seqmapping_IntToIntMapping *__pyx_v_copy = 0;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  int __pyx_t_3;
+  int __pyx_t_4;
+  int __pyx_t_5;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("collapse", 0);
+
+  /* "bx/_seqmapping.pyx":155
+ *         cdef int i
+ *         cdef IntToIntMapping copy
+ *         copy = IntToIntMapping( self.in_size )             # <<<<<<<<<<<<<<
+ *         copy.out_size = self.out_size - 1
+ *         if a > b: a, b = b, a
+ */
+  __pyx_t_1 = PyInt_FromLong(__pyx_v_self->in_size); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 155; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 155; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
+  __Pyx_GIVEREF(__pyx_t_1);
+  __pyx_t_1 = 0;
+  __pyx_t_1 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_2bx_11_seqmapping_IntToIntMapping)), ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 155; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
+  __pyx_v_copy = ((struct __pyx_obj_2bx_11_seqmapping_IntToIntMapping *)__pyx_t_1);
+  __pyx_t_1 = 0;
+
+  /* "bx/_seqmapping.pyx":156
+ *         cdef IntToIntMapping copy
+ *         copy = IntToIntMapping( self.in_size )
+ *         copy.out_size = self.out_size - 1             # <<<<<<<<<<<<<<
+ *         if a > b: a, b = b, a
+ *         for i from 0 <= i < self.in_size:
+ */
+  __pyx_v_copy->out_size = (__pyx_v_self->out_size - 1);
+
+  /* "bx/_seqmapping.pyx":157
+ *         copy = IntToIntMapping( self.in_size )
+ *         copy.out_size = self.out_size - 1
+ *         if a > b: a, b = b, a             # <<<<<<<<<<<<<<
+ *         for i from 0 <= i < self.in_size:
+ *             if self.table[i] == b: copy.table[i] = a
+ */
+  __pyx_t_3 = (__pyx_v_a > __pyx_v_b);
+  if (__pyx_t_3) {
+    __pyx_t_4 = __pyx_v_b;
+    __pyx_t_5 = __pyx_v_a;
+    __pyx_v_a = __pyx_t_4;
+    __pyx_v_b = __pyx_t_5;
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  /* "bx/_seqmapping.pyx":158
+ *         copy.out_size = self.out_size - 1
+ *         if a > b: a, b = b, a
+ *         for i from 0 <= i < self.in_size:             # <<<<<<<<<<<<<<
+ *             if self.table[i] == b: copy.table[i] = a
+ *             elif self.table[i] == copy.out_size: copy.table[i] = b
+ */
+  __pyx_t_5 = __pyx_v_self->in_size;
+  for (__pyx_v_i = 0; __pyx_v_i < __pyx_t_5; __pyx_v_i++) {
+
+    /* "bx/_seqmapping.pyx":159
+ *         if a > b: a, b = b, a
+ *         for i from 0 <= i < self.in_size:
+ *             if self.table[i] == b: copy.table[i] = a             # <<<<<<<<<<<<<<
+ *             elif self.table[i] == copy.out_size: copy.table[i] = b
+ *             else: copy.table[i] = self.table[i]
+ */
+    __pyx_t_3 = ((__pyx_v_self->table[__pyx_v_i]) == __pyx_v_b);
+    if (__pyx_t_3) {
+      (__pyx_v_copy->table[__pyx_v_i]) = __pyx_v_a;
+      goto __pyx_L6;
+    }
+
+    /* "bx/_seqmapping.pyx":160
+ *         for i from 0 <= i < self.in_size:
+ *             if self.table[i] == b: copy.table[i] = a
+ *             elif self.table[i] == copy.out_size: copy.table[i] = b             # <<<<<<<<<<<<<<
+ *             else: copy.table[i] = self.table[i]
+ *         return copy
+ */
+    __pyx_t_3 = ((__pyx_v_self->table[__pyx_v_i]) == __pyx_v_copy->out_size);
+    if (__pyx_t_3) {
+      (__pyx_v_copy->table[__pyx_v_i]) = __pyx_v_b;
+      goto __pyx_L6;
+    }
+    /*else*/ {
+
+      /* "bx/_seqmapping.pyx":161
+ *             if self.table[i] == b: copy.table[i] = a
+ *             elif self.table[i] == copy.out_size: copy.table[i] = b
+ *             else: copy.table[i] = self.table[i]             # <<<<<<<<<<<<<<
+ *         return copy
+ * 
+ */
+      (__pyx_v_copy->table[__pyx_v_i]) = (__pyx_v_self->table[__pyx_v_i]);
+    }
+    __pyx_L6:;
+  }
+
+  /* "bx/_seqmapping.pyx":162
+ *             elif self.table[i] == copy.out_size: copy.table[i] = b
+ *             else: copy.table[i] = self.table[i]
+ *         return copy             # <<<<<<<<<<<<<<
+ * 
+ *     def expand( self, int x ):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __Pyx_INCREF(((PyObject *)__pyx_v_copy));
+  __pyx_r = ((PyObject *)__pyx_v_copy);
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_AddTraceback("bx._seqmapping.IntToIntMapping.collapse", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XDECREF((PyObject *)__pyx_v_copy);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_11_seqmapping_15IntToIntMapping_13expand(PyObject *__pyx_v_self, PyObject *__pyx_arg_x); /*proto*/
+static char __pyx_doc_2bx_11_seqmapping_15IntToIntMapping_12expand[] = "Grow the alphabet by making 'a' a seperate symbol. If it already mapped to a single symbol, do nothing";
+static PyObject *__pyx_pw_2bx_11_seqmapping_15IntToIntMapping_13expand(PyObject *__pyx_v_self, PyObject *__pyx_arg_x) {
+  int __pyx_v_x;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("expand (wrapper)", 0);
+  assert(__pyx_arg_x); {
+    __pyx_v_x = __Pyx_PyInt_AsInt(__pyx_arg_x); if (unlikely((__pyx_v_x == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 164; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx._seqmapping.IntToIntMapping.expand", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_11_seqmapping_15IntToIntMapping_12expand(((struct __pyx_obj_2bx_11_seqmapping_IntToIntMapping *)__pyx_v_self), ((int)__pyx_v_x));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/_seqmapping.pyx":164
+ *         return copy
+ * 
+ *     def expand( self, int x ):             # <<<<<<<<<<<<<<
+ *         """Grow the alphabet by making 'a' a seperate symbol. If it already mapped to a single symbol, do nothing"""
+ *         cdef int i, count, a, b
+ */
+
+static PyObject *__pyx_pf_2bx_11_seqmapping_15IntToIntMapping_12expand(struct __pyx_obj_2bx_11_seqmapping_IntToIntMapping *__pyx_v_self, int __pyx_v_x) {
+  int __pyx_v_i;
+  int __pyx_v_count;
+  int __pyx_v_a;
+  struct __pyx_obj_2bx_11_seqmapping_IntToIntMapping *__pyx_v_copy = 0;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  int __pyx_t_2;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("expand", 0);
+
+  /* "bx/_seqmapping.pyx":169
+ *         cdef IntToIntMapping copy
+ *         # Get the symbol x maps to
+ *         a = self.table[x]             # <<<<<<<<<<<<<<
+ *         # Symbols that map to -1 should not be touched
+ *         if a < 0: return self
+ */
+  __pyx_v_a = (__pyx_v_self->table[__pyx_v_x]);
+
+  /* "bx/_seqmapping.pyx":171
+ *         a = self.table[x]
+ *         # Symbols that map to -1 should not be touched
+ *         if a < 0: return self             # <<<<<<<<<<<<<<
+ *         # Count how many other input symbols map to a
+ *         count = 0
+ */
+  __pyx_t_1 = (__pyx_v_a < 0);
+  if (__pyx_t_1) {
+    __Pyx_XDECREF(__pyx_r);
+    __Pyx_INCREF(((PyObject *)__pyx_v_self));
+    __pyx_r = ((PyObject *)__pyx_v_self);
+    goto __pyx_L0;
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  /* "bx/_seqmapping.pyx":173
+ *         if a < 0: return self
+ *         # Count how many other input symbols map to a
+ *         count = 0             # <<<<<<<<<<<<<<
+ *         for i from 0 <= i < self.in_size:
+ *             if self.table[i] == a: count = count + 1
+ */
+  __pyx_v_count = 0;
+
+  /* "bx/_seqmapping.pyx":174
+ *         # Count how many other input symbols map to a
+ *         count = 0
+ *         for i from 0 <= i < self.in_size:             # <<<<<<<<<<<<<<
+ *             if self.table[i] == a: count = count + 1
+ *         # Already a singleton
+ */
+  __pyx_t_2 = __pyx_v_self->in_size;
+  for (__pyx_v_i = 0; __pyx_v_i < __pyx_t_2; __pyx_v_i++) {
+
+    /* "bx/_seqmapping.pyx":175
+ *         count = 0
+ *         for i from 0 <= i < self.in_size:
+ *             if self.table[i] == a: count = count + 1             # <<<<<<<<<<<<<<
+ *         # Already a singleton
+ *         if count < 2: return self
+ */
+    __pyx_t_1 = ((__pyx_v_self->table[__pyx_v_i]) == __pyx_v_a);
+    if (__pyx_t_1) {
+      __pyx_v_count = (__pyx_v_count + 1);
+      goto __pyx_L6;
+    }
+    __pyx_L6:;
+  }
+
+  /* "bx/_seqmapping.pyx":177
+ *             if self.table[i] == a: count = count + 1
+ *         # Already a singleton
+ *         if count < 2: return self             # <<<<<<<<<<<<<<
+ *         # Otherwise, make a copy with the separated symbol
+ *         copy = IntToIntMapping( self.in_size )
+ */
+  __pyx_t_1 = (__pyx_v_count < 2);
+  if (__pyx_t_1) {
+    __Pyx_XDECREF(__pyx_r);
+    __Pyx_INCREF(((PyObject *)__pyx_v_self));
+    __pyx_r = ((PyObject *)__pyx_v_self);
+    goto __pyx_L0;
+    goto __pyx_L7;
+  }
+  __pyx_L7:;
+
+  /* "bx/_seqmapping.pyx":179
+ *         if count < 2: return self
+ *         # Otherwise, make a copy with the separated symbol
+ *         copy = IntToIntMapping( self.in_size )             # <<<<<<<<<<<<<<
+ *         copy.out_size = self.out_size + 1
+ *         for i from 0 <= i < self.in_size:
+ */
+  __pyx_t_3 = PyInt_FromLong(__pyx_v_self->in_size); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 179; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 179; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
+  __Pyx_GIVEREF(__pyx_t_3);
+  __pyx_t_3 = 0;
+  __pyx_t_3 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_2bx_11_seqmapping_IntToIntMapping)), ((PyObject *)__pyx_t_4), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 179; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
+  __pyx_v_copy = ((struct __pyx_obj_2bx_11_seqmapping_IntToIntMapping *)__pyx_t_3);
+  __pyx_t_3 = 0;
+
+  /* "bx/_seqmapping.pyx":180
+ *         # Otherwise, make a copy with the separated symbol
+ *         copy = IntToIntMapping( self.in_size )
+ *         copy.out_size = self.out_size + 1             # <<<<<<<<<<<<<<
+ *         for i from 0 <= i < self.in_size:
+ *             copy.table[i] = self.table[i]
+ */
+  __pyx_v_copy->out_size = (__pyx_v_self->out_size + 1);
+
+  /* "bx/_seqmapping.pyx":181
+ *         copy = IntToIntMapping( self.in_size )
+ *         copy.out_size = self.out_size + 1
+ *         for i from 0 <= i < self.in_size:             # <<<<<<<<<<<<<<
+ *             copy.table[i] = self.table[i]
+ *         copy.table[x] = self.out_size
+ */
+  __pyx_t_2 = __pyx_v_self->in_size;
+  for (__pyx_v_i = 0; __pyx_v_i < __pyx_t_2; __pyx_v_i++) {
+
+    /* "bx/_seqmapping.pyx":182
+ *         copy.out_size = self.out_size + 1
+ *         for i from 0 <= i < self.in_size:
+ *             copy.table[i] = self.table[i]             # <<<<<<<<<<<<<<
+ *         copy.table[x] = self.out_size
+ *         return copy
+ */
+    (__pyx_v_copy->table[__pyx_v_i]) = (__pyx_v_self->table[__pyx_v_i]);
+  }
+
+  /* "bx/_seqmapping.pyx":183
+ *         for i from 0 <= i < self.in_size:
+ *             copy.table[i] = self.table[i]
+ *         copy.table[x] = self.out_size             # <<<<<<<<<<<<<<
+ *         return copy
+ * 
+ */
+  __pyx_t_2 = __pyx_v_self->out_size;
+  (__pyx_v_copy->table[__pyx_v_x]) = __pyx_t_2;
+
+  /* "bx/_seqmapping.pyx":184
+ *             copy.table[i] = self.table[i]
+ *         copy.table[x] = self.out_size
+ *         return copy             # <<<<<<<<<<<<<<
+ * 
+ *     def expand_out( self, int a ):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __Pyx_INCREF(((PyObject *)__pyx_v_copy));
+  __pyx_r = ((PyObject *)__pyx_v_copy);
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_AddTraceback("bx._seqmapping.IntToIntMapping.expand", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XDECREF((PyObject *)__pyx_v_copy);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_11_seqmapping_15IntToIntMapping_15expand_out(PyObject *__pyx_v_self, PyObject *__pyx_arg_a); /*proto*/
+static char __pyx_doc_2bx_11_seqmapping_15IntToIntMapping_14expand_out[] = "Grow the alphabet breaking 'a' into two symbols randomly";
+static PyObject *__pyx_pw_2bx_11_seqmapping_15IntToIntMapping_15expand_out(PyObject *__pyx_v_self, PyObject *__pyx_arg_a) {
+  int __pyx_v_a;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("expand_out (wrapper)", 0);
+  assert(__pyx_arg_a); {
+    __pyx_v_a = __Pyx_PyInt_AsInt(__pyx_arg_a); if (unlikely((__pyx_v_a == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 186; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx._seqmapping.IntToIntMapping.expand_out", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_11_seqmapping_15IntToIntMapping_14expand_out(((struct __pyx_obj_2bx_11_seqmapping_IntToIntMapping *)__pyx_v_self), ((int)__pyx_v_a));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/_seqmapping.pyx":186
+ *         return copy
+ * 
+ *     def expand_out( self, int a ):             # <<<<<<<<<<<<<<
+ *         """Grow the alphabet breaking 'a' into two symbols randomly"""
+ *         cdef int i, count, to_split, b
+ */
+
+static PyObject *__pyx_pf_2bx_11_seqmapping_15IntToIntMapping_14expand_out(struct __pyx_obj_2bx_11_seqmapping_IntToIntMapping *__pyx_v_self, int __pyx_v_a) {
+  int __pyx_v_i;
+  int __pyx_v_count;
+  int __pyx_v_to_split;
+  int __pyx_v_b;
+  struct __pyx_obj_2bx_11_seqmapping_IntToIntMapping *__pyx_v_copy = 0;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  int __pyx_t_2;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  PyObject *__pyx_t_5 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("expand_out", 0);
+
+  /* "bx/_seqmapping.pyx":190
+ *         cdef int i, count, to_split, b
+ *         cdef IntToIntMapping copy
+ *         count = 0             # <<<<<<<<<<<<<<
+ *         for i from 0 <= i < self.in_size:
+ *             if self.table[i] == a: count = count + 1
+ */
+  __pyx_v_count = 0;
+
+  /* "bx/_seqmapping.pyx":191
+ *         cdef IntToIntMapping copy
+ *         count = 0
+ *         for i from 0 <= i < self.in_size:             # <<<<<<<<<<<<<<
+ *             if self.table[i] == a: count = count + 1
+ *         if count < 2: return self
+ */
+  __pyx_t_1 = __pyx_v_self->in_size;
+  for (__pyx_v_i = 0; __pyx_v_i < __pyx_t_1; __pyx_v_i++) {
+
+    /* "bx/_seqmapping.pyx":192
+ *         count = 0
+ *         for i from 0 <= i < self.in_size:
+ *             if self.table[i] == a: count = count + 1             # <<<<<<<<<<<<<<
+ *         if count < 2: return self
+ *         copy = IntToIntMapping( self.in_size )
+ */
+    __pyx_t_2 = ((__pyx_v_self->table[__pyx_v_i]) == __pyx_v_a);
+    if (__pyx_t_2) {
+      __pyx_v_count = (__pyx_v_count + 1);
+      goto __pyx_L5;
+    }
+    __pyx_L5:;
+  }
+
+  /* "bx/_seqmapping.pyx":193
+ *         for i from 0 <= i < self.in_size:
+ *             if self.table[i] == a: count = count + 1
+ *         if count < 2: return self             # <<<<<<<<<<<<<<
+ *         copy = IntToIntMapping( self.in_size )
+ *         copy.out_size = self.out_size + 1
+ */
+  __pyx_t_2 = (__pyx_v_count < 2);
+  if (__pyx_t_2) {
+    __Pyx_XDECREF(__pyx_r);
+    __Pyx_INCREF(((PyObject *)__pyx_v_self));
+    __pyx_r = ((PyObject *)__pyx_v_self);
+    goto __pyx_L0;
+    goto __pyx_L6;
+  }
+  __pyx_L6:;
+
+  /* "bx/_seqmapping.pyx":194
+ *             if self.table[i] == a: count = count + 1
+ *         if count < 2: return self
+ *         copy = IntToIntMapping( self.in_size )             # <<<<<<<<<<<<<<
+ *         copy.out_size = self.out_size + 1
+ *         b = self.out_size
+ */
+  __pyx_t_3 = PyInt_FromLong(__pyx_v_self->in_size); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 194; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 194; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
+  __Pyx_GIVEREF(__pyx_t_3);
+  __pyx_t_3 = 0;
+  __pyx_t_3 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_2bx_11_seqmapping_IntToIntMapping)), ((PyObject *)__pyx_t_4), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 194; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
+  __pyx_v_copy = ((struct __pyx_obj_2bx_11_seqmapping_IntToIntMapping *)__pyx_t_3);
+  __pyx_t_3 = 0;
+
+  /* "bx/_seqmapping.pyx":195
+ *         if count < 2: return self
+ *         copy = IntToIntMapping( self.in_size )
+ *         copy.out_size = self.out_size + 1             # <<<<<<<<<<<<<<
+ *         b = self.out_size
+ *         to_split = random.randrange( count )
+ */
+  __pyx_v_copy->out_size = (__pyx_v_self->out_size + 1);
+
+  /* "bx/_seqmapping.pyx":196
+ *         copy = IntToIntMapping( self.in_size )
+ *         copy.out_size = self.out_size + 1
+ *         b = self.out_size             # <<<<<<<<<<<<<<
+ *         to_split = random.randrange( count )
+ *         count = 0
+ */
+  __pyx_t_1 = __pyx_v_self->out_size;
+  __pyx_v_b = __pyx_t_1;
+
+  /* "bx/_seqmapping.pyx":197
+ *         copy.out_size = self.out_size + 1
+ *         b = self.out_size
+ *         to_split = random.randrange( count )             # <<<<<<<<<<<<<<
+ *         count = 0
+ *         for i from 0 <= i < self.in_size:
+ */
+  __pyx_t_3 = __Pyx_GetName(__pyx_m, __pyx_n_s__random); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 197; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_4 = PyObject_GetAttr(__pyx_t_3, __pyx_n_s__randrange); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 197; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __pyx_t_3 = PyInt_FromLong(__pyx_v_count); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 197; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 197; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_3);
+  __Pyx_GIVEREF(__pyx_t_3);
+  __pyx_t_3 = 0;
+  __pyx_t_3 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_t_5), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 197; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_5)); __pyx_t_5 = 0;
+  __pyx_t_1 = __Pyx_PyInt_AsInt(__pyx_t_3); if (unlikely((__pyx_t_1 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 197; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __pyx_v_to_split = __pyx_t_1;
+
+  /* "bx/_seqmapping.pyx":198
+ *         b = self.out_size
+ *         to_split = random.randrange( count )
+ *         count = 0             # <<<<<<<<<<<<<<
+ *         for i from 0 <= i < self.in_size:
+ *             if self.table[i] == a:
+ */
+  __pyx_v_count = 0;
+
+  /* "bx/_seqmapping.pyx":199
+ *         to_split = random.randrange( count )
+ *         count = 0
+ *         for i from 0 <= i < self.in_size:             # <<<<<<<<<<<<<<
+ *             if self.table[i] == a:
+ *                 if count == to_split: copy.table[i] = b
+ */
+  __pyx_t_1 = __pyx_v_self->in_size;
+  for (__pyx_v_i = 0; __pyx_v_i < __pyx_t_1; __pyx_v_i++) {
+
+    /* "bx/_seqmapping.pyx":200
+ *         count = 0
+ *         for i from 0 <= i < self.in_size:
+ *             if self.table[i] == a:             # <<<<<<<<<<<<<<
+ *                 if count == to_split: copy.table[i] = b
+ *                 else: copy.table[i] = a
+ */
+    __pyx_t_2 = ((__pyx_v_self->table[__pyx_v_i]) == __pyx_v_a);
+    if (__pyx_t_2) {
+
+      /* "bx/_seqmapping.pyx":201
+ *         for i from 0 <= i < self.in_size:
+ *             if self.table[i] == a:
+ *                 if count == to_split: copy.table[i] = b             # <<<<<<<<<<<<<<
+ *                 else: copy.table[i] = a
+ *                 count = count + 1
+ */
+      __pyx_t_2 = (__pyx_v_count == __pyx_v_to_split);
+      if (__pyx_t_2) {
+        (__pyx_v_copy->table[__pyx_v_i]) = __pyx_v_b;
+        goto __pyx_L10;
+      }
+      /*else*/ {
+
+        /* "bx/_seqmapping.pyx":202
+ *             if self.table[i] == a:
+ *                 if count == to_split: copy.table[i] = b
+ *                 else: copy.table[i] = a             # <<<<<<<<<<<<<<
+ *                 count = count + 1
+ *             else:
+ */
+        (__pyx_v_copy->table[__pyx_v_i]) = __pyx_v_a;
+      }
+      __pyx_L10:;
+
+      /* "bx/_seqmapping.pyx":203
+ *                 if count == to_split: copy.table[i] = b
+ *                 else: copy.table[i] = a
+ *                 count = count + 1             # <<<<<<<<<<<<<<
+ *             else:
+ *                 copy.table[i] = self.table[i]
+ */
+      __pyx_v_count = (__pyx_v_count + 1);
+      goto __pyx_L9;
+    }
+    /*else*/ {
+
+      /* "bx/_seqmapping.pyx":205
+ *                 count = count + 1
+ *             else:
+ *                 copy.table[i] = self.table[i]             # <<<<<<<<<<<<<<
+ *         return copy
+ * 
+ */
+      (__pyx_v_copy->table[__pyx_v_i]) = (__pyx_v_self->table[__pyx_v_i]);
+    }
+    __pyx_L9:;
+  }
+
+  /* "bx/_seqmapping.pyx":206
+ *             else:
+ *                 copy.table[i] = self.table[i]
+ *         return copy             # <<<<<<<<<<<<<<
+ * 
+ *     def expand_random_split( self, int a ):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __Pyx_INCREF(((PyObject *)__pyx_v_copy));
+  __pyx_r = ((PyObject *)__pyx_v_copy);
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_XDECREF(__pyx_t_5);
+  __Pyx_AddTraceback("bx._seqmapping.IntToIntMapping.expand_out", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XDECREF((PyObject *)__pyx_v_copy);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_11_seqmapping_15IntToIntMapping_17expand_random_split(PyObject *__pyx_v_self, PyObject *__pyx_arg_a); /*proto*/
+static char __pyx_doc_2bx_11_seqmapping_15IntToIntMapping_16expand_random_split[] = "Grow the alphabet breaking 'a' into two symbols randomly";
+static PyObject *__pyx_pw_2bx_11_seqmapping_15IntToIntMapping_17expand_random_split(PyObject *__pyx_v_self, PyObject *__pyx_arg_a) {
+  int __pyx_v_a;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("expand_random_split (wrapper)", 0);
+  assert(__pyx_arg_a); {
+    __pyx_v_a = __Pyx_PyInt_AsInt(__pyx_arg_a); if (unlikely((__pyx_v_a == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 208; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx._seqmapping.IntToIntMapping.expand_random_split", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_11_seqmapping_15IntToIntMapping_16expand_random_split(((struct __pyx_obj_2bx_11_seqmapping_IntToIntMapping *)__pyx_v_self), ((int)__pyx_v_a));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/_seqmapping.pyx":208
+ *         return copy
+ * 
+ *     def expand_random_split( self, int a ):             # <<<<<<<<<<<<<<
+ *         """Grow the alphabet breaking 'a' into two symbols randomly"""
+ *         cdef int i, count, b
+ */
+
+static PyObject *__pyx_pf_2bx_11_seqmapping_15IntToIntMapping_16expand_random_split(struct __pyx_obj_2bx_11_seqmapping_IntToIntMapping *__pyx_v_self, int __pyx_v_a) {
+  int __pyx_v_i;
+  int __pyx_v_count;
+  int __pyx_v_b;
+  struct __pyx_obj_2bx_11_seqmapping_IntToIntMapping *__pyx_v_copy = 0;
+  PyObject *__pyx_v_to_split = NULL;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  int __pyx_t_2;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  PyObject *__pyx_t_5 = NULL;
+  PyObject *__pyx_t_6 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("expand_random_split", 0);
+
+  /* "bx/_seqmapping.pyx":212
+ *         cdef int i, count, b
+ *         cdef IntToIntMapping copy
+ *         count = 0             # <<<<<<<<<<<<<<
+ *         for i from 0 <= i < self.in_size:
+ *             if self.table[i] == a: count = count + 1
+ */
+  __pyx_v_count = 0;
+
+  /* "bx/_seqmapping.pyx":213
+ *         cdef IntToIntMapping copy
+ *         count = 0
+ *         for i from 0 <= i < self.in_size:             # <<<<<<<<<<<<<<
+ *             if self.table[i] == a: count = count + 1
+ *         if count < 2: return self
+ */
+  __pyx_t_1 = __pyx_v_self->in_size;
+  for (__pyx_v_i = 0; __pyx_v_i < __pyx_t_1; __pyx_v_i++) {
+
+    /* "bx/_seqmapping.pyx":214
+ *         count = 0
+ *         for i from 0 <= i < self.in_size:
+ *             if self.table[i] == a: count = count + 1             # <<<<<<<<<<<<<<
+ *         if count < 2: return self
+ *         copy = IntToIntMapping( self.in_size )
+ */
+    __pyx_t_2 = ((__pyx_v_self->table[__pyx_v_i]) == __pyx_v_a);
+    if (__pyx_t_2) {
+      __pyx_v_count = (__pyx_v_count + 1);
+      goto __pyx_L5;
+    }
+    __pyx_L5:;
+  }
+
+  /* "bx/_seqmapping.pyx":215
+ *         for i from 0 <= i < self.in_size:
+ *             if self.table[i] == a: count = count + 1
+ *         if count < 2: return self             # <<<<<<<<<<<<<<
+ *         copy = IntToIntMapping( self.in_size )
+ *         copy.out_size = self.out_size + 1
+ */
+  __pyx_t_2 = (__pyx_v_count < 2);
+  if (__pyx_t_2) {
+    __Pyx_XDECREF(__pyx_r);
+    __Pyx_INCREF(((PyObject *)__pyx_v_self));
+    __pyx_r = ((PyObject *)__pyx_v_self);
+    goto __pyx_L0;
+    goto __pyx_L6;
+  }
+  __pyx_L6:;
+
+  /* "bx/_seqmapping.pyx":216
+ *             if self.table[i] == a: count = count + 1
+ *         if count < 2: return self
+ *         copy = IntToIntMapping( self.in_size )             # <<<<<<<<<<<<<<
+ *         copy.out_size = self.out_size + 1
+ *         b = self.out_size
+ */
+  __pyx_t_3 = PyInt_FromLong(__pyx_v_self->in_size); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 216; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 216; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
+  __Pyx_GIVEREF(__pyx_t_3);
+  __pyx_t_3 = 0;
+  __pyx_t_3 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_2bx_11_seqmapping_IntToIntMapping)), ((PyObject *)__pyx_t_4), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 216; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
+  __pyx_v_copy = ((struct __pyx_obj_2bx_11_seqmapping_IntToIntMapping *)__pyx_t_3);
+  __pyx_t_3 = 0;
+
+  /* "bx/_seqmapping.pyx":217
+ *         if count < 2: return self
+ *         copy = IntToIntMapping( self.in_size )
+ *         copy.out_size = self.out_size + 1             # <<<<<<<<<<<<<<
+ *         b = self.out_size
+ *         to_split = random.sample( range( count ), count/2 )
+ */
+  __pyx_v_copy->out_size = (__pyx_v_self->out_size + 1);
+
+  /* "bx/_seqmapping.pyx":218
+ *         copy = IntToIntMapping( self.in_size )
+ *         copy.out_size = self.out_size + 1
+ *         b = self.out_size             # <<<<<<<<<<<<<<
+ *         to_split = random.sample( range( count ), count/2 )
+ *         count = 0
+ */
+  __pyx_t_1 = __pyx_v_self->out_size;
+  __pyx_v_b = __pyx_t_1;
+
+  /* "bx/_seqmapping.pyx":219
+ *         copy.out_size = self.out_size + 1
+ *         b = self.out_size
+ *         to_split = random.sample( range( count ), count/2 )             # <<<<<<<<<<<<<<
+ *         count = 0
+ *         for i from 0 <= i < self.in_size:
+ */
+  __pyx_t_3 = __Pyx_GetName(__pyx_m, __pyx_n_s__random); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 219; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_4 = PyObject_GetAttr(__pyx_t_3, __pyx_n_s__sample); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 219; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __pyx_t_3 = PyInt_FromLong(__pyx_v_count); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 219; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 219; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_3);
+  __Pyx_GIVEREF(__pyx_t_3);
+  __pyx_t_3 = 0;
+  __pyx_t_3 = PyObject_Call(__pyx_builtin_range, ((PyObject *)__pyx_t_5), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 219; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(((PyObject *)__pyx_t_5)); __pyx_t_5 = 0;
+  __pyx_t_5 = PyInt_FromLong(__Pyx_div_long(__pyx_v_count, 2)); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 219; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __pyx_t_6 = PyTuple_New(2); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 219; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_6);
+  PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_3);
+  __Pyx_GIVEREF(__pyx_t_3);
+  PyTuple_SET_ITEM(__pyx_t_6, 1, __pyx_t_5);
+  __Pyx_GIVEREF(__pyx_t_5);
+  __pyx_t_3 = 0;
+  __pyx_t_5 = 0;
+  __pyx_t_5 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_t_6), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 219; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_6)); __pyx_t_6 = 0;
+  __pyx_v_to_split = __pyx_t_5;
+  __pyx_t_5 = 0;
+
+  /* "bx/_seqmapping.pyx":220
+ *         b = self.out_size
+ *         to_split = random.sample( range( count ), count/2 )
+ *         count = 0             # <<<<<<<<<<<<<<
+ *         for i from 0 <= i < self.in_size:
+ *             if self.table[i] == a:
+ */
+  __pyx_v_count = 0;
+
+  /* "bx/_seqmapping.pyx":221
+ *         to_split = random.sample( range( count ), count/2 )
+ *         count = 0
+ *         for i from 0 <= i < self.in_size:             # <<<<<<<<<<<<<<
+ *             if self.table[i] == a:
+ *                 if count in to_split: copy.table[i] = b
+ */
+  __pyx_t_1 = __pyx_v_self->in_size;
+  for (__pyx_v_i = 0; __pyx_v_i < __pyx_t_1; __pyx_v_i++) {
+
+    /* "bx/_seqmapping.pyx":222
+ *         count = 0
+ *         for i from 0 <= i < self.in_size:
+ *             if self.table[i] == a:             # <<<<<<<<<<<<<<
+ *                 if count in to_split: copy.table[i] = b
+ *                 else: copy.table[i] = a
+ */
+    __pyx_t_2 = ((__pyx_v_self->table[__pyx_v_i]) == __pyx_v_a);
+    if (__pyx_t_2) {
+
+      /* "bx/_seqmapping.pyx":223
+ *         for i from 0 <= i < self.in_size:
+ *             if self.table[i] == a:
+ *                 if count in to_split: copy.table[i] = b             # <<<<<<<<<<<<<<
+ *                 else: copy.table[i] = a
+ *                 count = count + 1
+ */
+      __pyx_t_5 = PyInt_FromLong(__pyx_v_count); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 223; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_5);
+      __pyx_t_2 = (__Pyx_PySequence_Contains(__pyx_t_5, __pyx_v_to_split, Py_EQ)); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 223; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      if (__pyx_t_2) {
+        (__pyx_v_copy->table[__pyx_v_i]) = __pyx_v_b;
+        goto __pyx_L10;
+      }
+      /*else*/ {
+
+        /* "bx/_seqmapping.pyx":224
+ *             if self.table[i] == a:
+ *                 if count in to_split: copy.table[i] = b
+ *                 else: copy.table[i] = a             # <<<<<<<<<<<<<<
+ *                 count = count + 1
+ *             else:
+ */
+        (__pyx_v_copy->table[__pyx_v_i]) = __pyx_v_a;
+      }
+      __pyx_L10:;
+
+      /* "bx/_seqmapping.pyx":225
+ *                 if count in to_split: copy.table[i] = b
+ *                 else: copy.table[i] = a
+ *                 count = count + 1             # <<<<<<<<<<<<<<
+ *             else:
+ *                 copy.table[i] = self.table[i]
+ */
+      __pyx_v_count = (__pyx_v_count + 1);
+      goto __pyx_L9;
+    }
+    /*else*/ {
+
+      /* "bx/_seqmapping.pyx":227
+ *                 count = count + 1
+ *             else:
+ *                 copy.table[i] = self.table[i]             # <<<<<<<<<<<<<<
+ *         return copy
+ * 
+ */
+      (__pyx_v_copy->table[__pyx_v_i]) = (__pyx_v_self->table[__pyx_v_i]);
+    }
+    __pyx_L9:;
+  }
+
+  /* "bx/_seqmapping.pyx":228
+ *             else:
+ *                 copy.table[i] = self.table[i]
+ *         return copy             # <<<<<<<<<<<<<<
+ * 
+ *     def get_in_size( self ):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __Pyx_INCREF(((PyObject *)__pyx_v_copy));
+  __pyx_r = ((PyObject *)__pyx_v_copy);
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_XDECREF(__pyx_t_5);
+  __Pyx_XDECREF(__pyx_t_6);
+  __Pyx_AddTraceback("bx._seqmapping.IntToIntMapping.expand_random_split", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XDECREF((PyObject *)__pyx_v_copy);
+  __Pyx_XDECREF(__pyx_v_to_split);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_11_seqmapping_15IntToIntMapping_19get_in_size(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static PyObject *__pyx_pw_2bx_11_seqmapping_15IntToIntMapping_19get_in_size(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("get_in_size (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_11_seqmapping_15IntToIntMapping_18get_in_size(((struct __pyx_obj_2bx_11_seqmapping_IntToIntMapping *)__pyx_v_self));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/_seqmapping.pyx":230
+ *         return copy
+ * 
+ *     def get_in_size( self ):             # <<<<<<<<<<<<<<
+ *         return self.in_size
+ * 
+ */
+
+static PyObject *__pyx_pf_2bx_11_seqmapping_15IntToIntMapping_18get_in_size(struct __pyx_obj_2bx_11_seqmapping_IntToIntMapping *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("get_in_size", 0);
+
+  /* "bx/_seqmapping.pyx":231
+ * 
+ *     def get_in_size( self ):
+ *         return self.in_size             # <<<<<<<<<<<<<<
+ * 
+ *     def get_out_size( self ):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = PyInt_FromLong(__pyx_v_self->in_size); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 231; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("bx._seqmapping.IntToIntMapping.get_in_size", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_11_seqmapping_15IntToIntMapping_21get_out_size(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static PyObject *__pyx_pw_2bx_11_seqmapping_15IntToIntMapping_21get_out_size(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("get_out_size (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_11_seqmapping_15IntToIntMapping_20get_out_size(((struct __pyx_obj_2bx_11_seqmapping_IntToIntMapping *)__pyx_v_self));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/_seqmapping.pyx":233
+ *         return self.in_size
+ * 
+ *     def get_out_size( self ):             # <<<<<<<<<<<<<<
+ *         return self.out_size
+ * 
+ */
+
+static PyObject *__pyx_pf_2bx_11_seqmapping_15IntToIntMapping_20get_out_size(struct __pyx_obj_2bx_11_seqmapping_IntToIntMapping *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("get_out_size", 0);
+
+  /* "bx/_seqmapping.pyx":234
+ * 
+ *     def get_out_size( self ):
+ *         return self.out_size             # <<<<<<<<<<<<<<
+ * 
+ *     def get_table( self ):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = PyInt_FromLong(__pyx_v_self->out_size); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 234; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("bx._seqmapping.IntToIntMapping.get_out_size", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_11_seqmapping_15IntToIntMapping_23get_table(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static PyObject *__pyx_pw_2bx_11_seqmapping_15IntToIntMapping_23get_table(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("get_table (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_11_seqmapping_15IntToIntMapping_22get_table(((struct __pyx_obj_2bx_11_seqmapping_IntToIntMapping *)__pyx_v_self));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/_seqmapping.pyx":236
+ *         return self.out_size
+ * 
+ *     def get_table( self ):             # <<<<<<<<<<<<<<
+ *         rval = zeros( self.in_size, 'i' )
+ *         for i in range( self.in_size ):
+ */
+
+static PyObject *__pyx_pf_2bx_11_seqmapping_15IntToIntMapping_22get_table(struct __pyx_obj_2bx_11_seqmapping_IntToIntMapping *__pyx_v_self) {
+  PyObject *__pyx_v_rval = NULL;
+  int __pyx_v_i;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  int __pyx_t_4;
+  int __pyx_t_5;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("get_table", 0);
+
+  /* "bx/_seqmapping.pyx":237
+ * 
+ *     def get_table( self ):
+ *         rval = zeros( self.in_size, 'i' )             # <<<<<<<<<<<<<<
+ *         for i in range( self.in_size ):
+ *             rval[i] = self.table[i]
+ */
+  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__zeros); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 237; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = PyInt_FromLong(__pyx_v_self->in_size); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 237; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 237; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_2);
+  __Pyx_GIVEREF(__pyx_t_2);
+  __Pyx_INCREF(((PyObject *)__pyx_n_s__i));
+  PyTuple_SET_ITEM(__pyx_t_3, 1, ((PyObject *)__pyx_n_s__i));
+  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__i));
+  __pyx_t_2 = 0;
+  __pyx_t_2 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 237; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
+  __pyx_v_rval = __pyx_t_2;
+  __pyx_t_2 = 0;
+
+  /* "bx/_seqmapping.pyx":238
+ *     def get_table( self ):
+ *         rval = zeros( self.in_size, 'i' )
+ *         for i in range( self.in_size ):             # <<<<<<<<<<<<<<
+ *             rval[i] = self.table[i]
+ *         return rval
+ */
+  __pyx_t_4 = __pyx_v_self->in_size;
+  for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_4; __pyx_t_5+=1) {
+    __pyx_v_i = __pyx_t_5;
+
+    /* "bx/_seqmapping.pyx":239
+ *         rval = zeros( self.in_size, 'i' )
+ *         for i in range( self.in_size ):
+ *             rval[i] = self.table[i]             # <<<<<<<<<<<<<<
+ *         return rval
+ * 
+ */
+    __pyx_t_2 = PyInt_FromLong((__pyx_v_self->table[__pyx_v_i])); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 239; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    if (__Pyx_SetItemInt(__pyx_v_rval, __pyx_v_i, __pyx_t_2, sizeof(int), PyInt_FromLong) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 239; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  }
+
+  /* "bx/_seqmapping.pyx":240
+ *         for i in range( self.in_size ):
+ *             rval[i] = self.table[i]
+ *         return rval             # <<<<<<<<<<<<<<
+ * 
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __Pyx_INCREF(__pyx_v_rval);
+  __pyx_r = __pyx_v_rval;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_AddTraceback("bx._seqmapping.IntToIntMapping.get_table", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_rval);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_tp_new_2bx_11_seqmapping_CharToIntArrayMapping(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) {
+  struct __pyx_obj_2bx_11_seqmapping_CharToIntArrayMapping *p;
+  PyObject *o = (*t->tp_alloc)(t, 0);
+  if (!o) return 0;
+  p = ((struct __pyx_obj_2bx_11_seqmapping_CharToIntArrayMapping *)o);
+  p->reverse_table = Py_None; Py_INCREF(Py_None);
+  if (__pyx_pw_2bx_11_seqmapping_21CharToIntArrayMapping_1__cinit__(o, __pyx_empty_tuple, NULL) < 0) {
+    Py_DECREF(o); o = 0;
+  }
+  return o;
+}
+
+static void __pyx_tp_dealloc_2bx_11_seqmapping_CharToIntArrayMapping(PyObject *o) {
+  struct __pyx_obj_2bx_11_seqmapping_CharToIntArrayMapping *p = (struct __pyx_obj_2bx_11_seqmapping_CharToIntArrayMapping *)o;
+  PyObject_GC_UnTrack(o);
+  Py_CLEAR(p->reverse_table);
+  PyObject_GC_Track(o);
+  (*Py_TYPE(o)->tp_free)(o);
+}
+
+static int __pyx_tp_traverse_2bx_11_seqmapping_CharToIntArrayMapping(PyObject *o, visitproc v, void *a) {
+  int e;
+  struct __pyx_obj_2bx_11_seqmapping_CharToIntArrayMapping *p = (struct __pyx_obj_2bx_11_seqmapping_CharToIntArrayMapping *)o;
+  if (p->reverse_table) {
+    e = (*v)(p->reverse_table, a); if (e) return e;
+  }
+  return 0;
+}
+
+static int __pyx_tp_clear_2bx_11_seqmapping_CharToIntArrayMapping(PyObject *o) {
+  struct __pyx_obj_2bx_11_seqmapping_CharToIntArrayMapping *p = (struct __pyx_obj_2bx_11_seqmapping_CharToIntArrayMapping *)o;
+  PyObject* tmp;
+  tmp = ((PyObject*)p->reverse_table);
+  p->reverse_table = Py_None; Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  return 0;
+}
+
+static PyMethodDef __pyx_methods_2bx_11_seqmapping_CharToIntArrayMapping[] = {
+  {__Pyx_NAMESTR("set_mapping"), (PyCFunction)__pyx_pw_2bx_11_seqmapping_21CharToIntArrayMapping_5set_mapping, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(__pyx_doc_2bx_11_seqmapping_21CharToIntArrayMapping_4set_mapping)},
+  {__Pyx_NAMESTR("translate"), (PyCFunction)__pyx_pw_2bx_11_seqmapping_21CharToIntArrayMapping_7translate, METH_O, __Pyx_DOCSTR(__pyx_doc_2bx_11_seqmapping_21CharToIntArrayMapping_6translate)},
+  {__Pyx_NAMESTR("translate_list"), (PyCFunction)__pyx_pw_2bx_11_seqmapping_21CharToIntArrayMapping_9translate_list, METH_O, __Pyx_DOCSTR(__pyx_doc_2bx_11_seqmapping_21CharToIntArrayMapping_8translate_list)},
+  {__Pyx_NAMESTR("reverse_map"), (PyCFunction)__pyx_pw_2bx_11_seqmapping_21CharToIntArrayMapping_11reverse_map, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(0)},
+  {__Pyx_NAMESTR("get_out_size"), (PyCFunction)__pyx_pw_2bx_11_seqmapping_21CharToIntArrayMapping_13get_out_size, METH_NOARGS, __Pyx_DOCSTR(0)},
+  {0, 0, 0, 0}
+};
+
+static PyNumberMethods __pyx_tp_as_number_CharToIntArrayMapping = {
+  0, /*nb_add*/
+  0, /*nb_subtract*/
+  0, /*nb_multiply*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_divide*/
+  #endif
+  0, /*nb_remainder*/
+  0, /*nb_divmod*/
+  0, /*nb_power*/
+  0, /*nb_negative*/
+  0, /*nb_positive*/
+  0, /*nb_absolute*/
+  0, /*nb_nonzero*/
+  0, /*nb_invert*/
+  0, /*nb_lshift*/
+  0, /*nb_rshift*/
+  0, /*nb_and*/
+  0, /*nb_xor*/
+  0, /*nb_or*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_coerce*/
+  #endif
+  0, /*nb_int*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_long*/
+  #else
+  0, /*reserved*/
+  #endif
+  0, /*nb_float*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_oct*/
+  #endif
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_hex*/
+  #endif
+  0, /*nb_inplace_add*/
+  0, /*nb_inplace_subtract*/
+  0, /*nb_inplace_multiply*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_inplace_divide*/
+  #endif
+  0, /*nb_inplace_remainder*/
+  0, /*nb_inplace_power*/
+  0, /*nb_inplace_lshift*/
+  0, /*nb_inplace_rshift*/
+  0, /*nb_inplace_and*/
+  0, /*nb_inplace_xor*/
+  0, /*nb_inplace_or*/
+  0, /*nb_floor_divide*/
+  0, /*nb_true_divide*/
+  0, /*nb_inplace_floor_divide*/
+  0, /*nb_inplace_true_divide*/
+  #if PY_VERSION_HEX >= 0x02050000
+  0, /*nb_index*/
+  #endif
+};
+
+static PySequenceMethods __pyx_tp_as_sequence_CharToIntArrayMapping = {
+  0, /*sq_length*/
+  0, /*sq_concat*/
+  0, /*sq_repeat*/
+  0, /*sq_item*/
+  0, /*sq_slice*/
+  0, /*sq_ass_item*/
+  0, /*sq_ass_slice*/
+  0, /*sq_contains*/
+  0, /*sq_inplace_concat*/
+  0, /*sq_inplace_repeat*/
+};
+
+static PyMappingMethods __pyx_tp_as_mapping_CharToIntArrayMapping = {
+  0, /*mp_length*/
+  0, /*mp_subscript*/
+  0, /*mp_ass_subscript*/
+};
+
+static PyBufferProcs __pyx_tp_as_buffer_CharToIntArrayMapping = {
+  #if PY_MAJOR_VERSION < 3
+  0, /*bf_getreadbuffer*/
+  #endif
+  #if PY_MAJOR_VERSION < 3
+  0, /*bf_getwritebuffer*/
+  #endif
+  #if PY_MAJOR_VERSION < 3
+  0, /*bf_getsegcount*/
+  #endif
+  #if PY_MAJOR_VERSION < 3
+  0, /*bf_getcharbuffer*/
+  #endif
+  #if PY_VERSION_HEX >= 0x02060000
+  0, /*bf_getbuffer*/
+  #endif
+  #if PY_VERSION_HEX >= 0x02060000
+  0, /*bf_releasebuffer*/
+  #endif
+};
+
+static PyTypeObject __pyx_type_2bx_11_seqmapping_CharToIntArrayMapping = {
+  PyVarObject_HEAD_INIT(0, 0)
+  __Pyx_NAMESTR("bx._seqmapping.CharToIntArrayMapping"), /*tp_name*/
+  sizeof(struct __pyx_obj_2bx_11_seqmapping_CharToIntArrayMapping), /*tp_basicsize*/
+  0, /*tp_itemsize*/
+  __pyx_tp_dealloc_2bx_11_seqmapping_CharToIntArrayMapping, /*tp_dealloc*/
+  0, /*tp_print*/
+  0, /*tp_getattr*/
+  0, /*tp_setattr*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*tp_compare*/
+  #else
+  0, /*reserved*/
+  #endif
+  0, /*tp_repr*/
+  &__pyx_tp_as_number_CharToIntArrayMapping, /*tp_as_number*/
+  &__pyx_tp_as_sequence_CharToIntArrayMapping, /*tp_as_sequence*/
+  &__pyx_tp_as_mapping_CharToIntArrayMapping, /*tp_as_mapping*/
+  0, /*tp_hash*/
+  0, /*tp_call*/
+  0, /*tp_str*/
+  0, /*tp_getattro*/
+  0, /*tp_setattro*/
+  &__pyx_tp_as_buffer_CharToIntArrayMapping, /*tp_as_buffer*/
+  Py_TPFLAGS_DEFAULT|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+  __Pyx_DOCSTR("Mapping for converting strings to int arrays"), /*tp_doc*/
+  __pyx_tp_traverse_2bx_11_seqmapping_CharToIntArrayMapping, /*tp_traverse*/
+  __pyx_tp_clear_2bx_11_seqmapping_CharToIntArrayMapping, /*tp_clear*/
+  0, /*tp_richcompare*/
+  0, /*tp_weaklistoffset*/
+  0, /*tp_iter*/
+  0, /*tp_iternext*/
+  __pyx_methods_2bx_11_seqmapping_CharToIntArrayMapping, /*tp_methods*/
+  0, /*tp_members*/
+  0, /*tp_getset*/
+  0, /*tp_base*/
+  0, /*tp_dict*/
+  0, /*tp_descr_get*/
+  0, /*tp_descr_set*/
+  0, /*tp_dictoffset*/
+  __pyx_pw_2bx_11_seqmapping_21CharToIntArrayMapping_3__init__, /*tp_init*/
+  0, /*tp_alloc*/
+  __pyx_tp_new_2bx_11_seqmapping_CharToIntArrayMapping, /*tp_new*/
+  0, /*tp_free*/
+  0, /*tp_is_gc*/
+  0, /*tp_bases*/
+  0, /*tp_mro*/
+  0, /*tp_cache*/
+  0, /*tp_subclasses*/
+  0, /*tp_weaklist*/
+  0, /*tp_del*/
+  #if PY_VERSION_HEX >= 0x02060000
+  0, /*tp_version_tag*/
+  #endif
+};
+
+static PyObject *__pyx_tp_new_2bx_11_seqmapping_IntToIntMapping(PyTypeObject *t, PyObject *a, PyObject *k) {
+  PyObject *o = (*t->tp_alloc)(t, 0);
+  if (!o) return 0;
+  if (__pyx_pw_2bx_11_seqmapping_15IntToIntMapping_1__cinit__(o, a, k) < 0) {
+    Py_DECREF(o); o = 0;
+  }
+  return o;
+}
+
+static void __pyx_tp_dealloc_2bx_11_seqmapping_IntToIntMapping(PyObject *o) {
+  {
+    PyObject *etype, *eval, *etb;
+    PyErr_Fetch(&etype, &eval, &etb);
+    ++Py_REFCNT(o);
+    __pyx_pw_2bx_11_seqmapping_15IntToIntMapping_3__dealloc__(o);
+    if (PyErr_Occurred()) PyErr_WriteUnraisable(o);
+    --Py_REFCNT(o);
+    PyErr_Restore(etype, eval, etb);
+  }
+  (*Py_TYPE(o)->tp_free)(o);
+}
+static PyObject *__pyx_sq_item_2bx_11_seqmapping_IntToIntMapping(PyObject *o, Py_ssize_t i) {
+  PyObject *r;
+  PyObject *x = PyInt_FromSsize_t(i); if(!x) return 0;
+  r = Py_TYPE(o)->tp_as_mapping->mp_subscript(o, x);
+  Py_DECREF(x);
+  return r;
+}
+
+static PyMethodDef __pyx_methods_2bx_11_seqmapping_IntToIntMapping[] = {
+  {__Pyx_NAMESTR("set_mapping"), (PyCFunction)__pyx_pw_2bx_11_seqmapping_15IntToIntMapping_5set_mapping, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(0)},
+  {__Pyx_NAMESTR("translate"), (PyCFunction)__pyx_pw_2bx_11_seqmapping_15IntToIntMapping_7translate, METH_O, __Pyx_DOCSTR(__pyx_doc_2bx_11_seqmapping_15IntToIntMapping_6translate)},
+  {__Pyx_NAMESTR("collapse"), (PyCFunction)__pyx_pw_2bx_11_seqmapping_15IntToIntMapping_11collapse, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(0)},
+  {__Pyx_NAMESTR("expand"), (PyCFunction)__pyx_pw_2bx_11_seqmapping_15IntToIntMapping_13expand, METH_O, __Pyx_DOCSTR(__pyx_doc_2bx_11_seqmapping_15IntToIntMapping_12expand)},
+  {__Pyx_NAMESTR("expand_out"), (PyCFunction)__pyx_pw_2bx_11_seqmapping_15IntToIntMapping_15expand_out, METH_O, __Pyx_DOCSTR(__pyx_doc_2bx_11_seqmapping_15IntToIntMapping_14expand_out)},
+  {__Pyx_NAMESTR("expand_random_split"), (PyCFunction)__pyx_pw_2bx_11_seqmapping_15IntToIntMapping_17expand_random_split, METH_O, __Pyx_DOCSTR(__pyx_doc_2bx_11_seqmapping_15IntToIntMapping_16expand_random_split)},
+  {__Pyx_NAMESTR("get_in_size"), (PyCFunction)__pyx_pw_2bx_11_seqmapping_15IntToIntMapping_19get_in_size, METH_NOARGS, __Pyx_DOCSTR(0)},
+  {__Pyx_NAMESTR("get_out_size"), (PyCFunction)__pyx_pw_2bx_11_seqmapping_15IntToIntMapping_21get_out_size, METH_NOARGS, __Pyx_DOCSTR(0)},
+  {__Pyx_NAMESTR("get_table"), (PyCFunction)__pyx_pw_2bx_11_seqmapping_15IntToIntMapping_23get_table, METH_NOARGS, __Pyx_DOCSTR(0)},
+  {0, 0, 0, 0}
+};
+
+static PyNumberMethods __pyx_tp_as_number_IntToIntMapping = {
+  0, /*nb_add*/
+  0, /*nb_subtract*/
+  0, /*nb_multiply*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_divide*/
+  #endif
+  0, /*nb_remainder*/
+  0, /*nb_divmod*/
+  0, /*nb_power*/
+  0, /*nb_negative*/
+  0, /*nb_positive*/
+  0, /*nb_absolute*/
+  0, /*nb_nonzero*/
+  0, /*nb_invert*/
+  0, /*nb_lshift*/
+  0, /*nb_rshift*/
+  0, /*nb_and*/
+  0, /*nb_xor*/
+  0, /*nb_or*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_coerce*/
+  #endif
+  0, /*nb_int*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_long*/
+  #else
+  0, /*reserved*/
+  #endif
+  0, /*nb_float*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_oct*/
+  #endif
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_hex*/
+  #endif
+  0, /*nb_inplace_add*/
+  0, /*nb_inplace_subtract*/
+  0, /*nb_inplace_multiply*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_inplace_divide*/
+  #endif
+  0, /*nb_inplace_remainder*/
+  0, /*nb_inplace_power*/
+  0, /*nb_inplace_lshift*/
+  0, /*nb_inplace_rshift*/
+  0, /*nb_inplace_and*/
+  0, /*nb_inplace_xor*/
+  0, /*nb_inplace_or*/
+  0, /*nb_floor_divide*/
+  0, /*nb_true_divide*/
+  0, /*nb_inplace_floor_divide*/
+  0, /*nb_inplace_true_divide*/
+  #if PY_VERSION_HEX >= 0x02050000
+  0, /*nb_index*/
+  #endif
+};
+
+static PySequenceMethods __pyx_tp_as_sequence_IntToIntMapping = {
+  0, /*sq_length*/
+  0, /*sq_concat*/
+  0, /*sq_repeat*/
+  __pyx_sq_item_2bx_11_seqmapping_IntToIntMapping, /*sq_item*/
+  0, /*sq_slice*/
+  0, /*sq_ass_item*/
+  0, /*sq_ass_slice*/
+  0, /*sq_contains*/
+  0, /*sq_inplace_concat*/
+  0, /*sq_inplace_repeat*/
+};
+
+static PyMappingMethods __pyx_tp_as_mapping_IntToIntMapping = {
+  0, /*mp_length*/
+  __pyx_pw_2bx_11_seqmapping_15IntToIntMapping_9__getitem__, /*mp_subscript*/
+  0, /*mp_ass_subscript*/
+};
+
+static PyBufferProcs __pyx_tp_as_buffer_IntToIntMapping = {
+  #if PY_MAJOR_VERSION < 3
+  0, /*bf_getreadbuffer*/
+  #endif
+  #if PY_MAJOR_VERSION < 3
+  0, /*bf_getwritebuffer*/
+  #endif
+  #if PY_MAJOR_VERSION < 3
+  0, /*bf_getsegcount*/
+  #endif
+  #if PY_MAJOR_VERSION < 3
+  0, /*bf_getcharbuffer*/
+  #endif
+  #if PY_VERSION_HEX >= 0x02060000
+  0, /*bf_getbuffer*/
+  #endif
+  #if PY_VERSION_HEX >= 0x02060000
+  0, /*bf_releasebuffer*/
+  #endif
+};
+
+static PyTypeObject __pyx_type_2bx_11_seqmapping_IntToIntMapping = {
+  PyVarObject_HEAD_INIT(0, 0)
+  __Pyx_NAMESTR("bx._seqmapping.IntToIntMapping"), /*tp_name*/
+  sizeof(struct __pyx_obj_2bx_11_seqmapping_IntToIntMapping), /*tp_basicsize*/
+  0, /*tp_itemsize*/
+  __pyx_tp_dealloc_2bx_11_seqmapping_IntToIntMapping, /*tp_dealloc*/
+  0, /*tp_print*/
+  0, /*tp_getattr*/
+  0, /*tp_setattr*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*tp_compare*/
+  #else
+  0, /*reserved*/
+  #endif
+  0, /*tp_repr*/
+  &__pyx_tp_as_number_IntToIntMapping, /*tp_as_number*/
+  &__pyx_tp_as_sequence_IntToIntMapping, /*tp_as_sequence*/
+  &__pyx_tp_as_mapping_IntToIntMapping, /*tp_as_mapping*/
+  0, /*tp_hash*/
+  0, /*tp_call*/
+  0, /*tp_str*/
+  0, /*tp_getattro*/
+  0, /*tp_setattro*/
+  &__pyx_tp_as_buffer_IntToIntMapping, /*tp_as_buffer*/
+  Py_TPFLAGS_DEFAULT|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE, /*tp_flags*/
+  0, /*tp_doc*/
+  0, /*tp_traverse*/
+  0, /*tp_clear*/
+  0, /*tp_richcompare*/
+  0, /*tp_weaklistoffset*/
+  0, /*tp_iter*/
+  0, /*tp_iternext*/
+  __pyx_methods_2bx_11_seqmapping_IntToIntMapping, /*tp_methods*/
+  0, /*tp_members*/
+  0, /*tp_getset*/
+  0, /*tp_base*/
+  0, /*tp_dict*/
+  0, /*tp_descr_get*/
+  0, /*tp_descr_set*/
+  0, /*tp_dictoffset*/
+  0, /*tp_init*/
+  0, /*tp_alloc*/
+  __pyx_tp_new_2bx_11_seqmapping_IntToIntMapping, /*tp_new*/
+  0, /*tp_free*/
+  0, /*tp_is_gc*/
+  0, /*tp_bases*/
+  0, /*tp_mro*/
+  0, /*tp_cache*/
+  0, /*tp_subclasses*/
+  0, /*tp_weaklist*/
+  0, /*tp_del*/
+  #if PY_VERSION_HEX >= 0x02060000
+  0, /*tp_version_tag*/
+  #endif
+};
+
+static PyMethodDef __pyx_methods[] = {
+  {0, 0, 0, 0}
+};
+
+#if PY_MAJOR_VERSION >= 3
+static struct PyModuleDef __pyx_moduledef = {
+  #if PY_VERSION_HEX < 0x03020000
+    { PyObject_HEAD_INIT(NULL) NULL, 0, NULL },
+  #else
+    PyModuleDef_HEAD_INIT,
+  #endif
+    __Pyx_NAMESTR("_seqmapping"),
+    __Pyx_DOCSTR(__pyx_k_4), /* m_doc */
+    -1, /* m_size */
+    __pyx_methods /* m_methods */,
+    NULL, /* m_reload */
+    NULL, /* m_traverse */
+    NULL, /* m_clear */
+    NULL /* m_free */
+};
+#endif
+
+static __Pyx_StringTabEntry __pyx_string_tab[] = {
+  {&__pyx_kp_s_1, __pyx_k_1, sizeof(__pyx_k_1), 0, 0, 1, 0},
+  {&__pyx_kp_s_2, __pyx_k_2, sizeof(__pyx_k_2), 0, 0, 1, 0},
+  {&__pyx_kp_s_3, __pyx_k_3, sizeof(__pyx_k_3), 0, 0, 1, 0},
+  {&__pyx_n_s____main__, __pyx_k____main__, sizeof(__pyx_k____main__), 0, 0, 1, 1},
+  {&__pyx_n_s____test__, __pyx_k____test__, sizeof(__pyx_k____test__), 0, 0, 1, 1},
+  {&__pyx_n_s__a, __pyx_k__a, sizeof(__pyx_k__a), 0, 0, 1, 1},
+  {&__pyx_n_s__b, __pyx_k__b, sizeof(__pyx_k__b), 0, 0, 1, 1},
+  {&__pyx_n_s__c, __pyx_k__c, sizeof(__pyx_k__c), 0, 0, 1, 1},
+  {&__pyx_n_s__chr, __pyx_k__chr, sizeof(__pyx_k__chr), 0, 0, 1, 1},
+  {&__pyx_n_s__floor, __pyx_k__floor, sizeof(__pyx_k__floor), 0, 0, 1, 1},
+  {&__pyx_n_s__i, __pyx_k__i, sizeof(__pyx_k__i), 0, 0, 1, 1},
+  {&__pyx_n_s__in_size, __pyx_k__in_size, sizeof(__pyx_k__in_size), 0, 0, 1, 1},
+  {&__pyx_n_s__index, __pyx_k__index, sizeof(__pyx_k__index), 0, 0, 1, 1},
+  {&__pyx_n_s__math, __pyx_k__math, sizeof(__pyx_k__math), 0, 0, 1, 1},
+  {&__pyx_n_s__nseqs, __pyx_k__nseqs, sizeof(__pyx_k__nseqs), 0, 0, 1, 1},
+  {&__pyx_n_s__numpy, __pyx_k__numpy, sizeof(__pyx_k__numpy), 0, 0, 1, 1},
+  {&__pyx_n_s__ord, __pyx_k__ord, sizeof(__pyx_k__ord), 0, 0, 1, 1},
+  {&__pyx_n_s__random, __pyx_k__random, sizeof(__pyx_k__random), 0, 0, 1, 1},
+  {&__pyx_n_s__randrange, __pyx_k__randrange, sizeof(__pyx_k__randrange), 0, 0, 1, 1},
+  {&__pyx_n_s__range, __pyx_k__range, sizeof(__pyx_k__range), 0, 0, 1, 1},
+  {&__pyx_n_s__sample, __pyx_k__sample, sizeof(__pyx_k__sample), 0, 0, 1, 1},
+  {&__pyx_n_s__symbol, __pyx_k__symbol, sizeof(__pyx_k__symbol), 0, 0, 1, 1},
+  {&__pyx_n_s__sys, __pyx_k__sys, sizeof(__pyx_k__sys), 0, 0, 1, 1},
+  {&__pyx_n_s__val, __pyx_k__val, sizeof(__pyx_k__val), 0, 0, 1, 1},
+  {&__pyx_n_s__zeros, __pyx_k__zeros, sizeof(__pyx_k__zeros), 0, 0, 1, 1},
+  {0, 0, 0, 0, 0, 0, 0}
+};
+static int __Pyx_InitCachedBuiltins(void) {
+  __pyx_builtin_ord = __Pyx_GetName(__pyx_b, __pyx_n_s__ord); if (!__pyx_builtin_ord) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 37; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_builtin_chr = __Pyx_GetName(__pyx_b, __pyx_n_s__chr); if (!__pyx_builtin_chr) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 41; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_builtin_range = __Pyx_GetName(__pyx_b, __pyx_n_s__range); if (!__pyx_builtin_range) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 219; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  return 0;
+  __pyx_L1_error:;
+  return -1;
+}
+
+static int __Pyx_InitCachedConstants(void) {
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0);
+  __Pyx_RefNannyFinishContext();
+  return 0;
+}
+
+static int __Pyx_InitGlobals(void) {
+  if (__Pyx_InitStrings(__pyx_string_tab) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  __pyx_int_0 = PyInt_FromLong(0); if (unlikely(!__pyx_int_0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  __pyx_int_1 = PyInt_FromLong(1); if (unlikely(!__pyx_int_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  __pyx_int_neg_1 = PyInt_FromLong(-1); if (unlikely(!__pyx_int_neg_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  return 0;
+  __pyx_L1_error:;
+  return -1;
+}
+
+#if PY_MAJOR_VERSION < 3
+PyMODINIT_FUNC init_seqmapping(void); /*proto*/
+PyMODINIT_FUNC init_seqmapping(void)
+#else
+PyMODINIT_FUNC PyInit__seqmapping(void); /*proto*/
+PyMODINIT_FUNC PyInit__seqmapping(void)
+#endif
+{
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  __Pyx_RefNannyDeclarations
+  #if CYTHON_REFNANNY
+  __Pyx_RefNanny = __Pyx_RefNannyImportAPI("refnanny");
+  if (!__Pyx_RefNanny) {
+      PyErr_Clear();
+      __Pyx_RefNanny = __Pyx_RefNannyImportAPI("Cython.Runtime.refnanny");
+      if (!__Pyx_RefNanny)
+          Py_FatalError("failed to import 'refnanny' module");
+  }
+  #endif
+  __Pyx_RefNannySetupContext("PyMODINIT_FUNC PyInit__seqmapping(void)", 0);
+  if ( __Pyx_check_binary_version() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_bytes)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #ifdef __Pyx_CyFunction_USED
+  if (__Pyx_CyFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #endif
+  #ifdef __Pyx_FusedFunction_USED
+  if (__pyx_FusedFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #endif
+  #ifdef __Pyx_Generator_USED
+  if (__pyx_Generator_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #endif
+  /*--- Library function declarations ---*/
+  /*--- Threads initialization code ---*/
+  #if defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS
+  #ifdef WITH_THREAD /* Python build with threading support? */
+  PyEval_InitThreads();
+  #endif
+  #endif
+  /*--- Module creation code ---*/
+  #if PY_MAJOR_VERSION < 3
+  __pyx_m = Py_InitModule4(__Pyx_NAMESTR("_seqmapping"), __pyx_methods, __Pyx_DOCSTR(__pyx_k_4), 0, PYTHON_API_VERSION); Py_XINCREF(__pyx_m);
+  #else
+  __pyx_m = PyModule_Create(&__pyx_moduledef);
+  #endif
+  if (unlikely(!__pyx_m)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #if PY_MAJOR_VERSION >= 3
+  {
+    PyObject *modules = PyImport_GetModuleDict(); if (unlikely(!modules)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (!PyDict_GetItemString(modules, "bx._seqmapping")) {
+      if (unlikely(PyDict_SetItemString(modules, "bx._seqmapping", __pyx_m) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+  }
+  #endif
+  __pyx_b = PyImport_AddModule(__Pyx_NAMESTR(__Pyx_BUILTIN_MODULE_NAME)); if (unlikely(!__pyx_b)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #if CYTHON_COMPILING_IN_PYPY
+  Py_INCREF(__pyx_b);
+  #endif
+  if (__Pyx_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  /*--- Initialize various global constants etc. ---*/
+  if (unlikely(__Pyx_InitGlobals() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (__pyx_module_is_main_bx___seqmapping) {
+    if (__Pyx_SetAttrString(__pyx_m, "__name__", __pyx_n_s____main__) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  }
+  /*--- Builtin init code ---*/
+  if (unlikely(__Pyx_InitCachedBuiltins() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  /*--- Constants init code ---*/
+  if (unlikely(__Pyx_InitCachedConstants() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  /*--- Global init code ---*/
+  /*--- Variable export code ---*/
+  /*--- Function export code ---*/
+  /*--- Type init code ---*/
+  if (PyType_Ready(&__pyx_type_2bx_11_seqmapping_CharToIntArrayMapping) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 19; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (__Pyx_SetAttrString(__pyx_m, "CharToIntArrayMapping", (PyObject *)&__pyx_type_2bx_11_seqmapping_CharToIntArrayMapping) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 19; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_2bx_11_seqmapping_CharToIntArrayMapping = &__pyx_type_2bx_11_seqmapping_CharToIntArrayMapping;
+  if (PyType_Ready(&__pyx_type_2bx_11_seqmapping_IntToIntMapping) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 102; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (__Pyx_SetAttrString(__pyx_m, "IntToIntMapping", (PyObject *)&__pyx_type_2bx_11_seqmapping_IntToIntMapping) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 102; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_2bx_11_seqmapping_IntToIntMapping = &__pyx_type_2bx_11_seqmapping_IntToIntMapping;
+  /*--- Type import code ---*/
+  /*--- Variable import code ---*/
+  /*--- Function import code ---*/
+  /*--- Execution code ---*/
+
+  /* "bx/_seqmapping.pyx":14
+ *     int PyString_AsStringAndSize(object, char **, int *) except -1
+ * 
+ * from numpy import zeros             # <<<<<<<<<<<<<<
+ * from math import floor
+ * import random
+ */
+  __pyx_t_1 = PyList_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 14; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_INCREF(((PyObject *)__pyx_n_s__zeros));
+  PyList_SET_ITEM(__pyx_t_1, 0, ((PyObject *)__pyx_n_s__zeros));
+  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__zeros));
+  __pyx_t_2 = __Pyx_Import(((PyObject *)__pyx_n_s__numpy), ((PyObject *)__pyx_t_1), -1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 14; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+  __pyx_t_1 = PyObject_GetAttr(__pyx_t_2, __pyx_n_s__zeros);
+  if (__pyx_t_1 == NULL) {
+    if (PyErr_ExceptionMatches(PyExc_AttributeError)) __Pyx_RaiseImportError(__pyx_n_s__zeros);
+    if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 14; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s__zeros, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 14; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+  /* "bx/_seqmapping.pyx":15
+ * 
+ * from numpy import zeros
+ * from math import floor             # <<<<<<<<<<<<<<
+ * import random
+ * import sys
+ */
+  __pyx_t_2 = PyList_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 15; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_INCREF(((PyObject *)__pyx_n_s__floor));
+  PyList_SET_ITEM(__pyx_t_2, 0, ((PyObject *)__pyx_n_s__floor));
+  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__floor));
+  __pyx_t_1 = __Pyx_Import(((PyObject *)__pyx_n_s__math), ((PyObject *)__pyx_t_2), -1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 15; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
+  __pyx_t_2 = PyObject_GetAttr(__pyx_t_1, __pyx_n_s__floor);
+  if (__pyx_t_2 == NULL) {
+    if (PyErr_ExceptionMatches(PyExc_AttributeError)) __Pyx_RaiseImportError(__pyx_n_s__floor);
+    if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 15; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s__floor, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 15; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "bx/_seqmapping.pyx":16
+ * from numpy import zeros
+ * from math import floor
+ * import random             # <<<<<<<<<<<<<<
+ * import sys
+ * 
+ */
+  __pyx_t_1 = __Pyx_Import(((PyObject *)__pyx_n_s__random), 0, -1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 16; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s__random, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 16; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "bx/_seqmapping.pyx":17
+ * from math import floor
+ * import random
+ * import sys             # <<<<<<<<<<<<<<
+ * 
+ * cdef class CharToIntArrayMapping:
+ */
+  __pyx_t_1 = __Pyx_Import(((PyObject *)__pyx_n_s__sys), 0, -1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s__sys, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "bx/_seqmapping.pyx":1
+ * """             # <<<<<<<<<<<<<<
+ * Pyrex extension classes used by `seqmapping.py`.
+ * """
+ */
+  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(((PyObject *)__pyx_t_1));
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s____test__, ((PyObject *)__pyx_t_1)) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  if (__pyx_m) {
+    __Pyx_AddTraceback("init bx._seqmapping", __pyx_clineno, __pyx_lineno, __pyx_filename);
+    Py_DECREF(__pyx_m); __pyx_m = 0;
+  } else if (!PyErr_Occurred()) {
+    PyErr_SetString(PyExc_ImportError, "init bx._seqmapping");
+  }
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  #if PY_MAJOR_VERSION < 3
+  return;
+  #else
+  return __pyx_m;
+  #endif
+}
+
+/* Runtime support code */
+#if CYTHON_REFNANNY
+static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) {
+    PyObject *m = NULL, *p = NULL;
+    void *r = NULL;
+    m = PyImport_ImportModule((char *)modname);
+    if (!m) goto end;
+    p = PyObject_GetAttrString(m, (char *)"RefNannyAPI");
+    if (!p) goto end;
+    r = PyLong_AsVoidPtr(p);
+end:
+    Py_XDECREF(p);
+    Py_XDECREF(m);
+    return (__Pyx_RefNannyAPIStruct *)r;
+}
+#endif /* CYTHON_REFNANNY */
+
+static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name) {
+    PyObject *result;
+    result = PyObject_GetAttr(dict, name);
+    if (!result) {
+        if (dict != __pyx_b) {
+            PyErr_Clear();
+            result = PyObject_GetAttr(__pyx_b, name);
+        }
+        if (!result) {
+            PyErr_SetObject(PyExc_NameError, name);
+        }
+    }
+    return result;
+}
+
+static void __Pyx_RaiseArgtupleInvalid(
+    const char* func_name,
+    int exact,
+    Py_ssize_t num_min,
+    Py_ssize_t num_max,
+    Py_ssize_t num_found)
+{
+    Py_ssize_t num_expected;
+    const char *more_or_less;
+    if (num_found < num_min) {
+        num_expected = num_min;
+        more_or_less = "at least";
+    } else {
+        num_expected = num_max;
+        more_or_less = "at most";
+    }
+    if (exact) {
+        more_or_less = "exactly";
+    }
+    PyErr_Format(PyExc_TypeError,
+                 "%s() takes %s %" CYTHON_FORMAT_SSIZE_T "d positional argument%s (%" CYTHON_FORMAT_SSIZE_T "d given)",
+                 func_name, more_or_less, num_expected,
+                 (num_expected == 1) ? "" : "s", num_found);
+}
+
+static CYTHON_INLINE int __Pyx_CheckKeywordStrings(
+    PyObject *kwdict,
+    const char* function_name,
+    int kw_allowed)
+{
+    PyObject* key = 0;
+    Py_ssize_t pos = 0;
+#if CPYTHON_COMPILING_IN_PYPY
+    if (!kw_allowed && PyDict_Next(kwdict, &pos, &key, 0))
+        goto invalid_keyword;
+    return 1;
+#else
+    while (PyDict_Next(kwdict, &pos, &key, 0)) {
+        #if PY_MAJOR_VERSION < 3
+        if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key)))
+        #endif
+            if (unlikely(!PyUnicode_Check(key)))
+                goto invalid_keyword_type;
+    }
+    if ((!kw_allowed) && unlikely(key))
+        goto invalid_keyword;
+    return 1;
+invalid_keyword_type:
+    PyErr_Format(PyExc_TypeError,
+        "%s() keywords must be strings", function_name);
+    return 0;
+#endif
+invalid_keyword:
+    PyErr_Format(PyExc_TypeError,
+    #if PY_MAJOR_VERSION < 3
+        "%s() got an unexpected keyword argument '%s'",
+        function_name, PyString_AsString(key));
+    #else
+        "%s() got an unexpected keyword argument '%U'",
+        function_name, key);
+    #endif
+    return 0;
+}
+
+static void __Pyx_RaiseDoubleKeywordsError(
+    const char* func_name,
+    PyObject* kw_name)
+{
+    PyErr_Format(PyExc_TypeError,
+        #if PY_MAJOR_VERSION >= 3
+        "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
+        #else
+        "%s() got multiple values for keyword argument '%s'", func_name,
+        PyString_AsString(kw_name));
+        #endif
+}
+
+static int __Pyx_ParseOptionalKeywords(
+    PyObject *kwds,
+    PyObject **argnames[],
+    PyObject *kwds2,
+    PyObject *values[],
+    Py_ssize_t num_pos_args,
+    const char* function_name)
+{
+    PyObject *key = 0, *value = 0;
+    Py_ssize_t pos = 0;
+    PyObject*** name;
+    PyObject*** first_kw_arg = argnames + num_pos_args;
+    while (PyDict_Next(kwds, &pos, &key, &value)) {
+        name = first_kw_arg;
+        while (*name && (**name != key)) name++;
+        if (*name) {
+            values[name-argnames] = value;
+            continue;
+        }
+        name = first_kw_arg;
+        #if PY_MAJOR_VERSION < 3
+        if (likely(PyString_CheckExact(key)) || likely(PyString_Check(key))) {
+            while (*name) {
+                if ((CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**name) == PyString_GET_SIZE(key))
+                        && _PyString_Eq(**name, key)) {
+                    values[name-argnames] = value;
+                    break;
+                }
+                name++;
+            }
+            if (*name) continue;
+            else {
+                PyObject*** argname = argnames;
+                while (argname != first_kw_arg) {
+                    if ((**argname == key) || (
+                            (CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**argname) == PyString_GET_SIZE(key))
+                             && _PyString_Eq(**argname, key))) {
+                        goto arg_passed_twice;
+                    }
+                    argname++;
+                }
+            }
+        } else
+        #endif
+        if (likely(PyUnicode_Check(key))) {
+            while (*name) {
+                int cmp = (**name == key) ? 0 :
+                #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3
+                    (PyUnicode_GET_SIZE(**name) != PyUnicode_GET_SIZE(key)) ? 1 :
+                #endif
+                    PyUnicode_Compare(**name, key);
+                if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad;
+                if (cmp == 0) {
+                    values[name-argnames] = value;
+                    break;
+                }
+                name++;
+            }
+            if (*name) continue;
+            else {
+                PyObject*** argname = argnames;
+                while (argname != first_kw_arg) {
+                    int cmp = (**argname == key) ? 0 :
+                    #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3
+                        (PyUnicode_GET_SIZE(**argname) != PyUnicode_GET_SIZE(key)) ? 1 :
+                    #endif
+                        PyUnicode_Compare(**argname, key);
+                    if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad;
+                    if (cmp == 0) goto arg_passed_twice;
+                    argname++;
+                }
+            }
+        } else
+            goto invalid_keyword_type;
+        if (kwds2) {
+            if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
+        } else {
+            goto invalid_keyword;
+        }
+    }
+    return 0;
+arg_passed_twice:
+    __Pyx_RaiseDoubleKeywordsError(function_name, key);
+    goto bad;
+invalid_keyword_type:
+    PyErr_Format(PyExc_TypeError,
+        "%s() keywords must be strings", function_name);
+    goto bad;
+invalid_keyword:
+    PyErr_Format(PyExc_TypeError,
+    #if PY_MAJOR_VERSION < 3
+        "%s() got an unexpected keyword argument '%s'",
+        function_name, PyString_AsString(key));
+    #else
+        "%s() got an unexpected keyword argument '%U'",
+        function_name, key);
+    #endif
+bad:
+    return -1;
+}
+
+static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    PyObject *tmp_type, *tmp_value, *tmp_tb;
+    PyThreadState *tstate = PyThreadState_GET();
+    tmp_type = tstate->curexc_type;
+    tmp_value = tstate->curexc_value;
+    tmp_tb = tstate->curexc_traceback;
+    tstate->curexc_type = type;
+    tstate->curexc_value = value;
+    tstate->curexc_traceback = tb;
+    Py_XDECREF(tmp_type);
+    Py_XDECREF(tmp_value);
+    Py_XDECREF(tmp_tb);
+#else
+    PyErr_Restore(type, value, tb);
+#endif
+}
+static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    PyThreadState *tstate = PyThreadState_GET();
+    *type = tstate->curexc_type;
+    *value = tstate->curexc_value;
+    *tb = tstate->curexc_traceback;
+    tstate->curexc_type = 0;
+    tstate->curexc_value = 0;
+    tstate->curexc_traceback = 0;
+#else
+    PyErr_Fetch(type, value, tb);
+#endif
+}
+
+#if PY_MAJOR_VERSION < 3
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb,
+                        CYTHON_UNUSED PyObject *cause) {
+    Py_XINCREF(type);
+    if (!value || value == Py_None)
+        value = NULL;
+    else
+        Py_INCREF(value);
+    if (!tb || tb == Py_None)
+        tb = NULL;
+    else {
+        Py_INCREF(tb);
+        if (!PyTraceBack_Check(tb)) {
+            PyErr_SetString(PyExc_TypeError,
+                "raise: arg 3 must be a traceback or None");
+            goto raise_error;
+        }
+    }
+    #if PY_VERSION_HEX < 0x02050000
+    if (PyClass_Check(type)) {
+    #else
+    if (PyType_Check(type)) {
+    #endif
+#if CYTHON_COMPILING_IN_PYPY
+        if (!value) {
+            Py_INCREF(Py_None);
+            value = Py_None;
+        }
+#endif
+        PyErr_NormalizeException(&type, &value, &tb);
+    } else {
+        if (value) {
+            PyErr_SetString(PyExc_TypeError,
+                "instance exception may not have a separate value");
+            goto raise_error;
+        }
+        value = type;
+        #if PY_VERSION_HEX < 0x02050000
+            if (PyInstance_Check(type)) {
+                type = (PyObject*) ((PyInstanceObject*)type)->in_class;
+                Py_INCREF(type);
+            }
+            else {
+                type = 0;
+                PyErr_SetString(PyExc_TypeError,
+                    "raise: exception must be an old-style class or instance");
+                goto raise_error;
+            }
+        #else
+            type = (PyObject*) Py_TYPE(type);
+            Py_INCREF(type);
+            if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
+                PyErr_SetString(PyExc_TypeError,
+                    "raise: exception class must be a subclass of BaseException");
+                goto raise_error;
+            }
+        #endif
+    }
+    __Pyx_ErrRestore(type, value, tb);
+    return;
+raise_error:
+    Py_XDECREF(value);
+    Py_XDECREF(type);
+    Py_XDECREF(tb);
+    return;
+}
+#else /* Python 3+ */
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause) {
+    PyObject* owned_instance = NULL;
+    if (tb == Py_None) {
+        tb = 0;
+    } else if (tb && !PyTraceBack_Check(tb)) {
+        PyErr_SetString(PyExc_TypeError,
+            "raise: arg 3 must be a traceback or None");
+        goto bad;
+    }
+    if (value == Py_None)
+        value = 0;
+    if (PyExceptionInstance_Check(type)) {
+        if (value) {
+            PyErr_SetString(PyExc_TypeError,
+                "instance exception may not have a separate value");
+            goto bad;
+        }
+        value = type;
+        type = (PyObject*) Py_TYPE(value);
+    } else if (PyExceptionClass_Check(type)) {
+        PyObject *args;
+        if (!value)
+            args = PyTuple_New(0);
+        else if (PyTuple_Check(value)) {
+            Py_INCREF(value);
+            args = value;
+        }
+        else
+            args = PyTuple_Pack(1, value);
+        if (!args)
+            goto bad;
+        owned_instance = PyEval_CallObject(type, args);
+        Py_DECREF(args);
+        if (!owned_instance)
+            goto bad;
+        value = owned_instance;
+        if (!PyExceptionInstance_Check(value)) {
+            PyErr_Format(PyExc_TypeError,
+                         "calling %R should have returned an instance of "
+                         "BaseException, not %R",
+                         type, Py_TYPE(value));
+            goto bad;
+        }
+    } else {
+        PyErr_SetString(PyExc_TypeError,
+            "raise: exception class must be a subclass of BaseException");
+        goto bad;
+    }
+    if (cause && cause != Py_None) {
+        PyObject *fixed_cause;
+        if (PyExceptionClass_Check(cause)) {
+            fixed_cause = PyObject_CallObject(cause, NULL);
+            if (fixed_cause == NULL)
+                goto bad;
+        }
+        else if (PyExceptionInstance_Check(cause)) {
+            fixed_cause = cause;
+            Py_INCREF(fixed_cause);
+        }
+        else {
+            PyErr_SetString(PyExc_TypeError,
+                            "exception causes must derive from "
+                            "BaseException");
+            goto bad;
+        }
+        PyException_SetCause(value, fixed_cause);
+    }
+    PyErr_SetObject(type, value);
+    if (tb) {
+        PyThreadState *tstate = PyThreadState_GET();
+        PyObject* tmp_tb = tstate->curexc_traceback;
+        if (tb != tmp_tb) {
+            Py_INCREF(tb);
+            tstate->curexc_traceback = tb;
+            Py_XDECREF(tmp_tb);
+        }
+    }
+bad:
+    Py_XDECREF(owned_instance);
+    return;
+}
+#endif
+
+static CYTHON_INLINE long __Pyx_div_long(long a, long b) {
+    long q = a / b;
+    long r = a - q*b;
+    q -= ((r != 0) & ((r ^ b) < 0));
+    return q;
+}
+
+static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level) {
+    PyObject *empty_list = 0;
+    PyObject *module = 0;
+    PyObject *global_dict = 0;
+    PyObject *empty_dict = 0;
+    PyObject *list;
+    #if PY_VERSION_HEX < 0x03030000
+    PyObject *py_import = 0;
+    py_import = __Pyx_GetAttrString(__pyx_b, "__import__");
+    if (!py_import)
+        goto bad;
+    #endif
+    if (from_list)
+        list = from_list;
+    else {
+        empty_list = PyList_New(0);
+        if (!empty_list)
+            goto bad;
+        list = empty_list;
+    }
+    global_dict = PyModule_GetDict(__pyx_m);
+    if (!global_dict)
+        goto bad;
+    empty_dict = PyDict_New();
+    if (!empty_dict)
+        goto bad;
+    #if PY_VERSION_HEX >= 0x02050000
+    {
+        #if PY_MAJOR_VERSION >= 3
+        if (level == -1) {
+            if (strchr(__Pyx_MODULE_NAME, '.')) {
+                #if PY_VERSION_HEX < 0x03030000
+                PyObject *py_level = PyInt_FromLong(1);
+                if (!py_level)
+                    goto bad;
+                module = PyObject_CallFunctionObjArgs(py_import,
+                    name, global_dict, empty_dict, list, py_level, NULL);
+                Py_DECREF(py_level);
+                #else
+                module = PyImport_ImportModuleLevelObject(
+                    name, global_dict, empty_dict, list, 1);
+                #endif
+                if (!module) {
+                    if (!PyErr_ExceptionMatches(PyExc_ImportError))
+                        goto bad;
+                    PyErr_Clear();
+                }
+            }
+            level = 0; /* try absolute import on failure */
+        }
+        #endif
+        if (!module) {
+            #if PY_VERSION_HEX < 0x03030000
+            PyObject *py_level = PyInt_FromLong(level);
+            if (!py_level)
+                goto bad;
+            module = PyObject_CallFunctionObjArgs(py_import,
+                name, global_dict, empty_dict, list, py_level, NULL);
+            Py_DECREF(py_level);
+            #else
+            module = PyImport_ImportModuleLevelObject(
+                name, global_dict, empty_dict, list, level);
+            #endif
+        }
+    }
+    #else
+    if (level>0) {
+        PyErr_SetString(PyExc_RuntimeError, "Relative import is not supported for Python <=2.4.");
+        goto bad;
+    }
+    module = PyObject_CallFunctionObjArgs(py_import,
+        name, global_dict, empty_dict, list, NULL);
+    #endif
+bad:
+    #if PY_VERSION_HEX < 0x03030000
+    Py_XDECREF(py_import);
+    #endif
+    Py_XDECREF(empty_list);
+    Py_XDECREF(empty_dict);
+    return module;
+}
+
+static CYTHON_INLINE void __Pyx_RaiseImportError(PyObject *name) {
+#if PY_MAJOR_VERSION < 3
+    PyErr_Format(PyExc_ImportError, "cannot import name %.230s",
+                 PyString_AsString(name));
+#else
+    PyErr_Format(PyExc_ImportError, "cannot import name %S", name);
+#endif
+}
+
+static CYTHON_INLINE unsigned char __Pyx_PyInt_AsUnsignedChar(PyObject* x) {
+    const unsigned char neg_one = (unsigned char)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(unsigned char) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(unsigned char)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to unsigned char" :
+                    "value too large to convert to unsigned char");
+            }
+            return (unsigned char)-1;
+        }
+        return (unsigned char)val;
+    }
+    return (unsigned char)__Pyx_PyInt_AsUnsignedLong(x);
+}
+
+static CYTHON_INLINE unsigned short __Pyx_PyInt_AsUnsignedShort(PyObject* x) {
+    const unsigned short neg_one = (unsigned short)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(unsigned short) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(unsigned short)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to unsigned short" :
+                    "value too large to convert to unsigned short");
+            }
+            return (unsigned short)-1;
+        }
+        return (unsigned short)val;
+    }
+    return (unsigned short)__Pyx_PyInt_AsUnsignedLong(x);
+}
+
+static CYTHON_INLINE unsigned int __Pyx_PyInt_AsUnsignedInt(PyObject* x) {
+    const unsigned int neg_one = (unsigned int)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(unsigned int) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(unsigned int)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to unsigned int" :
+                    "value too large to convert to unsigned int");
+            }
+            return (unsigned int)-1;
+        }
+        return (unsigned int)val;
+    }
+    return (unsigned int)__Pyx_PyInt_AsUnsignedLong(x);
+}
+
+static CYTHON_INLINE char __Pyx_PyInt_AsChar(PyObject* x) {
+    const char neg_one = (char)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(char) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(char)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to char" :
+                    "value too large to convert to char");
+            }
+            return (char)-1;
+        }
+        return (char)val;
+    }
+    return (char)__Pyx_PyInt_AsLong(x);
+}
+
+static CYTHON_INLINE short __Pyx_PyInt_AsShort(PyObject* x) {
+    const short neg_one = (short)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(short) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(short)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to short" :
+                    "value too large to convert to short");
+            }
+            return (short)-1;
+        }
+        return (short)val;
+    }
+    return (short)__Pyx_PyInt_AsLong(x);
+}
+
+static CYTHON_INLINE int __Pyx_PyInt_AsInt(PyObject* x) {
+    const int neg_one = (int)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(int) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(int)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to int" :
+                    "value too large to convert to int");
+            }
+            return (int)-1;
+        }
+        return (int)val;
+    }
+    return (int)__Pyx_PyInt_AsLong(x);
+}
+
+static CYTHON_INLINE signed char __Pyx_PyInt_AsSignedChar(PyObject* x) {
+    const signed char neg_one = (signed char)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(signed char) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(signed char)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to signed char" :
+                    "value too large to convert to signed char");
+            }
+            return (signed char)-1;
+        }
+        return (signed char)val;
+    }
+    return (signed char)__Pyx_PyInt_AsSignedLong(x);
+}
+
+static CYTHON_INLINE signed short __Pyx_PyInt_AsSignedShort(PyObject* x) {
+    const signed short neg_one = (signed short)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(signed short) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(signed short)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to signed short" :
+                    "value too large to convert to signed short");
+            }
+            return (signed short)-1;
+        }
+        return (signed short)val;
+    }
+    return (signed short)__Pyx_PyInt_AsSignedLong(x);
+}
+
+static CYTHON_INLINE signed int __Pyx_PyInt_AsSignedInt(PyObject* x) {
+    const signed int neg_one = (signed int)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(signed int) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(signed int)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to signed int" :
+                    "value too large to convert to signed int");
+            }
+            return (signed int)-1;
+        }
+        return (signed int)val;
+    }
+    return (signed int)__Pyx_PyInt_AsSignedLong(x);
+}
+
+static CYTHON_INLINE int __Pyx_PyInt_AsLongDouble(PyObject* x) {
+    const int neg_one = (int)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(int) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(int)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to int" :
+                    "value too large to convert to int");
+            }
+            return (int)-1;
+        }
+        return (int)val;
+    }
+    return (int)__Pyx_PyInt_AsLong(x);
+}
+
+static CYTHON_INLINE unsigned long __Pyx_PyInt_AsUnsignedLong(PyObject* x) {
+    const unsigned long neg_one = (unsigned long)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to unsigned long");
+            return (unsigned long)-1;
+        }
+        return (unsigned long)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to unsigned long");
+                return (unsigned long)-1;
+            }
+            return (unsigned long)PyLong_AsUnsignedLong(x);
+        } else {
+            return (unsigned long)PyLong_AsLong(x);
+        }
+    } else {
+        unsigned long val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (unsigned long)-1;
+        val = __Pyx_PyInt_AsUnsignedLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE unsigned PY_LONG_LONG __Pyx_PyInt_AsUnsignedLongLong(PyObject* x) {
+    const unsigned PY_LONG_LONG neg_one = (unsigned PY_LONG_LONG)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to unsigned PY_LONG_LONG");
+            return (unsigned PY_LONG_LONG)-1;
+        }
+        return (unsigned PY_LONG_LONG)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to unsigned PY_LONG_LONG");
+                return (unsigned PY_LONG_LONG)-1;
+            }
+            return (unsigned PY_LONG_LONG)PyLong_AsUnsignedLongLong(x);
+        } else {
+            return (unsigned PY_LONG_LONG)PyLong_AsLongLong(x);
+        }
+    } else {
+        unsigned PY_LONG_LONG val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (unsigned PY_LONG_LONG)-1;
+        val = __Pyx_PyInt_AsUnsignedLongLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE long __Pyx_PyInt_AsLong(PyObject* x) {
+    const long neg_one = (long)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to long");
+            return (long)-1;
+        }
+        return (long)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to long");
+                return (long)-1;
+            }
+            return (long)PyLong_AsUnsignedLong(x);
+        } else {
+            return (long)PyLong_AsLong(x);
+        }
+    } else {
+        long val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (long)-1;
+        val = __Pyx_PyInt_AsLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE PY_LONG_LONG __Pyx_PyInt_AsLongLong(PyObject* x) {
+    const PY_LONG_LONG neg_one = (PY_LONG_LONG)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to PY_LONG_LONG");
+            return (PY_LONG_LONG)-1;
+        }
+        return (PY_LONG_LONG)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to PY_LONG_LONG");
+                return (PY_LONG_LONG)-1;
+            }
+            return (PY_LONG_LONG)PyLong_AsUnsignedLongLong(x);
+        } else {
+            return (PY_LONG_LONG)PyLong_AsLongLong(x);
+        }
+    } else {
+        PY_LONG_LONG val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (PY_LONG_LONG)-1;
+        val = __Pyx_PyInt_AsLongLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE signed long __Pyx_PyInt_AsSignedLong(PyObject* x) {
+    const signed long neg_one = (signed long)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to signed long");
+            return (signed long)-1;
+        }
+        return (signed long)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to signed long");
+                return (signed long)-1;
+            }
+            return (signed long)PyLong_AsUnsignedLong(x);
+        } else {
+            return (signed long)PyLong_AsLong(x);
+        }
+    } else {
+        signed long val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (signed long)-1;
+        val = __Pyx_PyInt_AsSignedLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE signed PY_LONG_LONG __Pyx_PyInt_AsSignedLongLong(PyObject* x) {
+    const signed PY_LONG_LONG neg_one = (signed PY_LONG_LONG)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to signed PY_LONG_LONG");
+            return (signed PY_LONG_LONG)-1;
+        }
+        return (signed PY_LONG_LONG)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to signed PY_LONG_LONG");
+                return (signed PY_LONG_LONG)-1;
+            }
+            return (signed PY_LONG_LONG)PyLong_AsUnsignedLongLong(x);
+        } else {
+            return (signed PY_LONG_LONG)PyLong_AsLongLong(x);
+        }
+    } else {
+        signed PY_LONG_LONG val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (signed PY_LONG_LONG)-1;
+        val = __Pyx_PyInt_AsSignedLongLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static int __Pyx_check_binary_version(void) {
+    char ctversion[4], rtversion[4];
+    PyOS_snprintf(ctversion, 4, "%d.%d", PY_MAJOR_VERSION, PY_MINOR_VERSION);
+    PyOS_snprintf(rtversion, 4, "%s", Py_GetVersion());
+    if (ctversion[0] != rtversion[0] || ctversion[2] != rtversion[2]) {
+        char message[200];
+        PyOS_snprintf(message, sizeof(message),
+                      "compiletime version %s of module '%.100s' "
+                      "does not match runtime version %s",
+                      ctversion, __Pyx_MODULE_NAME, rtversion);
+        #if PY_VERSION_HEX < 0x02050000
+        return PyErr_Warn(NULL, message);
+        #else
+        return PyErr_WarnEx(NULL, message, 1);
+        #endif
+    }
+    return 0;
+}
+
+static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) {
+    int start = 0, mid = 0, end = count - 1;
+    if (end >= 0 && code_line > entries[end].code_line) {
+        return count;
+    }
+    while (start < end) {
+        mid = (start + end) / 2;
+        if (code_line < entries[mid].code_line) {
+            end = mid;
+        } else if (code_line > entries[mid].code_line) {
+             start = mid + 1;
+        } else {
+            return mid;
+        }
+    }
+    if (code_line <= entries[mid].code_line) {
+        return mid;
+    } else {
+        return mid + 1;
+    }
+}
+static PyCodeObject *__pyx_find_code_object(int code_line) {
+    PyCodeObject* code_object;
+    int pos;
+    if (unlikely(!code_line) || unlikely(!__pyx_code_cache.entries)) {
+        return NULL;
+    }
+    pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line);
+    if (unlikely(pos >= __pyx_code_cache.count) || unlikely(__pyx_code_cache.entries[pos].code_line != code_line)) {
+        return NULL;
+    }
+    code_object = __pyx_code_cache.entries[pos].code_object;
+    Py_INCREF(code_object);
+    return code_object;
+}
+static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) {
+    int pos, i;
+    __Pyx_CodeObjectCacheEntry* entries = __pyx_code_cache.entries;
+    if (unlikely(!code_line)) {
+        return;
+    }
+    if (unlikely(!entries)) {
+        entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Malloc(64*sizeof(__Pyx_CodeObjectCacheEntry));
+        if (likely(entries)) {
+            __pyx_code_cache.entries = entries;
+            __pyx_code_cache.max_count = 64;
+            __pyx_code_cache.count = 1;
+            entries[0].code_line = code_line;
+            entries[0].code_object = code_object;
+            Py_INCREF(code_object);
+        }
+        return;
+    }
+    pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line);
+    if ((pos < __pyx_code_cache.count) && unlikely(__pyx_code_cache.entries[pos].code_line == code_line)) {
+        PyCodeObject* tmp = entries[pos].code_object;
+        entries[pos].code_object = code_object;
+        Py_DECREF(tmp);
+        return;
+    }
+    if (__pyx_code_cache.count == __pyx_code_cache.max_count) {
+        int new_max = __pyx_code_cache.max_count + 64;
+        entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Realloc(
+            __pyx_code_cache.entries, new_max*sizeof(__Pyx_CodeObjectCacheEntry));
+        if (unlikely(!entries)) {
+            return;
+        }
+        __pyx_code_cache.entries = entries;
+        __pyx_code_cache.max_count = new_max;
+    }
+    for (i=__pyx_code_cache.count; i>pos; i--) {
+        entries[i] = entries[i-1];
+    }
+    entries[pos].code_line = code_line;
+    entries[pos].code_object = code_object;
+    __pyx_code_cache.count++;
+    Py_INCREF(code_object);
+}
+
+#include "compile.h"
+#include "frameobject.h"
+#include "traceback.h"
+static PyCodeObject* __Pyx_CreateCodeObjectForTraceback(
+            const char *funcname, int c_line,
+            int py_line, const char *filename) {
+    PyCodeObject *py_code = 0;
+    PyObject *py_srcfile = 0;
+    PyObject *py_funcname = 0;
+    #if PY_MAJOR_VERSION < 3
+    py_srcfile = PyString_FromString(filename);
+    #else
+    py_srcfile = PyUnicode_FromString(filename);
+    #endif
+    if (!py_srcfile) goto bad;
+    if (c_line) {
+        #if PY_MAJOR_VERSION < 3
+        py_funcname = PyString_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line);
+        #else
+        py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line);
+        #endif
+    }
+    else {
+        #if PY_MAJOR_VERSION < 3
+        py_funcname = PyString_FromString(funcname);
+        #else
+        py_funcname = PyUnicode_FromString(funcname);
+        #endif
+    }
+    if (!py_funcname) goto bad;
+    py_code = __Pyx_PyCode_New(
+        0,            /*int argcount,*/
+        0,            /*int kwonlyargcount,*/
+        0,            /*int nlocals,*/
+        0,            /*int stacksize,*/
+        0,            /*int flags,*/
+        __pyx_empty_bytes, /*PyObject *code,*/
+        __pyx_empty_tuple, /*PyObject *consts,*/
+        __pyx_empty_tuple, /*PyObject *names,*/
+        __pyx_empty_tuple, /*PyObject *varnames,*/
+        __pyx_empty_tuple, /*PyObject *freevars,*/
+        __pyx_empty_tuple, /*PyObject *cellvars,*/
+        py_srcfile,   /*PyObject *filename,*/
+        py_funcname,  /*PyObject *name,*/
+        py_line,      /*int firstlineno,*/
+        __pyx_empty_bytes  /*PyObject *lnotab*/
+    );
+    Py_DECREF(py_srcfile);
+    Py_DECREF(py_funcname);
+    return py_code;
+bad:
+    Py_XDECREF(py_srcfile);
+    Py_XDECREF(py_funcname);
+    return NULL;
+}
+static void __Pyx_AddTraceback(const char *funcname, int c_line,
+                               int py_line, const char *filename) {
+    PyCodeObject *py_code = 0;
+    PyObject *py_globals = 0;
+    PyFrameObject *py_frame = 0;
+    py_code = __pyx_find_code_object(c_line ? c_line : py_line);
+    if (!py_code) {
+        py_code = __Pyx_CreateCodeObjectForTraceback(
+            funcname, c_line, py_line, filename);
+        if (!py_code) goto bad;
+        __pyx_insert_code_object(c_line ? c_line : py_line, py_code);
+    }
+    py_globals = PyModule_GetDict(__pyx_m);
+    if (!py_globals) goto bad;
+    py_frame = PyFrame_New(
+        PyThreadState_GET(), /*PyThreadState *tstate,*/
+        py_code,             /*PyCodeObject *code,*/
+        py_globals,          /*PyObject *globals,*/
+        0                    /*PyObject *locals*/
+    );
+    if (!py_frame) goto bad;
+    py_frame->f_lineno = py_line;
+    PyTraceBack_Here(py_frame);
+bad:
+    Py_XDECREF(py_code);
+    Py_XDECREF(py_frame);
+}
+
+static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
+    while (t->p) {
+        #if PY_MAJOR_VERSION < 3
+        if (t->is_unicode) {
+            *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
+        } else if (t->intern) {
+            *t->p = PyString_InternFromString(t->s);
+        } else {
+            *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
+        }
+        #else  /* Python 3+ has unicode identifiers */
+        if (t->is_unicode | t->is_str) {
+            if (t->intern) {
+                *t->p = PyUnicode_InternFromString(t->s);
+            } else if (t->encoding) {
+                *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL);
+            } else {
+                *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
+            }
+        } else {
+            *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
+        }
+        #endif
+        if (!*t->p)
+            return -1;
+        ++t;
+    }
+    return 0;
+}
+
+static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) {
+   int is_true = x == Py_True;
+   if (is_true | (x == Py_False) | (x == Py_None)) return is_true;
+   else return PyObject_IsTrue(x);
+}
+static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x) {
+  PyNumberMethods *m;
+  const char *name = NULL;
+  PyObject *res = NULL;
+#if PY_VERSION_HEX < 0x03000000
+  if (PyInt_Check(x) || PyLong_Check(x))
+#else
+  if (PyLong_Check(x))
+#endif
+    return Py_INCREF(x), x;
+  m = Py_TYPE(x)->tp_as_number;
+#if PY_VERSION_HEX < 0x03000000
+  if (m && m->nb_int) {
+    name = "int";
+    res = PyNumber_Int(x);
+  }
+  else if (m && m->nb_long) {
+    name = "long";
+    res = PyNumber_Long(x);
+  }
+#else
+  if (m && m->nb_int) {
+    name = "int";
+    res = PyNumber_Long(x);
+  }
+#endif
+  if (res) {
+#if PY_VERSION_HEX < 0x03000000
+    if (!PyInt_Check(res) && !PyLong_Check(res)) {
+#else
+    if (!PyLong_Check(res)) {
+#endif
+      PyErr_Format(PyExc_TypeError,
+                   "__%s__ returned non-%s (type %.200s)",
+                   name, name, Py_TYPE(res)->tp_name);
+      Py_DECREF(res);
+      return NULL;
+    }
+  }
+  else if (!PyErr_Occurred()) {
+    PyErr_SetString(PyExc_TypeError,
+                    "an integer is required");
+  }
+  return res;
+}
+static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) {
+  Py_ssize_t ival;
+  PyObject* x = PyNumber_Index(b);
+  if (!x) return -1;
+  ival = PyInt_AsSsize_t(x);
+  Py_DECREF(x);
+  return ival;
+}
+static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) {
+#if PY_VERSION_HEX < 0x02050000
+   if (ival <= LONG_MAX)
+       return PyInt_FromLong((long)ival);
+   else {
+       unsigned char *bytes = (unsigned char *) &ival;
+       int one = 1; int little = (int)*(unsigned char*)&one;
+       return _PyLong_FromByteArray(bytes, sizeof(size_t), little, 0);
+   }
+#else
+   return PyInt_FromSize_t(ival);
+#endif
+}
+static CYTHON_INLINE size_t __Pyx_PyInt_AsSize_t(PyObject* x) {
+   unsigned PY_LONG_LONG val = __Pyx_PyInt_AsUnsignedLongLong(x);
+   if (unlikely(val == (unsigned PY_LONG_LONG)-1 && PyErr_Occurred())) {
+       return (size_t)-1;
+   } else if (unlikely(val != (unsigned PY_LONG_LONG)(size_t)val)) {
+       PyErr_SetString(PyExc_OverflowError,
+                       "value too large to convert to size_t");
+       return (size_t)-1;
+   }
+   return (size_t)val;
+}
+
+
+#endif /* Py_PYTHON_H */
diff --git a/lib/bx/_seqmapping.pyx b/lib/bx/_seqmapping.pyx
new file mode 100644
index 0000000..0fae64d
--- /dev/null
+++ b/lib/bx/_seqmapping.pyx
@@ -0,0 +1,241 @@
+"""
+Pyrex extension classes used by `seqmapping.py`.
+"""
+
+cdef extern from "stdlib.h":
+    void* malloc( int )
+    void free( void* )
+
+cdef extern from "Python.h":
+    int PyObject_AsReadBuffer(object, void **, int *) except -1
+    int PyObject_AsWriteBuffer(object, void **, int *) except -1
+    int PyString_AsStringAndSize(object, char **, int *) except -1
+
+from numpy import zeros
+from math import floor
+import random
+import sys
+
+cdef class CharToIntArrayMapping:
+    """Mapping for converting strings to int arrays"""
+    
+    cdef int table[256]
+    cdef int out_size
+    cdef object reverse_table
+    
+    def __cinit__( self ):
+        """Init empty mapping (all characters map to -1)"""
+        cdef int i
+        for i from 0 <= i < 256: self.table[i] = -1
+        self.out_size = 0
+        
+    def __init__( self ):
+        self.reverse_table = dict()
+
+    def set_mapping( self, c, int symbol ):
+        """Modify mapping so 'chars' map to 'symbol'"""
+        char = ord( c )
+        self.table[ char ] = symbol
+        if self.out_size <= symbol:
+            self.out_size = symbol + 1
+        self.reverse_table[ symbol ] = chr( char )
+
+    def translate( self, string ):
+        """Translate 'string' and return as int array"""
+        cdef int s_len, t_len
+        cdef unsigned char * s_buf
+        cdef int * t_buf
+        # Get direct access to string
+        PyString_AsStringAndSize( string, <char **> &s_buf, &s_len )
+        # Initialize empty array
+        rval = zeros( s_len, 'i' )
+        PyObject_AsWriteBuffer( rval, <void **> &t_buf, &t_len ) 
+        # Translate
+        for i from 0 <= i < s_len:
+            t_buf[i] = self.table[ s_buf[ i ] ]
+        # Done
+        return rval
+        
+    def translate_list( self, strings ):
+        """Translate a list of strings into an int array"""
+        cdef int text_len, factor, i
+        cdef int s_len, t_len
+        cdef unsigned char * s_buf
+        cdef int * t_buf
+
+        # No input, no output
+        if len( strings ) < 1: return None
+        
+        # Length of result
+        text_len = len( strings[0] )
+
+        # Init result array
+        rval = zeros( text_len, 'i' )
+        PyObject_AsWriteBuffer( rval, <void **> &t_buf, &t_len )  
+
+        # Loop over seqs and accumulate result values
+        factor = 1
+        for string in strings:
+            PyString_AsStringAndSize( string, <char **> &s_buf, &s_len )
+            for i from 0 <= i < text_len:
+                if t_buf[i] >= 0: 
+                    if self.table[ s_buf[i] ] == -1: 
+                        t_buf[i] = -1
+                    else: 
+                        t_buf[i] = t_buf[i] + ( self.table[ s_buf[i] ] * factor )
+            factor = factor * self.out_size
+        return rval
+        
+    def reverse_map( self, val, nseqs ):
+        factor = self.out_size ** (nseqs-1)
+        rval = []
+        while factor > 0:
+            rval.append( self.reverse_table[ int( floor( val / factor ) ) ] )
+            val = val - ( floor(val/factor) * factor )
+            factor = floor( factor / self.out_size )
+        rval.reverse()
+        return rval
+        
+    def get_out_size( self ): 
+        return self.out_size
+         
+cdef class IntToIntMapping:
+    
+    cdef int* table
+    cdef int in_size
+    cdef int out_size
+    
+    def __cinit__( self, int in_size ):
+        self.in_size = in_size
+        self.table = <int *> malloc( in_size * sizeof( int ) )
+        if self.table == NULL: raise "Malloc Failed"
+        for i from 0 <= i < in_size: self.table[i] = -1
+        self.out_size = 0
+        
+    def __dealloc__( self ):
+        # sys.stderr.write( "freeing mapping_helper.IntToIntMapping\n" ); sys.stderr.flush()
+        free( self.table )
+
+    def set_mapping( self, int index, int symbol ):
+        assert ( -1 <= index < self.in_size ), "%d not between 0 and %s" % ( index, self.in_size )
+        self.table[index] = symbol
+        if self.out_size <= symbol:
+            self.out_size = symbol + 1
+
+    def translate( self, src ):
+        """Translate `string` and return as int array"""
+        cdef int s_len, t_len
+        cdef int *s_buf, *t_buf
+        # Get direct access to string
+        PyObject_AsReadBuffer( src, <void **> &s_buf, &s_len )
+        s_len = s_len / sizeof( int )
+        assert s_len == len( src ), "`src` argument must be a buffer of 32bit integers"
+        # Initialize empty array
+        rval = zeros( s_len, 'i' )
+        PyObject_AsWriteBuffer( rval, <void **> &t_buf, &t_len )
+        # Translate
+        for i from 0 <= i < s_len:
+            if s_buf[i] == -1:
+                t_buf[i] = -1
+            elif s_buf[i] >= self.in_size:
+                t_buf[i] = -1
+            else:
+                t_buf[i] = self.table[ s_buf[ i ] ]
+        # Done
+        return rval
+
+    def __getitem__( self, int x ):
+        if x == -1: return -1
+        assert 0 <= x < self.in_size
+        return self.table[ x ]
+
+    def collapse( self, int a, int b ):
+        cdef int i
+        cdef IntToIntMapping copy
+        copy = IntToIntMapping( self.in_size )
+        copy.out_size = self.out_size - 1
+        if a > b: a, b = b, a
+        for i from 0 <= i < self.in_size:
+            if self.table[i] == b: copy.table[i] = a
+            elif self.table[i] == copy.out_size: copy.table[i] = b
+            else: copy.table[i] = self.table[i]
+        return copy
+
+    def expand( self, int x ):
+        """Grow the alphabet by making 'a' a seperate symbol. If it already mapped to a single symbol, do nothing"""
+        cdef int i, count, a, b
+        cdef IntToIntMapping copy
+        # Get the symbol x maps to
+        a = self.table[x]
+        # Symbols that map to -1 should not be touched
+        if a < 0: return self
+        # Count how many other input symbols map to a
+        count = 0
+        for i from 0 <= i < self.in_size:
+            if self.table[i] == a: count = count + 1
+        # Already a singleton
+        if count < 2: return self
+        # Otherwise, make a copy with the separated symbol
+        copy = IntToIntMapping( self.in_size )
+        copy.out_size = self.out_size + 1
+        for i from 0 <= i < self.in_size:
+            copy.table[i] = self.table[i]
+        copy.table[x] = self.out_size
+        return copy
+
+    def expand_out( self, int a ):
+        """Grow the alphabet breaking 'a' into two symbols randomly"""
+        cdef int i, count, to_split, b
+        cdef IntToIntMapping copy
+        count = 0
+        for i from 0 <= i < self.in_size:
+            if self.table[i] == a: count = count + 1
+        if count < 2: return self
+        copy = IntToIntMapping( self.in_size )
+        copy.out_size = self.out_size + 1
+        b = self.out_size
+        to_split = random.randrange( count )
+        count = 0
+        for i from 0 <= i < self.in_size:
+            if self.table[i] == a: 
+                if count == to_split: copy.table[i] = b
+                else: copy.table[i] = a
+                count = count + 1
+            else:
+                copy.table[i] = self.table[i]
+        return copy
+
+    def expand_random_split( self, int a ):
+        """Grow the alphabet breaking 'a' into two symbols randomly"""
+        cdef int i, count, b
+        cdef IntToIntMapping copy
+        count = 0
+        for i from 0 <= i < self.in_size:
+            if self.table[i] == a: count = count + 1
+        if count < 2: return self
+        copy = IntToIntMapping( self.in_size )
+        copy.out_size = self.out_size + 1
+        b = self.out_size
+        to_split = random.sample( range( count ), count/2 )
+        count = 0
+        for i from 0 <= i < self.in_size:
+            if self.table[i] == a: 
+                if count in to_split: copy.table[i] = b
+                else: copy.table[i] = a
+                count = count + 1
+            else:
+                copy.table[i] = self.table[i]
+        return copy
+
+    def get_in_size( self ): 
+        return self.in_size
+
+    def get_out_size( self ): 
+        return self.out_size
+    
+    def get_table( self ):
+        rval = zeros( self.in_size, 'i' )
+        for i in range( self.in_size ):
+            rval[i] = self.table[i]
+        return rval
+
diff --git a/lib/bx/align/__init__.py b/lib/bx/align/__init__.py
new file mode 100644
index 0000000..96441db
--- /dev/null
+++ b/lib/bx/align/__init__.py
@@ -0,0 +1,7 @@
+"""
+Support for dealing with (genome scale) sequence alignments. See `core` for
+the abstract alignment classes and `maf`, `axt`, and `lav` for readers and
+writers in various formats.
+"""
+
+from bx.align.core import *
diff --git a/lib/bx/align/_core.c b/lib/bx/align/_core.c
new file mode 100644
index 0000000..dfac5d7
--- /dev/null
+++ b/lib/bx/align/_core.c
@@ -0,0 +1,1673 @@
+/* Generated by Cython 0.18 on Mon Jul 15 13:25:44 2013 */
+
+#define PY_SSIZE_T_CLEAN
+#include "Python.h"
+#ifndef Py_PYTHON_H
+    #error Python headers needed to compile C extensions, please install development version of Python.
+#elif PY_VERSION_HEX < 0x02040000
+    #error Cython requires Python 2.4+.
+#else
+#include <stddef.h> /* For offsetof */
+#ifndef offsetof
+#define offsetof(type, member) ( (size_t) & ((type*)0) -> member )
+#endif
+#if !defined(WIN32) && !defined(MS_WINDOWS)
+  #ifndef __stdcall
+    #define __stdcall
+  #endif
+  #ifndef __cdecl
+    #define __cdecl
+  #endif
+  #ifndef __fastcall
+    #define __fastcall
+  #endif
+#endif
+#ifndef DL_IMPORT
+  #define DL_IMPORT(t) t
+#endif
+#ifndef DL_EXPORT
+  #define DL_EXPORT(t) t
+#endif
+#ifndef PY_LONG_LONG
+  #define PY_LONG_LONG LONG_LONG
+#endif
+#ifndef Py_HUGE_VAL
+  #define Py_HUGE_VAL HUGE_VAL
+#endif
+#ifdef PYPY_VERSION
+#define CYTHON_COMPILING_IN_PYPY 1
+#define CYTHON_COMPILING_IN_CPYTHON 0
+#else
+#define CYTHON_COMPILING_IN_PYPY 0
+#define CYTHON_COMPILING_IN_CPYTHON 1
+#endif
+#if PY_VERSION_HEX < 0x02050000
+  typedef int Py_ssize_t;
+  #define PY_SSIZE_T_MAX INT_MAX
+  #define PY_SSIZE_T_MIN INT_MIN
+  #define PY_FORMAT_SIZE_T ""
+  #define CYTHON_FORMAT_SSIZE_T ""
+  #define PyInt_FromSsize_t(z) PyInt_FromLong(z)
+  #define PyInt_AsSsize_t(o)   __Pyx_PyInt_AsInt(o)
+  #define PyNumber_Index(o)    ((PyNumber_Check(o) && !PyFloat_Check(o)) ? PyNumber_Int(o) : \
+                                (PyErr_Format(PyExc_TypeError, \
+                                              "expected index value, got %.200s", Py_TYPE(o)->tp_name), \
+                                 (PyObject*)0))
+  #define __Pyx_PyIndex_Check(o) (PyNumber_Check(o) && !PyFloat_Check(o) && \
+                                  !PyComplex_Check(o))
+  #define PyIndex_Check __Pyx_PyIndex_Check
+  #define PyErr_WarnEx(category, message, stacklevel) PyErr_Warn(category, message)
+  #define __PYX_BUILD_PY_SSIZE_T "i"
+#else
+  #define __PYX_BUILD_PY_SSIZE_T "n"
+  #define CYTHON_FORMAT_SSIZE_T "z"
+  #define __Pyx_PyIndex_Check PyIndex_Check
+#endif
+#if PY_VERSION_HEX < 0x02060000
+  #define Py_REFCNT(ob) (((PyObject*)(ob))->ob_refcnt)
+  #define Py_TYPE(ob)   (((PyObject*)(ob))->ob_type)
+  #define Py_SIZE(ob)   (((PyVarObject*)(ob))->ob_size)
+  #define PyVarObject_HEAD_INIT(type, size) \
+          PyObject_HEAD_INIT(type) size,
+  #define PyType_Modified(t)
+  typedef struct {
+     void *buf;
+     PyObject *obj;
+     Py_ssize_t len;
+     Py_ssize_t itemsize;
+     int readonly;
+     int ndim;
+     char *format;
+     Py_ssize_t *shape;
+     Py_ssize_t *strides;
+     Py_ssize_t *suboffsets;
+     void *internal;
+  } Py_buffer;
+  #define PyBUF_SIMPLE 0
+  #define PyBUF_WRITABLE 0x0001
+  #define PyBUF_FORMAT 0x0004
+  #define PyBUF_ND 0x0008
+  #define PyBUF_STRIDES (0x0010 | PyBUF_ND)
+  #define PyBUF_C_CONTIGUOUS (0x0020 | PyBUF_STRIDES)
+  #define PyBUF_F_CONTIGUOUS (0x0040 | PyBUF_STRIDES)
+  #define PyBUF_ANY_CONTIGUOUS (0x0080 | PyBUF_STRIDES)
+  #define PyBUF_INDIRECT (0x0100 | PyBUF_STRIDES)
+  #define PyBUF_RECORDS (PyBUF_STRIDES | PyBUF_FORMAT | PyBUF_WRITABLE)
+  #define PyBUF_FULL (PyBUF_INDIRECT | PyBUF_FORMAT | PyBUF_WRITABLE)
+  typedef int (*getbufferproc)(PyObject *, Py_buffer *, int);
+  typedef void (*releasebufferproc)(PyObject *, Py_buffer *);
+#endif
+#if PY_MAJOR_VERSION < 3
+  #define __Pyx_BUILTIN_MODULE_NAME "__builtin__"
+  #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \
+          PyCode_New(a, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
+#else
+  #define __Pyx_BUILTIN_MODULE_NAME "builtins"
+  #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \
+          PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
+#endif
+#if PY_MAJOR_VERSION < 3 && PY_MINOR_VERSION < 6
+  #define PyUnicode_FromString(s) PyUnicode_Decode(s, strlen(s), "UTF-8", "strict")
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define Py_TPFLAGS_CHECKTYPES 0
+  #define Py_TPFLAGS_HAVE_INDEX 0
+#endif
+#if (PY_VERSION_HEX < 0x02060000) || (PY_MAJOR_VERSION >= 3)
+  #define Py_TPFLAGS_HAVE_NEWBUFFER 0
+#endif
+#if PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND)
+  #define CYTHON_PEP393_ENABLED 1
+  #define __Pyx_PyUnicode_READY(op)       (likely(PyUnicode_IS_READY(op)) ? \
+                                              0 : _PyUnicode_Ready((PyObject *)(op)))
+  #define __Pyx_PyUnicode_GET_LENGTH(u)   PyUnicode_GET_LENGTH(u)
+  #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_READ_CHAR(u, i)
+  #define __Pyx_PyUnicode_READ(k, d, i)   PyUnicode_READ(k, d, i)
+#else
+  #define CYTHON_PEP393_ENABLED 0
+  #define __Pyx_PyUnicode_READY(op)       (0)
+  #define __Pyx_PyUnicode_GET_LENGTH(u)   PyUnicode_GET_SIZE(u)
+  #define __Pyx_PyUnicode_READ_CHAR(u, i) ((Py_UCS4)(PyUnicode_AS_UNICODE(u)[i]))
+  #define __Pyx_PyUnicode_READ(k, d, i)   ((k=k), (Py_UCS4)(((Py_UNICODE*)d)[i]))
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define PyBaseString_Type            PyUnicode_Type
+  #define PyStringObject               PyUnicodeObject
+  #define PyString_Type                PyUnicode_Type
+  #define PyString_Check               PyUnicode_Check
+  #define PyString_CheckExact          PyUnicode_CheckExact
+#endif
+#if PY_VERSION_HEX < 0x02060000
+  #define PyBytesObject                PyStringObject
+  #define PyBytes_Type                 PyString_Type
+  #define PyBytes_Check                PyString_Check
+  #define PyBytes_CheckExact           PyString_CheckExact
+  #define PyBytes_FromString           PyString_FromString
+  #define PyBytes_FromStringAndSize    PyString_FromStringAndSize
+  #define PyBytes_FromFormat           PyString_FromFormat
+  #define PyBytes_DecodeEscape         PyString_DecodeEscape
+  #define PyBytes_AsString             PyString_AsString
+  #define PyBytes_AsStringAndSize      PyString_AsStringAndSize
+  #define PyBytes_Size                 PyString_Size
+  #define PyBytes_AS_STRING            PyString_AS_STRING
+  #define PyBytes_GET_SIZE             PyString_GET_SIZE
+  #define PyBytes_Repr                 PyString_Repr
+  #define PyBytes_Concat               PyString_Concat
+  #define PyBytes_ConcatAndDel         PyString_ConcatAndDel
+#endif
+#if PY_VERSION_HEX < 0x02060000
+  #define PySet_Check(obj)             PyObject_TypeCheck(obj, &PySet_Type)
+  #define PyFrozenSet_Check(obj)       PyObject_TypeCheck(obj, &PyFrozenSet_Type)
+#endif
+#ifndef PySet_CheckExact
+  #define PySet_CheckExact(obj)        (Py_TYPE(obj) == &PySet_Type)
+#endif
+#define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type)
+#if PY_MAJOR_VERSION >= 3
+  #define PyIntObject                  PyLongObject
+  #define PyInt_Type                   PyLong_Type
+  #define PyInt_Check(op)              PyLong_Check(op)
+  #define PyInt_CheckExact(op)         PyLong_CheckExact(op)
+  #define PyInt_FromString             PyLong_FromString
+  #define PyInt_FromUnicode            PyLong_FromUnicode
+  #define PyInt_FromLong               PyLong_FromLong
+  #define PyInt_FromSize_t             PyLong_FromSize_t
+  #define PyInt_FromSsize_t            PyLong_FromSsize_t
+  #define PyInt_AsLong                 PyLong_AsLong
+  #define PyInt_AS_LONG                PyLong_AS_LONG
+  #define PyInt_AsSsize_t              PyLong_AsSsize_t
+  #define PyInt_AsUnsignedLongMask     PyLong_AsUnsignedLongMask
+  #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define PyBoolObject                 PyLongObject
+#endif
+#if PY_VERSION_HEX < 0x03020000
+  typedef long Py_hash_t;
+  #define __Pyx_PyInt_FromHash_t PyInt_FromLong
+  #define __Pyx_PyInt_AsHash_t   PyInt_AsLong
+#else
+  #define __Pyx_PyInt_FromHash_t PyInt_FromSsize_t
+  #define __Pyx_PyInt_AsHash_t   PyInt_AsSsize_t
+#endif
+#if (PY_MAJOR_VERSION < 3) || (PY_VERSION_HEX >= 0x03010300)
+  #define __Pyx_PySequence_GetSlice(obj, a, b) PySequence_GetSlice(obj, a, b)
+  #define __Pyx_PySequence_SetSlice(obj, a, b, value) PySequence_SetSlice(obj, a, b, value)
+  #define __Pyx_PySequence_DelSlice(obj, a, b) PySequence_DelSlice(obj, a, b)
+#else
+  #define __Pyx_PySequence_GetSlice(obj, a, b) (unlikely(!(obj)) ? \
+        (PyErr_SetString(PyExc_SystemError, "null argument to internal routine"), (PyObject*)0) : \
+        (likely((obj)->ob_type->tp_as_mapping) ? (PySequence_GetSlice(obj, a, b)) : \
+            (PyErr_Format(PyExc_TypeError, "'%.200s' object is unsliceable", (obj)->ob_type->tp_name), (PyObject*)0)))
+  #define __Pyx_PySequence_SetSlice(obj, a, b, value) (unlikely(!(obj)) ? \
+        (PyErr_SetString(PyExc_SystemError, "null argument to internal routine"), -1) : \
+        (likely((obj)->ob_type->tp_as_mapping) ? (PySequence_SetSlice(obj, a, b, value)) : \
+            (PyErr_Format(PyExc_TypeError, "'%.200s' object doesn't support slice assignment", (obj)->ob_type->tp_name), -1)))
+  #define __Pyx_PySequence_DelSlice(obj, a, b) (unlikely(!(obj)) ? \
+        (PyErr_SetString(PyExc_SystemError, "null argument to internal routine"), -1) : \
+        (likely((obj)->ob_type->tp_as_mapping) ? (PySequence_DelSlice(obj, a, b)) : \
+            (PyErr_Format(PyExc_TypeError, "'%.200s' object doesn't support slice deletion", (obj)->ob_type->tp_name), -1)))
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define PyMethod_New(func, self, klass) ((self) ? PyMethod_New(func, self) : PyInstanceMethod_New(func))
+#endif
+#if PY_VERSION_HEX < 0x02050000
+  #define __Pyx_GetAttrString(o,n)   PyObject_GetAttrString((o),((char *)(n)))
+  #define __Pyx_SetAttrString(o,n,a) PyObject_SetAttrString((o),((char *)(n)),(a))
+  #define __Pyx_DelAttrString(o,n)   PyObject_DelAttrString((o),((char *)(n)))
+#else
+  #define __Pyx_GetAttrString(o,n)   PyObject_GetAttrString((o),(n))
+  #define __Pyx_SetAttrString(o,n,a) PyObject_SetAttrString((o),(n),(a))
+  #define __Pyx_DelAttrString(o,n)   PyObject_DelAttrString((o),(n))
+#endif
+#if PY_VERSION_HEX < 0x02050000
+  #define __Pyx_NAMESTR(n) ((char *)(n))
+  #define __Pyx_DOCSTR(n)  ((char *)(n))
+#else
+  #define __Pyx_NAMESTR(n) (n)
+  #define __Pyx_DOCSTR(n)  (n)
+#endif
+
+
+#if PY_MAJOR_VERSION >= 3
+  #define __Pyx_PyNumber_Divide(x,y)         PyNumber_TrueDivide(x,y)
+  #define __Pyx_PyNumber_InPlaceDivide(x,y)  PyNumber_InPlaceTrueDivide(x,y)
+#else
+  #define __Pyx_PyNumber_Divide(x,y)         PyNumber_Divide(x,y)
+  #define __Pyx_PyNumber_InPlaceDivide(x,y)  PyNumber_InPlaceDivide(x,y)
+#endif
+
+#ifndef __PYX_EXTERN_C
+  #ifdef __cplusplus
+    #define __PYX_EXTERN_C extern "C"
+  #else
+    #define __PYX_EXTERN_C extern
+  #endif
+#endif
+
+#if defined(WIN32) || defined(MS_WINDOWS)
+#define _USE_MATH_DEFINES
+#endif
+#include <math.h>
+#define __PYX_HAVE__bx__align___core
+#define __PYX_HAVE_API__bx__align___core
+#ifdef _OPENMP
+#include <omp.h>
+#endif /* _OPENMP */
+
+#ifdef PYREX_WITHOUT_ASSERTIONS
+#define CYTHON_WITHOUT_ASSERTIONS
+#endif
+
+#ifndef CYTHON_INLINE
+  #if defined(__GNUC__)
+    #define CYTHON_INLINE __inline__
+  #elif defined(_MSC_VER)
+    #define CYTHON_INLINE __inline
+  #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+    #define CYTHON_INLINE inline
+  #else
+    #define CYTHON_INLINE
+  #endif
+#endif
+#ifndef CYTHON_UNUSED
+# if defined(__GNUC__)
+#   if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
+#     define CYTHON_UNUSED __attribute__ ((__unused__))
+#   else
+#     define CYTHON_UNUSED
+#   endif
+# elif defined(__ICC) || (defined(__INTEL_COMPILER) && !defined(_MSC_VER))
+#   define CYTHON_UNUSED __attribute__ ((__unused__))
+# else
+#   define CYTHON_UNUSED
+# endif
+#endif
+typedef struct {PyObject **p; char *s; const long n; const char* encoding; const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry; /*proto*/
+
+#define __Pyx_PyBytes_FromUString(s) PyBytes_FromString((char*)s)
+#define __Pyx_PyBytes_AsUString(s)   ((unsigned char*) PyBytes_AsString(s))
+#define __Pyx_Owned_Py_None(b) (Py_INCREF(Py_None), Py_None)
+#define __Pyx_PyBool_FromLong(b) ((b) ? (Py_INCREF(Py_True), Py_True) : (Py_INCREF(Py_False), Py_False))
+static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*);
+static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x);
+static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*);
+static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t);
+static CYTHON_INLINE size_t __Pyx_PyInt_AsSize_t(PyObject*);
+#if CYTHON_COMPILING_IN_CPYTHON
+#define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x))
+#else
+#define __pyx_PyFloat_AsDouble(x) PyFloat_AsDouble(x)
+#endif
+#define __pyx_PyFloat_AsFloat(x) ((float) __pyx_PyFloat_AsDouble(x))
+
+
+#ifdef __GNUC__
+  /* Test for GCC > 2.95 */
+  #if __GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))
+    #define likely(x)   __builtin_expect(!!(x), 1)
+    #define unlikely(x) __builtin_expect(!!(x), 0)
+  #else /* __GNUC__ > 2 ... */
+    #define likely(x)   (x)
+    #define unlikely(x) (x)
+  #endif /* __GNUC__ > 2 ... */
+#else /* __GNUC__ */
+  #define likely(x)   (x)
+  #define unlikely(x) (x)
+#endif /* __GNUC__ */
+    
+static PyObject *__pyx_m;
+static PyObject *__pyx_b;
+static PyObject *__pyx_empty_tuple;
+static PyObject *__pyx_empty_bytes;
+static int __pyx_lineno;
+static int __pyx_clineno = 0;
+static const char * __pyx_cfilenm= __FILE__;
+static const char *__pyx_filename;
+
+
+static const char *__pyx_f[] = {
+  "_core.pyx",
+};
+
+/*--- Type declarations ---*/
+#ifndef CYTHON_REFNANNY
+  #define CYTHON_REFNANNY 0
+#endif
+#if CYTHON_REFNANNY
+  typedef struct {
+    void (*INCREF)(void*, PyObject*, int);
+    void (*DECREF)(void*, PyObject*, int);
+    void (*GOTREF)(void*, PyObject*, int);
+    void (*GIVEREF)(void*, PyObject*, int);
+    void* (*SetupContext)(const char*, int, const char*);
+    void (*FinishContext)(void**);
+  } __Pyx_RefNannyAPIStruct;
+  static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL;
+  static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname); /*proto*/
+  #define __Pyx_RefNannyDeclarations void *__pyx_refnanny = NULL;
+#ifdef WITH_THREAD
+  #define __Pyx_RefNannySetupContext(name, acquire_gil) \
+          if (acquire_gil) { \
+              PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure(); \
+              __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__); \
+              PyGILState_Release(__pyx_gilstate_save); \
+          } else { \
+              __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__); \
+          }
+#else
+  #define __Pyx_RefNannySetupContext(name, acquire_gil) \
+          __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__)
+#endif
+  #define __Pyx_RefNannyFinishContext() \
+          __Pyx_RefNanny->FinishContext(&__pyx_refnanny)
+  #define __Pyx_INCREF(r)  __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_DECREF(r)  __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_GOTREF(r)  __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_XINCREF(r)  do { if((r) != NULL) {__Pyx_INCREF(r); }} while(0)
+  #define __Pyx_XDECREF(r)  do { if((r) != NULL) {__Pyx_DECREF(r); }} while(0)
+  #define __Pyx_XGOTREF(r)  do { if((r) != NULL) {__Pyx_GOTREF(r); }} while(0)
+  #define __Pyx_XGIVEREF(r) do { if((r) != NULL) {__Pyx_GIVEREF(r);}} while(0)
+#else
+  #define __Pyx_RefNannyDeclarations
+  #define __Pyx_RefNannySetupContext(name, acquire_gil)
+  #define __Pyx_RefNannyFinishContext()
+  #define __Pyx_INCREF(r) Py_INCREF(r)
+  #define __Pyx_DECREF(r) Py_DECREF(r)
+  #define __Pyx_GOTREF(r)
+  #define __Pyx_GIVEREF(r)
+  #define __Pyx_XINCREF(r) Py_XINCREF(r)
+  #define __Pyx_XDECREF(r) Py_XDECREF(r)
+  #define __Pyx_XGOTREF(r)
+  #define __Pyx_XGIVEREF(r)
+#endif /* CYTHON_REFNANNY */
+#define __Pyx_CLEAR(r)    do { PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);} while(0)
+#define __Pyx_XCLEAR(r)   do { if((r) != NULL) {PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);}} while(0)
+
+static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
+    Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/
+
+static void __Pyx_RaiseDoubleKeywordsError(const char* func_name, PyObject* kw_name); /*proto*/
+
+static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
+    PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
+    const char* function_name); /*proto*/
+
+static CYTHON_INLINE unsigned char __Pyx_PyInt_AsUnsignedChar(PyObject *);
+
+static CYTHON_INLINE unsigned short __Pyx_PyInt_AsUnsignedShort(PyObject *);
+
+static CYTHON_INLINE unsigned int __Pyx_PyInt_AsUnsignedInt(PyObject *);
+
+static CYTHON_INLINE char __Pyx_PyInt_AsChar(PyObject *);
+
+static CYTHON_INLINE short __Pyx_PyInt_AsShort(PyObject *);
+
+static CYTHON_INLINE int __Pyx_PyInt_AsInt(PyObject *);
+
+static CYTHON_INLINE signed char __Pyx_PyInt_AsSignedChar(PyObject *);
+
+static CYTHON_INLINE signed short __Pyx_PyInt_AsSignedShort(PyObject *);
+
+static CYTHON_INLINE signed int __Pyx_PyInt_AsSignedInt(PyObject *);
+
+static CYTHON_INLINE int __Pyx_PyInt_AsLongDouble(PyObject *);
+
+static CYTHON_INLINE unsigned long __Pyx_PyInt_AsUnsignedLong(PyObject *);
+
+static CYTHON_INLINE unsigned PY_LONG_LONG __Pyx_PyInt_AsUnsignedLongLong(PyObject *);
+
+static CYTHON_INLINE long __Pyx_PyInt_AsLong(PyObject *);
+
+static CYTHON_INLINE PY_LONG_LONG __Pyx_PyInt_AsLongLong(PyObject *);
+
+static CYTHON_INLINE signed long __Pyx_PyInt_AsSignedLong(PyObject *);
+
+static CYTHON_INLINE signed PY_LONG_LONG __Pyx_PyInt_AsSignedLongLong(PyObject *);
+
+static int __Pyx_check_binary_version(void);
+
+typedef struct {
+    int code_line;
+    PyCodeObject* code_object;
+} __Pyx_CodeObjectCacheEntry;
+struct __Pyx_CodeObjectCache {
+    int count;
+    int max_count;
+    __Pyx_CodeObjectCacheEntry* entries;
+};
+static struct __Pyx_CodeObjectCache __pyx_code_cache = {0,0,NULL};
+static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line);
+static PyCodeObject *__pyx_find_code_object(int code_line);
+static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object);
+
+static void __Pyx_AddTraceback(const char *funcname, int c_line,
+                               int py_line, const char *filename); /*proto*/
+
+static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
+
+
+/* Module declarations from 'bx.align._core' */
+#define __Pyx_MODULE_NAME "bx.align._core"
+int __pyx_module_is_main_bx__align___core = 0;
+
+/* Implementation of 'bx.align._core' */
+static PyObject *__pyx_pf_2bx_5align_5_core_coord_to_col(CYTHON_UNUSED PyObject *__pyx_self, int __pyx_v_start, char *__pyx_v_text, int __pyx_v_pos); /* proto */
+static char __pyx_k_1[] = "\nPyrex extension to speed up some operations in `core.py`.\n";
+static char __pyx_k_4[] = "/aut/proj/odenas/software/bx-python/lib/bx/align/_core.pyx";
+static char __pyx_k_5[] = "bx.align._core";
+static char __pyx_k__col[] = "col";
+static char __pyx_k__pos[] = "pos";
+static char __pyx_k__text[] = "text";
+static char __pyx_k__start[] = "start";
+static char __pyx_k____main__[] = "__main__";
+static char __pyx_k____test__[] = "__test__";
+static char __pyx_k__coord_to_col[] = "coord_to_col";
+static PyObject *__pyx_kp_s_4;
+static PyObject *__pyx_n_s_5;
+static PyObject *__pyx_n_s____main__;
+static PyObject *__pyx_n_s____test__;
+static PyObject *__pyx_n_s__col;
+static PyObject *__pyx_n_s__coord_to_col;
+static PyObject *__pyx_n_s__pos;
+static PyObject *__pyx_n_s__start;
+static PyObject *__pyx_n_s__text;
+static PyObject *__pyx_k_tuple_2;
+static PyObject *__pyx_k_codeobj_3;
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_5align_5_core_1coord_to_col(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_mdef_2bx_5align_5_core_1coord_to_col = {__Pyx_NAMESTR("coord_to_col"), (PyCFunction)__pyx_pw_2bx_5align_5_core_1coord_to_col, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(0)};
+static PyObject *__pyx_pw_2bx_5align_5_core_1coord_to_col(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  int __pyx_v_start;
+  char *__pyx_v_text;
+  int __pyx_v_pos;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("coord_to_col (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__start,&__pyx_n_s__text,&__pyx_n_s__pos,0};
+    PyObject* values[3] = {0,0,0};
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__start)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__text)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("coord_to_col", 1, 3, 3, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 5; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+        case  2:
+        if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__pos)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("coord_to_col", 1, 3, 3, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 5; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "coord_to_col") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 5; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else if (PyTuple_GET_SIZE(__pyx_args) != 3) {
+      goto __pyx_L5_argtuple_error;
+    } else {
+      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+      values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+    }
+    __pyx_v_start = __Pyx_PyInt_AsInt(values[0]); if (unlikely((__pyx_v_start == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 5; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_text = PyBytes_AsString(values[1]); if (unlikely((!__pyx_v_text) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 5; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_pos = __Pyx_PyInt_AsInt(values[2]); if (unlikely((__pyx_v_pos == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 5; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("coord_to_col", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 5; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.align._core.coord_to_col", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_5align_5_core_coord_to_col(__pyx_self, __pyx_v_start, __pyx_v_text, __pyx_v_pos);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/align/_core.pyx":5
+ * """
+ * 
+ * def coord_to_col( int start, char * text, int pos ):             # <<<<<<<<<<<<<<
+ *     cdef int col
+ *     col = 0
+ */
+
+static PyObject *__pyx_pf_2bx_5align_5_core_coord_to_col(CYTHON_UNUSED PyObject *__pyx_self, int __pyx_v_start, char *__pyx_v_text, int __pyx_v_pos) {
+  int __pyx_v_col;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("coord_to_col", 0);
+
+  /* "bx/align/_core.pyx":7
+ * def coord_to_col( int start, char * text, int pos ):
+ *     cdef int col
+ *     col = 0             # <<<<<<<<<<<<<<
+ *     while start < pos:
+ *         # Note: ord( '-' ) = 45
+ */
+  __pyx_v_col = 0;
+
+  /* "bx/align/_core.pyx":8
+ *     cdef int col
+ *     col = 0
+ *     while start < pos:             # <<<<<<<<<<<<<<
+ *         # Note: ord( '-' ) = 45
+ *         if text[col] != 45:
+ */
+  while (1) {
+    __pyx_t_1 = (__pyx_v_start < __pyx_v_pos);
+    if (!__pyx_t_1) break;
+
+    /* "bx/align/_core.pyx":10
+ *     while start < pos:
+ *         # Note: ord( '-' ) = 45
+ *         if text[col] != 45:             # <<<<<<<<<<<<<<
+ *             start = start + 1
+ *         col = col + 1
+ */
+    __pyx_t_1 = ((__pyx_v_text[__pyx_v_col]) != 45);
+    if (__pyx_t_1) {
+
+      /* "bx/align/_core.pyx":11
+ *         # Note: ord( '-' ) = 45
+ *         if text[col] != 45:
+ *             start = start + 1             # <<<<<<<<<<<<<<
+ *         col = col + 1
+ *     return col
+ */
+      __pyx_v_start = (__pyx_v_start + 1);
+      goto __pyx_L5;
+    }
+    __pyx_L5:;
+
+    /* "bx/align/_core.pyx":12
+ *         if text[col] != 45:
+ *             start = start + 1
+ *         col = col + 1             # <<<<<<<<<<<<<<
+ *     return col
+ */
+    __pyx_v_col = (__pyx_v_col + 1);
+  }
+
+  /* "bx/align/_core.pyx":13
+ *             start = start + 1
+ *         col = col + 1
+ *     return col             # <<<<<<<<<<<<<<
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_2 = PyInt_FromLong(__pyx_v_col); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 13; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_r = __pyx_t_2;
+  __pyx_t_2 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_AddTraceback("bx.align._core.coord_to_col", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyMethodDef __pyx_methods[] = {
+  {0, 0, 0, 0}
+};
+
+#if PY_MAJOR_VERSION >= 3
+static struct PyModuleDef __pyx_moduledef = {
+  #if PY_VERSION_HEX < 0x03020000
+    { PyObject_HEAD_INIT(NULL) NULL, 0, NULL },
+  #else
+    PyModuleDef_HEAD_INIT,
+  #endif
+    __Pyx_NAMESTR("_core"),
+    __Pyx_DOCSTR(__pyx_k_1), /* m_doc */
+    -1, /* m_size */
+    __pyx_methods /* m_methods */,
+    NULL, /* m_reload */
+    NULL, /* m_traverse */
+    NULL, /* m_clear */
+    NULL /* m_free */
+};
+#endif
+
+static __Pyx_StringTabEntry __pyx_string_tab[] = {
+  {&__pyx_kp_s_4, __pyx_k_4, sizeof(__pyx_k_4), 0, 0, 1, 0},
+  {&__pyx_n_s_5, __pyx_k_5, sizeof(__pyx_k_5), 0, 0, 1, 1},
+  {&__pyx_n_s____main__, __pyx_k____main__, sizeof(__pyx_k____main__), 0, 0, 1, 1},
+  {&__pyx_n_s____test__, __pyx_k____test__, sizeof(__pyx_k____test__), 0, 0, 1, 1},
+  {&__pyx_n_s__col, __pyx_k__col, sizeof(__pyx_k__col), 0, 0, 1, 1},
+  {&__pyx_n_s__coord_to_col, __pyx_k__coord_to_col, sizeof(__pyx_k__coord_to_col), 0, 0, 1, 1},
+  {&__pyx_n_s__pos, __pyx_k__pos, sizeof(__pyx_k__pos), 0, 0, 1, 1},
+  {&__pyx_n_s__start, __pyx_k__start, sizeof(__pyx_k__start), 0, 0, 1, 1},
+  {&__pyx_n_s__text, __pyx_k__text, sizeof(__pyx_k__text), 0, 0, 1, 1},
+  {0, 0, 0, 0, 0, 0, 0}
+};
+static int __Pyx_InitCachedBuiltins(void) {
+  return 0;
+}
+
+static int __Pyx_InitCachedConstants(void) {
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0);
+
+  /* "bx/align/_core.pyx":5
+ * """
+ * 
+ * def coord_to_col( int start, char * text, int pos ):             # <<<<<<<<<<<<<<
+ *     cdef int col
+ *     col = 0
+ */
+  __pyx_k_tuple_2 = PyTuple_Pack(4, ((PyObject *)__pyx_n_s__start), ((PyObject *)__pyx_n_s__text), ((PyObject *)__pyx_n_s__pos), ((PyObject *)__pyx_n_s__col)); if (unlikely(!__pyx_k_tuple_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 5; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_k_tuple_2);
+  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_2));
+  __pyx_k_codeobj_3 = (PyObject*)__Pyx_PyCode_New(3, 0, 4, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_k_tuple_2, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_4, __pyx_n_s__coord_to_col, 5, __pyx_empty_bytes); if (unlikely(!__pyx_k_codeobj_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 5; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_RefNannyFinishContext();
+  return 0;
+  __pyx_L1_error:;
+  __Pyx_RefNannyFinishContext();
+  return -1;
+}
+
+static int __Pyx_InitGlobals(void) {
+  if (__Pyx_InitStrings(__pyx_string_tab) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  return 0;
+  __pyx_L1_error:;
+  return -1;
+}
+
+#if PY_MAJOR_VERSION < 3
+PyMODINIT_FUNC init_core(void); /*proto*/
+PyMODINIT_FUNC init_core(void)
+#else
+PyMODINIT_FUNC PyInit__core(void); /*proto*/
+PyMODINIT_FUNC PyInit__core(void)
+#endif
+{
+  PyObject *__pyx_t_1 = NULL;
+  __Pyx_RefNannyDeclarations
+  #if CYTHON_REFNANNY
+  __Pyx_RefNanny = __Pyx_RefNannyImportAPI("refnanny");
+  if (!__Pyx_RefNanny) {
+      PyErr_Clear();
+      __Pyx_RefNanny = __Pyx_RefNannyImportAPI("Cython.Runtime.refnanny");
+      if (!__Pyx_RefNanny)
+          Py_FatalError("failed to import 'refnanny' module");
+  }
+  #endif
+  __Pyx_RefNannySetupContext("PyMODINIT_FUNC PyInit__core(void)", 0);
+  if ( __Pyx_check_binary_version() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_bytes)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #ifdef __Pyx_CyFunction_USED
+  if (__Pyx_CyFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #endif
+  #ifdef __Pyx_FusedFunction_USED
+  if (__pyx_FusedFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #endif
+  #ifdef __Pyx_Generator_USED
+  if (__pyx_Generator_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #endif
+  /*--- Library function declarations ---*/
+  /*--- Threads initialization code ---*/
+  #if defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS
+  #ifdef WITH_THREAD /* Python build with threading support? */
+  PyEval_InitThreads();
+  #endif
+  #endif
+  /*--- Module creation code ---*/
+  #if PY_MAJOR_VERSION < 3
+  __pyx_m = Py_InitModule4(__Pyx_NAMESTR("_core"), __pyx_methods, __Pyx_DOCSTR(__pyx_k_1), 0, PYTHON_API_VERSION); Py_XINCREF(__pyx_m);
+  #else
+  __pyx_m = PyModule_Create(&__pyx_moduledef);
+  #endif
+  if (unlikely(!__pyx_m)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #if PY_MAJOR_VERSION >= 3
+  {
+    PyObject *modules = PyImport_GetModuleDict(); if (unlikely(!modules)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (!PyDict_GetItemString(modules, "bx.align._core")) {
+      if (unlikely(PyDict_SetItemString(modules, "bx.align._core", __pyx_m) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+  }
+  #endif
+  __pyx_b = PyImport_AddModule(__Pyx_NAMESTR(__Pyx_BUILTIN_MODULE_NAME)); if (unlikely(!__pyx_b)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #if CYTHON_COMPILING_IN_PYPY
+  Py_INCREF(__pyx_b);
+  #endif
+  if (__Pyx_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  /*--- Initialize various global constants etc. ---*/
+  if (unlikely(__Pyx_InitGlobals() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (__pyx_module_is_main_bx__align___core) {
+    if (__Pyx_SetAttrString(__pyx_m, "__name__", __pyx_n_s____main__) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  }
+  /*--- Builtin init code ---*/
+  if (unlikely(__Pyx_InitCachedBuiltins() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  /*--- Constants init code ---*/
+  if (unlikely(__Pyx_InitCachedConstants() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  /*--- Global init code ---*/
+  /*--- Variable export code ---*/
+  /*--- Function export code ---*/
+  /*--- Type init code ---*/
+  /*--- Type import code ---*/
+  /*--- Variable import code ---*/
+  /*--- Function import code ---*/
+  /*--- Execution code ---*/
+
+  /* "bx/align/_core.pyx":5
+ * """
+ * 
+ * def coord_to_col( int start, char * text, int pos ):             # <<<<<<<<<<<<<<
+ *     cdef int col
+ *     col = 0
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_2bx_5align_5_core_1coord_to_col, NULL, __pyx_n_s_5); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 5; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s__coord_to_col, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 5; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "bx/align/_core.pyx":1
+ * """             # <<<<<<<<<<<<<<
+ * Pyrex extension to speed up some operations in `core.py`.
+ * """
+ */
+  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(((PyObject *)__pyx_t_1));
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s____test__, ((PyObject *)__pyx_t_1)) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  if (__pyx_m) {
+    __Pyx_AddTraceback("init bx.align._core", __pyx_clineno, __pyx_lineno, __pyx_filename);
+    Py_DECREF(__pyx_m); __pyx_m = 0;
+  } else if (!PyErr_Occurred()) {
+    PyErr_SetString(PyExc_ImportError, "init bx.align._core");
+  }
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  #if PY_MAJOR_VERSION < 3
+  return;
+  #else
+  return __pyx_m;
+  #endif
+}
+
+/* Runtime support code */
+#if CYTHON_REFNANNY
+static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) {
+    PyObject *m = NULL, *p = NULL;
+    void *r = NULL;
+    m = PyImport_ImportModule((char *)modname);
+    if (!m) goto end;
+    p = PyObject_GetAttrString(m, (char *)"RefNannyAPI");
+    if (!p) goto end;
+    r = PyLong_AsVoidPtr(p);
+end:
+    Py_XDECREF(p);
+    Py_XDECREF(m);
+    return (__Pyx_RefNannyAPIStruct *)r;
+}
+#endif /* CYTHON_REFNANNY */
+
+static void __Pyx_RaiseArgtupleInvalid(
+    const char* func_name,
+    int exact,
+    Py_ssize_t num_min,
+    Py_ssize_t num_max,
+    Py_ssize_t num_found)
+{
+    Py_ssize_t num_expected;
+    const char *more_or_less;
+    if (num_found < num_min) {
+        num_expected = num_min;
+        more_or_less = "at least";
+    } else {
+        num_expected = num_max;
+        more_or_less = "at most";
+    }
+    if (exact) {
+        more_or_less = "exactly";
+    }
+    PyErr_Format(PyExc_TypeError,
+                 "%s() takes %s %" CYTHON_FORMAT_SSIZE_T "d positional argument%s (%" CYTHON_FORMAT_SSIZE_T "d given)",
+                 func_name, more_or_less, num_expected,
+                 (num_expected == 1) ? "" : "s", num_found);
+}
+
+static void __Pyx_RaiseDoubleKeywordsError(
+    const char* func_name,
+    PyObject* kw_name)
+{
+    PyErr_Format(PyExc_TypeError,
+        #if PY_MAJOR_VERSION >= 3
+        "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
+        #else
+        "%s() got multiple values for keyword argument '%s'", func_name,
+        PyString_AsString(kw_name));
+        #endif
+}
+
+static int __Pyx_ParseOptionalKeywords(
+    PyObject *kwds,
+    PyObject **argnames[],
+    PyObject *kwds2,
+    PyObject *values[],
+    Py_ssize_t num_pos_args,
+    const char* function_name)
+{
+    PyObject *key = 0, *value = 0;
+    Py_ssize_t pos = 0;
+    PyObject*** name;
+    PyObject*** first_kw_arg = argnames + num_pos_args;
+    while (PyDict_Next(kwds, &pos, &key, &value)) {
+        name = first_kw_arg;
+        while (*name && (**name != key)) name++;
+        if (*name) {
+            values[name-argnames] = value;
+            continue;
+        }
+        name = first_kw_arg;
+        #if PY_MAJOR_VERSION < 3
+        if (likely(PyString_CheckExact(key)) || likely(PyString_Check(key))) {
+            while (*name) {
+                if ((CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**name) == PyString_GET_SIZE(key))
+                        && _PyString_Eq(**name, key)) {
+                    values[name-argnames] = value;
+                    break;
+                }
+                name++;
+            }
+            if (*name) continue;
+            else {
+                PyObject*** argname = argnames;
+                while (argname != first_kw_arg) {
+                    if ((**argname == key) || (
+                            (CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**argname) == PyString_GET_SIZE(key))
+                             && _PyString_Eq(**argname, key))) {
+                        goto arg_passed_twice;
+                    }
+                    argname++;
+                }
+            }
+        } else
+        #endif
+        if (likely(PyUnicode_Check(key))) {
+            while (*name) {
+                int cmp = (**name == key) ? 0 :
+                #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3
+                    (PyUnicode_GET_SIZE(**name) != PyUnicode_GET_SIZE(key)) ? 1 :
+                #endif
+                    PyUnicode_Compare(**name, key);
+                if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad;
+                if (cmp == 0) {
+                    values[name-argnames] = value;
+                    break;
+                }
+                name++;
+            }
+            if (*name) continue;
+            else {
+                PyObject*** argname = argnames;
+                while (argname != first_kw_arg) {
+                    int cmp = (**argname == key) ? 0 :
+                    #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3
+                        (PyUnicode_GET_SIZE(**argname) != PyUnicode_GET_SIZE(key)) ? 1 :
+                    #endif
+                        PyUnicode_Compare(**argname, key);
+                    if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad;
+                    if (cmp == 0) goto arg_passed_twice;
+                    argname++;
+                }
+            }
+        } else
+            goto invalid_keyword_type;
+        if (kwds2) {
+            if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
+        } else {
+            goto invalid_keyword;
+        }
+    }
+    return 0;
+arg_passed_twice:
+    __Pyx_RaiseDoubleKeywordsError(function_name, key);
+    goto bad;
+invalid_keyword_type:
+    PyErr_Format(PyExc_TypeError,
+        "%s() keywords must be strings", function_name);
+    goto bad;
+invalid_keyword:
+    PyErr_Format(PyExc_TypeError,
+    #if PY_MAJOR_VERSION < 3
+        "%s() got an unexpected keyword argument '%s'",
+        function_name, PyString_AsString(key));
+    #else
+        "%s() got an unexpected keyword argument '%U'",
+        function_name, key);
+    #endif
+bad:
+    return -1;
+}
+
+static CYTHON_INLINE unsigned char __Pyx_PyInt_AsUnsignedChar(PyObject* x) {
+    const unsigned char neg_one = (unsigned char)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(unsigned char) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(unsigned char)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to unsigned char" :
+                    "value too large to convert to unsigned char");
+            }
+            return (unsigned char)-1;
+        }
+        return (unsigned char)val;
+    }
+    return (unsigned char)__Pyx_PyInt_AsUnsignedLong(x);
+}
+
+static CYTHON_INLINE unsigned short __Pyx_PyInt_AsUnsignedShort(PyObject* x) {
+    const unsigned short neg_one = (unsigned short)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(unsigned short) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(unsigned short)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to unsigned short" :
+                    "value too large to convert to unsigned short");
+            }
+            return (unsigned short)-1;
+        }
+        return (unsigned short)val;
+    }
+    return (unsigned short)__Pyx_PyInt_AsUnsignedLong(x);
+}
+
+static CYTHON_INLINE unsigned int __Pyx_PyInt_AsUnsignedInt(PyObject* x) {
+    const unsigned int neg_one = (unsigned int)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(unsigned int) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(unsigned int)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to unsigned int" :
+                    "value too large to convert to unsigned int");
+            }
+            return (unsigned int)-1;
+        }
+        return (unsigned int)val;
+    }
+    return (unsigned int)__Pyx_PyInt_AsUnsignedLong(x);
+}
+
+static CYTHON_INLINE char __Pyx_PyInt_AsChar(PyObject* x) {
+    const char neg_one = (char)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(char) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(char)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to char" :
+                    "value too large to convert to char");
+            }
+            return (char)-1;
+        }
+        return (char)val;
+    }
+    return (char)__Pyx_PyInt_AsLong(x);
+}
+
+static CYTHON_INLINE short __Pyx_PyInt_AsShort(PyObject* x) {
+    const short neg_one = (short)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(short) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(short)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to short" :
+                    "value too large to convert to short");
+            }
+            return (short)-1;
+        }
+        return (short)val;
+    }
+    return (short)__Pyx_PyInt_AsLong(x);
+}
+
+static CYTHON_INLINE int __Pyx_PyInt_AsInt(PyObject* x) {
+    const int neg_one = (int)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(int) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(int)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to int" :
+                    "value too large to convert to int");
+            }
+            return (int)-1;
+        }
+        return (int)val;
+    }
+    return (int)__Pyx_PyInt_AsLong(x);
+}
+
+static CYTHON_INLINE signed char __Pyx_PyInt_AsSignedChar(PyObject* x) {
+    const signed char neg_one = (signed char)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(signed char) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(signed char)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to signed char" :
+                    "value too large to convert to signed char");
+            }
+            return (signed char)-1;
+        }
+        return (signed char)val;
+    }
+    return (signed char)__Pyx_PyInt_AsSignedLong(x);
+}
+
+static CYTHON_INLINE signed short __Pyx_PyInt_AsSignedShort(PyObject* x) {
+    const signed short neg_one = (signed short)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(signed short) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(signed short)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to signed short" :
+                    "value too large to convert to signed short");
+            }
+            return (signed short)-1;
+        }
+        return (signed short)val;
+    }
+    return (signed short)__Pyx_PyInt_AsSignedLong(x);
+}
+
+static CYTHON_INLINE signed int __Pyx_PyInt_AsSignedInt(PyObject* x) {
+    const signed int neg_one = (signed int)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(signed int) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(signed int)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to signed int" :
+                    "value too large to convert to signed int");
+            }
+            return (signed int)-1;
+        }
+        return (signed int)val;
+    }
+    return (signed int)__Pyx_PyInt_AsSignedLong(x);
+}
+
+static CYTHON_INLINE int __Pyx_PyInt_AsLongDouble(PyObject* x) {
+    const int neg_one = (int)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(int) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(int)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to int" :
+                    "value too large to convert to int");
+            }
+            return (int)-1;
+        }
+        return (int)val;
+    }
+    return (int)__Pyx_PyInt_AsLong(x);
+}
+
+static CYTHON_INLINE unsigned long __Pyx_PyInt_AsUnsignedLong(PyObject* x) {
+    const unsigned long neg_one = (unsigned long)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to unsigned long");
+            return (unsigned long)-1;
+        }
+        return (unsigned long)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to unsigned long");
+                return (unsigned long)-1;
+            }
+            return (unsigned long)PyLong_AsUnsignedLong(x);
+        } else {
+            return (unsigned long)PyLong_AsLong(x);
+        }
+    } else {
+        unsigned long val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (unsigned long)-1;
+        val = __Pyx_PyInt_AsUnsignedLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE unsigned PY_LONG_LONG __Pyx_PyInt_AsUnsignedLongLong(PyObject* x) {
+    const unsigned PY_LONG_LONG neg_one = (unsigned PY_LONG_LONG)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to unsigned PY_LONG_LONG");
+            return (unsigned PY_LONG_LONG)-1;
+        }
+        return (unsigned PY_LONG_LONG)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to unsigned PY_LONG_LONG");
+                return (unsigned PY_LONG_LONG)-1;
+            }
+            return (unsigned PY_LONG_LONG)PyLong_AsUnsignedLongLong(x);
+        } else {
+            return (unsigned PY_LONG_LONG)PyLong_AsLongLong(x);
+        }
+    } else {
+        unsigned PY_LONG_LONG val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (unsigned PY_LONG_LONG)-1;
+        val = __Pyx_PyInt_AsUnsignedLongLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE long __Pyx_PyInt_AsLong(PyObject* x) {
+    const long neg_one = (long)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to long");
+            return (long)-1;
+        }
+        return (long)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to long");
+                return (long)-1;
+            }
+            return (long)PyLong_AsUnsignedLong(x);
+        } else {
+            return (long)PyLong_AsLong(x);
+        }
+    } else {
+        long val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (long)-1;
+        val = __Pyx_PyInt_AsLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE PY_LONG_LONG __Pyx_PyInt_AsLongLong(PyObject* x) {
+    const PY_LONG_LONG neg_one = (PY_LONG_LONG)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to PY_LONG_LONG");
+            return (PY_LONG_LONG)-1;
+        }
+        return (PY_LONG_LONG)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to PY_LONG_LONG");
+                return (PY_LONG_LONG)-1;
+            }
+            return (PY_LONG_LONG)PyLong_AsUnsignedLongLong(x);
+        } else {
+            return (PY_LONG_LONG)PyLong_AsLongLong(x);
+        }
+    } else {
+        PY_LONG_LONG val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (PY_LONG_LONG)-1;
+        val = __Pyx_PyInt_AsLongLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE signed long __Pyx_PyInt_AsSignedLong(PyObject* x) {
+    const signed long neg_one = (signed long)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to signed long");
+            return (signed long)-1;
+        }
+        return (signed long)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to signed long");
+                return (signed long)-1;
+            }
+            return (signed long)PyLong_AsUnsignedLong(x);
+        } else {
+            return (signed long)PyLong_AsLong(x);
+        }
+    } else {
+        signed long val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (signed long)-1;
+        val = __Pyx_PyInt_AsSignedLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE signed PY_LONG_LONG __Pyx_PyInt_AsSignedLongLong(PyObject* x) {
+    const signed PY_LONG_LONG neg_one = (signed PY_LONG_LONG)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to signed PY_LONG_LONG");
+            return (signed PY_LONG_LONG)-1;
+        }
+        return (signed PY_LONG_LONG)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to signed PY_LONG_LONG");
+                return (signed PY_LONG_LONG)-1;
+            }
+            return (signed PY_LONG_LONG)PyLong_AsUnsignedLongLong(x);
+        } else {
+            return (signed PY_LONG_LONG)PyLong_AsLongLong(x);
+        }
+    } else {
+        signed PY_LONG_LONG val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (signed PY_LONG_LONG)-1;
+        val = __Pyx_PyInt_AsSignedLongLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static int __Pyx_check_binary_version(void) {
+    char ctversion[4], rtversion[4];
+    PyOS_snprintf(ctversion, 4, "%d.%d", PY_MAJOR_VERSION, PY_MINOR_VERSION);
+    PyOS_snprintf(rtversion, 4, "%s", Py_GetVersion());
+    if (ctversion[0] != rtversion[0] || ctversion[2] != rtversion[2]) {
+        char message[200];
+        PyOS_snprintf(message, sizeof(message),
+                      "compiletime version %s of module '%.100s' "
+                      "does not match runtime version %s",
+                      ctversion, __Pyx_MODULE_NAME, rtversion);
+        #if PY_VERSION_HEX < 0x02050000
+        return PyErr_Warn(NULL, message);
+        #else
+        return PyErr_WarnEx(NULL, message, 1);
+        #endif
+    }
+    return 0;
+}
+
+static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) {
+    int start = 0, mid = 0, end = count - 1;
+    if (end >= 0 && code_line > entries[end].code_line) {
+        return count;
+    }
+    while (start < end) {
+        mid = (start + end) / 2;
+        if (code_line < entries[mid].code_line) {
+            end = mid;
+        } else if (code_line > entries[mid].code_line) {
+             start = mid + 1;
+        } else {
+            return mid;
+        }
+    }
+    if (code_line <= entries[mid].code_line) {
+        return mid;
+    } else {
+        return mid + 1;
+    }
+}
+static PyCodeObject *__pyx_find_code_object(int code_line) {
+    PyCodeObject* code_object;
+    int pos;
+    if (unlikely(!code_line) || unlikely(!__pyx_code_cache.entries)) {
+        return NULL;
+    }
+    pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line);
+    if (unlikely(pos >= __pyx_code_cache.count) || unlikely(__pyx_code_cache.entries[pos].code_line != code_line)) {
+        return NULL;
+    }
+    code_object = __pyx_code_cache.entries[pos].code_object;
+    Py_INCREF(code_object);
+    return code_object;
+}
+static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) {
+    int pos, i;
+    __Pyx_CodeObjectCacheEntry* entries = __pyx_code_cache.entries;
+    if (unlikely(!code_line)) {
+        return;
+    }
+    if (unlikely(!entries)) {
+        entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Malloc(64*sizeof(__Pyx_CodeObjectCacheEntry));
+        if (likely(entries)) {
+            __pyx_code_cache.entries = entries;
+            __pyx_code_cache.max_count = 64;
+            __pyx_code_cache.count = 1;
+            entries[0].code_line = code_line;
+            entries[0].code_object = code_object;
+            Py_INCREF(code_object);
+        }
+        return;
+    }
+    pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line);
+    if ((pos < __pyx_code_cache.count) && unlikely(__pyx_code_cache.entries[pos].code_line == code_line)) {
+        PyCodeObject* tmp = entries[pos].code_object;
+        entries[pos].code_object = code_object;
+        Py_DECREF(tmp);
+        return;
+    }
+    if (__pyx_code_cache.count == __pyx_code_cache.max_count) {
+        int new_max = __pyx_code_cache.max_count + 64;
+        entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Realloc(
+            __pyx_code_cache.entries, new_max*sizeof(__Pyx_CodeObjectCacheEntry));
+        if (unlikely(!entries)) {
+            return;
+        }
+        __pyx_code_cache.entries = entries;
+        __pyx_code_cache.max_count = new_max;
+    }
+    for (i=__pyx_code_cache.count; i>pos; i--) {
+        entries[i] = entries[i-1];
+    }
+    entries[pos].code_line = code_line;
+    entries[pos].code_object = code_object;
+    __pyx_code_cache.count++;
+    Py_INCREF(code_object);
+}
+
+#include "compile.h"
+#include "frameobject.h"
+#include "traceback.h"
+static PyCodeObject* __Pyx_CreateCodeObjectForTraceback(
+            const char *funcname, int c_line,
+            int py_line, const char *filename) {
+    PyCodeObject *py_code = 0;
+    PyObject *py_srcfile = 0;
+    PyObject *py_funcname = 0;
+    #if PY_MAJOR_VERSION < 3
+    py_srcfile = PyString_FromString(filename);
+    #else
+    py_srcfile = PyUnicode_FromString(filename);
+    #endif
+    if (!py_srcfile) goto bad;
+    if (c_line) {
+        #if PY_MAJOR_VERSION < 3
+        py_funcname = PyString_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line);
+        #else
+        py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line);
+        #endif
+    }
+    else {
+        #if PY_MAJOR_VERSION < 3
+        py_funcname = PyString_FromString(funcname);
+        #else
+        py_funcname = PyUnicode_FromString(funcname);
+        #endif
+    }
+    if (!py_funcname) goto bad;
+    py_code = __Pyx_PyCode_New(
+        0,            /*int argcount,*/
+        0,            /*int kwonlyargcount,*/
+        0,            /*int nlocals,*/
+        0,            /*int stacksize,*/
+        0,            /*int flags,*/
+        __pyx_empty_bytes, /*PyObject *code,*/
+        __pyx_empty_tuple, /*PyObject *consts,*/
+        __pyx_empty_tuple, /*PyObject *names,*/
+        __pyx_empty_tuple, /*PyObject *varnames,*/
+        __pyx_empty_tuple, /*PyObject *freevars,*/
+        __pyx_empty_tuple, /*PyObject *cellvars,*/
+        py_srcfile,   /*PyObject *filename,*/
+        py_funcname,  /*PyObject *name,*/
+        py_line,      /*int firstlineno,*/
+        __pyx_empty_bytes  /*PyObject *lnotab*/
+    );
+    Py_DECREF(py_srcfile);
+    Py_DECREF(py_funcname);
+    return py_code;
+bad:
+    Py_XDECREF(py_srcfile);
+    Py_XDECREF(py_funcname);
+    return NULL;
+}
+static void __Pyx_AddTraceback(const char *funcname, int c_line,
+                               int py_line, const char *filename) {
+    PyCodeObject *py_code = 0;
+    PyObject *py_globals = 0;
+    PyFrameObject *py_frame = 0;
+    py_code = __pyx_find_code_object(c_line ? c_line : py_line);
+    if (!py_code) {
+        py_code = __Pyx_CreateCodeObjectForTraceback(
+            funcname, c_line, py_line, filename);
+        if (!py_code) goto bad;
+        __pyx_insert_code_object(c_line ? c_line : py_line, py_code);
+    }
+    py_globals = PyModule_GetDict(__pyx_m);
+    if (!py_globals) goto bad;
+    py_frame = PyFrame_New(
+        PyThreadState_GET(), /*PyThreadState *tstate,*/
+        py_code,             /*PyCodeObject *code,*/
+        py_globals,          /*PyObject *globals,*/
+        0                    /*PyObject *locals*/
+    );
+    if (!py_frame) goto bad;
+    py_frame->f_lineno = py_line;
+    PyTraceBack_Here(py_frame);
+bad:
+    Py_XDECREF(py_code);
+    Py_XDECREF(py_frame);
+}
+
+static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
+    while (t->p) {
+        #if PY_MAJOR_VERSION < 3
+        if (t->is_unicode) {
+            *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
+        } else if (t->intern) {
+            *t->p = PyString_InternFromString(t->s);
+        } else {
+            *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
+        }
+        #else  /* Python 3+ has unicode identifiers */
+        if (t->is_unicode | t->is_str) {
+            if (t->intern) {
+                *t->p = PyUnicode_InternFromString(t->s);
+            } else if (t->encoding) {
+                *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL);
+            } else {
+                *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
+            }
+        } else {
+            *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
+        }
+        #endif
+        if (!*t->p)
+            return -1;
+        ++t;
+    }
+    return 0;
+}
+
+static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) {
+   int is_true = x == Py_True;
+   if (is_true | (x == Py_False) | (x == Py_None)) return is_true;
+   else return PyObject_IsTrue(x);
+}
+static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x) {
+  PyNumberMethods *m;
+  const char *name = NULL;
+  PyObject *res = NULL;
+#if PY_VERSION_HEX < 0x03000000
+  if (PyInt_Check(x) || PyLong_Check(x))
+#else
+  if (PyLong_Check(x))
+#endif
+    return Py_INCREF(x), x;
+  m = Py_TYPE(x)->tp_as_number;
+#if PY_VERSION_HEX < 0x03000000
+  if (m && m->nb_int) {
+    name = "int";
+    res = PyNumber_Int(x);
+  }
+  else if (m && m->nb_long) {
+    name = "long";
+    res = PyNumber_Long(x);
+  }
+#else
+  if (m && m->nb_int) {
+    name = "int";
+    res = PyNumber_Long(x);
+  }
+#endif
+  if (res) {
+#if PY_VERSION_HEX < 0x03000000
+    if (!PyInt_Check(res) && !PyLong_Check(res)) {
+#else
+    if (!PyLong_Check(res)) {
+#endif
+      PyErr_Format(PyExc_TypeError,
+                   "__%s__ returned non-%s (type %.200s)",
+                   name, name, Py_TYPE(res)->tp_name);
+      Py_DECREF(res);
+      return NULL;
+    }
+  }
+  else if (!PyErr_Occurred()) {
+    PyErr_SetString(PyExc_TypeError,
+                    "an integer is required");
+  }
+  return res;
+}
+static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) {
+  Py_ssize_t ival;
+  PyObject* x = PyNumber_Index(b);
+  if (!x) return -1;
+  ival = PyInt_AsSsize_t(x);
+  Py_DECREF(x);
+  return ival;
+}
+static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) {
+#if PY_VERSION_HEX < 0x02050000
+   if (ival <= LONG_MAX)
+       return PyInt_FromLong((long)ival);
+   else {
+       unsigned char *bytes = (unsigned char *) &ival;
+       int one = 1; int little = (int)*(unsigned char*)&one;
+       return _PyLong_FromByteArray(bytes, sizeof(size_t), little, 0);
+   }
+#else
+   return PyInt_FromSize_t(ival);
+#endif
+}
+static CYTHON_INLINE size_t __Pyx_PyInt_AsSize_t(PyObject* x) {
+   unsigned PY_LONG_LONG val = __Pyx_PyInt_AsUnsignedLongLong(x);
+   if (unlikely(val == (unsigned PY_LONG_LONG)-1 && PyErr_Occurred())) {
+       return (size_t)-1;
+   } else if (unlikely(val != (unsigned PY_LONG_LONG)(size_t)val)) {
+       PyErr_SetString(PyExc_OverflowError,
+                       "value too large to convert to size_t");
+       return (size_t)-1;
+   }
+   return (size_t)val;
+}
+
+
+#endif /* Py_PYTHON_H */
diff --git a/lib/bx/align/_core.pyx b/lib/bx/align/_core.pyx
new file mode 100644
index 0000000..5b2d8f4
--- /dev/null
+++ b/lib/bx/align/_core.pyx
@@ -0,0 +1,13 @@
+"""
+Pyrex extension to speed up some operations in `core.py`.
+"""
+
+def coord_to_col( int start, char * text, int pos ):
+    cdef int col
+    col = 0
+    while start < pos:
+        # Note: ord( '-' ) = 45
+        if text[col] != 45: 
+            start = start + 1
+        col = col + 1 
+    return col
\ No newline at end of file
diff --git a/lib/bx/align/_epo.c b/lib/bx/align/_epo.c
new file mode 100644
index 0000000..b837bc3
--- /dev/null
+++ b/lib/bx/align/_epo.c
@@ -0,0 +1,10839 @@
+/* Generated by Cython 0.18 on Mon Jul 15 13:25:44 2013 */
+
+#define PY_SSIZE_T_CLEAN
+#include "Python.h"
+#ifndef Py_PYTHON_H
+    #error Python headers needed to compile C extensions, please install development version of Python.
+#elif PY_VERSION_HEX < 0x02040000
+    #error Cython requires Python 2.4+.
+#else
+#include <stddef.h> /* For offsetof */
+#ifndef offsetof
+#define offsetof(type, member) ( (size_t) & ((type*)0) -> member )
+#endif
+#if !defined(WIN32) && !defined(MS_WINDOWS)
+  #ifndef __stdcall
+    #define __stdcall
+  #endif
+  #ifndef __cdecl
+    #define __cdecl
+  #endif
+  #ifndef __fastcall
+    #define __fastcall
+  #endif
+#endif
+#ifndef DL_IMPORT
+  #define DL_IMPORT(t) t
+#endif
+#ifndef DL_EXPORT
+  #define DL_EXPORT(t) t
+#endif
+#ifndef PY_LONG_LONG
+  #define PY_LONG_LONG LONG_LONG
+#endif
+#ifndef Py_HUGE_VAL
+  #define Py_HUGE_VAL HUGE_VAL
+#endif
+#ifdef PYPY_VERSION
+#define CYTHON_COMPILING_IN_PYPY 1
+#define CYTHON_COMPILING_IN_CPYTHON 0
+#else
+#define CYTHON_COMPILING_IN_PYPY 0
+#define CYTHON_COMPILING_IN_CPYTHON 1
+#endif
+#if PY_VERSION_HEX < 0x02050000
+  typedef int Py_ssize_t;
+  #define PY_SSIZE_T_MAX INT_MAX
+  #define PY_SSIZE_T_MIN INT_MIN
+  #define PY_FORMAT_SIZE_T ""
+  #define CYTHON_FORMAT_SSIZE_T ""
+  #define PyInt_FromSsize_t(z) PyInt_FromLong(z)
+  #define PyInt_AsSsize_t(o)   __Pyx_PyInt_AsInt(o)
+  #define PyNumber_Index(o)    ((PyNumber_Check(o) && !PyFloat_Check(o)) ? PyNumber_Int(o) : \
+                                (PyErr_Format(PyExc_TypeError, \
+                                              "expected index value, got %.200s", Py_TYPE(o)->tp_name), \
+                                 (PyObject*)0))
+  #define __Pyx_PyIndex_Check(o) (PyNumber_Check(o) && !PyFloat_Check(o) && \
+                                  !PyComplex_Check(o))
+  #define PyIndex_Check __Pyx_PyIndex_Check
+  #define PyErr_WarnEx(category, message, stacklevel) PyErr_Warn(category, message)
+  #define __PYX_BUILD_PY_SSIZE_T "i"
+#else
+  #define __PYX_BUILD_PY_SSIZE_T "n"
+  #define CYTHON_FORMAT_SSIZE_T "z"
+  #define __Pyx_PyIndex_Check PyIndex_Check
+#endif
+#if PY_VERSION_HEX < 0x02060000
+  #define Py_REFCNT(ob) (((PyObject*)(ob))->ob_refcnt)
+  #define Py_TYPE(ob)   (((PyObject*)(ob))->ob_type)
+  #define Py_SIZE(ob)   (((PyVarObject*)(ob))->ob_size)
+  #define PyVarObject_HEAD_INIT(type, size) \
+          PyObject_HEAD_INIT(type) size,
+  #define PyType_Modified(t)
+  typedef struct {
+     void *buf;
+     PyObject *obj;
+     Py_ssize_t len;
+     Py_ssize_t itemsize;
+     int readonly;
+     int ndim;
+     char *format;
+     Py_ssize_t *shape;
+     Py_ssize_t *strides;
+     Py_ssize_t *suboffsets;
+     void *internal;
+  } Py_buffer;
+  #define PyBUF_SIMPLE 0
+  #define PyBUF_WRITABLE 0x0001
+  #define PyBUF_FORMAT 0x0004
+  #define PyBUF_ND 0x0008
+  #define PyBUF_STRIDES (0x0010 | PyBUF_ND)
+  #define PyBUF_C_CONTIGUOUS (0x0020 | PyBUF_STRIDES)
+  #define PyBUF_F_CONTIGUOUS (0x0040 | PyBUF_STRIDES)
+  #define PyBUF_ANY_CONTIGUOUS (0x0080 | PyBUF_STRIDES)
+  #define PyBUF_INDIRECT (0x0100 | PyBUF_STRIDES)
+  #define PyBUF_RECORDS (PyBUF_STRIDES | PyBUF_FORMAT | PyBUF_WRITABLE)
+  #define PyBUF_FULL (PyBUF_INDIRECT | PyBUF_FORMAT | PyBUF_WRITABLE)
+  typedef int (*getbufferproc)(PyObject *, Py_buffer *, int);
+  typedef void (*releasebufferproc)(PyObject *, Py_buffer *);
+#endif
+#if PY_MAJOR_VERSION < 3
+  #define __Pyx_BUILTIN_MODULE_NAME "__builtin__"
+  #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \
+          PyCode_New(a, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
+#else
+  #define __Pyx_BUILTIN_MODULE_NAME "builtins"
+  #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \
+          PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
+#endif
+#if PY_MAJOR_VERSION < 3 && PY_MINOR_VERSION < 6
+  #define PyUnicode_FromString(s) PyUnicode_Decode(s, strlen(s), "UTF-8", "strict")
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define Py_TPFLAGS_CHECKTYPES 0
+  #define Py_TPFLAGS_HAVE_INDEX 0
+#endif
+#if (PY_VERSION_HEX < 0x02060000) || (PY_MAJOR_VERSION >= 3)
+  #define Py_TPFLAGS_HAVE_NEWBUFFER 0
+#endif
+#if PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND)
+  #define CYTHON_PEP393_ENABLED 1
+  #define __Pyx_PyUnicode_READY(op)       (likely(PyUnicode_IS_READY(op)) ? \
+                                              0 : _PyUnicode_Ready((PyObject *)(op)))
+  #define __Pyx_PyUnicode_GET_LENGTH(u)   PyUnicode_GET_LENGTH(u)
+  #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_READ_CHAR(u, i)
+  #define __Pyx_PyUnicode_READ(k, d, i)   PyUnicode_READ(k, d, i)
+#else
+  #define CYTHON_PEP393_ENABLED 0
+  #define __Pyx_PyUnicode_READY(op)       (0)
+  #define __Pyx_PyUnicode_GET_LENGTH(u)   PyUnicode_GET_SIZE(u)
+  #define __Pyx_PyUnicode_READ_CHAR(u, i) ((Py_UCS4)(PyUnicode_AS_UNICODE(u)[i]))
+  #define __Pyx_PyUnicode_READ(k, d, i)   ((k=k), (Py_UCS4)(((Py_UNICODE*)d)[i]))
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define PyBaseString_Type            PyUnicode_Type
+  #define PyStringObject               PyUnicodeObject
+  #define PyString_Type                PyUnicode_Type
+  #define PyString_Check               PyUnicode_Check
+  #define PyString_CheckExact          PyUnicode_CheckExact
+#endif
+#if PY_VERSION_HEX < 0x02060000
+  #define PyBytesObject                PyStringObject
+  #define PyBytes_Type                 PyString_Type
+  #define PyBytes_Check                PyString_Check
+  #define PyBytes_CheckExact           PyString_CheckExact
+  #define PyBytes_FromString           PyString_FromString
+  #define PyBytes_FromStringAndSize    PyString_FromStringAndSize
+  #define PyBytes_FromFormat           PyString_FromFormat
+  #define PyBytes_DecodeEscape         PyString_DecodeEscape
+  #define PyBytes_AsString             PyString_AsString
+  #define PyBytes_AsStringAndSize      PyString_AsStringAndSize
+  #define PyBytes_Size                 PyString_Size
+  #define PyBytes_AS_STRING            PyString_AS_STRING
+  #define PyBytes_GET_SIZE             PyString_GET_SIZE
+  #define PyBytes_Repr                 PyString_Repr
+  #define PyBytes_Concat               PyString_Concat
+  #define PyBytes_ConcatAndDel         PyString_ConcatAndDel
+#endif
+#if PY_VERSION_HEX < 0x02060000
+  #define PySet_Check(obj)             PyObject_TypeCheck(obj, &PySet_Type)
+  #define PyFrozenSet_Check(obj)       PyObject_TypeCheck(obj, &PyFrozenSet_Type)
+#endif
+#ifndef PySet_CheckExact
+  #define PySet_CheckExact(obj)        (Py_TYPE(obj) == &PySet_Type)
+#endif
+#define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type)
+#if PY_MAJOR_VERSION >= 3
+  #define PyIntObject                  PyLongObject
+  #define PyInt_Type                   PyLong_Type
+  #define PyInt_Check(op)              PyLong_Check(op)
+  #define PyInt_CheckExact(op)         PyLong_CheckExact(op)
+  #define PyInt_FromString             PyLong_FromString
+  #define PyInt_FromUnicode            PyLong_FromUnicode
+  #define PyInt_FromLong               PyLong_FromLong
+  #define PyInt_FromSize_t             PyLong_FromSize_t
+  #define PyInt_FromSsize_t            PyLong_FromSsize_t
+  #define PyInt_AsLong                 PyLong_AsLong
+  #define PyInt_AS_LONG                PyLong_AS_LONG
+  #define PyInt_AsSsize_t              PyLong_AsSsize_t
+  #define PyInt_AsUnsignedLongMask     PyLong_AsUnsignedLongMask
+  #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define PyBoolObject                 PyLongObject
+#endif
+#if PY_VERSION_HEX < 0x03020000
+  typedef long Py_hash_t;
+  #define __Pyx_PyInt_FromHash_t PyInt_FromLong
+  #define __Pyx_PyInt_AsHash_t   PyInt_AsLong
+#else
+  #define __Pyx_PyInt_FromHash_t PyInt_FromSsize_t
+  #define __Pyx_PyInt_AsHash_t   PyInt_AsSsize_t
+#endif
+#if (PY_MAJOR_VERSION < 3) || (PY_VERSION_HEX >= 0x03010300)
+  #define __Pyx_PySequence_GetSlice(obj, a, b) PySequence_GetSlice(obj, a, b)
+  #define __Pyx_PySequence_SetSlice(obj, a, b, value) PySequence_SetSlice(obj, a, b, value)
+  #define __Pyx_PySequence_DelSlice(obj, a, b) PySequence_DelSlice(obj, a, b)
+#else
+  #define __Pyx_PySequence_GetSlice(obj, a, b) (unlikely(!(obj)) ? \
+        (PyErr_SetString(PyExc_SystemError, "null argument to internal routine"), (PyObject*)0) : \
+        (likely((obj)->ob_type->tp_as_mapping) ? (PySequence_GetSlice(obj, a, b)) : \
+            (PyErr_Format(PyExc_TypeError, "'%.200s' object is unsliceable", (obj)->ob_type->tp_name), (PyObject*)0)))
+  #define __Pyx_PySequence_SetSlice(obj, a, b, value) (unlikely(!(obj)) ? \
+        (PyErr_SetString(PyExc_SystemError, "null argument to internal routine"), -1) : \
+        (likely((obj)->ob_type->tp_as_mapping) ? (PySequence_SetSlice(obj, a, b, value)) : \
+            (PyErr_Format(PyExc_TypeError, "'%.200s' object doesn't support slice assignment", (obj)->ob_type->tp_name), -1)))
+  #define __Pyx_PySequence_DelSlice(obj, a, b) (unlikely(!(obj)) ? \
+        (PyErr_SetString(PyExc_SystemError, "null argument to internal routine"), -1) : \
+        (likely((obj)->ob_type->tp_as_mapping) ? (PySequence_DelSlice(obj, a, b)) : \
+            (PyErr_Format(PyExc_TypeError, "'%.200s' object doesn't support slice deletion", (obj)->ob_type->tp_name), -1)))
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define PyMethod_New(func, self, klass) ((self) ? PyMethod_New(func, self) : PyInstanceMethod_New(func))
+#endif
+#if PY_VERSION_HEX < 0x02050000
+  #define __Pyx_GetAttrString(o,n)   PyObject_GetAttrString((o),((char *)(n)))
+  #define __Pyx_SetAttrString(o,n,a) PyObject_SetAttrString((o),((char *)(n)),(a))
+  #define __Pyx_DelAttrString(o,n)   PyObject_DelAttrString((o),((char *)(n)))
+#else
+  #define __Pyx_GetAttrString(o,n)   PyObject_GetAttrString((o),(n))
+  #define __Pyx_SetAttrString(o,n,a) PyObject_SetAttrString((o),(n),(a))
+  #define __Pyx_DelAttrString(o,n)   PyObject_DelAttrString((o),(n))
+#endif
+#if PY_VERSION_HEX < 0x02050000
+  #define __Pyx_NAMESTR(n) ((char *)(n))
+  #define __Pyx_DOCSTR(n)  ((char *)(n))
+#else
+  #define __Pyx_NAMESTR(n) (n)
+  #define __Pyx_DOCSTR(n)  (n)
+#endif
+
+
+#if PY_MAJOR_VERSION >= 3
+  #define __Pyx_PyNumber_Divide(x,y)         PyNumber_TrueDivide(x,y)
+  #define __Pyx_PyNumber_InPlaceDivide(x,y)  PyNumber_InPlaceTrueDivide(x,y)
+#else
+  #define __Pyx_PyNumber_Divide(x,y)         PyNumber_Divide(x,y)
+  #define __Pyx_PyNumber_InPlaceDivide(x,y)  PyNumber_InPlaceDivide(x,y)
+#endif
+
+#ifndef __PYX_EXTERN_C
+  #ifdef __cplusplus
+    #define __PYX_EXTERN_C extern "C"
+  #else
+    #define __PYX_EXTERN_C extern
+  #endif
+#endif
+
+#if defined(WIN32) || defined(MS_WINDOWS)
+#define _USE_MATH_DEFINES
+#endif
+#include <math.h>
+#define __PYX_HAVE__bx__align___epo
+#define __PYX_HAVE_API__bx__align___epo
+#include "string.h"
+#include "stdio.h"
+#include "stdlib.h"
+#include "numpy/arrayobject.h"
+#include "numpy/ufuncobject.h"
+#ifdef _OPENMP
+#include <omp.h>
+#endif /* _OPENMP */
+
+#ifdef PYREX_WITHOUT_ASSERTIONS
+#define CYTHON_WITHOUT_ASSERTIONS
+#endif
+
+#ifndef CYTHON_INLINE
+  #if defined(__GNUC__)
+    #define CYTHON_INLINE __inline__
+  #elif defined(_MSC_VER)
+    #define CYTHON_INLINE __inline
+  #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+    #define CYTHON_INLINE inline
+  #else
+    #define CYTHON_INLINE
+  #endif
+#endif
+#ifndef CYTHON_UNUSED
+# if defined(__GNUC__)
+#   if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
+#     define CYTHON_UNUSED __attribute__ ((__unused__))
+#   else
+#     define CYTHON_UNUSED
+#   endif
+# elif defined(__ICC) || (defined(__INTEL_COMPILER) && !defined(_MSC_VER))
+#   define CYTHON_UNUSED __attribute__ ((__unused__))
+# else
+#   define CYTHON_UNUSED
+# endif
+#endif
+typedef struct {PyObject **p; char *s; const long n; const char* encoding; const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry; /*proto*/
+
+#define __Pyx_PyBytes_FromUString(s) PyBytes_FromString((char*)s)
+#define __Pyx_PyBytes_AsUString(s)   ((unsigned char*) PyBytes_AsString(s))
+#define __Pyx_Owned_Py_None(b) (Py_INCREF(Py_None), Py_None)
+#define __Pyx_PyBool_FromLong(b) ((b) ? (Py_INCREF(Py_True), Py_True) : (Py_INCREF(Py_False), Py_False))
+static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*);
+static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x);
+static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*);
+static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t);
+static CYTHON_INLINE size_t __Pyx_PyInt_AsSize_t(PyObject*);
+#if CYTHON_COMPILING_IN_CPYTHON
+#define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x))
+#else
+#define __pyx_PyFloat_AsDouble(x) PyFloat_AsDouble(x)
+#endif
+#define __pyx_PyFloat_AsFloat(x) ((float) __pyx_PyFloat_AsDouble(x))
+
+
+#ifdef __GNUC__
+  /* Test for GCC > 2.95 */
+  #if __GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))
+    #define likely(x)   __builtin_expect(!!(x), 1)
+    #define unlikely(x) __builtin_expect(!!(x), 0)
+  #else /* __GNUC__ > 2 ... */
+    #define likely(x)   (x)
+    #define unlikely(x) (x)
+  #endif /* __GNUC__ > 2 ... */
+#else /* __GNUC__ */
+  #define likely(x)   (x)
+  #define unlikely(x) (x)
+#endif /* __GNUC__ */
+    
+static PyObject *__pyx_m;
+static PyObject *__pyx_b;
+static PyObject *__pyx_empty_tuple;
+static PyObject *__pyx_empty_bytes;
+static int __pyx_lineno;
+static int __pyx_clineno = 0;
+static const char * __pyx_cfilenm= __FILE__;
+static const char *__pyx_filename;
+
+#if !defined(CYTHON_CCOMPLEX)
+  #if defined(__cplusplus)
+    #define CYTHON_CCOMPLEX 1
+  #elif defined(_Complex_I)
+    #define CYTHON_CCOMPLEX 1
+  #else
+    #define CYTHON_CCOMPLEX 0
+  #endif
+#endif
+#if CYTHON_CCOMPLEX
+  #ifdef __cplusplus
+    #include <complex>
+  #else
+    #include <complex.h>
+  #endif
+#endif
+#if CYTHON_CCOMPLEX && !defined(__cplusplus) && defined(__sun__) && defined(__GNUC__)
+  #undef _Complex_I
+  #define _Complex_I 1.0fj
+#endif
+
+
+static const char *__pyx_f[] = {
+  "_epo.pyx",
+  "numpy.pxd",
+  "type.pxd",
+};
+#define IS_UNSIGNED(type) (((type) -1) > 0)
+struct __Pyx_StructField_;
+#define __PYX_BUF_FLAGS_PACKED_STRUCT (1 << 0)
+typedef struct {
+  const char* name; /* for error messages only */
+  struct __Pyx_StructField_* fields;
+  size_t size;     /* sizeof(type) */
+  size_t arraysize[8]; /* length of array in each dimension */
+  int ndim;
+  char typegroup; /* _R_eal, _C_omplex, Signed _I_nt, _U_nsigned int, _S_truct, _P_ointer, _O_bject, c_H_ar */
+  char is_unsigned;
+  int flags;
+} __Pyx_TypeInfo;
+typedef struct __Pyx_StructField_ {
+  __Pyx_TypeInfo* type;
+  const char* name;
+  size_t offset;
+} __Pyx_StructField;
+typedef struct {
+  __Pyx_StructField* field;
+  size_t parent_offset;
+} __Pyx_BufFmt_StackElem;
+typedef struct {
+  __Pyx_StructField root;
+  __Pyx_BufFmt_StackElem* head;
+  size_t fmt_offset;
+  size_t new_count, enc_count;
+  size_t struct_alignment;
+  int is_complex;
+  char enc_type;
+  char new_packmode;
+  char enc_packmode;
+  char is_valid_array;
+} __Pyx_BufFmt_Context;
+
+
+/* "numpy.pxd":723
+ * # in Cython to enable them only on the right systems.
+ * 
+ * ctypedef npy_int8       int8_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_int16      int16_t
+ * ctypedef npy_int32      int32_t
+ */
+typedef npy_int8 __pyx_t_5numpy_int8_t;
+
+/* "numpy.pxd":724
+ * 
+ * ctypedef npy_int8       int8_t
+ * ctypedef npy_int16      int16_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_int32      int32_t
+ * ctypedef npy_int64      int64_t
+ */
+typedef npy_int16 __pyx_t_5numpy_int16_t;
+
+/* "numpy.pxd":725
+ * ctypedef npy_int8       int8_t
+ * ctypedef npy_int16      int16_t
+ * ctypedef npy_int32      int32_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_int64      int64_t
+ * #ctypedef npy_int96      int96_t
+ */
+typedef npy_int32 __pyx_t_5numpy_int32_t;
+
+/* "numpy.pxd":726
+ * ctypedef npy_int16      int16_t
+ * ctypedef npy_int32      int32_t
+ * ctypedef npy_int64      int64_t             # <<<<<<<<<<<<<<
+ * #ctypedef npy_int96      int96_t
+ * #ctypedef npy_int128     int128_t
+ */
+typedef npy_int64 __pyx_t_5numpy_int64_t;
+
+/* "numpy.pxd":730
+ * #ctypedef npy_int128     int128_t
+ * 
+ * ctypedef npy_uint8      uint8_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_uint16     uint16_t
+ * ctypedef npy_uint32     uint32_t
+ */
+typedef npy_uint8 __pyx_t_5numpy_uint8_t;
+
+/* "numpy.pxd":731
+ * 
+ * ctypedef npy_uint8      uint8_t
+ * ctypedef npy_uint16     uint16_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_uint32     uint32_t
+ * ctypedef npy_uint64     uint64_t
+ */
+typedef npy_uint16 __pyx_t_5numpy_uint16_t;
+
+/* "numpy.pxd":732
+ * ctypedef npy_uint8      uint8_t
+ * ctypedef npy_uint16     uint16_t
+ * ctypedef npy_uint32     uint32_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_uint64     uint64_t
+ * #ctypedef npy_uint96     uint96_t
+ */
+typedef npy_uint32 __pyx_t_5numpy_uint32_t;
+
+/* "numpy.pxd":733
+ * ctypedef npy_uint16     uint16_t
+ * ctypedef npy_uint32     uint32_t
+ * ctypedef npy_uint64     uint64_t             # <<<<<<<<<<<<<<
+ * #ctypedef npy_uint96     uint96_t
+ * #ctypedef npy_uint128    uint128_t
+ */
+typedef npy_uint64 __pyx_t_5numpy_uint64_t;
+
+/* "numpy.pxd":737
+ * #ctypedef npy_uint128    uint128_t
+ * 
+ * ctypedef npy_float32    float32_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_float64    float64_t
+ * #ctypedef npy_float80    float80_t
+ */
+typedef npy_float32 __pyx_t_5numpy_float32_t;
+
+/* "numpy.pxd":738
+ * 
+ * ctypedef npy_float32    float32_t
+ * ctypedef npy_float64    float64_t             # <<<<<<<<<<<<<<
+ * #ctypedef npy_float80    float80_t
+ * #ctypedef npy_float128   float128_t
+ */
+typedef npy_float64 __pyx_t_5numpy_float64_t;
+
+/* "numpy.pxd":747
+ * # The int types are mapped a bit surprising --
+ * # numpy.int corresponds to 'l' and numpy.long to 'q'
+ * ctypedef npy_long       int_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_longlong   long_t
+ * ctypedef npy_longlong   longlong_t
+ */
+typedef npy_long __pyx_t_5numpy_int_t;
+
+/* "numpy.pxd":748
+ * # numpy.int corresponds to 'l' and numpy.long to 'q'
+ * ctypedef npy_long       int_t
+ * ctypedef npy_longlong   long_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_longlong   longlong_t
+ * 
+ */
+typedef npy_longlong __pyx_t_5numpy_long_t;
+
+/* "numpy.pxd":749
+ * ctypedef npy_long       int_t
+ * ctypedef npy_longlong   long_t
+ * ctypedef npy_longlong   longlong_t             # <<<<<<<<<<<<<<
+ * 
+ * ctypedef npy_ulong      uint_t
+ */
+typedef npy_longlong __pyx_t_5numpy_longlong_t;
+
+/* "numpy.pxd":751
+ * ctypedef npy_longlong   longlong_t
+ * 
+ * ctypedef npy_ulong      uint_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_ulonglong  ulong_t
+ * ctypedef npy_ulonglong  ulonglong_t
+ */
+typedef npy_ulong __pyx_t_5numpy_uint_t;
+
+/* "numpy.pxd":752
+ * 
+ * ctypedef npy_ulong      uint_t
+ * ctypedef npy_ulonglong  ulong_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_ulonglong  ulonglong_t
+ * 
+ */
+typedef npy_ulonglong __pyx_t_5numpy_ulong_t;
+
+/* "numpy.pxd":753
+ * ctypedef npy_ulong      uint_t
+ * ctypedef npy_ulonglong  ulong_t
+ * ctypedef npy_ulonglong  ulonglong_t             # <<<<<<<<<<<<<<
+ * 
+ * ctypedef npy_intp       intp_t
+ */
+typedef npy_ulonglong __pyx_t_5numpy_ulonglong_t;
+
+/* "numpy.pxd":755
+ * ctypedef npy_ulonglong  ulonglong_t
+ * 
+ * ctypedef npy_intp       intp_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_uintp      uintp_t
+ * 
+ */
+typedef npy_intp __pyx_t_5numpy_intp_t;
+
+/* "numpy.pxd":756
+ * 
+ * ctypedef npy_intp       intp_t
+ * ctypedef npy_uintp      uintp_t             # <<<<<<<<<<<<<<
+ * 
+ * ctypedef npy_double     float_t
+ */
+typedef npy_uintp __pyx_t_5numpy_uintp_t;
+
+/* "numpy.pxd":758
+ * ctypedef npy_uintp      uintp_t
+ * 
+ * ctypedef npy_double     float_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_double     double_t
+ * ctypedef npy_longdouble longdouble_t
+ */
+typedef npy_double __pyx_t_5numpy_float_t;
+
+/* "numpy.pxd":759
+ * 
+ * ctypedef npy_double     float_t
+ * ctypedef npy_double     double_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_longdouble longdouble_t
+ * 
+ */
+typedef npy_double __pyx_t_5numpy_double_t;
+
+/* "numpy.pxd":760
+ * ctypedef npy_double     float_t
+ * ctypedef npy_double     double_t
+ * ctypedef npy_longdouble longdouble_t             # <<<<<<<<<<<<<<
+ * 
+ * ctypedef npy_cfloat      cfloat_t
+ */
+typedef npy_longdouble __pyx_t_5numpy_longdouble_t;
+#if CYTHON_CCOMPLEX
+  #ifdef __cplusplus
+    typedef ::std::complex< float > __pyx_t_float_complex;
+  #else
+    typedef float _Complex __pyx_t_float_complex;
+  #endif
+#else
+    typedef struct { float real, imag; } __pyx_t_float_complex;
+#endif
+
+#if CYTHON_CCOMPLEX
+  #ifdef __cplusplus
+    typedef ::std::complex< double > __pyx_t_double_complex;
+  #else
+    typedef double _Complex __pyx_t_double_complex;
+  #endif
+#else
+    typedef struct { double real, imag; } __pyx_t_double_complex;
+#endif
+
+
+/*--- Type declarations ---*/
+struct __pyx_obj_2bx_5align_4_epo___pyx_scope_struct__rem_dash;
+
+/* "numpy.pxd":762
+ * ctypedef npy_longdouble longdouble_t
+ * 
+ * ctypedef npy_cfloat      cfloat_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_cdouble     cdouble_t
+ * ctypedef npy_clongdouble clongdouble_t
+ */
+typedef npy_cfloat __pyx_t_5numpy_cfloat_t;
+
+/* "numpy.pxd":763
+ * 
+ * ctypedef npy_cfloat      cfloat_t
+ * ctypedef npy_cdouble     cdouble_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_clongdouble clongdouble_t
+ * 
+ */
+typedef npy_cdouble __pyx_t_5numpy_cdouble_t;
+
+/* "numpy.pxd":764
+ * ctypedef npy_cfloat      cfloat_t
+ * ctypedef npy_cdouble     cdouble_t
+ * ctypedef npy_clongdouble clongdouble_t             # <<<<<<<<<<<<<<
+ * 
+ * ctypedef npy_cdouble     complex_t
+ */
+typedef npy_clongdouble __pyx_t_5numpy_clongdouble_t;
+
+/* "numpy.pxd":766
+ * ctypedef npy_clongdouble clongdouble_t
+ * 
+ * ctypedef npy_cdouble     complex_t             # <<<<<<<<<<<<<<
+ * 
+ * cdef inline object PyArray_MultiIterNew1(a):
+ */
+typedef npy_cdouble __pyx_t_5numpy_complex_t;
+
+/* "bx/align/_epo.pyx":26
+ * 
+ * 
+ * def rem_dash(p, q):             # <<<<<<<<<<<<<<
+ *     """remove dash columns and shift match intervals to the left. both iterables
+ *     are read on the same direction left-to-right.
+ */
+struct __pyx_obj_2bx_5align_4_epo___pyx_scope_struct__rem_dash {
+  PyObject_HEAD
+  PyObject *__pyx_v_P;
+  PyObject *__pyx_v_Q;
+  PyObject *__pyx_v_p;
+  PyObject *__pyx_v_q;
+};
+
+#ifndef CYTHON_REFNANNY
+  #define CYTHON_REFNANNY 0
+#endif
+#if CYTHON_REFNANNY
+  typedef struct {
+    void (*INCREF)(void*, PyObject*, int);
+    void (*DECREF)(void*, PyObject*, int);
+    void (*GOTREF)(void*, PyObject*, int);
+    void (*GIVEREF)(void*, PyObject*, int);
+    void* (*SetupContext)(const char*, int, const char*);
+    void (*FinishContext)(void**);
+  } __Pyx_RefNannyAPIStruct;
+  static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL;
+  static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname); /*proto*/
+  #define __Pyx_RefNannyDeclarations void *__pyx_refnanny = NULL;
+#ifdef WITH_THREAD
+  #define __Pyx_RefNannySetupContext(name, acquire_gil) \
+          if (acquire_gil) { \
+              PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure(); \
+              __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__); \
+              PyGILState_Release(__pyx_gilstate_save); \
+          } else { \
+              __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__); \
+          }
+#else
+  #define __Pyx_RefNannySetupContext(name, acquire_gil) \
+          __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__)
+#endif
+  #define __Pyx_RefNannyFinishContext() \
+          __Pyx_RefNanny->FinishContext(&__pyx_refnanny)
+  #define __Pyx_INCREF(r)  __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_DECREF(r)  __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_GOTREF(r)  __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_XINCREF(r)  do { if((r) != NULL) {__Pyx_INCREF(r); }} while(0)
+  #define __Pyx_XDECREF(r)  do { if((r) != NULL) {__Pyx_DECREF(r); }} while(0)
+  #define __Pyx_XGOTREF(r)  do { if((r) != NULL) {__Pyx_GOTREF(r); }} while(0)
+  #define __Pyx_XGIVEREF(r) do { if((r) != NULL) {__Pyx_GIVEREF(r);}} while(0)
+#else
+  #define __Pyx_RefNannyDeclarations
+  #define __Pyx_RefNannySetupContext(name, acquire_gil)
+  #define __Pyx_RefNannyFinishContext()
+  #define __Pyx_INCREF(r) Py_INCREF(r)
+  #define __Pyx_DECREF(r) Py_DECREF(r)
+  #define __Pyx_GOTREF(r)
+  #define __Pyx_GIVEREF(r)
+  #define __Pyx_XINCREF(r) Py_XINCREF(r)
+  #define __Pyx_XDECREF(r) Py_XDECREF(r)
+  #define __Pyx_XGOTREF(r)
+  #define __Pyx_XGIVEREF(r)
+#endif /* CYTHON_REFNANNY */
+#define __Pyx_CLEAR(r)    do { PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);} while(0)
+#define __Pyx_XCLEAR(r)   do { if((r) != NULL) {PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);}} while(0)
+
+static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/
+
+static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
+    Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/
+
+static void __Pyx_RaiseDoubleKeywordsError(const char* func_name, PyObject* kw_name); /*proto*/
+
+static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
+    PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
+    const char* function_name); /*proto*/
+
+static PyObject* __Pyx_PyObject_PopIndex(PyObject* L, Py_ssize_t ix) {
+    PyObject *r, *m, *t, *py_ix;
+#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x02040000
+    if (likely(PyList_CheckExact(L))) {
+        Py_ssize_t size = PyList_GET_SIZE(L);
+        if (likely(size > (((PyListObject*)L)->allocated >> 1))) {
+            if (ix < 0) {
+                ix += size;
+            }
+            if (likely(0 <= ix && ix < size)) {
+                PyObject* v = PyList_GET_ITEM(L, ix);
+                Py_SIZE(L) -= 1;
+                size -= 1;
+                memmove(&PyList_GET_ITEM(L, ix), &PyList_GET_ITEM(L, ix+1), (size-ix)*sizeof(PyObject*));
+                return v;
+            }
+        }
+    }
+#endif
+    py_ix = t = NULL;
+    m = __Pyx_GetAttrString(L, "pop");
+    if (!m) goto bad;
+    py_ix = PyInt_FromSsize_t(ix);
+    if (!py_ix) goto bad;
+    t = PyTuple_New(1);
+    if (!t) goto bad;
+    PyTuple_SET_ITEM(t, 0, py_ix);
+    py_ix = NULL;
+    r = PyObject_CallObject(m, t);
+    Py_DECREF(m);
+    Py_DECREF(t);
+    return r;
+bad:
+    Py_XDECREF(m);
+    Py_XDECREF(t);
+    Py_XDECREF(py_ix);
+    return NULL;
+}
+
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j) {
+    PyObject *r;
+    if (!j) return NULL;
+    r = PyObject_GetItem(o, j);
+    Py_DECREF(j);
+    return r;
+}
+#define __Pyx_GetItemInt_List(o, i, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \
+                                                    __Pyx_GetItemInt_List_Fast(o, i) : \
+                                                    __Pyx_GetItemInt_Generic(o, to_py_func(i)))
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    if (likely((0 <= i) & (i < PyList_GET_SIZE(o)))) {
+        PyObject *r = PyList_GET_ITEM(o, i);
+        Py_INCREF(r);
+        return r;
+    }
+    else if ((-PyList_GET_SIZE(o) <= i) & (i < 0)) {
+        PyObject *r = PyList_GET_ITEM(o, PyList_GET_SIZE(o) + i);
+        Py_INCREF(r);
+        return r;
+    }
+    return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
+#else
+    return PySequence_GetItem(o, i);
+#endif
+}
+#define __Pyx_GetItemInt_Tuple(o, i, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \
+                                                    __Pyx_GetItemInt_Tuple_Fast(o, i) : \
+                                                    __Pyx_GetItemInt_Generic(o, to_py_func(i)))
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    if (likely((0 <= i) & (i < PyTuple_GET_SIZE(o)))) {
+        PyObject *r = PyTuple_GET_ITEM(o, i);
+        Py_INCREF(r);
+        return r;
+    }
+    else if ((-PyTuple_GET_SIZE(o) <= i) & (i < 0)) {
+        PyObject *r = PyTuple_GET_ITEM(o, PyTuple_GET_SIZE(o) + i);
+        Py_INCREF(r);
+        return r;
+    }
+    return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
+#else
+    return PySequence_GetItem(o, i);
+#endif
+}
+#define __Pyx_GetItemInt(o, i, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \
+                                                    __Pyx_GetItemInt_Fast(o, i) : \
+                                                    __Pyx_GetItemInt_Generic(o, to_py_func(i)))
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    if (PyList_CheckExact(o)) {
+        Py_ssize_t n = (likely(i >= 0)) ? i : i + PyList_GET_SIZE(o);
+        if (likely((n >= 0) & (n < PyList_GET_SIZE(o)))) {
+            PyObject *r = PyList_GET_ITEM(o, n);
+            Py_INCREF(r);
+            return r;
+        }
+    }
+    else if (PyTuple_CheckExact(o)) {
+        Py_ssize_t n = (likely(i >= 0)) ? i : i + PyTuple_GET_SIZE(o);
+        if (likely((n >= 0) & (n < PyTuple_GET_SIZE(o)))) {
+            PyObject *r = PyTuple_GET_ITEM(o, n);
+            Py_INCREF(r);
+            return r;
+        }
+    } else {  /* inlined PySequence_GetItem() */
+        PySequenceMethods *m = Py_TYPE(o)->tp_as_sequence;
+        if (likely(m && m->sq_item)) {
+            if (unlikely(i < 0) && likely(m->sq_length)) {
+                Py_ssize_t l = m->sq_length(o);
+                if (unlikely(l < 0)) return NULL;
+                i += l;
+            }
+            return m->sq_item(o, i);
+        }
+    }
+#else
+    if (PySequence_Check(o)) {
+        return PySequence_GetItem(o, i);
+    }
+#endif
+    return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
+}
+
+#define __Pyx_SetItemInt(o, i, v, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \
+                                                    __Pyx_SetItemInt_Fast(o, i, v) : \
+                                                    __Pyx_SetItemInt_Generic(o, to_py_func(i), v))
+static CYTHON_INLINE int __Pyx_SetItemInt_Generic(PyObject *o, PyObject *j, PyObject *v) {
+    int r;
+    if (!j) return -1;
+    r = PyObject_SetItem(o, j, v);
+    Py_DECREF(j);
+    return r;
+}
+static CYTHON_INLINE int __Pyx_SetItemInt_Fast(PyObject *o, Py_ssize_t i, PyObject *v) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    if (PyList_CheckExact(o)) {
+        Py_ssize_t n = (likely(i >= 0)) ? i : i + PyList_GET_SIZE(o);
+        if (likely((n >= 0) & (n < PyList_GET_SIZE(o)))) {
+            PyObject* old = PyList_GET_ITEM(o, n);
+            Py_INCREF(v);
+            PyList_SET_ITEM(o, n, v);
+            Py_DECREF(old);
+            return 1;
+        }
+    } else {  /* inlined PySequence_SetItem() */
+        PySequenceMethods *m = Py_TYPE(o)->tp_as_sequence;
+        if (likely(m && m->sq_ass_item)) {
+            if (unlikely(i < 0) && likely(m->sq_length)) {
+                Py_ssize_t l = m->sq_length(o);
+                if (unlikely(l < 0)) return -1;
+                i += l;
+            }
+            return m->sq_ass_item(o, i, v);
+        }
+    }
+#else
+#if CYTHON_COMPILING_IN_PYPY
+    if (PySequence_Check(o) && !PyDict_Check(o)) {
+#else
+    if (PySequence_Check(o)) {
+#endif
+        return PySequence_SetItem(o, i, v);
+    }
+#endif
+    return __Pyx_SetItemInt_Generic(o, PyInt_FromSsize_t(i), v);
+}
+
+static CYTHON_INLINE PyObject* __Pyx_PyObject_Append(PyObject* L, PyObject* x) {
+    if (likely(PyList_CheckExact(L))) {
+        if (unlikely(PyList_Append(L, x) < 0)) return NULL;
+        Py_INCREF(Py_None);
+        return Py_None; /* this is just to have an accurate signature */
+    } else {
+        PyObject *r, *m;
+        m = __Pyx_GetAttrString(L, "append");
+        if (!m) return NULL;
+        r = PyObject_CallFunctionObjArgs(m, x, NULL);
+        Py_DECREF(m);
+        return r;
+    }
+}
+
+static CYTHON_INLINE void __Pyx_RaiseClosureNameError(const char *varname);
+
+static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
+static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
+
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause); /*proto*/
+
+static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected);
+
+static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index);
+
+static CYTHON_INLINE int __Pyx_IterFinish(void); /*proto*/
+
+static int __Pyx_IternextUnpackEndCheck(PyObject *retval, Py_ssize_t expected); /*proto*/
+
+static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
+
+static CYTHON_INLINE int  __Pyx_GetBufferAndValidate(Py_buffer* buf, PyObject* obj,
+    __Pyx_TypeInfo* dtype, int flags, int nd, int cast, __Pyx_BufFmt_StackElem* stack);
+static CYTHON_INLINE void __Pyx_SafeReleaseBuffer(Py_buffer* info);
+
+static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type); /*proto*/
+
+static void __Pyx_RaiseBufferFallbackError(void); /*proto*/
+
+#define __Pyx_BufPtrStrided2d(type, buf, i0, s0, i1, s1) (type)((char*)buf + i0 * s0 + i1 * s1)
+  static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
+    const char *name, int exact); /*proto*/
+
+static void __Pyx_RaiseBufferIndexError(int axis); /*proto*/
+
+#define __Pyx_BufPtrStrided1d(type, buf, i0, s0) (type)((char*)buf + i0 * s0)
+  static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void);
+
+static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
+static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
+
+typedef struct {
+  Py_ssize_t shape, strides, suboffsets;
+} __Pyx_Buf_DimInfo;
+typedef struct {
+  size_t refcount;
+  Py_buffer pybuffer;
+} __Pyx_Buffer;
+typedef struct {
+  __Pyx_Buffer *rcbuffer;
+  char *data;
+  __Pyx_Buf_DimInfo diminfo[8];
+} __Pyx_LocalBuf_ND;
+
+#if PY_MAJOR_VERSION < 3
+    static int __Pyx_GetBuffer(PyObject *obj, Py_buffer *view, int flags);
+    static void __Pyx_ReleaseBuffer(Py_buffer *view);
+#else
+    #define __Pyx_GetBuffer PyObject_GetBuffer
+    #define __Pyx_ReleaseBuffer PyBuffer_Release
+#endif
+
+
+  static Py_ssize_t __Pyx_zeros[] = {0, 0, 0, 0, 0, 0, 0, 0};
+static Py_ssize_t __Pyx_minusones[] = {-1, -1, -1, -1, -1, -1, -1, -1};
+
+static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level); /*proto*/
+
+static CYTHON_INLINE void __Pyx_RaiseImportError(PyObject *name);
+
+#define __Pyx_CyFunction_USED 1
+#include <structmember.h>
+#define __Pyx_CYFUNCTION_STATICMETHOD  0x01
+#define __Pyx_CYFUNCTION_CLASSMETHOD   0x02
+#define __Pyx_CYFUNCTION_CCLASS        0x04
+#define __Pyx_CyFunction_GetClosure(f) \
+    (((__pyx_CyFunctionObject *) (f))->func_closure)
+#define __Pyx_CyFunction_GetClassObj(f) \
+    (((__pyx_CyFunctionObject *) (f))->func_classobj)
+#define __Pyx_CyFunction_Defaults(type, f) \
+    ((type *)(((__pyx_CyFunctionObject *) (f))->defaults))
+#define __Pyx_CyFunction_SetDefaultsGetter(f, g) \
+    ((__pyx_CyFunctionObject *) (f))->defaults_getter = (g)
+typedef struct {
+    PyCFunctionObject func;
+    int flags;
+    PyObject *func_dict;
+    PyObject *func_weakreflist;
+    PyObject *func_name;
+    PyObject *func_qualname;
+    PyObject *func_doc;
+    PyObject *func_code;
+    PyObject *func_closure;
+    PyObject *func_classobj; /* No-args super() class cell */
+    void *defaults;
+    int defaults_pyobjects;
+    PyObject *defaults_tuple; /* Const defaults tuple */
+    PyObject *(*defaults_getter)(PyObject *);
+} __pyx_CyFunctionObject;
+static PyTypeObject *__pyx_CyFunctionType = 0;
+#define __Pyx_CyFunction_NewEx(ml, flags, qualname, self, module, code) \
+    __Pyx_CyFunction_New(__pyx_CyFunctionType, ml, flags, qualname, self, module, code)
+static PyObject *__Pyx_CyFunction_New(PyTypeObject *, PyMethodDef *ml,
+                                      int flags, PyObject* qualname,
+                                      PyObject *self, PyObject *module,
+                                      PyObject* code);
+static CYTHON_INLINE void *__Pyx_CyFunction_InitDefaults(PyObject *m,
+                                                         size_t size,
+                                                         int pyobjects);
+static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsTuple(PyObject *m,
+                                                            PyObject *tuple);
+static int __Pyx_CyFunction_init(void);
+
+static CYTHON_INLINE PyObject *__Pyx_PyInt_to_py_npy_uint64(npy_uint64);
+
+#if CYTHON_CCOMPLEX
+  #ifdef __cplusplus
+    #define __Pyx_CREAL(z) ((z).real())
+    #define __Pyx_CIMAG(z) ((z).imag())
+  #else
+    #define __Pyx_CREAL(z) (__real__(z))
+    #define __Pyx_CIMAG(z) (__imag__(z))
+  #endif
+#else
+    #define __Pyx_CREAL(z) ((z).real)
+    #define __Pyx_CIMAG(z) ((z).imag)
+#endif
+#if defined(_WIN32) && defined(__cplusplus) && CYTHON_CCOMPLEX
+    #define __Pyx_SET_CREAL(z,x) ((z).real(x))
+    #define __Pyx_SET_CIMAG(z,y) ((z).imag(y))
+#else
+    #define __Pyx_SET_CREAL(z,x) __Pyx_CREAL(z) = (x)
+    #define __Pyx_SET_CIMAG(z,y) __Pyx_CIMAG(z) = (y)
+#endif
+
+static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float, float);
+
+#if CYTHON_CCOMPLEX
+    #define __Pyx_c_eqf(a, b)   ((a)==(b))
+    #define __Pyx_c_sumf(a, b)  ((a)+(b))
+    #define __Pyx_c_difff(a, b) ((a)-(b))
+    #define __Pyx_c_prodf(a, b) ((a)*(b))
+    #define __Pyx_c_quotf(a, b) ((a)/(b))
+    #define __Pyx_c_negf(a)     (-(a))
+  #ifdef __cplusplus
+    #define __Pyx_c_is_zerof(z) ((z)==(float)0)
+    #define __Pyx_c_conjf(z)    (::std::conj(z))
+    #if 1
+        #define __Pyx_c_absf(z)     (::std::abs(z))
+        #define __Pyx_c_powf(a, b)  (::std::pow(a, b))
+    #endif
+  #else
+    #define __Pyx_c_is_zerof(z) ((z)==0)
+    #define __Pyx_c_conjf(z)    (conjf(z))
+    #if 1
+        #define __Pyx_c_absf(z)     (cabsf(z))
+        #define __Pyx_c_powf(a, b)  (cpowf(a, b))
+    #endif
+ #endif
+#else
+    static CYTHON_INLINE int __Pyx_c_eqf(__pyx_t_float_complex, __pyx_t_float_complex);
+    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_sumf(__pyx_t_float_complex, __pyx_t_float_complex);
+    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_difff(__pyx_t_float_complex, __pyx_t_float_complex);
+    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_prodf(__pyx_t_float_complex, __pyx_t_float_complex);
+    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_quotf(__pyx_t_float_complex, __pyx_t_float_complex);
+    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_negf(__pyx_t_float_complex);
+    static CYTHON_INLINE int __Pyx_c_is_zerof(__pyx_t_float_complex);
+    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_conjf(__pyx_t_float_complex);
+    #if 1
+        static CYTHON_INLINE float __Pyx_c_absf(__pyx_t_float_complex);
+        static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_powf(__pyx_t_float_complex, __pyx_t_float_complex);
+    #endif
+#endif
+
+static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double, double);
+
+#if CYTHON_CCOMPLEX
+    #define __Pyx_c_eq(a, b)   ((a)==(b))
+    #define __Pyx_c_sum(a, b)  ((a)+(b))
+    #define __Pyx_c_diff(a, b) ((a)-(b))
+    #define __Pyx_c_prod(a, b) ((a)*(b))
+    #define __Pyx_c_quot(a, b) ((a)/(b))
+    #define __Pyx_c_neg(a)     (-(a))
+  #ifdef __cplusplus
+    #define __Pyx_c_is_zero(z) ((z)==(double)0)
+    #define __Pyx_c_conj(z)    (::std::conj(z))
+    #if 1
+        #define __Pyx_c_abs(z)     (::std::abs(z))
+        #define __Pyx_c_pow(a, b)  (::std::pow(a, b))
+    #endif
+  #else
+    #define __Pyx_c_is_zero(z) ((z)==0)
+    #define __Pyx_c_conj(z)    (conj(z))
+    #if 1
+        #define __Pyx_c_abs(z)     (cabs(z))
+        #define __Pyx_c_pow(a, b)  (cpow(a, b))
+    #endif
+ #endif
+#else
+    static CYTHON_INLINE int __Pyx_c_eq(__pyx_t_double_complex, __pyx_t_double_complex);
+    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_sum(__pyx_t_double_complex, __pyx_t_double_complex);
+    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_diff(__pyx_t_double_complex, __pyx_t_double_complex);
+    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_prod(__pyx_t_double_complex, __pyx_t_double_complex);
+    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_quot(__pyx_t_double_complex, __pyx_t_double_complex);
+    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_neg(__pyx_t_double_complex);
+    static CYTHON_INLINE int __Pyx_c_is_zero(__pyx_t_double_complex);
+    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_conj(__pyx_t_double_complex);
+    #if 1
+        static CYTHON_INLINE double __Pyx_c_abs(__pyx_t_double_complex);
+        static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_pow(__pyx_t_double_complex, __pyx_t_double_complex);
+    #endif
+#endif
+
+static CYTHON_INLINE unsigned char __Pyx_PyInt_AsUnsignedChar(PyObject *);
+
+static CYTHON_INLINE unsigned short __Pyx_PyInt_AsUnsignedShort(PyObject *);
+
+static CYTHON_INLINE unsigned int __Pyx_PyInt_AsUnsignedInt(PyObject *);
+
+static CYTHON_INLINE char __Pyx_PyInt_AsChar(PyObject *);
+
+static CYTHON_INLINE short __Pyx_PyInt_AsShort(PyObject *);
+
+static CYTHON_INLINE int __Pyx_PyInt_AsInt(PyObject *);
+
+static CYTHON_INLINE signed char __Pyx_PyInt_AsSignedChar(PyObject *);
+
+static CYTHON_INLINE signed short __Pyx_PyInt_AsSignedShort(PyObject *);
+
+static CYTHON_INLINE signed int __Pyx_PyInt_AsSignedInt(PyObject *);
+
+static CYTHON_INLINE int __Pyx_PyInt_AsLongDouble(PyObject *);
+
+static CYTHON_INLINE unsigned long __Pyx_PyInt_AsUnsignedLong(PyObject *);
+
+static CYTHON_INLINE unsigned PY_LONG_LONG __Pyx_PyInt_AsUnsignedLongLong(PyObject *);
+
+static CYTHON_INLINE long __Pyx_PyInt_AsLong(PyObject *);
+
+static CYTHON_INLINE PY_LONG_LONG __Pyx_PyInt_AsLongLong(PyObject *);
+
+static CYTHON_INLINE signed long __Pyx_PyInt_AsSignedLong(PyObject *);
+
+static CYTHON_INLINE signed PY_LONG_LONG __Pyx_PyInt_AsSignedLongLong(PyObject *);
+
+static int __Pyx_check_binary_version(void);
+
+#if !defined(__Pyx_PyIdentifier_FromString)
+#if PY_MAJOR_VERSION < 3
+  #define __Pyx_PyIdentifier_FromString(s) PyString_FromString(s)
+#else
+  #define __Pyx_PyIdentifier_FromString(s) PyUnicode_FromString(s)
+#endif
+#endif
+
+static PyObject *__Pyx_ImportModule(const char *name); /*proto*/
+
+static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name, size_t size, int strict);  /*proto*/
+
+typedef struct {
+    int code_line;
+    PyCodeObject* code_object;
+} __Pyx_CodeObjectCacheEntry;
+struct __Pyx_CodeObjectCache {
+    int count;
+    int max_count;
+    __Pyx_CodeObjectCacheEntry* entries;
+};
+static struct __Pyx_CodeObjectCache __pyx_code_cache = {0,0,NULL};
+static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line);
+static PyCodeObject *__pyx_find_code_object(int code_line);
+static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object);
+
+static void __Pyx_AddTraceback(const char *funcname, int c_line,
+                               int py_line, const char *filename); /*proto*/
+
+static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
+
+
+/* Module declarations from 'cpython.buffer' */
+
+/* Module declarations from 'cpython.ref' */
+
+/* Module declarations from 'libc.string' */
+
+/* Module declarations from 'libc.stdio' */
+
+/* Module declarations from 'cpython.object' */
+
+/* Module declarations from '__builtin__' */
+
+/* Module declarations from 'cpython.type' */
+static PyTypeObject *__pyx_ptype_7cpython_4type_type = 0;
+
+/* Module declarations from 'libc.stdlib' */
+
+/* Module declarations from 'numpy' */
+
+/* Module declarations from 'numpy' */
+static PyTypeObject *__pyx_ptype_5numpy_dtype = 0;
+static PyTypeObject *__pyx_ptype_5numpy_flatiter = 0;
+static PyTypeObject *__pyx_ptype_5numpy_broadcast = 0;
+static PyTypeObject *__pyx_ptype_5numpy_ndarray = 0;
+static PyTypeObject *__pyx_ptype_5numpy_ufunc = 0;
+static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *, char *, char *, int *); /*proto*/
+
+/* Module declarations from 'cython' */
+
+/* Module declarations from 'bx.align._epo' */
+static PyTypeObject *__pyx_ptype_2bx_5align_4_epo___pyx_scope_struct__rem_dash = 0;
+static CYTHON_INLINE int __pyx_f_2bx_5align_4_epo_max2(int, int); /*proto*/
+static PyArrayObject *__pyx_f_2bx_5align_4_epo_bed_union(PyArrayObject *, int __pyx_skip_dispatch); /*proto*/
+static PyArrayObject *__pyx_f_2bx_5align_4_epo_cummulative_intervals(PyArrayObject *, PyArrayObject *, int __pyx_skip_dispatch); /*proto*/
+static __Pyx_TypeInfo __Pyx_TypeInfo_nn___pyx_t_5numpy_uint64_t = { "uint64_t", NULL, sizeof(__pyx_t_5numpy_uint64_t), { 0 }, 0, IS_UNSIGNED(__pyx_t_5numpy_uint64_t) ? 'U' : 'I', IS_UNSIGNED(__pyx_t_5numpy_uint64_t), 0 };
+static __Pyx_TypeInfo __Pyx_TypeInfo_nn___pyx_t_5numpy_int64_t = { "int64_t", NULL, sizeof(__pyx_t_5numpy_int64_t), { 0 }, 0, IS_UNSIGNED(__pyx_t_5numpy_int64_t) ? 'U' : 'I', IS_UNSIGNED(__pyx_t_5numpy_int64_t), 0 };
+#define __Pyx_MODULE_NAME "bx.align._epo"
+int __pyx_module_is_main_bx__align___epo = 0;
+
+/* Implementation of 'bx.align._epo' */
+static PyObject *__pyx_builtin_sum;
+static PyObject *__pyx_builtin_map;
+static PyObject *__pyx_builtin_range;
+static PyObject *__pyx_builtin_open;
+static PyObject *__pyx_builtin_ValueError;
+static PyObject *__pyx_builtin_zip;
+static PyObject *__pyx_builtin_RuntimeError;
+static PyObject *__pyx_pf_2bx_5align_4_epo_8rem_dash_myp(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_l); /* proto */
+static PyObject *__pyx_pf_2bx_5align_4_epo_8rem_dash_2adv(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_queue, PyObject *__pyx_v_i, PyObject *__pyx_v_d); /* proto */
+static PyObject *__pyx_lambda_funcdef_lambda1(PyObject *__pyx_self, PyObject *__pyx_v_i); /* proto */
+static PyObject *__pyx_lambda_funcdef_lambda2(PyObject *__pyx_self, PyObject *__pyx_v_i); /* proto */
+static PyObject *__pyx_lambda_funcdef_lambda3(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_i); /* proto */
+static PyObject *__pyx_lambda_funcdef_lambda4(PyObject *__pyx_self, PyObject *__pyx_v_i); /* proto */
+static PyObject *__pyx_lambda_funcdef_lambda5(PyObject *__pyx_self, PyObject *__pyx_v_i); /* proto */
+static PyObject *__pyx_pf_2bx_5align_4_epo_rem_dash(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_p, PyObject *__pyx_v_q); /* proto */
+static PyObject *__pyx_pf_2bx_5align_4_epo_2fastLoadChain(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_fname, PyObject *__pyx_v_hf); /* proto */
+static PyObject *__pyx_pf_2bx_5align_4_epo_4bed_union(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_elements); /* proto */
+static PyObject *__pyx_pf_2bx_5align_4_epo_6cummulative_intervals(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_S, PyArrayObject *__pyx_v_D); /* proto */
+static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /* proto */
+static void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info); /* proto */
+static char __pyx_k_3[] = "/aut/proj/odenas/software/bx-python/lib/bx/align/_epo.pyx";
+static char __pyx_k_4[] = "rem_dash.<locals>.myp";
+static char __pyx_k_5[] = "bx.align._epo";
+static char __pyx_k_8[] = "rem_dash.<locals>.adv";
+static char __pyx_k_9[] = "rem_dash.<locals>.<lambda>";
+static char __pyx_k_10[] = "one or both should be empty: p=%s, q=%s";
+static char __pyx_k_11[] = "%d != %d";
+static char __pyx_k_12[] = ".gz";
+static char __pyx_k_14[] = "";
+static char __pyx_k_15[] = "last matching block expected (found %s)";
+static char __pyx_k_16[] = "parsed %d elements from %s";
+static char __pyx_k_18[] = "fe=%d, e=%d";
+static char __pyx_k_19[] = "ndarray is not C contiguous";
+static char __pyx_k_21[] = "ndarray is not Fortran contiguous";
+static char __pyx_k_23[] = "Non-native byte order not supported";
+static char __pyx_k_25[] = "unknown dtype code in numpy.pxd (%d)";
+static char __pyx_k_26[] = "Format string allocated too short, see comment in numpy.pxd";
+static char __pyx_k_29[] = "Format string allocated too short.";
+static char __pyx_k__B[] = "B";
+static char __pyx_k__D[] = "D";
+static char __pyx_k__H[] = "H";
+static char __pyx_k__I[] = "I";
+static char __pyx_k__L[] = "L";
+static char __pyx_k__N[] = "N";
+static char __pyx_k__O[] = "O";
+static char __pyx_k__P[] = "P";
+static char __pyx_k__Q[] = "Q";
+static char __pyx_k__R[] = "R";
+static char __pyx_k__S[] = "S";
+static char __pyx_k__a[] = "a";
+static char __pyx_k__b[] = "b";
+static char __pyx_k__d[] = "d";
+static char __pyx_k__f[] = "f";
+static char __pyx_k__g[] = "g";
+static char __pyx_k__h[] = "h";
+static char __pyx_k__i[] = "i";
+static char __pyx_k__l[] = "l";
+static char __pyx_k__p[] = "p";
+static char __pyx_k__q[] = "q";
+static char __pyx_k__r[] = "r";
+static char __pyx_k__s[] = "s";
+static char __pyx_k__t[] = "t";
+static char __pyx_k__Zd[] = "Zd";
+static char __pyx_k__Zf[] = "Zf";
+static char __pyx_k__Zg[] = "Zg";
+static char __pyx_k__fd[] = "fd";
+static char __pyx_k__hd[] = "hd";
+static char __pyx_k__hf[] = "hf";
+static char __pyx_k__adv[] = "adv";
+static char __pyx_k__int[] = "int";
+static char __pyx_k__log[] = "log";
+static char __pyx_k__map[] = "map";
+static char __pyx_k__myp[] = "myp";
+static char __pyx_k__shi[] = "shi";
+static char __pyx_k__sum[] = "sum";
+static char __pyx_k__zip[] = "zip";
+static char __pyx_k__axis[] = "axis";
+static char __pyx_k__dash[] = "dash";
+static char __pyx_k__data[] = "data";
+static char __pyx_k__gzip[] = "gzip";
+static char __pyx_k__info[] = "info";
+static char __pyx_k__line[] = "line";
+static char __pyx_k__open[] = "open";
+static char __pyx_k__qEnd[] = "qEnd";
+static char __pyx_k__sort[] = "sort";
+static char __pyx_k__tEnd[] = "tEnd";
+static char __pyx_k__DTYPE[] = "DTYPE";
+static char __pyx_k__array[] = "array";
+static char __pyx_k__dtype[] = "dtype";
+static char __pyx_k__empty[] = "empty";
+static char __pyx_k__fname[] = "fname";
+static char __pyx_k__int64[] = "int64";
+static char __pyx_k__numpy[] = "numpy";
+static char __pyx_k__queue[] = "queue";
+static char __pyx_k__range[] = "range";
+static char __pyx_k__shape[] = "shape";
+static char __pyx_k__split[] = "split";
+static char __pyx_k__zeros[] = "zeros";
+static char __pyx_k__P_card[] = "P_card";
+static char __pyx_k__Q_card[] = "Q_card";
+static char __pyx_k__open_f[] = "open_f";
+static char __pyx_k__p_card[] = "p_card";
+static char __pyx_k__qStart[] = "qStart";
+static char __pyx_k__q_card[] = "q_card";
+static char __pyx_k__tStart[] = "tStart";
+static char __pyx_k__uint64[] = "uint64";
+static char __pyx_k__logging[] = "logging";
+static char __pyx_k____exit__[] = "__exit__";
+static char __pyx_k____main__[] = "__main__";
+static char __pyx_k____name__[] = "__name__";
+static char __pyx_k____test__[] = "__test__";
+static char __pyx_k__endswith[] = "endswith";
+static char __pyx_k__readline[] = "readline";
+static char __pyx_k__rem_dash[] = "rem_dash";
+static char __pyx_k____enter__[] = "__enter__";
+static char __pyx_k__getLogger[] = "getLogger";
+static char __pyx_k__ValueError[] = "ValueError";
+static char __pyx_k__namedtuple[] = "namedtuple";
+static char __pyx_k__collections[] = "collections";
+static char __pyx_k__RuntimeError[] = "RuntimeError";
+static char __pyx_k__fastLoadChain[] = "fastLoadChain";
+static PyObject *__pyx_kp_s_10;
+static PyObject *__pyx_kp_s_11;
+static PyObject *__pyx_kp_s_12;
+static PyObject *__pyx_kp_s_14;
+static PyObject *__pyx_kp_s_15;
+static PyObject *__pyx_kp_s_16;
+static PyObject *__pyx_kp_s_18;
+static PyObject *__pyx_kp_u_19;
+static PyObject *__pyx_kp_u_21;
+static PyObject *__pyx_kp_u_23;
+static PyObject *__pyx_kp_u_25;
+static PyObject *__pyx_kp_u_26;
+static PyObject *__pyx_kp_u_29;
+static PyObject *__pyx_kp_s_3;
+static PyObject *__pyx_n_s_4;
+static PyObject *__pyx_n_s_5;
+static PyObject *__pyx_n_s_8;
+static PyObject *__pyx_n_s_9;
+static PyObject *__pyx_n_s__D;
+static PyObject *__pyx_n_s__DTYPE;
+static PyObject *__pyx_n_s__N;
+static PyObject *__pyx_n_s__P;
+static PyObject *__pyx_n_s__P_card;
+static PyObject *__pyx_n_s__Q;
+static PyObject *__pyx_n_s__Q_card;
+static PyObject *__pyx_n_s__R;
+static PyObject *__pyx_n_s__RuntimeError;
+static PyObject *__pyx_n_s__S;
+static PyObject *__pyx_n_s__ValueError;
+static PyObject *__pyx_n_s____enter__;
+static PyObject *__pyx_n_s____exit__;
+static PyObject *__pyx_n_s____main__;
+static PyObject *__pyx_n_s____name__;
+static PyObject *__pyx_n_s____test__;
+static PyObject *__pyx_n_s__a;
+static PyObject *__pyx_n_s__adv;
+static PyObject *__pyx_n_s__array;
+static PyObject *__pyx_n_s__axis;
+static PyObject *__pyx_n_s__b;
+static PyObject *__pyx_n_s__collections;
+static PyObject *__pyx_n_s__d;
+static PyObject *__pyx_n_s__dash;
+static PyObject *__pyx_n_s__data;
+static PyObject *__pyx_n_s__dtype;
+static PyObject *__pyx_n_s__empty;
+static PyObject *__pyx_n_s__endswith;
+static PyObject *__pyx_n_s__fastLoadChain;
+static PyObject *__pyx_n_s__fd;
+static PyObject *__pyx_n_s__fname;
+static PyObject *__pyx_n_s__getLogger;
+static PyObject *__pyx_n_s__gzip;
+static PyObject *__pyx_n_s__hd;
+static PyObject *__pyx_n_s__hf;
+static PyObject *__pyx_n_s__i;
+static PyObject *__pyx_n_s__info;
+static PyObject *__pyx_n_s__int;
+static PyObject *__pyx_n_s__int64;
+static PyObject *__pyx_n_s__l;
+static PyObject *__pyx_n_s__line;
+static PyObject *__pyx_n_s__log;
+static PyObject *__pyx_n_s__logging;
+static PyObject *__pyx_n_s__map;
+static PyObject *__pyx_n_s__myp;
+static PyObject *__pyx_n_s__namedtuple;
+static PyObject *__pyx_n_s__numpy;
+static PyObject *__pyx_n_s__open;
+static PyObject *__pyx_n_s__open_f;
+static PyObject *__pyx_n_s__p;
+static PyObject *__pyx_n_s__p_card;
+static PyObject *__pyx_n_s__q;
+static PyObject *__pyx_n_s__qEnd;
+static PyObject *__pyx_n_s__qStart;
+static PyObject *__pyx_n_s__q_card;
+static PyObject *__pyx_n_s__queue;
+static PyObject *__pyx_n_s__r;
+static PyObject *__pyx_n_s__range;
+static PyObject *__pyx_n_s__readline;
+static PyObject *__pyx_n_s__rem_dash;
+static PyObject *__pyx_n_s__s;
+static PyObject *__pyx_n_s__shape;
+static PyObject *__pyx_n_s__shi;
+static PyObject *__pyx_n_s__sort;
+static PyObject *__pyx_n_s__split;
+static PyObject *__pyx_n_s__sum;
+static PyObject *__pyx_n_s__t;
+static PyObject *__pyx_n_s__tEnd;
+static PyObject *__pyx_n_s__tStart;
+static PyObject *__pyx_n_s__uint64;
+static PyObject *__pyx_n_s__zeros;
+static PyObject *__pyx_n_s__zip;
+static PyObject *__pyx_int_0;
+static PyObject *__pyx_int_1;
+static PyObject *__pyx_int_2;
+static PyObject *__pyx_int_15;
+static PyObject *__pyx_k_tuple_1;
+static PyObject *__pyx_k_tuple_6;
+static PyObject *__pyx_k_tuple_13;
+static PyObject *__pyx_k_tuple_17;
+static PyObject *__pyx_k_tuple_20;
+static PyObject *__pyx_k_tuple_22;
+static PyObject *__pyx_k_tuple_24;
+static PyObject *__pyx_k_tuple_27;
+static PyObject *__pyx_k_tuple_28;
+static PyObject *__pyx_k_tuple_30;
+static PyObject *__pyx_k_tuple_31;
+static PyObject *__pyx_k_tuple_33;
+static PyObject *__pyx_k_codeobj_2;
+static PyObject *__pyx_k_codeobj_7;
+static PyObject *__pyx_k_codeobj_32;
+static PyObject *__pyx_k_codeobj_34;
+
+/* "bx/align/_epo.pyx":15
+ * 
+ * 
+ * cdef inline int max2( int a, int b ):             # <<<<<<<<<<<<<<
+ *     if b > a:
+ *         return b
+ */
+
+static CYTHON_INLINE int __pyx_f_2bx_5align_4_epo_max2(int __pyx_v_a, int __pyx_v_b) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("max2", 0);
+
+  /* "bx/align/_epo.pyx":16
+ * 
+ * cdef inline int max2( int a, int b ):
+ *     if b > a:             # <<<<<<<<<<<<<<
+ *         return b
+ *     return a
+ */
+  __pyx_t_1 = (__pyx_v_b > __pyx_v_a);
+  if (__pyx_t_1) {
+
+    /* "bx/align/_epo.pyx":17
+ * cdef inline int max2( int a, int b ):
+ *     if b > a:
+ *         return b             # <<<<<<<<<<<<<<
+ *     return a
+ * 
+ */
+    __pyx_r = __pyx_v_b;
+    goto __pyx_L0;
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  /* "bx/align/_epo.pyx":18
+ *     if b > a:
+ *         return b
+ *     return a             # <<<<<<<<<<<<<<
+ * 
+ * cdef inline int min2( int a, int b ):
+ */
+  __pyx_r = __pyx_v_a;
+  goto __pyx_L0;
+
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/align/_epo.pyx":20
+ *     return a
+ * 
+ * cdef inline int min2( int a, int b ):             # <<<<<<<<<<<<<<
+ *     if b < a:
+ *         return b
+ */
+
+static CYTHON_INLINE int __pyx_f_2bx_5align_4_epo_min2(int __pyx_v_a, int __pyx_v_b) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("min2", 0);
+
+  /* "bx/align/_epo.pyx":21
+ * 
+ * cdef inline int min2( int a, int b ):
+ *     if b < a:             # <<<<<<<<<<<<<<
+ *         return b
+ *     return a
+ */
+  __pyx_t_1 = (__pyx_v_b < __pyx_v_a);
+  if (__pyx_t_1) {
+
+    /* "bx/align/_epo.pyx":22
+ * cdef inline int min2( int a, int b ):
+ *     if b < a:
+ *         return b             # <<<<<<<<<<<<<<
+ *     return a
+ * 
+ */
+    __pyx_r = __pyx_v_b;
+    goto __pyx_L0;
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  /* "bx/align/_epo.pyx":23
+ *     if b < a:
+ *         return b
+ *     return a             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+  __pyx_r = __pyx_v_a;
+  goto __pyx_L0;
+
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_5align_4_epo_1rem_dash(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_2bx_5align_4_epo_rem_dash[] = "remove dash columns and shift match intervals to the left. both iterables\n    are read on the same direction left-to-right.\n    ";
+static PyMethodDef __pyx_mdef_2bx_5align_4_epo_1rem_dash = {__Pyx_NAMESTR("rem_dash"), (PyCFunction)__pyx_pw_2bx_5align_4_epo_1rem_dash, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(__pyx_doc_2bx_5align_4_epo_rem_dash)};
+static PyObject *__pyx_pw_2bx_5align_4_epo_1rem_dash(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_p = 0;
+  PyObject *__pyx_v_q = 0;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("rem_dash (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__p,&__pyx_n_s__q,0};
+    PyObject* values[2] = {0,0};
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__p)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__q)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("rem_dash", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 26; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "rem_dash") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 26; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
+      goto __pyx_L5_argtuple_error;
+    } else {
+      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+    }
+    __pyx_v_p = values[0];
+    __pyx_v_q = values[1];
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("rem_dash", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 26; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.align._epo.rem_dash", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_5align_4_epo_rem_dash(__pyx_self, __pyx_v_p, __pyx_v_q);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_5align_4_epo_8rem_dash_1myp(PyObject *__pyx_self, PyObject *__pyx_v_l); /*proto*/
+static PyMethodDef __pyx_mdef_2bx_5align_4_epo_8rem_dash_1myp = {__Pyx_NAMESTR("myp"), (PyCFunction)__pyx_pw_2bx_5align_4_epo_8rem_dash_1myp, METH_O, __Pyx_DOCSTR(0)};
+static PyObject *__pyx_pw_2bx_5align_4_epo_8rem_dash_1myp(PyObject *__pyx_self, PyObject *__pyx_v_l) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("myp (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_5align_4_epo_8rem_dash_myp(__pyx_self, ((PyObject *)__pyx_v_l));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/align/_epo.pyx":31
+ *     """
+ * 
+ *     def myp(l):             # <<<<<<<<<<<<<<
+ *         if l: return l.pop(0)
+ * 
+ */
+
+static PyObject *__pyx_pf_2bx_5align_4_epo_8rem_dash_myp(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_l) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("myp", 0);
+
+  /* "bx/align/_epo.pyx":32
+ * 
+ *     def myp(l):
+ *         if l: return l.pop(0)             # <<<<<<<<<<<<<<
+ * 
+ *     def adv(queue, i, d):
+ */
+  __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_v_l); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 32; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (__pyx_t_1) {
+    __Pyx_XDECREF(__pyx_r);
+    __pyx_t_2 = __Pyx_PyObject_PopIndex(__pyx_v_l, 0); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 32; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_r = __pyx_t_2;
+    __pyx_t_2 = 0;
+    goto __pyx_L0;
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_AddTraceback("bx.align._epo.rem_dash.myp", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_5align_4_epo_8rem_dash_3adv(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_mdef_2bx_5align_4_epo_8rem_dash_3adv = {__Pyx_NAMESTR("adv"), (PyCFunction)__pyx_pw_2bx_5align_4_epo_8rem_dash_3adv, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(0)};
+static PyObject *__pyx_pw_2bx_5align_4_epo_8rem_dash_3adv(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_queue = 0;
+  PyObject *__pyx_v_i = 0;
+  PyObject *__pyx_v_d = 0;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("adv (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__queue,&__pyx_n_s__i,&__pyx_n_s__d,0};
+    PyObject* values[3] = {0,0,0};
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__queue)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__i)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("adv", 1, 3, 3, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 34; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+        case  2:
+        if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__d)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("adv", 1, 3, 3, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 34; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "adv") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 34; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else if (PyTuple_GET_SIZE(__pyx_args) != 3) {
+      goto __pyx_L5_argtuple_error;
+    } else {
+      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+      values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+    }
+    __pyx_v_queue = values[0];
+    __pyx_v_i = values[1];
+    __pyx_v_d = values[2];
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("adv", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 34; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.align._epo.rem_dash.adv", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_5align_4_epo_8rem_dash_2adv(__pyx_self, __pyx_v_queue, __pyx_v_i, __pyx_v_d);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/align/_epo.pyx":34
+ *         if l: return l.pop(0)
+ * 
+ *     def adv(queue, i, d):             # <<<<<<<<<<<<<<
+ *         # shifted interval
+ *         shi = i[0]-d, i[1]-d
+ */
+
+static PyObject *__pyx_pf_2bx_5align_4_epo_8rem_dash_2adv(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_queue, PyObject *__pyx_v_i, PyObject *__pyx_v_d) {
+  PyObject *__pyx_v_shi = NULL;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  int __pyx_t_4;
+  int __pyx_t_5;
+  int __pyx_t_6;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("adv", 0);
+
+  /* "bx/align/_epo.pyx":36
+ *     def adv(queue, i, d):
+ *         # shifted interval
+ *         shi = i[0]-d, i[1]-d             # <<<<<<<<<<<<<<
+ *         assert shi[0] >= 0
+ *         if queue and queue[-1][1] == shi[0]:
+ */
+  __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_i, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 36; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = PyNumber_Subtract(__pyx_t_1, __pyx_v_d); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 36; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_i, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 36; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_3 = PyNumber_Subtract(__pyx_t_1, __pyx_v_d); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 36; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 36; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_2);
+  __Pyx_GIVEREF(__pyx_t_2);
+  PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_t_3);
+  __Pyx_GIVEREF(__pyx_t_3);
+  __pyx_t_2 = 0;
+  __pyx_t_3 = 0;
+  __pyx_v_shi = ((PyObject*)__pyx_t_1);
+  __pyx_t_1 = 0;
+
+  /* "bx/align/_epo.pyx":37
+ *         # shifted interval
+ *         shi = i[0]-d, i[1]-d
+ *         assert shi[0] >= 0             # <<<<<<<<<<<<<<
+ *         if queue and queue[-1][1] == shi[0]:
+ *             # join to the preceeding one
+ */
+  #ifndef CYTHON_WITHOUT_ASSERTIONS
+  __pyx_t_1 = __Pyx_GetItemInt_Tuple(((PyObject *)__pyx_v_shi), 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 37; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_3 = PyObject_RichCompare(__pyx_t_1, __pyx_int_0, Py_GE); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 37; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 37; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  if (unlikely(!__pyx_t_4)) {
+    PyErr_SetNone(PyExc_AssertionError);
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 37; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  #endif
+
+  /* "bx/align/_epo.pyx":38
+ *         shi = i[0]-d, i[1]-d
+ *         assert shi[0] >= 0
+ *         if queue and queue[-1][1] == shi[0]:             # <<<<<<<<<<<<<<
+ *             # join to the preceeding one
+ *             queue[-1] = (queue[-1][0], shi[1])
+ */
+  __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_v_queue); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 38; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (__pyx_t_4) {
+    __pyx_t_3 = __Pyx_GetItemInt(__pyx_v_queue, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 38; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __pyx_t_1 = __Pyx_GetItemInt(__pyx_t_3, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 38; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __pyx_t_3 = __Pyx_GetItemInt_Tuple(((PyObject *)__pyx_v_shi), 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 38; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __pyx_t_2 = PyObject_RichCompare(__pyx_t_1, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 38; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 38; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    __pyx_t_6 = __pyx_t_5;
+  } else {
+    __pyx_t_6 = __pyx_t_4;
+  }
+  if (__pyx_t_6) {
+
+    /* "bx/align/_epo.pyx":40
+ *         if queue and queue[-1][1] == shi[0]:
+ *             # join to the preceeding one
+ *             queue[-1] = (queue[-1][0], shi[1])             # <<<<<<<<<<<<<<
+ *         else:
+ *             queue.append( shi )
+ */
+    __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_queue, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 40; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_t_3 = __Pyx_GetItemInt(__pyx_t_2, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 40; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    __pyx_t_2 = __Pyx_GetItemInt_Tuple(((PyObject *)__pyx_v_shi), 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 40; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 40; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_3);
+    __Pyx_GIVEREF(__pyx_t_3);
+    PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_t_2);
+    __Pyx_GIVEREF(__pyx_t_2);
+    __pyx_t_3 = 0;
+    __pyx_t_2 = 0;
+    if (__Pyx_SetItemInt(__pyx_v_queue, -1, ((PyObject *)__pyx_t_1), sizeof(long), PyInt_FromLong) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 40; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+    goto __pyx_L3;
+  }
+  /*else*/ {
+
+    /* "bx/align/_epo.pyx":42
+ *             queue[-1] = (queue[-1][0], shi[1])
+ *         else:
+ *             queue.append( shi )             # <<<<<<<<<<<<<<
+ *         return queue
+ * 
+ */
+    __pyx_t_1 = __Pyx_PyObject_Append(__pyx_v_queue, ((PyObject *)__pyx_v_shi)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 42; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  }
+  __pyx_L3:;
+
+  /* "bx/align/_epo.pyx":43
+ *         else:
+ *             queue.append( shi )
+ *         return queue             # <<<<<<<<<<<<<<
+ * 
+ *     p_card = sum( map(lambda i: p[i][1] - p[i][0], range(len(p))) )
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __Pyx_INCREF(__pyx_v_queue);
+  __pyx_r = __pyx_v_queue;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_AddTraceback("bx.align._epo.rem_dash.adv", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_shi);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_5align_4_epo_8rem_dash_4lambda1(PyObject *__pyx_self, PyObject *__pyx_v_i); /*proto*/
+static PyMethodDef __pyx_mdef_2bx_5align_4_epo_8rem_dash_4lambda1 = {__Pyx_NAMESTR("lambda1"), (PyCFunction)__pyx_pw_2bx_5align_4_epo_8rem_dash_4lambda1, METH_O, __Pyx_DOCSTR(0)};
+static PyObject *__pyx_pw_2bx_5align_4_epo_8rem_dash_4lambda1(PyObject *__pyx_self, PyObject *__pyx_v_i) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("lambda1 (wrapper)", 0);
+  __pyx_r = __pyx_lambda_funcdef_lambda1(__pyx_self, ((PyObject *)__pyx_v_i));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/align/_epo.pyx":45
+ *         return queue
+ * 
+ *     p_card = sum( map(lambda i: p[i][1] - p[i][0], range(len(p))) )             # <<<<<<<<<<<<<<
+ *     q_card = sum( map(lambda i: q[i][1] - q[i][0], range(len(q))) )
+ * 
+ */
+
+static PyObject *__pyx_lambda_funcdef_lambda1(PyObject *__pyx_self, PyObject *__pyx_v_i) {
+  struct __pyx_obj_2bx_5align_4_epo___pyx_scope_struct__rem_dash *__pyx_cur_scope;
+  struct __pyx_obj_2bx_5align_4_epo___pyx_scope_struct__rem_dash *__pyx_outer_scope;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("lambda1", 0);
+  __pyx_outer_scope = (struct __pyx_obj_2bx_5align_4_epo___pyx_scope_struct__rem_dash *) __Pyx_CyFunction_GetClosure(__pyx_self);
+  __pyx_cur_scope = __pyx_outer_scope;
+  __Pyx_XDECREF(__pyx_r);
+  if (unlikely(!__pyx_cur_scope->__pyx_v_p)) { __Pyx_RaiseClosureNameError("p"); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 45; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+  __pyx_t_1 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_p, __pyx_v_i); if (!__pyx_t_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 45; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_1, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 45; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_1 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_p, __pyx_v_i); if (!__pyx_t_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 45; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_3 = __Pyx_GetItemInt(__pyx_t_1, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 45; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_1 = PyNumber_Subtract(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 45; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_AddTraceback("bx.align._epo.rem_dash.lambda1", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_5align_4_epo_8rem_dash_5lambda2(PyObject *__pyx_self, PyObject *__pyx_v_i); /*proto*/
+static PyMethodDef __pyx_mdef_2bx_5align_4_epo_8rem_dash_5lambda2 = {__Pyx_NAMESTR("lambda2"), (PyCFunction)__pyx_pw_2bx_5align_4_epo_8rem_dash_5lambda2, METH_O, __Pyx_DOCSTR(0)};
+static PyObject *__pyx_pw_2bx_5align_4_epo_8rem_dash_5lambda2(PyObject *__pyx_self, PyObject *__pyx_v_i) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("lambda2 (wrapper)", 0);
+  __pyx_r = __pyx_lambda_funcdef_lambda2(__pyx_self, ((PyObject *)__pyx_v_i));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/align/_epo.pyx":46
+ * 
+ *     p_card = sum( map(lambda i: p[i][1] - p[i][0], range(len(p))) )
+ *     q_card = sum( map(lambda i: q[i][1] - q[i][0], range(len(q))) )             # <<<<<<<<<<<<<<
+ * 
+ *     P, Q = [], []
+ */
+
+static PyObject *__pyx_lambda_funcdef_lambda2(PyObject *__pyx_self, PyObject *__pyx_v_i) {
+  struct __pyx_obj_2bx_5align_4_epo___pyx_scope_struct__rem_dash *__pyx_cur_scope;
+  struct __pyx_obj_2bx_5align_4_epo___pyx_scope_struct__rem_dash *__pyx_outer_scope;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("lambda2", 0);
+  __pyx_outer_scope = (struct __pyx_obj_2bx_5align_4_epo___pyx_scope_struct__rem_dash *) __Pyx_CyFunction_GetClosure(__pyx_self);
+  __pyx_cur_scope = __pyx_outer_scope;
+  __Pyx_XDECREF(__pyx_r);
+  if (unlikely(!__pyx_cur_scope->__pyx_v_q)) { __Pyx_RaiseClosureNameError("q"); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 46; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+  __pyx_t_1 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_q, __pyx_v_i); if (!__pyx_t_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 46; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_1, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 46; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_1 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_q, __pyx_v_i); if (!__pyx_t_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 46; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_3 = __Pyx_GetItemInt(__pyx_t_1, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 46; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_1 = PyNumber_Subtract(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 46; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_AddTraceback("bx.align._epo.rem_dash.lambda2", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_5align_4_epo_8rem_dash_6lambda3(PyObject *__pyx_self, PyObject *__pyx_v_i); /*proto*/
+static PyMethodDef __pyx_mdef_2bx_5align_4_epo_8rem_dash_6lambda3 = {__Pyx_NAMESTR("lambda3"), (PyCFunction)__pyx_pw_2bx_5align_4_epo_8rem_dash_6lambda3, METH_O, __Pyx_DOCSTR(0)};
+static PyObject *__pyx_pw_2bx_5align_4_epo_8rem_dash_6lambda3(PyObject *__pyx_self, PyObject *__pyx_v_i) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("lambda3 (wrapper)", 0);
+  __pyx_r = __pyx_lambda_funcdef_lambda3(__pyx_self, ((PyObject *)__pyx_v_i));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/align/_epo.pyx":83
+ *     if q: r, R = q, Q
+ *     # just extend the last inteval by the remaining bases
+ *     R[-1] = (R[-1][0], R[-1][1] + sum( map(lambda i: i[1]-i[0], r) ))             # <<<<<<<<<<<<<<
+ * 
+ *     P_card = sum( map(lambda i: P[i][1] - P[i][0], range(len(P))) )
+ */
+
+static PyObject *__pyx_lambda_funcdef_lambda3(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_i) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("lambda3", 0);
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_i, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 83; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_i, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 83; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = PyNumber_Subtract(__pyx_t_1, __pyx_t_2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 83; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_r = __pyx_t_3;
+  __pyx_t_3 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_AddTraceback("bx.align._epo.rem_dash.lambda3", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_5align_4_epo_8rem_dash_7lambda4(PyObject *__pyx_self, PyObject *__pyx_v_i); /*proto*/
+static PyMethodDef __pyx_mdef_2bx_5align_4_epo_8rem_dash_7lambda4 = {__Pyx_NAMESTR("lambda4"), (PyCFunction)__pyx_pw_2bx_5align_4_epo_8rem_dash_7lambda4, METH_O, __Pyx_DOCSTR(0)};
+static PyObject *__pyx_pw_2bx_5align_4_epo_8rem_dash_7lambda4(PyObject *__pyx_self, PyObject *__pyx_v_i) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("lambda4 (wrapper)", 0);
+  __pyx_r = __pyx_lambda_funcdef_lambda4(__pyx_self, ((PyObject *)__pyx_v_i));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/align/_epo.pyx":85
+ *     R[-1] = (R[-1][0], R[-1][1] + sum( map(lambda i: i[1]-i[0], r) ))
+ * 
+ *     P_card = sum( map(lambda i: P[i][1] - P[i][0], range(len(P))) )             # <<<<<<<<<<<<<<
+ *     Q_card = sum( map(lambda i: Q[i][1] - Q[i][0], range(len(Q))) )
+ * 
+ */
+
+static PyObject *__pyx_lambda_funcdef_lambda4(PyObject *__pyx_self, PyObject *__pyx_v_i) {
+  struct __pyx_obj_2bx_5align_4_epo___pyx_scope_struct__rem_dash *__pyx_cur_scope;
+  struct __pyx_obj_2bx_5align_4_epo___pyx_scope_struct__rem_dash *__pyx_outer_scope;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("lambda4", 0);
+  __pyx_outer_scope = (struct __pyx_obj_2bx_5align_4_epo___pyx_scope_struct__rem_dash *) __Pyx_CyFunction_GetClosure(__pyx_self);
+  __pyx_cur_scope = __pyx_outer_scope;
+  __Pyx_XDECREF(__pyx_r);
+  if (unlikely(!__pyx_cur_scope->__pyx_v_P)) { __Pyx_RaiseClosureNameError("P"); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 85; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+  __pyx_t_1 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_P, __pyx_v_i); if (!__pyx_t_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 85; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_1, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 85; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_1 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_P, __pyx_v_i); if (!__pyx_t_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 85; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_3 = __Pyx_GetItemInt(__pyx_t_1, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 85; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_1 = PyNumber_Subtract(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 85; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_AddTraceback("bx.align._epo.rem_dash.lambda4", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_5align_4_epo_8rem_dash_8lambda5(PyObject *__pyx_self, PyObject *__pyx_v_i); /*proto*/
+static PyMethodDef __pyx_mdef_2bx_5align_4_epo_8rem_dash_8lambda5 = {__Pyx_NAMESTR("lambda5"), (PyCFunction)__pyx_pw_2bx_5align_4_epo_8rem_dash_8lambda5, METH_O, __Pyx_DOCSTR(0)};
+static PyObject *__pyx_pw_2bx_5align_4_epo_8rem_dash_8lambda5(PyObject *__pyx_self, PyObject *__pyx_v_i) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("lambda5 (wrapper)", 0);
+  __pyx_r = __pyx_lambda_funcdef_lambda5(__pyx_self, ((PyObject *)__pyx_v_i));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/align/_epo.pyx":86
+ * 
+ *     P_card = sum( map(lambda i: P[i][1] - P[i][0], range(len(P))) )
+ *     Q_card = sum( map(lambda i: Q[i][1] - Q[i][0], range(len(Q))) )             # <<<<<<<<<<<<<<
+ * 
+ *     assert p_card == P_card, "%d != %d" % (p_card, P_card)
+ */
+
+static PyObject *__pyx_lambda_funcdef_lambda5(PyObject *__pyx_self, PyObject *__pyx_v_i) {
+  struct __pyx_obj_2bx_5align_4_epo___pyx_scope_struct__rem_dash *__pyx_cur_scope;
+  struct __pyx_obj_2bx_5align_4_epo___pyx_scope_struct__rem_dash *__pyx_outer_scope;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("lambda5", 0);
+  __pyx_outer_scope = (struct __pyx_obj_2bx_5align_4_epo___pyx_scope_struct__rem_dash *) __Pyx_CyFunction_GetClosure(__pyx_self);
+  __pyx_cur_scope = __pyx_outer_scope;
+  __Pyx_XDECREF(__pyx_r);
+  if (unlikely(!__pyx_cur_scope->__pyx_v_Q)) { __Pyx_RaiseClosureNameError("Q"); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 86; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+  __pyx_t_1 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_Q, __pyx_v_i); if (!__pyx_t_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 86; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_1, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 86; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_1 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_Q, __pyx_v_i); if (!__pyx_t_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 86; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_3 = __Pyx_GetItemInt(__pyx_t_1, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 86; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_1 = PyNumber_Subtract(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 86; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_AddTraceback("bx.align._epo.rem_dash.lambda5", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/align/_epo.pyx":26
+ * 
+ * 
+ * def rem_dash(p, q):             # <<<<<<<<<<<<<<
+ *     """remove dash columns and shift match intervals to the left. both iterables
+ *     are read on the same direction left-to-right.
+ */
+
+static PyObject *__pyx_pf_2bx_5align_4_epo_rem_dash(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_p, PyObject *__pyx_v_q) {
+  struct __pyx_obj_2bx_5align_4_epo___pyx_scope_struct__rem_dash *__pyx_cur_scope;
+  PyObject *__pyx_v_myp = 0;
+  PyObject *__pyx_v_adv = 0;
+  PyObject *__pyx_v_p_card = NULL;
+  PyObject *__pyx_v_q_card = NULL;
+  PyObject *__pyx_v_dash = NULL;
+  PyObject *__pyx_v_a = NULL;
+  PyObject *__pyx_v_b = NULL;
+  PyObject *__pyx_v_i = NULL;
+  PyObject *__pyx_v_r = NULL;
+  PyObject *__pyx_v_R = NULL;
+  PyObject *__pyx_v_P_card = NULL;
+  PyObject *__pyx_v_Q_card = NULL;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  Py_ssize_t __pyx_t_3;
+  PyObject *__pyx_t_4 = NULL;
+  int __pyx_t_5;
+  int __pyx_t_6;
+  int __pyx_t_7;
+  PyObject *__pyx_t_8 = NULL;
+  PyObject *__pyx_t_9 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("rem_dash", 0);
+  __pyx_cur_scope = (struct __pyx_obj_2bx_5align_4_epo___pyx_scope_struct__rem_dash *)__pyx_ptype_2bx_5align_4_epo___pyx_scope_struct__rem_dash->tp_new(__pyx_ptype_2bx_5align_4_epo___pyx_scope_struct__rem_dash, __pyx_empty_tuple, NULL);
+  if (unlikely(!__pyx_cur_scope)) {
+    __Pyx_RefNannyFinishContext();
+    return NULL;
+  }
+  __Pyx_GOTREF(__pyx_cur_scope);
+  __pyx_cur_scope->__pyx_v_p = __pyx_v_p;
+  __Pyx_INCREF(__pyx_cur_scope->__pyx_v_p);
+  __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_p);
+  __pyx_cur_scope->__pyx_v_q = __pyx_v_q;
+  __Pyx_INCREF(__pyx_cur_scope->__pyx_v_q);
+  __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_q);
+
+  /* "bx/align/_epo.pyx":31
+ *     """
+ * 
+ *     def myp(l):             # <<<<<<<<<<<<<<
+ *         if l: return l.pop(0)
+ * 
+ */
+  __pyx_t_1 = __Pyx_CyFunction_NewEx(&__pyx_mdef_2bx_5align_4_epo_8rem_dash_1myp, 0, __pyx_n_s_4, NULL, __pyx_n_s_5, ((PyObject *)__pyx_k_codeobj_2)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 31; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_v_myp = __pyx_t_1;
+  __pyx_t_1 = 0;
+
+  /* "bx/align/_epo.pyx":34
+ *         if l: return l.pop(0)
+ * 
+ *     def adv(queue, i, d):             # <<<<<<<<<<<<<<
+ *         # shifted interval
+ *         shi = i[0]-d, i[1]-d
+ */
+  __pyx_t_1 = __Pyx_CyFunction_NewEx(&__pyx_mdef_2bx_5align_4_epo_8rem_dash_3adv, 0, __pyx_n_s_8, NULL, __pyx_n_s_5, ((PyObject *)__pyx_k_codeobj_7)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 34; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_v_adv = __pyx_t_1;
+  __pyx_t_1 = 0;
+
+  /* "bx/align/_epo.pyx":45
+ *         return queue
+ * 
+ *     p_card = sum( map(lambda i: p[i][1] - p[i][0], range(len(p))) )             # <<<<<<<<<<<<<<
+ *     q_card = sum( map(lambda i: q[i][1] - q[i][0], range(len(q))) )
+ * 
+ */
+  __pyx_t_1 = __Pyx_CyFunction_NewEx(&__pyx_mdef_2bx_5align_4_epo_8rem_dash_4lambda1, 0, __pyx_n_s_9, ((PyObject*)__pyx_cur_scope), __pyx_n_s_5, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 45; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = __pyx_cur_scope->__pyx_v_p;
+  __Pyx_INCREF(__pyx_t_2);
+  __pyx_t_3 = PyObject_Length(__pyx_t_2); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 45; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_2 = PyInt_FromSsize_t(__pyx_t_3); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 45; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 45; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_2);
+  __Pyx_GIVEREF(__pyx_t_2);
+  __pyx_t_2 = 0;
+  __pyx_t_2 = PyObject_Call(__pyx_builtin_range, ((PyObject *)__pyx_t_4), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 45; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
+  __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 45; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_1);
+  __Pyx_GIVEREF(__pyx_t_1);
+  PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_2);
+  __Pyx_GIVEREF(__pyx_t_2);
+  __pyx_t_1 = 0;
+  __pyx_t_2 = 0;
+  __pyx_t_2 = PyObject_Call(__pyx_builtin_map, ((PyObject *)__pyx_t_4), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 45; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
+  __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 45; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_2);
+  __Pyx_GIVEREF(__pyx_t_2);
+  __pyx_t_2 = 0;
+  __pyx_t_2 = PyObject_Call(__pyx_builtin_sum, ((PyObject *)__pyx_t_4), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 45; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
+  __pyx_v_p_card = __pyx_t_2;
+  __pyx_t_2 = 0;
+
+  /* "bx/align/_epo.pyx":46
+ * 
+ *     p_card = sum( map(lambda i: p[i][1] - p[i][0], range(len(p))) )
+ *     q_card = sum( map(lambda i: q[i][1] - q[i][0], range(len(q))) )             # <<<<<<<<<<<<<<
+ * 
+ *     P, Q = [], []
+ */
+  __pyx_t_2 = __Pyx_CyFunction_NewEx(&__pyx_mdef_2bx_5align_4_epo_8rem_dash_5lambda2, 0, __pyx_n_s_9, ((PyObject*)__pyx_cur_scope), __pyx_n_s_5, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 46; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_4 = __pyx_cur_scope->__pyx_v_q;
+  __Pyx_INCREF(__pyx_t_4);
+  __pyx_t_3 = PyObject_Length(__pyx_t_4); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 46; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  __pyx_t_4 = PyInt_FromSsize_t(__pyx_t_3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 46; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 46; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_4);
+  __Pyx_GIVEREF(__pyx_t_4);
+  __pyx_t_4 = 0;
+  __pyx_t_4 = PyObject_Call(__pyx_builtin_range, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 46; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+  __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 46; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_2);
+  __Pyx_GIVEREF(__pyx_t_2);
+  PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_t_4);
+  __Pyx_GIVEREF(__pyx_t_4);
+  __pyx_t_2 = 0;
+  __pyx_t_4 = 0;
+  __pyx_t_4 = PyObject_Call(__pyx_builtin_map, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 46; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 46; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_4);
+  __Pyx_GIVEREF(__pyx_t_4);
+  __pyx_t_4 = 0;
+  __pyx_t_4 = PyObject_Call(__pyx_builtin_sum, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 46; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+  __pyx_v_q_card = __pyx_t_4;
+  __pyx_t_4 = 0;
+
+  /* "bx/align/_epo.pyx":48
+ *     q_card = sum( map(lambda i: q[i][1] - q[i][0], range(len(q))) )
+ * 
+ *     P, Q = [], []             # <<<<<<<<<<<<<<
+ *     dash = 0 # dash (on both cigars) count so far
+ *     a, b = p.pop(0), q.pop(0)
+ */
+  __pyx_t_4 = PyList_New(0); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 48; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 48; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_GIVEREF(((PyObject *)__pyx_t_4));
+  __pyx_cur_scope->__pyx_v_P = ((PyObject *)__pyx_t_4);
+  __pyx_t_4 = 0;
+  __Pyx_GIVEREF(((PyObject *)__pyx_t_1));
+  __pyx_cur_scope->__pyx_v_Q = ((PyObject *)__pyx_t_1);
+  __pyx_t_1 = 0;
+
+  /* "bx/align/_epo.pyx":49
+ * 
+ *     P, Q = [], []
+ *     dash = 0 # dash (on both cigars) count so far             # <<<<<<<<<<<<<<
+ *     a, b = p.pop(0), q.pop(0)
+ *     #while p or q:
+ */
+  __Pyx_INCREF(__pyx_int_0);
+  __pyx_v_dash = __pyx_int_0;
+
+  /* "bx/align/_epo.pyx":50
+ *     P, Q = [], []
+ *     dash = 0 # dash (on both cigars) count so far
+ *     a, b = p.pop(0), q.pop(0)             # <<<<<<<<<<<<<<
+ *     #while p or q:
+ *     while a and b:
+ */
+  __pyx_t_1 = __Pyx_PyObject_PopIndex(__pyx_cur_scope->__pyx_v_p, 0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 50; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_4 = __Pyx_PyObject_PopIndex(__pyx_cur_scope->__pyx_v_q, 0); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 50; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __pyx_v_a = __pyx_t_1;
+  __pyx_t_1 = 0;
+  __pyx_v_b = __pyx_t_4;
+  __pyx_t_4 = 0;
+
+  /* "bx/align/_epo.pyx":52
+ *     a, b = p.pop(0), q.pop(0)
+ *     #while p or q:
+ *     while a and b:             # <<<<<<<<<<<<<<
+ *         assert dash <= min(a[0], b[0])
+ *         i = max(a[0], b[0]) - min(a[1], b[1])
+ */
+  while (1) {
+    __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_v_a); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 52; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (__pyx_t_5) {
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_v_b); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 52; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_7 = __pyx_t_6;
+    } else {
+      __pyx_t_7 = __pyx_t_5;
+    }
+    if (!__pyx_t_7) break;
+
+    /* "bx/align/_epo.pyx":53
+ *     #while p or q:
+ *     while a and b:
+ *         assert dash <= min(a[0], b[0])             # <<<<<<<<<<<<<<
+ *         i = max(a[0], b[0]) - min(a[1], b[1])
+ *         if i >= 0: # no intersection
+ */
+    #ifndef CYTHON_WITHOUT_ASSERTIONS
+    __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_b, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 53; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_a, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 53; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __pyx_t_8 = PyObject_RichCompare(__pyx_t_4, __pyx_t_1, Py_LT); __Pyx_XGOTREF(__pyx_t_8); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 53; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_8); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 53; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+    if (__pyx_t_7) {
+      __Pyx_INCREF(__pyx_t_4);
+      __pyx_t_2 = __pyx_t_4;
+    } else {
+      __Pyx_INCREF(__pyx_t_1);
+      __pyx_t_2 = __pyx_t_1;
+    }
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    __pyx_t_4 = PyObject_RichCompare(__pyx_v_dash, __pyx_t_2, Py_LE); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 53; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 53; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    if (unlikely(!__pyx_t_7)) {
+      PyErr_SetNone(PyExc_AssertionError);
+      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 53; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+    #endif
+
+    /* "bx/align/_epo.pyx":54
+ *     while a and b:
+ *         assert dash <= min(a[0], b[0])
+ *         i = max(a[0], b[0]) - min(a[1], b[1])             # <<<<<<<<<<<<<<
+ *         if i >= 0: # no intersection
+ *             if a[1] <= b[0]:
+ */
+    __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_b, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 54; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_a, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 54; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_t_8 = PyObject_RichCompare(__pyx_t_4, __pyx_t_2, Py_GT); __Pyx_XGOTREF(__pyx_t_8); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 54; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_8); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 54; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+    if (__pyx_t_7) {
+      __Pyx_INCREF(__pyx_t_4);
+      __pyx_t_1 = __pyx_t_4;
+    } else {
+      __Pyx_INCREF(__pyx_t_2);
+      __pyx_t_1 = __pyx_t_2;
+    }
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_b, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 54; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_a, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 54; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_t_9 = PyObject_RichCompare(__pyx_t_4, __pyx_t_2, Py_LT); __Pyx_XGOTREF(__pyx_t_9); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 54; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_9); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 54; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+    if (__pyx_t_7) {
+      __Pyx_INCREF(__pyx_t_4);
+      __pyx_t_8 = __pyx_t_4;
+    } else {
+      __Pyx_INCREF(__pyx_t_2);
+      __pyx_t_8 = __pyx_t_2;
+    }
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    __pyx_t_4 = PyNumber_Subtract(__pyx_t_1, __pyx_t_8); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 54; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+    __Pyx_XDECREF(__pyx_v_i);
+    __pyx_v_i = __pyx_t_4;
+    __pyx_t_4 = 0;
+
+    /* "bx/align/_epo.pyx":55
+ *         assert dash <= min(a[0], b[0])
+ *         i = max(a[0], b[0]) - min(a[1], b[1])
+ *         if i >= 0: # no intersection             # <<<<<<<<<<<<<<
+ *             if a[1] <= b[0]:
+ *                 if p:
+ */
+    __pyx_t_4 = PyObject_RichCompare(__pyx_v_i, __pyx_int_0, Py_GE); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 55; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 55; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    if (__pyx_t_7) {
+
+      /* "bx/align/_epo.pyx":56
+ *         i = max(a[0], b[0]) - min(a[1], b[1])
+ *         if i >= 0: # no intersection
+ *             if a[1] <= b[0]:             # <<<<<<<<<<<<<<
+ *                 if p:
+ *                     i = min(i, p[0][0] - a[1])
+ */
+      __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_a, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 56; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __pyx_t_8 = __Pyx_GetItemInt(__pyx_v_b, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_8) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 56; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_8);
+      __pyx_t_1 = PyObject_RichCompare(__pyx_t_4, __pyx_t_8, Py_LE); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 56; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+      __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 56; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+      if (__pyx_t_7) {
+
+        /* "bx/align/_epo.pyx":57
+ *         if i >= 0: # no intersection
+ *             if a[1] <= b[0]:
+ *                 if p:             # <<<<<<<<<<<<<<
+ *                     i = min(i, p[0][0] - a[1])
+ *                 P = adv(P, a, dash)
+ */
+        __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_cur_scope->__pyx_v_p); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 57; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        if (__pyx_t_7) {
+
+          /* "bx/align/_epo.pyx":58
+ *             if a[1] <= b[0]:
+ *                 if p:
+ *                     i = min(i, p[0][0] - a[1])             # <<<<<<<<<<<<<<
+ *                 P = adv(P, a, dash)
+ *                 a = myp(p)
+ */
+          __pyx_t_1 = __Pyx_GetItemInt(__pyx_cur_scope->__pyx_v_p, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 58; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __Pyx_GOTREF(__pyx_t_1);
+          __pyx_t_8 = __Pyx_GetItemInt(__pyx_t_1, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_8) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 58; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __Pyx_GOTREF(__pyx_t_8);
+          __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+          __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_a, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 58; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __Pyx_GOTREF(__pyx_t_1);
+          __pyx_t_4 = PyNumber_Subtract(__pyx_t_8, __pyx_t_1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 58; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __Pyx_GOTREF(__pyx_t_4);
+          __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+          __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+          __Pyx_INCREF(__pyx_v_i);
+          __pyx_t_1 = __pyx_v_i;
+          __pyx_t_2 = PyObject_RichCompare(__pyx_t_4, __pyx_t_1, Py_LT); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 58; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 58; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+          if (__pyx_t_7) {
+            __Pyx_INCREF(__pyx_t_4);
+            __pyx_t_8 = __pyx_t_4;
+          } else {
+            __Pyx_INCREF(__pyx_t_1);
+            __pyx_t_8 = __pyx_t_1;
+          }
+          __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+          __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+          __pyx_t_4 = __pyx_t_8;
+          __Pyx_INCREF(__pyx_t_4);
+          __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+          __Pyx_DECREF(__pyx_v_i);
+          __pyx_v_i = __pyx_t_4;
+          __pyx_t_4 = 0;
+          goto __pyx_L7;
+        }
+        __pyx_L7:;
+
+        /* "bx/align/_epo.pyx":59
+ *                 if p:
+ *                     i = min(i, p[0][0] - a[1])
+ *                 P = adv(P, a, dash)             # <<<<<<<<<<<<<<
+ *                 a = myp(p)
+ *             else:
+ */
+        __pyx_t_4 = __pyx_cur_scope->__pyx_v_P;
+        __Pyx_INCREF(__pyx_t_4);
+        __pyx_t_8 = __pyx_pf_2bx_5align_4_epo_8rem_dash_2adv(__pyx_v_adv, __pyx_t_4, __pyx_v_a, __pyx_v_dash); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 59; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_8);
+        __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+        __Pyx_GOTREF(__pyx_cur_scope->__pyx_v_P);
+        __Pyx_DECREF(__pyx_cur_scope->__pyx_v_P);
+        __Pyx_GIVEREF(__pyx_t_8);
+        __pyx_cur_scope->__pyx_v_P = __pyx_t_8;
+        __pyx_t_8 = 0;
+
+        /* "bx/align/_epo.pyx":60
+ *                     i = min(i, p[0][0] - a[1])
+ *                 P = adv(P, a, dash)
+ *                 a = myp(p)             # <<<<<<<<<<<<<<
+ *             else:
+ *                 if q:
+ */
+        __pyx_t_8 = __pyx_cur_scope->__pyx_v_p;
+        __Pyx_INCREF(__pyx_t_8);
+        __pyx_t_4 = __pyx_pf_2bx_5align_4_epo_8rem_dash_myp(__pyx_v_myp, __pyx_t_8); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 60; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_4);
+        __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+        __Pyx_DECREF(__pyx_v_a);
+        __pyx_v_a = __pyx_t_4;
+        __pyx_t_4 = 0;
+        goto __pyx_L6;
+      }
+      /*else*/ {
+
+        /* "bx/align/_epo.pyx":62
+ *                 a = myp(p)
+ *             else:
+ *                 if q:             # <<<<<<<<<<<<<<
+ *                     i = min(i, q[0][0] - b[1])
+ *                 Q = adv(Q, b, dash)
+ */
+        __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_cur_scope->__pyx_v_q); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 62; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        if (__pyx_t_7) {
+
+          /* "bx/align/_epo.pyx":63
+ *             else:
+ *                 if q:
+ *                     i = min(i, q[0][0] - b[1])             # <<<<<<<<<<<<<<
+ *                 Q = adv(Q, b, dash)
+ *                 b = myp(q)
+ */
+          __pyx_t_4 = __Pyx_GetItemInt(__pyx_cur_scope->__pyx_v_q, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 63; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __Pyx_GOTREF(__pyx_t_4);
+          __pyx_t_8 = __Pyx_GetItemInt(__pyx_t_4, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_8) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 63; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __Pyx_GOTREF(__pyx_t_8);
+          __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+          __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_b, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 63; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __Pyx_GOTREF(__pyx_t_4);
+          __pyx_t_1 = PyNumber_Subtract(__pyx_t_8, __pyx_t_4); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 63; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __Pyx_GOTREF(__pyx_t_1);
+          __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+          __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+          __Pyx_INCREF(__pyx_v_i);
+          __pyx_t_4 = __pyx_v_i;
+          __pyx_t_2 = PyObject_RichCompare(__pyx_t_1, __pyx_t_4, Py_LT); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 63; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 63; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+          if (__pyx_t_7) {
+            __Pyx_INCREF(__pyx_t_1);
+            __pyx_t_8 = __pyx_t_1;
+          } else {
+            __Pyx_INCREF(__pyx_t_4);
+            __pyx_t_8 = __pyx_t_4;
+          }
+          __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+          __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+          __pyx_t_1 = __pyx_t_8;
+          __Pyx_INCREF(__pyx_t_1);
+          __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+          __Pyx_DECREF(__pyx_v_i);
+          __pyx_v_i = __pyx_t_1;
+          __pyx_t_1 = 0;
+          goto __pyx_L8;
+        }
+        __pyx_L8:;
+
+        /* "bx/align/_epo.pyx":64
+ *                 if q:
+ *                     i = min(i, q[0][0] - b[1])
+ *                 Q = adv(Q, b, dash)             # <<<<<<<<<<<<<<
+ *                 b = myp(q)
+ *             dash += i
+ */
+        __pyx_t_1 = __pyx_cur_scope->__pyx_v_Q;
+        __Pyx_INCREF(__pyx_t_1);
+        __pyx_t_8 = __pyx_pf_2bx_5align_4_epo_8rem_dash_2adv(__pyx_v_adv, __pyx_t_1, __pyx_v_b, __pyx_v_dash); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 64; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_8);
+        __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+        __Pyx_GOTREF(__pyx_cur_scope->__pyx_v_Q);
+        __Pyx_DECREF(__pyx_cur_scope->__pyx_v_Q);
+        __Pyx_GIVEREF(__pyx_t_8);
+        __pyx_cur_scope->__pyx_v_Q = __pyx_t_8;
+        __pyx_t_8 = 0;
+
+        /* "bx/align/_epo.pyx":65
+ *                     i = min(i, q[0][0] - b[1])
+ *                 Q = adv(Q, b, dash)
+ *                 b = myp(q)             # <<<<<<<<<<<<<<
+ *             dash += i
+ *         else: # intersection
+ */
+        __pyx_t_8 = __pyx_cur_scope->__pyx_v_q;
+        __Pyx_INCREF(__pyx_t_8);
+        __pyx_t_1 = __pyx_pf_2bx_5align_4_epo_8rem_dash_myp(__pyx_v_myp, __pyx_t_8); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 65; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_1);
+        __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+        __Pyx_DECREF(__pyx_v_b);
+        __pyx_v_b = __pyx_t_1;
+        __pyx_t_1 = 0;
+      }
+      __pyx_L6:;
+
+      /* "bx/align/_epo.pyx":66
+ *                 Q = adv(Q, b, dash)
+ *                 b = myp(q)
+ *             dash += i             # <<<<<<<<<<<<<<
+ *         else: # intersection
+ *             if a[1] >= b[1]:
+ */
+      __pyx_t_1 = PyNumber_InPlaceAdd(__pyx_v_dash, __pyx_v_i); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 66; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_1);
+      __Pyx_DECREF(__pyx_v_dash);
+      __pyx_v_dash = __pyx_t_1;
+      __pyx_t_1 = 0;
+      goto __pyx_L5;
+    }
+    /*else*/ {
+
+      /* "bx/align/_epo.pyx":68
+ *             dash += i
+ *         else: # intersection
+ *             if a[1] >= b[1]:             # <<<<<<<<<<<<<<
+ *                 Q = adv(Q, b, dash); b = myp(q)
+ *             elif a[1] < b[1]:
+ */
+      __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_a, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 68; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_1);
+      __pyx_t_8 = __Pyx_GetItemInt(__pyx_v_b, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_8) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 68; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_8);
+      __pyx_t_4 = PyObject_RichCompare(__pyx_t_1, __pyx_t_8, Py_GE); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 68; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+      __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+      __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 68; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      if (__pyx_t_7) {
+
+        /* "bx/align/_epo.pyx":69
+ *         else: # intersection
+ *             if a[1] >= b[1]:
+ *                 Q = adv(Q, b, dash); b = myp(q)             # <<<<<<<<<<<<<<
+ *             elif a[1] < b[1]:
+ *                 P = adv(P, a, dash); a = myp(p)
+ */
+        __pyx_t_4 = __pyx_cur_scope->__pyx_v_Q;
+        __Pyx_INCREF(__pyx_t_4);
+        __pyx_t_8 = __pyx_pf_2bx_5align_4_epo_8rem_dash_2adv(__pyx_v_adv, __pyx_t_4, __pyx_v_b, __pyx_v_dash); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 69; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_8);
+        __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+        __Pyx_GOTREF(__pyx_cur_scope->__pyx_v_Q);
+        __Pyx_DECREF(__pyx_cur_scope->__pyx_v_Q);
+        __Pyx_GIVEREF(__pyx_t_8);
+        __pyx_cur_scope->__pyx_v_Q = __pyx_t_8;
+        __pyx_t_8 = 0;
+        __pyx_t_8 = __pyx_cur_scope->__pyx_v_q;
+        __Pyx_INCREF(__pyx_t_8);
+        __pyx_t_4 = __pyx_pf_2bx_5align_4_epo_8rem_dash_myp(__pyx_v_myp, __pyx_t_8); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 69; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_4);
+        __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+        __Pyx_DECREF(__pyx_v_b);
+        __pyx_v_b = __pyx_t_4;
+        __pyx_t_4 = 0;
+        goto __pyx_L9;
+      }
+
+      /* "bx/align/_epo.pyx":70
+ *             if a[1] >= b[1]:
+ *                 Q = adv(Q, b, dash); b = myp(q)
+ *             elif a[1] < b[1]:             # <<<<<<<<<<<<<<
+ *                 P = adv(P, a, dash); a = myp(p)
+ *         #if not a or not b: # no more matchings
+ */
+      __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_a, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 70; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __pyx_t_8 = __Pyx_GetItemInt(__pyx_v_b, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_8) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 70; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_8);
+      __pyx_t_1 = PyObject_RichCompare(__pyx_t_4, __pyx_t_8, Py_LT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 70; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+      __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 70; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+      if (__pyx_t_7) {
+
+        /* "bx/align/_epo.pyx":71
+ *                 Q = adv(Q, b, dash); b = myp(q)
+ *             elif a[1] < b[1]:
+ *                 P = adv(P, a, dash); a = myp(p)             # <<<<<<<<<<<<<<
+ *         #if not a or not b: # no more matchings
+ *         #    break
+ */
+        __pyx_t_1 = __pyx_cur_scope->__pyx_v_P;
+        __Pyx_INCREF(__pyx_t_1);
+        __pyx_t_8 = __pyx_pf_2bx_5align_4_epo_8rem_dash_2adv(__pyx_v_adv, __pyx_t_1, __pyx_v_a, __pyx_v_dash); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 71; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_8);
+        __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+        __Pyx_GOTREF(__pyx_cur_scope->__pyx_v_P);
+        __Pyx_DECREF(__pyx_cur_scope->__pyx_v_P);
+        __Pyx_GIVEREF(__pyx_t_8);
+        __pyx_cur_scope->__pyx_v_P = __pyx_t_8;
+        __pyx_t_8 = 0;
+        __pyx_t_8 = __pyx_cur_scope->__pyx_v_p;
+        __Pyx_INCREF(__pyx_t_8);
+        __pyx_t_1 = __pyx_pf_2bx_5align_4_epo_8rem_dash_myp(__pyx_v_myp, __pyx_t_8); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 71; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_1);
+        __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+        __Pyx_DECREF(__pyx_v_a);
+        __pyx_v_a = __pyx_t_1;
+        __pyx_t_1 = 0;
+        goto __pyx_L9;
+      }
+      __pyx_L9:;
+    }
+    __pyx_L5:;
+  }
+
+  /* "bx/align/_epo.pyx":74
+ *         #if not a or not b: # no more matchings
+ *         #    break
+ *     assert (not p) or (not q), "one or both should be empty: p=%s, q=%s" % (str(p), str(q))             # <<<<<<<<<<<<<<
+ * 
+ *     if a: P = adv(P, a, dash)
+ */
+  #ifndef CYTHON_WITHOUT_ASSERTIONS
+  __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_cur_scope->__pyx_v_p); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 74; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_5 = (!__pyx_t_7);
+  if (!__pyx_t_5) {
+    __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_cur_scope->__pyx_v_q); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 74; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_6 = (!__pyx_t_7);
+    __pyx_t_7 = __pyx_t_6;
+  } else {
+    __pyx_t_7 = __pyx_t_5;
+  }
+  if (unlikely(!__pyx_t_7)) {
+    __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 74; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __Pyx_INCREF(__pyx_cur_scope->__pyx_v_p);
+    PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_cur_scope->__pyx_v_p);
+    __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_p);
+    __pyx_t_8 = PyObject_Call(((PyObject *)((PyObject*)(&PyString_Type))), ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 74; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_8);
+    __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+    __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 74; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __Pyx_INCREF(__pyx_cur_scope->__pyx_v_q);
+    PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_cur_scope->__pyx_v_q);
+    __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_q);
+    __pyx_t_4 = PyObject_Call(((PyObject *)((PyObject*)(&PyString_Type))), ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 74; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+    __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 74; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_8);
+    __Pyx_GIVEREF(__pyx_t_8);
+    PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_t_4);
+    __Pyx_GIVEREF(__pyx_t_4);
+    __pyx_t_8 = 0;
+    __pyx_t_4 = 0;
+    __pyx_t_4 = PyNumber_Remainder(((PyObject *)__pyx_kp_s_10), ((PyObject *)__pyx_t_1)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 74; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(((PyObject *)__pyx_t_4));
+    __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+    PyErr_SetObject(PyExc_AssertionError, ((PyObject *)__pyx_t_4));
+    __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 74; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  #endif
+
+  /* "bx/align/_epo.pyx":76
+ *     assert (not p) or (not q), "one or both should be empty: p=%s, q=%s" % (str(p), str(q))
+ * 
+ *     if a: P = adv(P, a, dash)             # <<<<<<<<<<<<<<
+ *     if b: Q = adv(Q, b, dash)
+ * 
+ */
+  __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_v_a); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 76; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (__pyx_t_7) {
+    __pyx_t_4 = __pyx_cur_scope->__pyx_v_P;
+    __Pyx_INCREF(__pyx_t_4);
+    __pyx_t_1 = __pyx_pf_2bx_5align_4_epo_8rem_dash_2adv(__pyx_v_adv, __pyx_t_4, __pyx_v_a, __pyx_v_dash); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 76; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    __Pyx_GOTREF(__pyx_cur_scope->__pyx_v_P);
+    __Pyx_DECREF(__pyx_cur_scope->__pyx_v_P);
+    __Pyx_GIVEREF(__pyx_t_1);
+    __pyx_cur_scope->__pyx_v_P = __pyx_t_1;
+    __pyx_t_1 = 0;
+    goto __pyx_L10;
+  }
+  __pyx_L10:;
+
+  /* "bx/align/_epo.pyx":77
+ * 
+ *     if a: P = adv(P, a, dash)
+ *     if b: Q = adv(Q, b, dash)             # <<<<<<<<<<<<<<
+ * 
+ *     # remaining intervals (in q or p)
+ */
+  __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_v_b); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 77; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (__pyx_t_7) {
+    __pyx_t_1 = __pyx_cur_scope->__pyx_v_Q;
+    __Pyx_INCREF(__pyx_t_1);
+    __pyx_t_4 = __pyx_pf_2bx_5align_4_epo_8rem_dash_2adv(__pyx_v_adv, __pyx_t_1, __pyx_v_b, __pyx_v_dash); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 77; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    __Pyx_GOTREF(__pyx_cur_scope->__pyx_v_Q);
+    __Pyx_DECREF(__pyx_cur_scope->__pyx_v_Q);
+    __Pyx_GIVEREF(__pyx_t_4);
+    __pyx_cur_scope->__pyx_v_Q = __pyx_t_4;
+    __pyx_t_4 = 0;
+    goto __pyx_L11;
+  }
+  __pyx_L11:;
+
+  /* "bx/align/_epo.pyx":80
+ * 
+ *     # remaining intervals (in q or p)
+ *     r, R = p, P             # <<<<<<<<<<<<<<
+ *     if q: r, R = q, Q
+ *     # just extend the last inteval by the remaining bases
+ */
+  __pyx_t_4 = __pyx_cur_scope->__pyx_v_p;
+  __Pyx_INCREF(__pyx_t_4);
+  __pyx_t_1 = __pyx_cur_scope->__pyx_v_P;
+  __Pyx_INCREF(__pyx_t_1);
+  __pyx_v_r = __pyx_t_4;
+  __pyx_t_4 = 0;
+  __pyx_v_R = __pyx_t_1;
+  __pyx_t_1 = 0;
+
+  /* "bx/align/_epo.pyx":81
+ *     # remaining intervals (in q or p)
+ *     r, R = p, P
+ *     if q: r, R = q, Q             # <<<<<<<<<<<<<<
+ *     # just extend the last inteval by the remaining bases
+ *     R[-1] = (R[-1][0], R[-1][1] + sum( map(lambda i: i[1]-i[0], r) ))
+ */
+  __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_cur_scope->__pyx_v_q); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 81; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (__pyx_t_7) {
+    __pyx_t_1 = __pyx_cur_scope->__pyx_v_q;
+    __Pyx_INCREF(__pyx_t_1);
+    __pyx_t_4 = __pyx_cur_scope->__pyx_v_Q;
+    __Pyx_INCREF(__pyx_t_4);
+    __Pyx_DECREF(__pyx_v_r);
+    __pyx_v_r = __pyx_t_1;
+    __pyx_t_1 = 0;
+    __Pyx_DECREF(__pyx_v_R);
+    __pyx_v_R = __pyx_t_4;
+    __pyx_t_4 = 0;
+    goto __pyx_L12;
+  }
+  __pyx_L12:;
+
+  /* "bx/align/_epo.pyx":83
+ *     if q: r, R = q, Q
+ *     # just extend the last inteval by the remaining bases
+ *     R[-1] = (R[-1][0], R[-1][1] + sum( map(lambda i: i[1]-i[0], r) ))             # <<<<<<<<<<<<<<
+ * 
+ *     P_card = sum( map(lambda i: P[i][1] - P[i][0], range(len(P))) )
+ */
+  __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_R, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 83; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __pyx_t_1 = __Pyx_GetItemInt(__pyx_t_4, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 83; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_R, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 83; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __pyx_t_8 = __Pyx_GetItemInt(__pyx_t_4, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_8) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 83; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_8);
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  __pyx_t_4 = __Pyx_CyFunction_NewEx(&__pyx_mdef_2bx_5align_4_epo_8rem_dash_6lambda3, 0, __pyx_n_s_9, NULL, __pyx_n_s_5, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 83; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 83; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_4);
+  __Pyx_GIVEREF(__pyx_t_4);
+  __Pyx_INCREF(__pyx_v_r);
+  PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_v_r);
+  __Pyx_GIVEREF(__pyx_v_r);
+  __pyx_t_4 = 0;
+  __pyx_t_4 = PyObject_Call(__pyx_builtin_map, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 83; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
+  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 83; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_4);
+  __Pyx_GIVEREF(__pyx_t_4);
+  __pyx_t_4 = 0;
+  __pyx_t_4 = PyObject_Call(__pyx_builtin_sum, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 83; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
+  __pyx_t_2 = PyNumber_Add(__pyx_t_8, __pyx_t_4); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 83; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 83; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_1);
+  __Pyx_GIVEREF(__pyx_t_1);
+  PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_2);
+  __Pyx_GIVEREF(__pyx_t_2);
+  __pyx_t_1 = 0;
+  __pyx_t_2 = 0;
+  if (__Pyx_SetItemInt(__pyx_v_R, -1, ((PyObject *)__pyx_t_4), sizeof(long), PyInt_FromLong) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 83; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
+
+  /* "bx/align/_epo.pyx":85
+ *     R[-1] = (R[-1][0], R[-1][1] + sum( map(lambda i: i[1]-i[0], r) ))
+ * 
+ *     P_card = sum( map(lambda i: P[i][1] - P[i][0], range(len(P))) )             # <<<<<<<<<<<<<<
+ *     Q_card = sum( map(lambda i: Q[i][1] - Q[i][0], range(len(Q))) )
+ * 
+ */
+  __pyx_t_4 = __Pyx_CyFunction_NewEx(&__pyx_mdef_2bx_5align_4_epo_8rem_dash_7lambda4, 0, __pyx_n_s_9, ((PyObject*)__pyx_cur_scope), __pyx_n_s_5, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 85; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __pyx_t_2 = __pyx_cur_scope->__pyx_v_P;
+  __Pyx_INCREF(__pyx_t_2);
+  __pyx_t_3 = PyObject_Length(__pyx_t_2); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 85; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_2 = PyInt_FromSsize_t(__pyx_t_3); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 85; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 85; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_2);
+  __Pyx_GIVEREF(__pyx_t_2);
+  __pyx_t_2 = 0;
+  __pyx_t_2 = PyObject_Call(__pyx_builtin_range, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 85; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+  __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 85; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_4);
+  __Pyx_GIVEREF(__pyx_t_4);
+  PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_t_2);
+  __Pyx_GIVEREF(__pyx_t_2);
+  __pyx_t_4 = 0;
+  __pyx_t_2 = 0;
+  __pyx_t_2 = PyObject_Call(__pyx_builtin_map, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 85; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 85; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_2);
+  __Pyx_GIVEREF(__pyx_t_2);
+  __pyx_t_2 = 0;
+  __pyx_t_2 = PyObject_Call(__pyx_builtin_sum, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 85; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+  __pyx_v_P_card = __pyx_t_2;
+  __pyx_t_2 = 0;
+
+  /* "bx/align/_epo.pyx":86
+ * 
+ *     P_card = sum( map(lambda i: P[i][1] - P[i][0], range(len(P))) )
+ *     Q_card = sum( map(lambda i: Q[i][1] - Q[i][0], range(len(Q))) )             # <<<<<<<<<<<<<<
+ * 
+ *     assert p_card == P_card, "%d != %d" % (p_card, P_card)
+ */
+  __pyx_t_2 = __Pyx_CyFunction_NewEx(&__pyx_mdef_2bx_5align_4_epo_8rem_dash_8lambda5, 0, __pyx_n_s_9, ((PyObject*)__pyx_cur_scope), __pyx_n_s_5, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 86; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_1 = __pyx_cur_scope->__pyx_v_Q;
+  __Pyx_INCREF(__pyx_t_1);
+  __pyx_t_3 = PyObject_Length(__pyx_t_1); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 86; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_1 = PyInt_FromSsize_t(__pyx_t_3); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 86; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 86; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_1);
+  __Pyx_GIVEREF(__pyx_t_1);
+  __pyx_t_1 = 0;
+  __pyx_t_1 = PyObject_Call(__pyx_builtin_range, ((PyObject *)__pyx_t_4), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 86; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
+  __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 86; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_2);
+  __Pyx_GIVEREF(__pyx_t_2);
+  PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_1);
+  __Pyx_GIVEREF(__pyx_t_1);
+  __pyx_t_2 = 0;
+  __pyx_t_1 = 0;
+  __pyx_t_1 = PyObject_Call(__pyx_builtin_map, ((PyObject *)__pyx_t_4), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 86; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
+  __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 86; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_1);
+  __Pyx_GIVEREF(__pyx_t_1);
+  __pyx_t_1 = 0;
+  __pyx_t_1 = PyObject_Call(__pyx_builtin_sum, ((PyObject *)__pyx_t_4), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 86; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
+  __pyx_v_Q_card = __pyx_t_1;
+  __pyx_t_1 = 0;
+
+  /* "bx/align/_epo.pyx":88
+ *     Q_card = sum( map(lambda i: Q[i][1] - Q[i][0], range(len(Q))) )
+ * 
+ *     assert p_card == P_card, "%d != %d" % (p_card, P_card)             # <<<<<<<<<<<<<<
+ *     assert q_card == Q_card, "%d != %d" % (q_card, Q_card)
+ * 
+ */
+  #ifndef CYTHON_WITHOUT_ASSERTIONS
+  __pyx_t_1 = PyObject_RichCompare(__pyx_v_p_card, __pyx_v_P_card, Py_EQ); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 88; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 88; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  if (unlikely(!__pyx_t_7)) {
+    __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 88; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __Pyx_INCREF(__pyx_v_p_card);
+    PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_p_card);
+    __Pyx_GIVEREF(__pyx_v_p_card);
+    __Pyx_INCREF(__pyx_v_P_card);
+    PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_v_P_card);
+    __Pyx_GIVEREF(__pyx_v_P_card);
+    __pyx_t_4 = PyNumber_Remainder(((PyObject *)__pyx_kp_s_11), ((PyObject *)__pyx_t_1)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 88; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(((PyObject *)__pyx_t_4));
+    __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+    PyErr_SetObject(PyExc_AssertionError, ((PyObject *)__pyx_t_4));
+    __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 88; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  #endif
+
+  /* "bx/align/_epo.pyx":89
+ * 
+ *     assert p_card == P_card, "%d != %d" % (p_card, P_card)
+ *     assert q_card == Q_card, "%d != %d" % (q_card, Q_card)             # <<<<<<<<<<<<<<
+ * 
+ *     return P, Q
+ */
+  #ifndef CYTHON_WITHOUT_ASSERTIONS
+  __pyx_t_4 = PyObject_RichCompare(__pyx_v_q_card, __pyx_v_Q_card, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 89; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 89; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  if (unlikely(!__pyx_t_7)) {
+    __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 89; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    __Pyx_INCREF(__pyx_v_q_card);
+    PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_v_q_card);
+    __Pyx_GIVEREF(__pyx_v_q_card);
+    __Pyx_INCREF(__pyx_v_Q_card);
+    PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_v_Q_card);
+    __Pyx_GIVEREF(__pyx_v_Q_card);
+    __pyx_t_1 = PyNumber_Remainder(((PyObject *)__pyx_kp_s_11), ((PyObject *)__pyx_t_4)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 89; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(((PyObject *)__pyx_t_1));
+    __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
+    PyErr_SetObject(PyExc_AssertionError, ((PyObject *)__pyx_t_1));
+    __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 89; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  #endif
+
+  /* "bx/align/_epo.pyx":91
+ *     assert q_card == Q_card, "%d != %d" % (q_card, Q_card)
+ * 
+ *     return P, Q             # <<<<<<<<<<<<<<
+ * 
+ * def fastLoadChain(fname, hf):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 91; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_INCREF(__pyx_cur_scope->__pyx_v_P);
+  PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_cur_scope->__pyx_v_P);
+  __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_P);
+  __Pyx_INCREF(__pyx_cur_scope->__pyx_v_Q);
+  PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_cur_scope->__pyx_v_Q);
+  __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_Q);
+  __pyx_r = ((PyObject *)__pyx_t_1);
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_XDECREF(__pyx_t_8);
+  __Pyx_XDECREF(__pyx_t_9);
+  __Pyx_AddTraceback("bx.align._epo.rem_dash", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_myp);
+  __Pyx_XDECREF(__pyx_v_adv);
+  __Pyx_XDECREF(__pyx_v_p_card);
+  __Pyx_XDECREF(__pyx_v_q_card);
+  __Pyx_XDECREF(__pyx_v_dash);
+  __Pyx_XDECREF(__pyx_v_a);
+  __Pyx_XDECREF(__pyx_v_b);
+  __Pyx_XDECREF(__pyx_v_i);
+  __Pyx_XDECREF(__pyx_v_r);
+  __Pyx_XDECREF(__pyx_v_R);
+  __Pyx_XDECREF(__pyx_v_P_card);
+  __Pyx_XDECREF(__pyx_v_Q_card);
+  __Pyx_DECREF(((PyObject *)__pyx_cur_scope));
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_5align_4_epo_3fastLoadChain(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_mdef_2bx_5align_4_epo_3fastLoadChain = {__Pyx_NAMESTR("fastLoadChain"), (PyCFunction)__pyx_pw_2bx_5align_4_epo_3fastLoadChain, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(0)};
+static PyObject *__pyx_pw_2bx_5align_4_epo_3fastLoadChain(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_fname = 0;
+  PyObject *__pyx_v_hf = 0;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("fastLoadChain (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__fname,&__pyx_n_s__hf,0};
+    PyObject* values[2] = {0,0};
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__fname)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__hf)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("fastLoadChain", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 93; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "fastLoadChain") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 93; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
+      goto __pyx_L5_argtuple_error;
+    } else {
+      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+    }
+    __pyx_v_fname = values[0];
+    __pyx_v_hf = values[1];
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("fastLoadChain", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 93; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.align._epo.fastLoadChain", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_5align_4_epo_2fastLoadChain(__pyx_self, __pyx_v_fname, __pyx_v_hf);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/align/_epo.pyx":93
+ *     return P, Q
+ * 
+ * def fastLoadChain(fname, hf):             # <<<<<<<<<<<<<<
+ *     data = []
+ *     open_f = (fname.endswith(".gz") and gzip.open or open)
+ */
+
+static PyObject *__pyx_pf_2bx_5align_4_epo_2fastLoadChain(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_fname, PyObject *__pyx_v_hf) {
+  PyObject *__pyx_v_data = NULL;
+  PyObject *__pyx_v_open_f = NULL;
+  PyObject *__pyx_v_fd = NULL;
+  PyObject *__pyx_v_line = NULL;
+  PyObject *__pyx_v_hd = NULL;
+  PyObject *__pyx_v_N = NULL;
+  PyObject *__pyx_v_s = NULL;
+  PyObject *__pyx_v_t = NULL;
+  PyObject *__pyx_v_q = NULL;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  int __pyx_t_3;
+  PyObject *__pyx_t_4 = NULL;
+  PyObject *__pyx_t_5 = NULL;
+  PyObject *__pyx_t_6 = NULL;
+  PyObject *__pyx_t_7 = NULL;
+  PyObject *__pyx_t_8 = NULL;
+  Py_ssize_t __pyx_t_9;
+  PyObject *__pyx_t_10 = NULL;
+  int __pyx_t_11;
+  PyObject *__pyx_t_12 = NULL;
+  PyObject *(*__pyx_t_13)(PyObject *);
+  PyObject *__pyx_t_14 = NULL;
+  PyObject *__pyx_t_15 = NULL;
+  PyObject *__pyx_t_16 = NULL;
+  int __pyx_t_17;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("fastLoadChain", 0);
+
+  /* "bx/align/_epo.pyx":94
+ * 
+ * def fastLoadChain(fname, hf):
+ *     data = []             # <<<<<<<<<<<<<<
+ *     open_f = (fname.endswith(".gz") and gzip.open or open)
+ *     with open_f(fname) as fd:
+ */
+  __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 94; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_v_data = ((PyObject*)__pyx_t_1);
+  __pyx_t_1 = 0;
+
+  /* "bx/align/_epo.pyx":95
+ * def fastLoadChain(fname, hf):
+ *     data = []
+ *     open_f = (fname.endswith(".gz") and gzip.open or open)             # <<<<<<<<<<<<<<
+ *     with open_f(fname) as fd:
+ *         while True:
+ */
+  __pyx_t_1 = PyObject_GetAttr(__pyx_v_fname, __pyx_n_s__endswith); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 95; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_k_tuple_13), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 95; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 95; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (__pyx_t_3) {
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__gzip); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 95; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __pyx_t_4 = PyObject_GetAttr(__pyx_t_1, __pyx_n_s__open); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 95; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    __pyx_t_1 = __pyx_t_4;
+    __pyx_t_4 = 0;
+  } else {
+    __pyx_t_1 = __pyx_t_2;
+    __pyx_t_2 = 0;
+  }
+  __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 95; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (!__pyx_t_3) {
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    __Pyx_INCREF(__pyx_builtin_open);
+    __pyx_t_2 = __pyx_builtin_open;
+  } else {
+    __pyx_t_2 = __pyx_t_1;
+    __pyx_t_1 = 0;
+  }
+  __pyx_v_open_f = __pyx_t_2;
+  __pyx_t_2 = 0;
+
+  /* "bx/align/_epo.pyx":96
+ *     data = []
+ *     open_f = (fname.endswith(".gz") and gzip.open or open)
+ *     with open_f(fname) as fd:             # <<<<<<<<<<<<<<
+ *         while True:
+ *             line = fd.readline()
+ */
+  /*with:*/ {
+    __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 96; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __Pyx_INCREF(__pyx_v_fname);
+    PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_fname);
+    __Pyx_GIVEREF(__pyx_v_fname);
+    __pyx_t_1 = PyObject_Call(__pyx_v_open_f, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 96; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
+    __pyx_t_5 = PyObject_GetAttr(__pyx_t_1, __pyx_n_s____exit__); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 96; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_5);
+    __pyx_t_2 = PyObject_GetAttr(__pyx_t_1, __pyx_n_s____enter__); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 96; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_t_4 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 96; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    /*try:*/ {
+      {
+        __Pyx_ExceptionSave(&__pyx_t_6, &__pyx_t_7, &__pyx_t_8);
+        __Pyx_XGOTREF(__pyx_t_6);
+        __Pyx_XGOTREF(__pyx_t_7);
+        __Pyx_XGOTREF(__pyx_t_8);
+        /*try:*/ {
+          __Pyx_INCREF(__pyx_t_4);
+          __pyx_v_fd = __pyx_t_4;
+          __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+
+          /* "bx/align/_epo.pyx":97
+ *     open_f = (fname.endswith(".gz") and gzip.open or open)
+ *     with open_f(fname) as fd:
+ *         while True:             # <<<<<<<<<<<<<<
+ *             line = fd.readline()
+ *             if line == "":
+ */
+          while (1) {
+            if (!1) break;
+
+            /* "bx/align/_epo.pyx":98
+ *     with open_f(fname) as fd:
+ *         while True:
+ *             line = fd.readline()             # <<<<<<<<<<<<<<
+ *             if line == "":
+ *                 break
+ */
+            __pyx_t_4 = PyObject_GetAttr(__pyx_v_fd, __pyx_n_s__readline); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 98; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+            __Pyx_GOTREF(__pyx_t_4);
+            __pyx_t_1 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 98; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+            __Pyx_GOTREF(__pyx_t_1);
+            __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+            __Pyx_XDECREF(__pyx_v_line);
+            __pyx_v_line = __pyx_t_1;
+            __pyx_t_1 = 0;
+
+            /* "bx/align/_epo.pyx":99
+ *         while True:
+ *             line = fd.readline()
+ *             if line == "":             # <<<<<<<<<<<<<<
+ *                 break
+ *             hd = hf(line)
+ */
+            __pyx_t_1 = PyObject_RichCompare(__pyx_v_line, ((PyObject *)__pyx_kp_s_14), Py_EQ); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 99; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+            __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 99; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+            __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+            if (__pyx_t_3) {
+
+              /* "bx/align/_epo.pyx":100
+ *             line = fd.readline()
+ *             if line == "":
+ *                 break             # <<<<<<<<<<<<<<
+ *             hd = hf(line)
+ *             N = []
+ */
+              goto __pyx_L17_break;
+              goto __pyx_L18;
+            }
+            __pyx_L18:;
+
+            /* "bx/align/_epo.pyx":101
+ *             if line == "":
+ *                 break
+ *             hd = hf(line)             # <<<<<<<<<<<<<<
+ *             N = []
+ *             line = fd.readline().split()
+ */
+            __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 101; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+            __Pyx_GOTREF(__pyx_t_1);
+            __Pyx_INCREF(__pyx_v_line);
+            PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_line);
+            __Pyx_GIVEREF(__pyx_v_line);
+            __pyx_t_4 = PyObject_Call(__pyx_v_hf, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 101; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+            __Pyx_GOTREF(__pyx_t_4);
+            __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+            __Pyx_XDECREF(__pyx_v_hd);
+            __pyx_v_hd = __pyx_t_4;
+            __pyx_t_4 = 0;
+
+            /* "bx/align/_epo.pyx":102
+ *                 break
+ *             hd = hf(line)
+ *             N = []             # <<<<<<<<<<<<<<
+ *             line = fd.readline().split()
+ *             while len(line) == 3:
+ */
+            __pyx_t_4 = PyList_New(0); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 102; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+            __Pyx_GOTREF(__pyx_t_4);
+            __Pyx_XDECREF(((PyObject *)__pyx_v_N));
+            __pyx_v_N = ((PyObject*)__pyx_t_4);
+            __pyx_t_4 = 0;
+
+            /* "bx/align/_epo.pyx":103
+ *             hd = hf(line)
+ *             N = []
+ *             line = fd.readline().split()             # <<<<<<<<<<<<<<
+ *             while len(line) == 3:
+ *                 N.append( (int(line[0]), int(line[1]), int(line[2])) )
+ */
+            __pyx_t_4 = PyObject_GetAttr(__pyx_v_fd, __pyx_n_s__readline); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 103; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+            __Pyx_GOTREF(__pyx_t_4);
+            __pyx_t_1 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 103; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+            __Pyx_GOTREF(__pyx_t_1);
+            __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+            __pyx_t_4 = PyObject_GetAttr(__pyx_t_1, __pyx_n_s__split); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 103; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+            __Pyx_GOTREF(__pyx_t_4);
+            __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+            __pyx_t_1 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 103; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+            __Pyx_GOTREF(__pyx_t_1);
+            __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+            __Pyx_DECREF(__pyx_v_line);
+            __pyx_v_line = __pyx_t_1;
+            __pyx_t_1 = 0;
+
+            /* "bx/align/_epo.pyx":104
+ *             N = []
+ *             line = fd.readline().split()
+ *             while len(line) == 3:             # <<<<<<<<<<<<<<
+ *                 N.append( (int(line[0]), int(line[1]), int(line[2])) )
+ *                 line = fd.readline().split()
+ */
+            while (1) {
+              __pyx_t_9 = PyObject_Length(__pyx_v_line); if (unlikely(__pyx_t_9 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 104; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+              __pyx_t_3 = (__pyx_t_9 == 3);
+              if (!__pyx_t_3) break;
+
+              /* "bx/align/_epo.pyx":105
+ *             line = fd.readline().split()
+ *             while len(line) == 3:
+ *                 N.append( (int(line[0]), int(line[1]), int(line[2])) )             # <<<<<<<<<<<<<<
+ *                 line = fd.readline().split()
+ *             if len(line) != 1:
+ */
+              __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_line, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 105; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+              __Pyx_GOTREF(__pyx_t_1);
+              __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 105; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+              __Pyx_GOTREF(__pyx_t_4);
+              PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_1);
+              __Pyx_GIVEREF(__pyx_t_1);
+              __pyx_t_1 = 0;
+              __pyx_t_1 = PyObject_Call(((PyObject *)((PyObject*)(&PyInt_Type))), ((PyObject *)__pyx_t_4), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 105; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+              __Pyx_GOTREF(__pyx_t_1);
+              __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
+              __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_line, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 105; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+              __Pyx_GOTREF(__pyx_t_4);
+              __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 105; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+              __Pyx_GOTREF(__pyx_t_2);
+              PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_4);
+              __Pyx_GIVEREF(__pyx_t_4);
+              __pyx_t_4 = 0;
+              __pyx_t_4 = PyObject_Call(((PyObject *)((PyObject*)(&PyInt_Type))), ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 105; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+              __Pyx_GOTREF(__pyx_t_4);
+              __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
+              __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_line, 2, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 105; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+              __Pyx_GOTREF(__pyx_t_2);
+              __pyx_t_10 = PyTuple_New(1); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 105; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+              __Pyx_GOTREF(__pyx_t_10);
+              PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_2);
+              __Pyx_GIVEREF(__pyx_t_2);
+              __pyx_t_2 = 0;
+              __pyx_t_2 = PyObject_Call(((PyObject *)((PyObject*)(&PyInt_Type))), ((PyObject *)__pyx_t_10), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 105; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+              __Pyx_GOTREF(__pyx_t_2);
+              __Pyx_DECREF(((PyObject *)__pyx_t_10)); __pyx_t_10 = 0;
+              __pyx_t_10 = PyTuple_New(3); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 105; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+              __Pyx_GOTREF(__pyx_t_10);
+              PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_1);
+              __Pyx_GIVEREF(__pyx_t_1);
+              PyTuple_SET_ITEM(__pyx_t_10, 1, __pyx_t_4);
+              __Pyx_GIVEREF(__pyx_t_4);
+              PyTuple_SET_ITEM(__pyx_t_10, 2, __pyx_t_2);
+              __Pyx_GIVEREF(__pyx_t_2);
+              __pyx_t_1 = 0;
+              __pyx_t_4 = 0;
+              __pyx_t_2 = 0;
+              __pyx_t_11 = PyList_Append(__pyx_v_N, ((PyObject *)__pyx_t_10)); if (unlikely(__pyx_t_11 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 105; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+              __Pyx_DECREF(((PyObject *)__pyx_t_10)); __pyx_t_10 = 0;
+
+              /* "bx/align/_epo.pyx":106
+ *             while len(line) == 3:
+ *                 N.append( (int(line[0]), int(line[1]), int(line[2])) )
+ *                 line = fd.readline().split()             # <<<<<<<<<<<<<<
+ *             if len(line) != 1:
+ *                 raise ValueError("last matching block expected (found %s)" % str(line))
+ */
+              __pyx_t_10 = PyObject_GetAttr(__pyx_v_fd, __pyx_n_s__readline); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 106; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+              __Pyx_GOTREF(__pyx_t_10);
+              __pyx_t_2 = PyObject_Call(__pyx_t_10, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 106; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+              __Pyx_GOTREF(__pyx_t_2);
+              __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+              __pyx_t_10 = PyObject_GetAttr(__pyx_t_2, __pyx_n_s__split); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 106; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+              __Pyx_GOTREF(__pyx_t_10);
+              __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+              __pyx_t_2 = PyObject_Call(__pyx_t_10, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 106; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+              __Pyx_GOTREF(__pyx_t_2);
+              __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+              __Pyx_DECREF(__pyx_v_line);
+              __pyx_v_line = __pyx_t_2;
+              __pyx_t_2 = 0;
+            }
+
+            /* "bx/align/_epo.pyx":107
+ *                 N.append( (int(line[0]), int(line[1]), int(line[2])) )
+ *                 line = fd.readline().split()
+ *             if len(line) != 1:             # <<<<<<<<<<<<<<
+ *                 raise ValueError("last matching block expected (found %s)" % str(line))
+ *             N.append( (int(line[0]), 0, 0) )
+ */
+            __pyx_t_9 = PyObject_Length(__pyx_v_line); if (unlikely(__pyx_t_9 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 107; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+            __pyx_t_3 = (__pyx_t_9 != 1);
+            if (__pyx_t_3) {
+
+              /* "bx/align/_epo.pyx":108
+ *                 line = fd.readline().split()
+ *             if len(line) != 1:
+ *                 raise ValueError("last matching block expected (found %s)" % str(line))             # <<<<<<<<<<<<<<
+ *             N.append( (int(line[0]), 0, 0) )
+ *             s, t, q = zip( *N )
+ */
+              __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 108; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+              __Pyx_GOTREF(__pyx_t_2);
+              __Pyx_INCREF(__pyx_v_line);
+              PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_line);
+              __Pyx_GIVEREF(__pyx_v_line);
+              __pyx_t_10 = PyObject_Call(((PyObject *)((PyObject*)(&PyString_Type))), ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 108; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+              __Pyx_GOTREF(__pyx_t_10);
+              __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
+              __pyx_t_2 = PyNumber_Remainder(((PyObject *)__pyx_kp_s_15), __pyx_t_10); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 108; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+              __Pyx_GOTREF(((PyObject *)__pyx_t_2));
+              __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+              __pyx_t_10 = PyTuple_New(1); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 108; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+              __Pyx_GOTREF(__pyx_t_10);
+              PyTuple_SET_ITEM(__pyx_t_10, 0, ((PyObject *)__pyx_t_2));
+              __Pyx_GIVEREF(((PyObject *)__pyx_t_2));
+              __pyx_t_2 = 0;
+              __pyx_t_2 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_t_10), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 108; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+              __Pyx_GOTREF(__pyx_t_2);
+              __Pyx_DECREF(((PyObject *)__pyx_t_10)); __pyx_t_10 = 0;
+              __Pyx_Raise(__pyx_t_2, 0, 0, 0);
+              __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+              {__pyx_filename = __pyx_f[0]; __pyx_lineno = 108; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+              goto __pyx_L21;
+            }
+            __pyx_L21:;
+
+            /* "bx/align/_epo.pyx":109
+ *             if len(line) != 1:
+ *                 raise ValueError("last matching block expected (found %s)" % str(line))
+ *             N.append( (int(line[0]), 0, 0) )             # <<<<<<<<<<<<<<
+ *             s, t, q = zip( *N )
+ *             data.append( (hd,
+ */
+            __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_line, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 109; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+            __Pyx_GOTREF(__pyx_t_2);
+            __pyx_t_10 = PyTuple_New(1); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 109; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+            __Pyx_GOTREF(__pyx_t_10);
+            PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_2);
+            __Pyx_GIVEREF(__pyx_t_2);
+            __pyx_t_2 = 0;
+            __pyx_t_2 = PyObject_Call(((PyObject *)((PyObject*)(&PyInt_Type))), ((PyObject *)__pyx_t_10), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 109; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+            __Pyx_GOTREF(__pyx_t_2);
+            __Pyx_DECREF(((PyObject *)__pyx_t_10)); __pyx_t_10 = 0;
+            __pyx_t_10 = PyTuple_New(3); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 109; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+            __Pyx_GOTREF(__pyx_t_10);
+            PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_2);
+            __Pyx_GIVEREF(__pyx_t_2);
+            __Pyx_INCREF(__pyx_int_0);
+            PyTuple_SET_ITEM(__pyx_t_10, 1, __pyx_int_0);
+            __Pyx_GIVEREF(__pyx_int_0);
+            __Pyx_INCREF(__pyx_int_0);
+            PyTuple_SET_ITEM(__pyx_t_10, 2, __pyx_int_0);
+            __Pyx_GIVEREF(__pyx_int_0);
+            __pyx_t_2 = 0;
+            __pyx_t_11 = PyList_Append(__pyx_v_N, ((PyObject *)__pyx_t_10)); if (unlikely(__pyx_t_11 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 109; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+            __Pyx_DECREF(((PyObject *)__pyx_t_10)); __pyx_t_10 = 0;
+
+            /* "bx/align/_epo.pyx":110
+ *                 raise ValueError("last matching block expected (found %s)" % str(line))
+ *             N.append( (int(line[0]), 0, 0) )
+ *             s, t, q = zip( *N )             # <<<<<<<<<<<<<<
+ *             data.append( (hd,
+ *                 numpy.array(s, dtype=numpy.int),
+ */
+            __pyx_t_10 = PySequence_Tuple(((PyObject *)__pyx_v_N)); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+            __Pyx_GOTREF(((PyObject *)__pyx_t_10));
+            __pyx_t_2 = PyObject_Call(__pyx_builtin_zip, ((PyObject *)__pyx_t_10), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+            __Pyx_GOTREF(__pyx_t_2);
+            __Pyx_DECREF(((PyObject *)__pyx_t_10)); __pyx_t_10 = 0;
+            if ((likely(PyTuple_CheckExact(__pyx_t_2))) || (PyList_CheckExact(__pyx_t_2))) {
+              PyObject* sequence = __pyx_t_2;
+              #if CYTHON_COMPILING_IN_CPYTHON
+              Py_ssize_t size = Py_SIZE(sequence);
+              #else
+              Py_ssize_t size = PySequence_Size(sequence);
+              #endif
+              if (unlikely(size != 3)) {
+                if (size > 3) __Pyx_RaiseTooManyValuesError(3);
+                else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
+                {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+              }
+              #if CYTHON_COMPILING_IN_CPYTHON
+              if (likely(PyTuple_CheckExact(sequence))) {
+                __pyx_t_10 = PyTuple_GET_ITEM(sequence, 0); 
+                __pyx_t_4 = PyTuple_GET_ITEM(sequence, 1); 
+                __pyx_t_1 = PyTuple_GET_ITEM(sequence, 2); 
+              } else {
+                __pyx_t_10 = PyList_GET_ITEM(sequence, 0); 
+                __pyx_t_4 = PyList_GET_ITEM(sequence, 1); 
+                __pyx_t_1 = PyList_GET_ITEM(sequence, 2); 
+              }
+              __Pyx_INCREF(__pyx_t_10);
+              __Pyx_INCREF(__pyx_t_4);
+              __Pyx_INCREF(__pyx_t_1);
+              #else
+              __pyx_t_10 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+              __Pyx_GOTREF(__pyx_t_10);
+              __pyx_t_4 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+              __Pyx_GOTREF(__pyx_t_4);
+              __pyx_t_1 = PySequence_ITEM(sequence, 2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+              __Pyx_GOTREF(__pyx_t_1);
+              #endif
+              __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+            } else
+            {
+              Py_ssize_t index = -1;
+              __pyx_t_12 = PyObject_GetIter(__pyx_t_2); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+              __Pyx_GOTREF(__pyx_t_12);
+              __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+              __pyx_t_13 = Py_TYPE(__pyx_t_12)->tp_iternext;
+              index = 0; __pyx_t_10 = __pyx_t_13(__pyx_t_12); if (unlikely(!__pyx_t_10)) goto __pyx_L22_unpacking_failed;
+              __Pyx_GOTREF(__pyx_t_10);
+              index = 1; __pyx_t_4 = __pyx_t_13(__pyx_t_12); if (unlikely(!__pyx_t_4)) goto __pyx_L22_unpacking_failed;
+              __Pyx_GOTREF(__pyx_t_4);
+              index = 2; __pyx_t_1 = __pyx_t_13(__pyx_t_12); if (unlikely(!__pyx_t_1)) goto __pyx_L22_unpacking_failed;
+              __Pyx_GOTREF(__pyx_t_1);
+              if (__Pyx_IternextUnpackEndCheck(__pyx_t_13(__pyx_t_12), 3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+              __pyx_t_13 = NULL;
+              __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
+              goto __pyx_L23_unpacking_done;
+              __pyx_L22_unpacking_failed:;
+              __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
+              __pyx_t_13 = NULL;
+              if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
+              {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+              __pyx_L23_unpacking_done:;
+            }
+            __Pyx_XDECREF(__pyx_v_s);
+            __pyx_v_s = __pyx_t_10;
+            __pyx_t_10 = 0;
+            __Pyx_XDECREF(__pyx_v_t);
+            __pyx_v_t = __pyx_t_4;
+            __pyx_t_4 = 0;
+            __Pyx_XDECREF(__pyx_v_q);
+            __pyx_v_q = __pyx_t_1;
+            __pyx_t_1 = 0;
+
+            /* "bx/align/_epo.pyx":112
+ *             s, t, q = zip( *N )
+ *             data.append( (hd,
+ *                 numpy.array(s, dtype=numpy.int),             # <<<<<<<<<<<<<<
+ *                 numpy.array(t, dtype=numpy.int),
+ *                 numpy.array(q, dtype=numpy.int)) )
+ */
+            __pyx_t_2 = __Pyx_GetName(__pyx_m, __pyx_n_s__numpy); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 112; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+            __Pyx_GOTREF(__pyx_t_2);
+            __pyx_t_1 = PyObject_GetAttr(__pyx_t_2, __pyx_n_s__array); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 112; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+            __Pyx_GOTREF(__pyx_t_1);
+            __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+            __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 112; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+            __Pyx_GOTREF(__pyx_t_2);
+            __Pyx_INCREF(__pyx_v_s);
+            PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_s);
+            __Pyx_GIVEREF(__pyx_v_s);
+            __pyx_t_4 = PyDict_New(); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 112; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+            __Pyx_GOTREF(((PyObject *)__pyx_t_4));
+            __pyx_t_10 = __Pyx_GetName(__pyx_m, __pyx_n_s__numpy); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 112; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+            __Pyx_GOTREF(__pyx_t_10);
+            __pyx_t_12 = PyObject_GetAttr(__pyx_t_10, __pyx_n_s__int); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 112; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+            __Pyx_GOTREF(__pyx_t_12);
+            __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+            if (PyDict_SetItem(__pyx_t_4, ((PyObject *)__pyx_n_s__dtype), __pyx_t_12) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 112; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+            __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
+            __pyx_t_12 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_2), ((PyObject *)__pyx_t_4)); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 112; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+            __Pyx_GOTREF(__pyx_t_12);
+            __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+            __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
+            __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
+
+            /* "bx/align/_epo.pyx":113
+ *             data.append( (hd,
+ *                 numpy.array(s, dtype=numpy.int),
+ *                 numpy.array(t, dtype=numpy.int),             # <<<<<<<<<<<<<<
+ *                 numpy.array(q, dtype=numpy.int)) )
+ *             assert hd.tEnd - hd.tStart == sum(s) + sum(t)
+ */
+            __pyx_t_4 = __Pyx_GetName(__pyx_m, __pyx_n_s__numpy); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 113; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+            __Pyx_GOTREF(__pyx_t_4);
+            __pyx_t_2 = PyObject_GetAttr(__pyx_t_4, __pyx_n_s__array); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 113; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+            __Pyx_GOTREF(__pyx_t_2);
+            __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+            __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 113; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+            __Pyx_GOTREF(__pyx_t_4);
+            __Pyx_INCREF(__pyx_v_t);
+            PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_v_t);
+            __Pyx_GIVEREF(__pyx_v_t);
+            __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 113; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+            __Pyx_GOTREF(((PyObject *)__pyx_t_1));
+            __pyx_t_10 = __Pyx_GetName(__pyx_m, __pyx_n_s__numpy); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 113; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+            __Pyx_GOTREF(__pyx_t_10);
+            __pyx_t_14 = PyObject_GetAttr(__pyx_t_10, __pyx_n_s__int); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 113; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+            __Pyx_GOTREF(__pyx_t_14);
+            __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+            if (PyDict_SetItem(__pyx_t_1, ((PyObject *)__pyx_n_s__dtype), __pyx_t_14) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 113; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+            __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
+            __pyx_t_14 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_4), ((PyObject *)__pyx_t_1)); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 113; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+            __Pyx_GOTREF(__pyx_t_14);
+            __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+            __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
+            __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+
+            /* "bx/align/_epo.pyx":114
+ *                 numpy.array(s, dtype=numpy.int),
+ *                 numpy.array(t, dtype=numpy.int),
+ *                 numpy.array(q, dtype=numpy.int)) )             # <<<<<<<<<<<<<<
+ *             assert hd.tEnd - hd.tStart == sum(s) + sum(t)
+ *             assert hd.qEnd - hd.qStart == sum(s) + sum(q)
+ */
+            __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__numpy); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 114; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+            __Pyx_GOTREF(__pyx_t_1);
+            __pyx_t_4 = PyObject_GetAttr(__pyx_t_1, __pyx_n_s__array); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 114; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+            __Pyx_GOTREF(__pyx_t_4);
+            __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+            __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 114; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+            __Pyx_GOTREF(__pyx_t_1);
+            __Pyx_INCREF(__pyx_v_q);
+            PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_q);
+            __Pyx_GIVEREF(__pyx_v_q);
+            __pyx_t_2 = PyDict_New(); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 114; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+            __Pyx_GOTREF(((PyObject *)__pyx_t_2));
+            __pyx_t_10 = __Pyx_GetName(__pyx_m, __pyx_n_s__numpy); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 114; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+            __Pyx_GOTREF(__pyx_t_10);
+            __pyx_t_15 = PyObject_GetAttr(__pyx_t_10, __pyx_n_s__int); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 114; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+            __Pyx_GOTREF(__pyx_t_15);
+            __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+            if (PyDict_SetItem(__pyx_t_2, ((PyObject *)__pyx_n_s__dtype), __pyx_t_15) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 114; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+            __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
+            __pyx_t_15 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_t_1), ((PyObject *)__pyx_t_2)); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 114; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+            __Pyx_GOTREF(__pyx_t_15);
+            __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+            __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+            __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
+            __pyx_t_2 = PyTuple_New(4); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 111; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+            __Pyx_GOTREF(__pyx_t_2);
+            __Pyx_INCREF(__pyx_v_hd);
+            PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_hd);
+            __Pyx_GIVEREF(__pyx_v_hd);
+            PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_12);
+            __Pyx_GIVEREF(__pyx_t_12);
+            PyTuple_SET_ITEM(__pyx_t_2, 2, __pyx_t_14);
+            __Pyx_GIVEREF(__pyx_t_14);
+            PyTuple_SET_ITEM(__pyx_t_2, 3, __pyx_t_15);
+            __Pyx_GIVEREF(__pyx_t_15);
+            __pyx_t_12 = 0;
+            __pyx_t_14 = 0;
+            __pyx_t_15 = 0;
+            __pyx_t_11 = PyList_Append(__pyx_v_data, ((PyObject *)__pyx_t_2)); if (unlikely(__pyx_t_11 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 111; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+            __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
+
+            /* "bx/align/_epo.pyx":115
+ *                 numpy.array(t, dtype=numpy.int),
+ *                 numpy.array(q, dtype=numpy.int)) )
+ *             assert hd.tEnd - hd.tStart == sum(s) + sum(t)             # <<<<<<<<<<<<<<
+ *             assert hd.qEnd - hd.qStart == sum(s) + sum(q)
+ *             fd.readline() # a blank line
+ */
+            #ifndef CYTHON_WITHOUT_ASSERTIONS
+            __pyx_t_2 = PyObject_GetAttr(__pyx_v_hd, __pyx_n_s__tEnd); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 115; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+            __Pyx_GOTREF(__pyx_t_2);
+            __pyx_t_15 = PyObject_GetAttr(__pyx_v_hd, __pyx_n_s__tStart); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 115; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+            __Pyx_GOTREF(__pyx_t_15);
+            __pyx_t_14 = PyNumber_Subtract(__pyx_t_2, __pyx_t_15); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 115; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+            __Pyx_GOTREF(__pyx_t_14);
+            __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+            __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
+            __pyx_t_15 = PyTuple_New(1); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 115; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+            __Pyx_GOTREF(__pyx_t_15);
+            __Pyx_INCREF(__pyx_v_s);
+            PyTuple_SET_ITEM(__pyx_t_15, 0, __pyx_v_s);
+            __Pyx_GIVEREF(__pyx_v_s);
+            __pyx_t_2 = PyObject_Call(__pyx_builtin_sum, ((PyObject *)__pyx_t_15), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 115; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+            __Pyx_GOTREF(__pyx_t_2);
+            __Pyx_DECREF(((PyObject *)__pyx_t_15)); __pyx_t_15 = 0;
+            __pyx_t_15 = PyTuple_New(1); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 115; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+            __Pyx_GOTREF(__pyx_t_15);
+            __Pyx_INCREF(__pyx_v_t);
+            PyTuple_SET_ITEM(__pyx_t_15, 0, __pyx_v_t);
+            __Pyx_GIVEREF(__pyx_v_t);
+            __pyx_t_12 = PyObject_Call(__pyx_builtin_sum, ((PyObject *)__pyx_t_15), NULL); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 115; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+            __Pyx_GOTREF(__pyx_t_12);
+            __Pyx_DECREF(((PyObject *)__pyx_t_15)); __pyx_t_15 = 0;
+            __pyx_t_15 = PyNumber_Add(__pyx_t_2, __pyx_t_12); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 115; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+            __Pyx_GOTREF(__pyx_t_15);
+            __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+            __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
+            __pyx_t_12 = PyObject_RichCompare(__pyx_t_14, __pyx_t_15, Py_EQ); __Pyx_XGOTREF(__pyx_t_12); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 115; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+            __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
+            __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
+            __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_12); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 115; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+            __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
+            if (unlikely(!__pyx_t_3)) {
+              PyErr_SetNone(PyExc_AssertionError);
+              {__pyx_filename = __pyx_f[0]; __pyx_lineno = 115; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+            }
+            #endif
+
+            /* "bx/align/_epo.pyx":116
+ *                 numpy.array(q, dtype=numpy.int)) )
+ *             assert hd.tEnd - hd.tStart == sum(s) + sum(t)
+ *             assert hd.qEnd - hd.qStart == sum(s) + sum(q)             # <<<<<<<<<<<<<<
+ *             fd.readline() # a blank line
+ *         log.info("parsed %d elements from %s" % (len(data), fname))
+ */
+            #ifndef CYTHON_WITHOUT_ASSERTIONS
+            __pyx_t_12 = PyObject_GetAttr(__pyx_v_hd, __pyx_n_s__qEnd); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+            __Pyx_GOTREF(__pyx_t_12);
+            __pyx_t_15 = PyObject_GetAttr(__pyx_v_hd, __pyx_n_s__qStart); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+            __Pyx_GOTREF(__pyx_t_15);
+            __pyx_t_14 = PyNumber_Subtract(__pyx_t_12, __pyx_t_15); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+            __Pyx_GOTREF(__pyx_t_14);
+            __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
+            __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
+            __pyx_t_15 = PyTuple_New(1); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+            __Pyx_GOTREF(__pyx_t_15);
+            __Pyx_INCREF(__pyx_v_s);
+            PyTuple_SET_ITEM(__pyx_t_15, 0, __pyx_v_s);
+            __Pyx_GIVEREF(__pyx_v_s);
+            __pyx_t_12 = PyObject_Call(__pyx_builtin_sum, ((PyObject *)__pyx_t_15), NULL); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+            __Pyx_GOTREF(__pyx_t_12);
+            __Pyx_DECREF(((PyObject *)__pyx_t_15)); __pyx_t_15 = 0;
+            __pyx_t_15 = PyTuple_New(1); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+            __Pyx_GOTREF(__pyx_t_15);
+            __Pyx_INCREF(__pyx_v_q);
+            PyTuple_SET_ITEM(__pyx_t_15, 0, __pyx_v_q);
+            __Pyx_GIVEREF(__pyx_v_q);
+            __pyx_t_2 = PyObject_Call(__pyx_builtin_sum, ((PyObject *)__pyx_t_15), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+            __Pyx_GOTREF(__pyx_t_2);
+            __Pyx_DECREF(((PyObject *)__pyx_t_15)); __pyx_t_15 = 0;
+            __pyx_t_15 = PyNumber_Add(__pyx_t_12, __pyx_t_2); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+            __Pyx_GOTREF(__pyx_t_15);
+            __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
+            __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+            __pyx_t_2 = PyObject_RichCompare(__pyx_t_14, __pyx_t_15, Py_EQ); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+            __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
+            __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
+            __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+            __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+            if (unlikely(!__pyx_t_3)) {
+              PyErr_SetNone(PyExc_AssertionError);
+              {__pyx_filename = __pyx_f[0]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+            }
+            #endif
+
+            /* "bx/align/_epo.pyx":117
+ *             assert hd.tEnd - hd.tStart == sum(s) + sum(t)
+ *             assert hd.qEnd - hd.qStart == sum(s) + sum(q)
+ *             fd.readline() # a blank line             # <<<<<<<<<<<<<<
+ *         log.info("parsed %d elements from %s" % (len(data), fname))
+ *     return data
+ */
+            __pyx_t_2 = PyObject_GetAttr(__pyx_v_fd, __pyx_n_s__readline); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 117; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+            __Pyx_GOTREF(__pyx_t_2);
+            __pyx_t_15 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 117; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+            __Pyx_GOTREF(__pyx_t_15);
+            __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+            __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
+          }
+          __pyx_L17_break:;
+
+          /* "bx/align/_epo.pyx":118
+ *             assert hd.qEnd - hd.qStart == sum(s) + sum(q)
+ *             fd.readline() # a blank line
+ *         log.info("parsed %d elements from %s" % (len(data), fname))             # <<<<<<<<<<<<<<
+ *     return data
+ * 
+ */
+          __pyx_t_15 = __Pyx_GetName(__pyx_m, __pyx_n_s__log); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 118; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+          __Pyx_GOTREF(__pyx_t_15);
+          __pyx_t_2 = PyObject_GetAttr(__pyx_t_15, __pyx_n_s__info); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 118; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+          __Pyx_GOTREF(__pyx_t_2);
+          __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
+          __pyx_t_9 = PyList_GET_SIZE(((PyObject *)__pyx_v_data)); if (unlikely(__pyx_t_9 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 118; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+          __pyx_t_15 = PyInt_FromSsize_t(__pyx_t_9); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 118; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+          __Pyx_GOTREF(__pyx_t_15);
+          __pyx_t_14 = PyTuple_New(2); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 118; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+          __Pyx_GOTREF(__pyx_t_14);
+          PyTuple_SET_ITEM(__pyx_t_14, 0, __pyx_t_15);
+          __Pyx_GIVEREF(__pyx_t_15);
+          __Pyx_INCREF(__pyx_v_fname);
+          PyTuple_SET_ITEM(__pyx_t_14, 1, __pyx_v_fname);
+          __Pyx_GIVEREF(__pyx_v_fname);
+          __pyx_t_15 = 0;
+          __pyx_t_15 = PyNumber_Remainder(((PyObject *)__pyx_kp_s_16), ((PyObject *)__pyx_t_14)); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 118; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+          __Pyx_GOTREF(((PyObject *)__pyx_t_15));
+          __Pyx_DECREF(((PyObject *)__pyx_t_14)); __pyx_t_14 = 0;
+          __pyx_t_14 = PyTuple_New(1); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 118; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+          __Pyx_GOTREF(__pyx_t_14);
+          PyTuple_SET_ITEM(__pyx_t_14, 0, ((PyObject *)__pyx_t_15));
+          __Pyx_GIVEREF(((PyObject *)__pyx_t_15));
+          __pyx_t_15 = 0;
+          __pyx_t_15 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_14), NULL); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 118; __pyx_clineno = __LINE__; goto __pyx_L7_error;}
+          __Pyx_GOTREF(__pyx_t_15);
+          __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+          __Pyx_DECREF(((PyObject *)__pyx_t_14)); __pyx_t_14 = 0;
+          __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
+        }
+        __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
+        __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
+        __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0;
+        goto __pyx_L14_try_end;
+        __pyx_L7_error:;
+        __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0;
+        __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
+        __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0;
+        __Pyx_XDECREF(__pyx_t_12); __pyx_t_12 = 0;
+        __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0;
+        __Pyx_XDECREF(__pyx_t_14); __pyx_t_14 = 0;
+        __Pyx_XDECREF(__pyx_t_15); __pyx_t_15 = 0;
+
+        /* "bx/align/_epo.pyx":96
+ *     data = []
+ *     open_f = (fname.endswith(".gz") and gzip.open or open)
+ *     with open_f(fname) as fd:             # <<<<<<<<<<<<<<
+ *         while True:
+ *             line = fd.readline()
+ */
+        /*except:*/ {
+          __Pyx_AddTraceback("bx.align._epo.fastLoadChain", __pyx_clineno, __pyx_lineno, __pyx_filename);
+          if (__Pyx_GetException(&__pyx_t_15, &__pyx_t_14, &__pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 96; __pyx_clineno = __LINE__; goto __pyx_L9_except_error;}
+          __Pyx_GOTREF(__pyx_t_15);
+          __Pyx_GOTREF(__pyx_t_14);
+          __Pyx_GOTREF(__pyx_t_2);
+          __pyx_t_12 = PyTuple_New(3); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 96; __pyx_clineno = __LINE__; goto __pyx_L9_except_error;}
+          __Pyx_GOTREF(__pyx_t_12);
+          __Pyx_INCREF(__pyx_t_15);
+          PyTuple_SET_ITEM(__pyx_t_12, 0, __pyx_t_15);
+          __Pyx_GIVEREF(__pyx_t_15);
+          __Pyx_INCREF(__pyx_t_14);
+          PyTuple_SET_ITEM(__pyx_t_12, 1, __pyx_t_14);
+          __Pyx_GIVEREF(__pyx_t_14);
+          __Pyx_INCREF(__pyx_t_2);
+          PyTuple_SET_ITEM(__pyx_t_12, 2, __pyx_t_2);
+          __Pyx_GIVEREF(__pyx_t_2);
+          __pyx_t_16 = PyObject_Call(__pyx_t_5, __pyx_t_12, NULL);
+          __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+          if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 96; __pyx_clineno = __LINE__; goto __pyx_L9_except_error;}
+          __Pyx_GOTREF(__pyx_t_16);
+          __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_16);
+          __Pyx_DECREF(__pyx_t_16); __pyx_t_16 = 0;
+          if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 96; __pyx_clineno = __LINE__; goto __pyx_L9_except_error;}
+          __pyx_t_17 = (!__pyx_t_3);
+          if (__pyx_t_17) {
+            __Pyx_GIVEREF(__pyx_t_15);
+            __Pyx_GIVEREF(__pyx_t_14);
+            __Pyx_GIVEREF(__pyx_t_2);
+            __Pyx_ErrRestore(__pyx_t_15, __pyx_t_14, __pyx_t_2);
+            __pyx_t_15 = 0; __pyx_t_14 = 0; __pyx_t_2 = 0; 
+            {__pyx_filename = __pyx_f[0]; __pyx_lineno = 96; __pyx_clineno = __LINE__; goto __pyx_L9_except_error;}
+            goto __pyx_L26;
+          }
+          __pyx_L26:;
+          __Pyx_DECREF(((PyObject *)__pyx_t_12)); __pyx_t_12 = 0;
+          __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
+          __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
+          __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+          goto __pyx_L8_exception_handled;
+        }
+        __pyx_L9_except_error:;
+        __Pyx_XGIVEREF(__pyx_t_6);
+        __Pyx_XGIVEREF(__pyx_t_7);
+        __Pyx_XGIVEREF(__pyx_t_8);
+        __Pyx_ExceptionReset(__pyx_t_6, __pyx_t_7, __pyx_t_8);
+        goto __pyx_L1_error;
+        __pyx_L8_exception_handled:;
+        __Pyx_XGIVEREF(__pyx_t_6);
+        __Pyx_XGIVEREF(__pyx_t_7);
+        __Pyx_XGIVEREF(__pyx_t_8);
+        __Pyx_ExceptionReset(__pyx_t_6, __pyx_t_7, __pyx_t_8);
+        __pyx_L14_try_end:;
+      }
+    }
+    /*finally:*/ {
+      if (__pyx_t_5) {
+        __pyx_t_8 = PyObject_Call(__pyx_t_5, __pyx_k_tuple_17, NULL);
+        __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+        if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 96; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_8);
+        __pyx_t_17 = __Pyx_PyObject_IsTrue(__pyx_t_8);
+        __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+        if (unlikely(__pyx_t_17 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 96; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      }
+    }
+    goto __pyx_L27;
+    __pyx_L3_error:;
+    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+    goto __pyx_L1_error;
+    __pyx_L27:;
+  }
+
+  /* "bx/align/_epo.pyx":119
+ *             fd.readline() # a blank line
+ *         log.info("parsed %d elements from %s" % (len(data), fname))
+ *     return data             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __Pyx_INCREF(((PyObject *)__pyx_v_data));
+  __pyx_r = ((PyObject *)__pyx_v_data);
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_XDECREF(__pyx_t_10);
+  __Pyx_XDECREF(__pyx_t_12);
+  __Pyx_XDECREF(__pyx_t_14);
+  __Pyx_XDECREF(__pyx_t_15);
+  __Pyx_AddTraceback("bx.align._epo.fastLoadChain", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_data);
+  __Pyx_XDECREF(__pyx_v_open_f);
+  __Pyx_XDECREF(__pyx_v_fd);
+  __Pyx_XDECREF(__pyx_v_line);
+  __Pyx_XDECREF(__pyx_v_hd);
+  __Pyx_XDECREF(__pyx_v_N);
+  __Pyx_XDECREF(__pyx_v_s);
+  __Pyx_XDECREF(__pyx_v_t);
+  __Pyx_XDECREF(__pyx_v_q);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/align/_epo.pyx":125
+ * @cython.wraparound(False)
+ * @cython.boundscheck(False)
+ * cpdef numpy.ndarray[numpy.uint64_t, ndim=2] bed_union( numpy.ndarray[numpy.uint64_t, ndim=2] elements ):             # <<<<<<<<<<<<<<
+ *     """compute the union of these elements. simply walk the sorted elements and join the intersecting ones
+ *     works on half-open intervals, i.e., [a, b), [b, c) ---> [a, c)
+ */
+
+static PyObject *__pyx_pw_2bx_5align_4_epo_5bed_union(PyObject *__pyx_self, PyObject *__pyx_v_elements); /*proto*/
+static PyArrayObject *__pyx_f_2bx_5align_4_epo_bed_union(PyArrayObject *__pyx_v_elements, CYTHON_UNUSED int __pyx_skip_dispatch) {
+  Py_ssize_t __pyx_v_cst;
+  Py_ssize_t __pyx_v_cen;
+  Py_ssize_t __pyx_v_i;
+  Py_ssize_t __pyx_v_j;
+  PyArrayObject *__pyx_v_tmp_elems = 0;
+  PyArrayObject *__pyx_v_final_elems = 0;
+  __Pyx_LocalBuf_ND __pyx_pybuffernd_elements;
+  __Pyx_Buffer __pyx_pybuffer_elements;
+  __Pyx_LocalBuf_ND __pyx_pybuffernd_final_elems;
+  __Pyx_Buffer __pyx_pybuffer_final_elems;
+  __Pyx_LocalBuf_ND __pyx_pybuffernd_tmp_elems;
+  __Pyx_Buffer __pyx_pybuffer_tmp_elems;
+  PyArrayObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  int __pyx_t_4;
+  PyObject *__pyx_t_5 = NULL;
+  PyArrayObject *__pyx_t_6 = NULL;
+  int __pyx_t_7;
+  PyObject *__pyx_t_8 = NULL;
+  PyObject *__pyx_t_9 = NULL;
+  PyObject *__pyx_t_10 = NULL;
+  long __pyx_t_11;
+  long __pyx_t_12;
+  long __pyx_t_13;
+  long __pyx_t_14;
+  long __pyx_t_15;
+  Py_ssize_t __pyx_t_16;
+  Py_ssize_t __pyx_t_17;
+  long __pyx_t_18;
+  Py_ssize_t __pyx_t_19;
+  long __pyx_t_20;
+  Py_ssize_t __pyx_t_21;
+  long __pyx_t_22;
+  Py_ssize_t __pyx_t_23;
+  long __pyx_t_24;
+  Py_ssize_t __pyx_t_25;
+  long __pyx_t_26;
+  Py_ssize_t __pyx_t_27;
+  long __pyx_t_28;
+  Py_ssize_t __pyx_t_29;
+  long __pyx_t_30;
+  Py_ssize_t __pyx_t_31;
+  Py_ssize_t __pyx_t_32;
+  Py_ssize_t __pyx_t_33;
+  long __pyx_t_34;
+  Py_ssize_t __pyx_t_35;
+  long __pyx_t_36;
+  Py_ssize_t __pyx_t_37;
+  long __pyx_t_38;
+  Py_ssize_t __pyx_t_39;
+  long __pyx_t_40;
+  long __pyx_t_41;
+  long __pyx_t_42;
+  long __pyx_t_43;
+  long __pyx_t_44;
+  long __pyx_t_45;
+  long __pyx_t_46;
+  long __pyx_t_47;
+  long __pyx_t_48;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("bed_union", 0);
+  __pyx_pybuffer_tmp_elems.pybuffer.buf = NULL;
+  __pyx_pybuffer_tmp_elems.refcount = 0;
+  __pyx_pybuffernd_tmp_elems.data = NULL;
+  __pyx_pybuffernd_tmp_elems.rcbuffer = &__pyx_pybuffer_tmp_elems;
+  __pyx_pybuffer_final_elems.pybuffer.buf = NULL;
+  __pyx_pybuffer_final_elems.refcount = 0;
+  __pyx_pybuffernd_final_elems.data = NULL;
+  __pyx_pybuffernd_final_elems.rcbuffer = &__pyx_pybuffer_final_elems;
+  __pyx_pybuffer_elements.pybuffer.buf = NULL;
+  __pyx_pybuffer_elements.refcount = 0;
+  __pyx_pybuffernd_elements.data = NULL;
+  __pyx_pybuffernd_elements.rcbuffer = &__pyx_pybuffer_elements;
+  {
+    __Pyx_BufFmt_StackElem __pyx_stack[1];
+    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_elements.rcbuffer->pybuffer, (PyObject*)__pyx_v_elements, &__Pyx_TypeInfo_nn___pyx_t_5numpy_uint64_t, PyBUF_FORMAT| PyBUF_STRIDES, 2, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  __pyx_pybuffernd_elements.diminfo[0].strides = __pyx_pybuffernd_elements.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_elements.diminfo[0].shape = __pyx_pybuffernd_elements.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_elements.diminfo[1].strides = __pyx_pybuffernd_elements.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_elements.diminfo[1].shape = __pyx_pybuffernd_elements.rcbuffer->pybuffer.shape[1];
+
+  /* "bx/align/_epo.pyx":132
+ *     @return: 2-dim numpy array of unsigned64 ints"""
+ * 
+ *     assert numpy.shape(elements)[0] > 0             # <<<<<<<<<<<<<<
+ * 
+ *     cdef Py_ssize_t cst, cen, i, j
+ */
+  #ifndef CYTHON_WITHOUT_ASSERTIONS
+  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__numpy); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = PyObject_GetAttr(__pyx_t_1, __pyx_n_s__shape); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_INCREF(((PyObject *)__pyx_v_elements));
+  PyTuple_SET_ITEM(__pyx_t_1, 0, ((PyObject *)__pyx_v_elements));
+  __Pyx_GIVEREF(((PyObject *)__pyx_v_elements));
+  __pyx_t_3 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+  __pyx_t_1 = __Pyx_GetItemInt(__pyx_t_3, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __pyx_t_3 = PyObject_RichCompare(__pyx_t_1, __pyx_int_0, Py_GT); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  if (unlikely(!__pyx_t_4)) {
+    PyErr_SetNone(PyExc_AssertionError);
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  #endif
+
+  /* "bx/align/_epo.pyx":137
+ *     cdef numpy.ndarray[numpy.uint64_t, ndim=2] tmp_elems, final_elems
+ * 
+ *     elements.sort(axis=0)             # <<<<<<<<<<<<<<
+ *     assert elements[0][0] <= elements[numpy.shape(elements)[0]-1][0]
+ *     tmp_elems = numpy.zeros((numpy.shape(elements)[0], 2), dtype=DTYPE)
+ */
+  __pyx_t_3 = PyObject_GetAttr(((PyObject *)__pyx_v_elements), __pyx_n_s__sort); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 137; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 137; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(((PyObject *)__pyx_t_1));
+  if (PyDict_SetItem(__pyx_t_1, ((PyObject *)__pyx_n_s__axis), __pyx_int_0) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 137; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_empty_tuple), ((PyObject *)__pyx_t_1)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 137; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+  /* "bx/align/_epo.pyx":138
+ * 
+ *     elements.sort(axis=0)
+ *     assert elements[0][0] <= elements[numpy.shape(elements)[0]-1][0]             # <<<<<<<<<<<<<<
+ *     tmp_elems = numpy.zeros((numpy.shape(elements)[0], 2), dtype=DTYPE)
+ *     cst = elements[0, 0]
+ */
+  #ifndef CYTHON_WITHOUT_ASSERTIONS
+  __pyx_t_2 = __Pyx_GetItemInt(((PyObject *)__pyx_v_elements), 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 138; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_1 = __Pyx_GetItemInt(__pyx_t_2, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 138; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_2 = __Pyx_GetName(__pyx_m, __pyx_n_s__numpy); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 138; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = PyObject_GetAttr(__pyx_t_2, __pyx_n_s__shape); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 138; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 138; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_INCREF(((PyObject *)__pyx_v_elements));
+  PyTuple_SET_ITEM(__pyx_t_2, 0, ((PyObject *)__pyx_v_elements));
+  __Pyx_GIVEREF(((PyObject *)__pyx_v_elements));
+  __pyx_t_5 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 138; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
+  __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_5, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 138; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+  __pyx_t_5 = PyNumber_Subtract(__pyx_t_2, __pyx_int_1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 138; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_2 = PyObject_GetItem(((PyObject *)__pyx_v_elements), __pyx_t_5); if (!__pyx_t_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 138; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+  __pyx_t_5 = __Pyx_GetItemInt(__pyx_t_2, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 138; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_2 = PyObject_RichCompare(__pyx_t_1, __pyx_t_5, Py_LE); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 138; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+  __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 138; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  if (unlikely(!__pyx_t_4)) {
+    PyErr_SetNone(PyExc_AssertionError);
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 138; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  #endif
+
+  /* "bx/align/_epo.pyx":139
+ *     elements.sort(axis=0)
+ *     assert elements[0][0] <= elements[numpy.shape(elements)[0]-1][0]
+ *     tmp_elems = numpy.zeros((numpy.shape(elements)[0], 2), dtype=DTYPE)             # <<<<<<<<<<<<<<
+ *     cst = elements[0, 0]
+ *     cen = elements[0, 1]
+ */
+  __pyx_t_2 = __Pyx_GetName(__pyx_m, __pyx_n_s__numpy); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 139; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_5 = PyObject_GetAttr(__pyx_t_2, __pyx_n_s__zeros); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 139; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_2 = __Pyx_GetName(__pyx_m, __pyx_n_s__numpy); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 139; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_1 = PyObject_GetAttr(__pyx_t_2, __pyx_n_s__shape); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 139; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 139; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_INCREF(((PyObject *)__pyx_v_elements));
+  PyTuple_SET_ITEM(__pyx_t_2, 0, ((PyObject *)__pyx_v_elements));
+  __Pyx_GIVEREF(((PyObject *)__pyx_v_elements));
+  __pyx_t_3 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 139; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
+  __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_3, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 139; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 139; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_2);
+  __Pyx_GIVEREF(__pyx_t_2);
+  __Pyx_INCREF(__pyx_int_2);
+  PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_int_2);
+  __Pyx_GIVEREF(__pyx_int_2);
+  __pyx_t_2 = 0;
+  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 139; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  PyTuple_SET_ITEM(__pyx_t_2, 0, ((PyObject *)__pyx_t_3));
+  __Pyx_GIVEREF(((PyObject *)__pyx_t_3));
+  __pyx_t_3 = 0;
+  __pyx_t_3 = PyDict_New(); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 139; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(((PyObject *)__pyx_t_3));
+  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__DTYPE); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 139; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_t_3, ((PyObject *)__pyx_n_s__dtype), __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 139; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_1 = PyObject_Call(__pyx_t_5, ((PyObject *)__pyx_t_2), ((PyObject *)__pyx_t_3)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 139; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
+  if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 139; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_6 = ((PyArrayObject *)__pyx_t_1);
+  {
+    __Pyx_BufFmt_StackElem __pyx_stack[1];
+    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_tmp_elems.rcbuffer->pybuffer);
+    __pyx_t_7 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_tmp_elems.rcbuffer->pybuffer, (PyObject*)__pyx_t_6, &__Pyx_TypeInfo_nn___pyx_t_5numpy_uint64_t, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 2, 0, __pyx_stack);
+    if (unlikely(__pyx_t_7 < 0)) {
+      PyErr_Fetch(&__pyx_t_8, &__pyx_t_9, &__pyx_t_10);
+      if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_tmp_elems.rcbuffer->pybuffer, (PyObject*)__pyx_v_tmp_elems, &__Pyx_TypeInfo_nn___pyx_t_5numpy_uint64_t, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 2, 0, __pyx_stack) == -1)) {
+        Py_XDECREF(__pyx_t_8); Py_XDECREF(__pyx_t_9); Py_XDECREF(__pyx_t_10);
+        __Pyx_RaiseBufferFallbackError();
+      } else {
+        PyErr_Restore(__pyx_t_8, __pyx_t_9, __pyx_t_10);
+      }
+    }
+    __pyx_pybuffernd_tmp_elems.diminfo[0].strides = __pyx_pybuffernd_tmp_elems.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_tmp_elems.diminfo[0].shape = __pyx_pybuffernd_tmp_elems.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_tmp_elems.diminfo[1].strides = __pyx_pybuffernd_tmp_elems.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_tmp_elems.diminfo[1].shape = __pyx_pybuffernd_tmp_elems.rcbuffer->pybuffer.shape[1];
+    if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 139; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  __pyx_t_6 = 0;
+  __pyx_v_tmp_elems = ((PyArrayObject *)__pyx_t_1);
+  __pyx_t_1 = 0;
+
+  /* "bx/align/_epo.pyx":140
+ *     assert elements[0][0] <= elements[numpy.shape(elements)[0]-1][0]
+ *     tmp_elems = numpy.zeros((numpy.shape(elements)[0], 2), dtype=DTYPE)
+ *     cst = elements[0, 0]             # <<<<<<<<<<<<<<
+ *     cen = elements[0, 1]
+ *     j = 0
+ */
+  __pyx_t_11 = 0;
+  __pyx_t_12 = 0;
+  __pyx_v_cst = (*__Pyx_BufPtrStrided2d(__pyx_t_5numpy_uint64_t *, __pyx_pybuffernd_elements.rcbuffer->pybuffer.buf, __pyx_t_11, __pyx_pybuffernd_elements.diminfo[0].strides, __pyx_t_12, __pyx_pybuffernd_elements.diminfo[1].strides));
+
+  /* "bx/align/_epo.pyx":141
+ *     tmp_elems = numpy.zeros((numpy.shape(elements)[0], 2), dtype=DTYPE)
+ *     cst = elements[0, 0]
+ *     cen = elements[0, 1]             # <<<<<<<<<<<<<<
+ *     j = 0
+ * 
+ */
+  __pyx_t_13 = 0;
+  __pyx_t_14 = 1;
+  __pyx_v_cen = (*__Pyx_BufPtrStrided2d(__pyx_t_5numpy_uint64_t *, __pyx_pybuffernd_elements.rcbuffer->pybuffer.buf, __pyx_t_13, __pyx_pybuffernd_elements.diminfo[0].strides, __pyx_t_14, __pyx_pybuffernd_elements.diminfo[1].strides));
+
+  /* "bx/align/_epo.pyx":142
+ *     cst = elements[0, 0]
+ *     cen = elements[0, 1]
+ *     j = 0             # <<<<<<<<<<<<<<
+ * 
+ *     for i in range(1, numpy.shape(elements)[0]):
+ */
+  __pyx_v_j = 0;
+
+  /* "bx/align/_epo.pyx":144
+ *     j = 0
+ * 
+ *     for i in range(1, numpy.shape(elements)[0]):             # <<<<<<<<<<<<<<
+ *         if elements[i, 0] <= cen: # overlaps with the last one
+ *             cen = max2(cen, elements[i, 1])
+ */
+  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__numpy); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 144; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_3 = PyObject_GetAttr(__pyx_t_1, __pyx_n_s__shape); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 144; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 144; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_INCREF(((PyObject *)__pyx_v_elements));
+  PyTuple_SET_ITEM(__pyx_t_1, 0, ((PyObject *)__pyx_v_elements));
+  __Pyx_GIVEREF(((PyObject *)__pyx_v_elements));
+  __pyx_t_2 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 144; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+  __pyx_t_1 = __Pyx_GetItemInt(__pyx_t_2, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 144; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_15 = __Pyx_PyInt_AsLong(__pyx_t_1); if (unlikely((__pyx_t_15 == (long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 144; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  for (__pyx_t_16 = 1; __pyx_t_16 < __pyx_t_15; __pyx_t_16+=1) {
+    __pyx_v_i = __pyx_t_16;
+
+    /* "bx/align/_epo.pyx":145
+ * 
+ *     for i in range(1, numpy.shape(elements)[0]):
+ *         if elements[i, 0] <= cen: # overlaps with the last one             # <<<<<<<<<<<<<<
+ *             cen = max2(cen, elements[i, 1])
+ *         else:
+ */
+    __pyx_t_17 = __pyx_v_i;
+    __pyx_t_18 = 0;
+    __pyx_t_4 = ((*__Pyx_BufPtrStrided2d(__pyx_t_5numpy_uint64_t *, __pyx_pybuffernd_elements.rcbuffer->pybuffer.buf, __pyx_t_17, __pyx_pybuffernd_elements.diminfo[0].strides, __pyx_t_18, __pyx_pybuffernd_elements.diminfo[1].strides)) <= __pyx_v_cen);
+    if (__pyx_t_4) {
+
+      /* "bx/align/_epo.pyx":146
+ *     for i in range(1, numpy.shape(elements)[0]):
+ *         if elements[i, 0] <= cen: # overlaps with the last one
+ *             cen = max2(cen, elements[i, 1])             # <<<<<<<<<<<<<<
+ *         else:
+ *             tmp_elems[j, 0] = cst
+ */
+      __pyx_t_19 = __pyx_v_i;
+      __pyx_t_20 = 1;
+      __pyx_v_cen = __pyx_f_2bx_5align_4_epo_max2(__pyx_v_cen, (*__Pyx_BufPtrStrided2d(__pyx_t_5numpy_uint64_t *, __pyx_pybuffernd_elements.rcbuffer->pybuffer.buf, __pyx_t_19, __pyx_pybuffernd_elements.diminfo[0].strides, __pyx_t_20, __pyx_pybuffernd_elements.diminfo[1].strides)));
+      goto __pyx_L5;
+    }
+    /*else*/ {
+
+      /* "bx/align/_epo.pyx":148
+ *             cen = max2(cen, elements[i, 1])
+ *         else:
+ *             tmp_elems[j, 0] = cst             # <<<<<<<<<<<<<<
+ *             tmp_elems[j, 1] = cen
+ *             j += 1
+ */
+      __pyx_t_21 = __pyx_v_j;
+      __pyx_t_22 = 0;
+      *__Pyx_BufPtrStrided2d(__pyx_t_5numpy_uint64_t *, __pyx_pybuffernd_tmp_elems.rcbuffer->pybuffer.buf, __pyx_t_21, __pyx_pybuffernd_tmp_elems.diminfo[0].strides, __pyx_t_22, __pyx_pybuffernd_tmp_elems.diminfo[1].strides) = __pyx_v_cst;
+
+      /* "bx/align/_epo.pyx":149
+ *         else:
+ *             tmp_elems[j, 0] = cst
+ *             tmp_elems[j, 1] = cen             # <<<<<<<<<<<<<<
+ *             j += 1
+ *             cst = elements[i, 0]
+ */
+      __pyx_t_23 = __pyx_v_j;
+      __pyx_t_24 = 1;
+      *__Pyx_BufPtrStrided2d(__pyx_t_5numpy_uint64_t *, __pyx_pybuffernd_tmp_elems.rcbuffer->pybuffer.buf, __pyx_t_23, __pyx_pybuffernd_tmp_elems.diminfo[0].strides, __pyx_t_24, __pyx_pybuffernd_tmp_elems.diminfo[1].strides) = __pyx_v_cen;
+
+      /* "bx/align/_epo.pyx":150
+ *             tmp_elems[j, 0] = cst
+ *             tmp_elems[j, 1] = cen
+ *             j += 1             # <<<<<<<<<<<<<<
+ *             cst = elements[i, 0]
+ *             cen = elements[i, 1]
+ */
+      __pyx_v_j = (__pyx_v_j + 1);
+
+      /* "bx/align/_epo.pyx":151
+ *             tmp_elems[j, 1] = cen
+ *             j += 1
+ *             cst = elements[i, 0]             # <<<<<<<<<<<<<<
+ *             cen = elements[i, 1]
+ *     tmp_elems[j, 0] = cst
+ */
+      __pyx_t_25 = __pyx_v_i;
+      __pyx_t_26 = 0;
+      __pyx_v_cst = (*__Pyx_BufPtrStrided2d(__pyx_t_5numpy_uint64_t *, __pyx_pybuffernd_elements.rcbuffer->pybuffer.buf, __pyx_t_25, __pyx_pybuffernd_elements.diminfo[0].strides, __pyx_t_26, __pyx_pybuffernd_elements.diminfo[1].strides));
+
+      /* "bx/align/_epo.pyx":152
+ *             j += 1
+ *             cst = elements[i, 0]
+ *             cen = elements[i, 1]             # <<<<<<<<<<<<<<
+ *     tmp_elems[j, 0] = cst
+ *     tmp_elems[j, 1] = cen
+ */
+      __pyx_t_27 = __pyx_v_i;
+      __pyx_t_28 = 1;
+      __pyx_v_cen = (*__Pyx_BufPtrStrided2d(__pyx_t_5numpy_uint64_t *, __pyx_pybuffernd_elements.rcbuffer->pybuffer.buf, __pyx_t_27, __pyx_pybuffernd_elements.diminfo[0].strides, __pyx_t_28, __pyx_pybuffernd_elements.diminfo[1].strides));
+    }
+    __pyx_L5:;
+  }
+
+  /* "bx/align/_epo.pyx":153
+ *             cst = elements[i, 0]
+ *             cen = elements[i, 1]
+ *     tmp_elems[j, 0] = cst             # <<<<<<<<<<<<<<
+ *     tmp_elems[j, 1] = cen
+ *     j += 1
+ */
+  __pyx_t_16 = __pyx_v_j;
+  __pyx_t_15 = 0;
+  *__Pyx_BufPtrStrided2d(__pyx_t_5numpy_uint64_t *, __pyx_pybuffernd_tmp_elems.rcbuffer->pybuffer.buf, __pyx_t_16, __pyx_pybuffernd_tmp_elems.diminfo[0].strides, __pyx_t_15, __pyx_pybuffernd_tmp_elems.diminfo[1].strides) = __pyx_v_cst;
+
+  /* "bx/align/_epo.pyx":154
+ *             cen = elements[i, 1]
+ *     tmp_elems[j, 0] = cst
+ *     tmp_elems[j, 1] = cen             # <<<<<<<<<<<<<<
+ *     j += 1
+ *     final_elems = numpy.empty((j, 2), dtype=DTYPE)
+ */
+  __pyx_t_29 = __pyx_v_j;
+  __pyx_t_30 = 1;
+  *__Pyx_BufPtrStrided2d(__pyx_t_5numpy_uint64_t *, __pyx_pybuffernd_tmp_elems.rcbuffer->pybuffer.buf, __pyx_t_29, __pyx_pybuffernd_tmp_elems.diminfo[0].strides, __pyx_t_30, __pyx_pybuffernd_tmp_elems.diminfo[1].strides) = __pyx_v_cen;
+
+  /* "bx/align/_epo.pyx":155
+ *     tmp_elems[j, 0] = cst
+ *     tmp_elems[j, 1] = cen
+ *     j += 1             # <<<<<<<<<<<<<<
+ *     final_elems = numpy.empty((j, 2), dtype=DTYPE)
+ *     for i in range(j):
+ */
+  __pyx_v_j = (__pyx_v_j + 1);
+
+  /* "bx/align/_epo.pyx":156
+ *     tmp_elems[j, 1] = cen
+ *     j += 1
+ *     final_elems = numpy.empty((j, 2), dtype=DTYPE)             # <<<<<<<<<<<<<<
+ *     for i in range(j):
+ *         final_elems[i, 0] = tmp_elems[i, 0]
+ */
+  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__numpy); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = PyObject_GetAttr(__pyx_t_1, __pyx_n_s__empty); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_1 = PyInt_FromSsize_t(__pyx_v_j); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1);
+  __Pyx_GIVEREF(__pyx_t_1);
+  __Pyx_INCREF(__pyx_int_2);
+  PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_int_2);
+  __Pyx_GIVEREF(__pyx_int_2);
+  __pyx_t_1 = 0;
+  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  PyTuple_SET_ITEM(__pyx_t_1, 0, ((PyObject *)__pyx_t_3));
+  __Pyx_GIVEREF(((PyObject *)__pyx_t_3));
+  __pyx_t_3 = 0;
+  __pyx_t_3 = PyDict_New(); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(((PyObject *)__pyx_t_3));
+  __pyx_t_5 = __Pyx_GetName(__pyx_m, __pyx_n_s__DTYPE); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  if (PyDict_SetItem(__pyx_t_3, ((PyObject *)__pyx_n_s__dtype), __pyx_t_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+  __pyx_t_5 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_1), ((PyObject *)__pyx_t_3)); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
+  if (!(likely(((__pyx_t_5) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_5, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_6 = ((PyArrayObject *)__pyx_t_5);
+  {
+    __Pyx_BufFmt_StackElem __pyx_stack[1];
+    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_final_elems.rcbuffer->pybuffer);
+    __pyx_t_7 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_final_elems.rcbuffer->pybuffer, (PyObject*)__pyx_t_6, &__Pyx_TypeInfo_nn___pyx_t_5numpy_uint64_t, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 2, 0, __pyx_stack);
+    if (unlikely(__pyx_t_7 < 0)) {
+      PyErr_Fetch(&__pyx_t_10, &__pyx_t_9, &__pyx_t_8);
+      if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_final_elems.rcbuffer->pybuffer, (PyObject*)__pyx_v_final_elems, &__Pyx_TypeInfo_nn___pyx_t_5numpy_uint64_t, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 2, 0, __pyx_stack) == -1)) {
+        Py_XDECREF(__pyx_t_10); Py_XDECREF(__pyx_t_9); Py_XDECREF(__pyx_t_8);
+        __Pyx_RaiseBufferFallbackError();
+      } else {
+        PyErr_Restore(__pyx_t_10, __pyx_t_9, __pyx_t_8);
+      }
+    }
+    __pyx_pybuffernd_final_elems.diminfo[0].strides = __pyx_pybuffernd_final_elems.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_final_elems.diminfo[0].shape = __pyx_pybuffernd_final_elems.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_final_elems.diminfo[1].strides = __pyx_pybuffernd_final_elems.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_final_elems.diminfo[1].shape = __pyx_pybuffernd_final_elems.rcbuffer->pybuffer.shape[1];
+    if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  __pyx_t_6 = 0;
+  __pyx_v_final_elems = ((PyArrayObject *)__pyx_t_5);
+  __pyx_t_5 = 0;
+
+  /* "bx/align/_epo.pyx":157
+ *     j += 1
+ *     final_elems = numpy.empty((j, 2), dtype=DTYPE)
+ *     for i in range(j):             # <<<<<<<<<<<<<<
+ *         final_elems[i, 0] = tmp_elems[i, 0]
+ *         final_elems[i, 1] = tmp_elems[i, 1]
+ */
+  __pyx_t_31 = __pyx_v_j;
+  for (__pyx_t_32 = 0; __pyx_t_32 < __pyx_t_31; __pyx_t_32+=1) {
+    __pyx_v_i = __pyx_t_32;
+
+    /* "bx/align/_epo.pyx":158
+ *     final_elems = numpy.empty((j, 2), dtype=DTYPE)
+ *     for i in range(j):
+ *         final_elems[i, 0] = tmp_elems[i, 0]             # <<<<<<<<<<<<<<
+ *         final_elems[i, 1] = tmp_elems[i, 1]
+ *     assert final_elems[0, 0] == elements[0, 0], "fe=%d, e=%d" % (final_elems[0,0], elements[0,0])
+ */
+    __pyx_t_33 = __pyx_v_i;
+    __pyx_t_34 = 0;
+    __pyx_t_35 = __pyx_v_i;
+    __pyx_t_36 = 0;
+    *__Pyx_BufPtrStrided2d(__pyx_t_5numpy_uint64_t *, __pyx_pybuffernd_final_elems.rcbuffer->pybuffer.buf, __pyx_t_35, __pyx_pybuffernd_final_elems.diminfo[0].strides, __pyx_t_36, __pyx_pybuffernd_final_elems.diminfo[1].strides) = (*__Pyx_BufPtrStrided2d(__pyx_t_5numpy_uint64_t *, __pyx_pybuffernd_tmp_elems.rcbuffer->pybuffer.buf, __pyx_t_33, __pyx_pybuffernd_tmp_elems.diminfo[0].strides, __pyx_t_34, __pyx_pybuffernd_tmp_elems.diminfo[1].strides));
+
+    /* "bx/align/_epo.pyx":159
+ *     for i in range(j):
+ *         final_elems[i, 0] = tmp_elems[i, 0]
+ *         final_elems[i, 1] = tmp_elems[i, 1]             # <<<<<<<<<<<<<<
+ *     assert final_elems[0, 0] == elements[0, 0], "fe=%d, e=%d" % (final_elems[0,0], elements[0,0])
+ *     return final_elems
+ */
+    __pyx_t_37 = __pyx_v_i;
+    __pyx_t_38 = 1;
+    __pyx_t_39 = __pyx_v_i;
+    __pyx_t_40 = 1;
+    *__Pyx_BufPtrStrided2d(__pyx_t_5numpy_uint64_t *, __pyx_pybuffernd_final_elems.rcbuffer->pybuffer.buf, __pyx_t_39, __pyx_pybuffernd_final_elems.diminfo[0].strides, __pyx_t_40, __pyx_pybuffernd_final_elems.diminfo[1].strides) = (*__Pyx_BufPtrStrided2d(__pyx_t_5numpy_uint64_t *, __pyx_pybuffernd_tmp_elems.rcbuffer->pybuffer.buf, __pyx_t_37, __pyx_pybuffernd_tmp_elems.diminfo[0].strides, __pyx_t_38, __pyx_pybuffernd_tmp_elems.diminfo[1].strides));
+  }
+
+  /* "bx/align/_epo.pyx":160
+ *         final_elems[i, 0] = tmp_elems[i, 0]
+ *         final_elems[i, 1] = tmp_elems[i, 1]
+ *     assert final_elems[0, 0] == elements[0, 0], "fe=%d, e=%d" % (final_elems[0,0], elements[0,0])             # <<<<<<<<<<<<<<
+ *     return final_elems
+ * 
+ */
+  #ifndef CYTHON_WITHOUT_ASSERTIONS
+  __pyx_t_41 = 0;
+  __pyx_t_42 = 0;
+  __pyx_t_43 = 0;
+  __pyx_t_44 = 0;
+  if (unlikely(!((*__Pyx_BufPtrStrided2d(__pyx_t_5numpy_uint64_t *, __pyx_pybuffernd_final_elems.rcbuffer->pybuffer.buf, __pyx_t_41, __pyx_pybuffernd_final_elems.diminfo[0].strides, __pyx_t_42, __pyx_pybuffernd_final_elems.diminfo[1].strides)) == (*__Pyx_BufPtrStrided2d(__pyx_t_5numpy_uint64_t *, __pyx_pybuffernd_elements.rcbuffer->pybuffer.buf, __pyx_t_43, __pyx_pybuffernd_elements.diminfo[0].strides, __pyx_t_44, __pyx_pybuffernd_elements.diminfo[1].strides))))) {
+    __pyx_t_45 = 0;
+    __pyx_t_46 = 0;
+    __pyx_t_5 = __Pyx_PyInt_to_py_npy_uint64((*__Pyx_BufPtrStrided2d(__pyx_t_5numpy_uint64_t *, __pyx_pybuffernd_final_elems.rcbuffer->pybuffer.buf, __pyx_t_45, __pyx_pybuffernd_final_elems.diminfo[0].strides, __pyx_t_46, __pyx_pybuffernd_final_elems.diminfo[1].strides))); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 160; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_5);
+    __pyx_t_47 = 0;
+    __pyx_t_48 = 0;
+    __pyx_t_3 = __Pyx_PyInt_to_py_npy_uint64((*__Pyx_BufPtrStrided2d(__pyx_t_5numpy_uint64_t *, __pyx_pybuffernd_elements.rcbuffer->pybuffer.buf, __pyx_t_47, __pyx_pybuffernd_elements.diminfo[0].strides, __pyx_t_48, __pyx_pybuffernd_elements.diminfo[1].strides))); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 160; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 160; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_5);
+    __Pyx_GIVEREF(__pyx_t_5);
+    PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_t_3);
+    __Pyx_GIVEREF(__pyx_t_3);
+    __pyx_t_5 = 0;
+    __pyx_t_3 = 0;
+    __pyx_t_3 = PyNumber_Remainder(((PyObject *)__pyx_kp_s_18), ((PyObject *)__pyx_t_1)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 160; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(((PyObject *)__pyx_t_3));
+    __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+    PyErr_SetObject(PyExc_AssertionError, ((PyObject *)__pyx_t_3));
+    __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 160; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  #endif
+
+  /* "bx/align/_epo.pyx":161
+ *         final_elems[i, 1] = tmp_elems[i, 1]
+ *     assert final_elems[0, 0] == elements[0, 0], "fe=%d, e=%d" % (final_elems[0,0], elements[0,0])
+ *     return final_elems             # <<<<<<<<<<<<<<
+ * 
+ * #@cython.wraparound(False)
+ */
+  __Pyx_XDECREF(((PyObject *)__pyx_r));
+  __Pyx_INCREF(((PyObject *)__pyx_v_final_elems));
+  __pyx_r = ((PyArrayObject *)__pyx_v_final_elems);
+  goto __pyx_L0;
+
+  __pyx_r = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_5);
+  { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
+    __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
+    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_elements.rcbuffer->pybuffer);
+    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_final_elems.rcbuffer->pybuffer);
+    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_tmp_elems.rcbuffer->pybuffer);
+  __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}
+  __Pyx_AddTraceback("bx.align._epo.bed_union", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  goto __pyx_L2;
+  __pyx_L0:;
+  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_elements.rcbuffer->pybuffer);
+  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_final_elems.rcbuffer->pybuffer);
+  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_tmp_elems.rcbuffer->pybuffer);
+  __pyx_L2:;
+  __Pyx_XDECREF((PyObject *)__pyx_v_tmp_elems);
+  __Pyx_XDECREF((PyObject *)__pyx_v_final_elems);
+  __Pyx_XGIVEREF((PyObject *)__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_5align_4_epo_5bed_union(PyObject *__pyx_self, PyObject *__pyx_v_elements); /*proto*/
+static char __pyx_doc_2bx_5align_4_epo_4bed_union[] = "compute the union of these elements. simply walk the sorted elements and join the intersecting ones\n    works on half-open intervals, i.e., [a, b), [b, c) ---> [a, c)\n\n    @param elements: 2-dim numpy array of unsigned64 ints\n    @return: 2-dim numpy array of unsigned64 ints";
+static PyObject *__pyx_pw_2bx_5align_4_epo_5bed_union(PyObject *__pyx_self, PyObject *__pyx_v_elements) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("bed_union (wrapper)", 0);
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_elements), __pyx_ptype_5numpy_ndarray, 1, "elements", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_r = __pyx_pf_2bx_5align_4_epo_4bed_union(__pyx_self, ((PyArrayObject *)__pyx_v_elements));
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/align/_epo.pyx":125
+ * @cython.wraparound(False)
+ * @cython.boundscheck(False)
+ * cpdef numpy.ndarray[numpy.uint64_t, ndim=2] bed_union( numpy.ndarray[numpy.uint64_t, ndim=2] elements ):             # <<<<<<<<<<<<<<
+ *     """compute the union of these elements. simply walk the sorted elements and join the intersecting ones
+ *     works on half-open intervals, i.e., [a, b), [b, c) ---> [a, c)
+ */
+
+static PyObject *__pyx_pf_2bx_5align_4_epo_4bed_union(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_elements) {
+  __Pyx_LocalBuf_ND __pyx_pybuffernd_elements;
+  __Pyx_Buffer __pyx_pybuffer_elements;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("bed_union", 0);
+  __pyx_pybuffer_elements.pybuffer.buf = NULL;
+  __pyx_pybuffer_elements.refcount = 0;
+  __pyx_pybuffernd_elements.data = NULL;
+  __pyx_pybuffernd_elements.rcbuffer = &__pyx_pybuffer_elements;
+  {
+    __Pyx_BufFmt_StackElem __pyx_stack[1];
+    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_elements.rcbuffer->pybuffer, (PyObject*)__pyx_v_elements, &__Pyx_TypeInfo_nn___pyx_t_5numpy_uint64_t, PyBUF_FORMAT| PyBUF_STRIDES, 2, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  __pyx_pybuffernd_elements.diminfo[0].strides = __pyx_pybuffernd_elements.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_elements.diminfo[0].shape = __pyx_pybuffernd_elements.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_elements.diminfo[1].strides = __pyx_pybuffernd_elements.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_elements.diminfo[1].shape = __pyx_pybuffernd_elements.rcbuffer->pybuffer.shape[1];
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = ((PyObject *)__pyx_f_2bx_5align_4_epo_bed_union(__pyx_v_elements, 0)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
+    __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
+    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_elements.rcbuffer->pybuffer);
+  __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}
+  __Pyx_AddTraceback("bx.align._epo.bed_union", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  goto __pyx_L2;
+  __pyx_L0:;
+  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_elements.rcbuffer->pybuffer);
+  __pyx_L2:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/align/_epo.pyx":165
+ * #@cython.wraparound(False)
+ * #@cython.boundscheck(False)
+ * cpdef numpy.ndarray[numpy.int64_t, ndim=2] cummulative_intervals(numpy.ndarray[numpy.int64_t, ndim=1] S,             # <<<<<<<<<<<<<<
+ *         numpy.ndarray[numpy.int64_t, ndim=1] D ):
+ *     """compute cummulative intervals for this side of an aligmnent. S and D are one side of
+ */
+
+static PyObject *__pyx_pw_2bx_5align_4_epo_7cummulative_intervals(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyArrayObject *__pyx_f_2bx_5align_4_epo_cummulative_intervals(PyArrayObject *__pyx_v_S, PyArrayObject *__pyx_v_D, CYTHON_UNUSED int __pyx_skip_dispatch) {
+  int __pyx_v_N;
+  int __pyx_v_i;
+  int __pyx_v_j;
+  PyArrayObject *__pyx_v_cumm_i = 0;
+  __Pyx_LocalBuf_ND __pyx_pybuffernd_D;
+  __Pyx_Buffer __pyx_pybuffer_D;
+  __Pyx_LocalBuf_ND __pyx_pybuffernd_S;
+  __Pyx_Buffer __pyx_pybuffer_S;
+  __Pyx_LocalBuf_ND __pyx_pybuffernd_cumm_i;
+  __Pyx_Buffer __pyx_pybuffer_cumm_i;
+  PyArrayObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  PyObject *__pyx_t_5 = NULL;
+  PyArrayObject *__pyx_t_6 = NULL;
+  long __pyx_t_7;
+  long __pyx_t_8;
+  int __pyx_t_9;
+  long __pyx_t_10;
+  long __pyx_t_11;
+  long __pyx_t_12;
+  long __pyx_t_13;
+  int __pyx_t_14;
+  long __pyx_t_15;
+  int __pyx_t_16;
+  int __pyx_t_17;
+  long __pyx_t_18;
+  int __pyx_t_19;
+  long __pyx_t_20;
+  int __pyx_t_21;
+  int __pyx_t_22;
+  long __pyx_t_23;
+  int __pyx_t_24;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("cummulative_intervals", 0);
+  __pyx_pybuffer_cumm_i.pybuffer.buf = NULL;
+  __pyx_pybuffer_cumm_i.refcount = 0;
+  __pyx_pybuffernd_cumm_i.data = NULL;
+  __pyx_pybuffernd_cumm_i.rcbuffer = &__pyx_pybuffer_cumm_i;
+  __pyx_pybuffer_S.pybuffer.buf = NULL;
+  __pyx_pybuffer_S.refcount = 0;
+  __pyx_pybuffernd_S.data = NULL;
+  __pyx_pybuffernd_S.rcbuffer = &__pyx_pybuffer_S;
+  __pyx_pybuffer_D.pybuffer.buf = NULL;
+  __pyx_pybuffer_D.refcount = 0;
+  __pyx_pybuffernd_D.data = NULL;
+  __pyx_pybuffernd_D.rcbuffer = &__pyx_pybuffer_D;
+  {
+    __Pyx_BufFmt_StackElem __pyx_stack[1];
+    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_S.rcbuffer->pybuffer, (PyObject*)__pyx_v_S, &__Pyx_TypeInfo_nn___pyx_t_5numpy_int64_t, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 165; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  __pyx_pybuffernd_S.diminfo[0].strides = __pyx_pybuffernd_S.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_S.diminfo[0].shape = __pyx_pybuffernd_S.rcbuffer->pybuffer.shape[0];
+  {
+    __Pyx_BufFmt_StackElem __pyx_stack[1];
+    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_D.rcbuffer->pybuffer, (PyObject*)__pyx_v_D, &__Pyx_TypeInfo_nn___pyx_t_5numpy_int64_t, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 165; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  __pyx_pybuffernd_D.diminfo[0].strides = __pyx_pybuffernd_D.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_D.diminfo[0].shape = __pyx_pybuffernd_D.rcbuffer->pybuffer.shape[0];
+
+  /* "bx/align/_epo.pyx":170
+ *     the alignment as described in the chain file format"""
+ * 
+ *     cdef int N = S.shape[0]             # <<<<<<<<<<<<<<
+ *     cdef int i = 0, j = 0
+ *     assert N  == D.shape[0]
+ */
+  __pyx_v_N = (__pyx_v_S->dimensions[0]);
+
+  /* "bx/align/_epo.pyx":171
+ * 
+ *     cdef int N = S.shape[0]
+ *     cdef int i = 0, j = 0             # <<<<<<<<<<<<<<
+ *     assert N  == D.shape[0]
+ *     cdef numpy.ndarray[numpy.int64_t, ndim=2] cumm_i = numpy.empty((N, 2), dtype=numpy.int64)
+ */
+  __pyx_v_i = 0;
+  __pyx_v_j = 0;
+
+  /* "bx/align/_epo.pyx":172
+ *     cdef int N = S.shape[0]
+ *     cdef int i = 0, j = 0
+ *     assert N  == D.shape[0]             # <<<<<<<<<<<<<<
+ *     cdef numpy.ndarray[numpy.int64_t, ndim=2] cumm_i = numpy.empty((N, 2), dtype=numpy.int64)
+ * 
+ */
+  #ifndef CYTHON_WITHOUT_ASSERTIONS
+  if (unlikely(!(__pyx_v_N == (__pyx_v_D->dimensions[0])))) {
+    PyErr_SetNone(PyExc_AssertionError);
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 172; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  #endif
+
+  /* "bx/align/_epo.pyx":173
+ *     cdef int i = 0, j = 0
+ *     assert N  == D.shape[0]
+ *     cdef numpy.ndarray[numpy.int64_t, ndim=2] cumm_i = numpy.empty((N, 2), dtype=numpy.int64)             # <<<<<<<<<<<<<<
+ * 
+ *     cumm_i[0,0] = 0
+ */
+  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__numpy); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 173; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = PyObject_GetAttr(__pyx_t_1, __pyx_n_s__empty); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 173; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_1 = PyInt_FromLong(__pyx_v_N); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 173; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 173; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1);
+  __Pyx_GIVEREF(__pyx_t_1);
+  __Pyx_INCREF(__pyx_int_2);
+  PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_int_2);
+  __Pyx_GIVEREF(__pyx_int_2);
+  __pyx_t_1 = 0;
+  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 173; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  PyTuple_SET_ITEM(__pyx_t_1, 0, ((PyObject *)__pyx_t_3));
+  __Pyx_GIVEREF(((PyObject *)__pyx_t_3));
+  __pyx_t_3 = 0;
+  __pyx_t_3 = PyDict_New(); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 173; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(((PyObject *)__pyx_t_3));
+  __pyx_t_4 = __Pyx_GetName(__pyx_m, __pyx_n_s__numpy); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 173; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __pyx_t_5 = PyObject_GetAttr(__pyx_t_4, __pyx_n_s__int64); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 173; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  if (PyDict_SetItem(__pyx_t_3, ((PyObject *)__pyx_n_s__dtype), __pyx_t_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 173; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+  __pyx_t_5 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_1), ((PyObject *)__pyx_t_3)); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 173; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
+  if (!(likely(((__pyx_t_5) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_5, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 173; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_6 = ((PyArrayObject *)__pyx_t_5);
+  {
+    __Pyx_BufFmt_StackElem __pyx_stack[1];
+    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_cumm_i.rcbuffer->pybuffer, (PyObject*)__pyx_t_6, &__Pyx_TypeInfo_nn___pyx_t_5numpy_int64_t, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 2, 0, __pyx_stack) == -1)) {
+      __pyx_v_cumm_i = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_cumm_i.rcbuffer->pybuffer.buf = NULL;
+      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 173; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    } else {__pyx_pybuffernd_cumm_i.diminfo[0].strides = __pyx_pybuffernd_cumm_i.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_cumm_i.diminfo[0].shape = __pyx_pybuffernd_cumm_i.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_cumm_i.diminfo[1].strides = __pyx_pybuffernd_cumm_i.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_cumm_i.diminfo[1].shape = __pyx_pybuffernd_cumm_i.rcbuffer->pybuffer.shape[1];
+    }
+  }
+  __pyx_t_6 = 0;
+  __pyx_v_cumm_i = ((PyArrayObject *)__pyx_t_5);
+  __pyx_t_5 = 0;
+
+  /* "bx/align/_epo.pyx":175
+ *     cdef numpy.ndarray[numpy.int64_t, ndim=2] cumm_i = numpy.empty((N, 2), dtype=numpy.int64)
+ * 
+ *     cumm_i[0,0] = 0             # <<<<<<<<<<<<<<
+ *     cumm_i[0,1] = S[0]
+ *     for i in range(N-1):
+ */
+  __pyx_t_7 = 0;
+  __pyx_t_8 = 0;
+  __pyx_t_9 = -1;
+  if (__pyx_t_7 < 0) {
+    __pyx_t_7 += __pyx_pybuffernd_cumm_i.diminfo[0].shape;
+    if (unlikely(__pyx_t_7 < 0)) __pyx_t_9 = 0;
+  } else if (unlikely(__pyx_t_7 >= __pyx_pybuffernd_cumm_i.diminfo[0].shape)) __pyx_t_9 = 0;
+  if (__pyx_t_8 < 0) {
+    __pyx_t_8 += __pyx_pybuffernd_cumm_i.diminfo[1].shape;
+    if (unlikely(__pyx_t_8 < 0)) __pyx_t_9 = 1;
+  } else if (unlikely(__pyx_t_8 >= __pyx_pybuffernd_cumm_i.diminfo[1].shape)) __pyx_t_9 = 1;
+  if (unlikely(__pyx_t_9 != -1)) {
+    __Pyx_RaiseBufferIndexError(__pyx_t_9);
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 175; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  *__Pyx_BufPtrStrided2d(__pyx_t_5numpy_int64_t *, __pyx_pybuffernd_cumm_i.rcbuffer->pybuffer.buf, __pyx_t_7, __pyx_pybuffernd_cumm_i.diminfo[0].strides, __pyx_t_8, __pyx_pybuffernd_cumm_i.diminfo[1].strides) = 0;
+
+  /* "bx/align/_epo.pyx":176
+ * 
+ *     cumm_i[0,0] = 0
+ *     cumm_i[0,1] = S[0]             # <<<<<<<<<<<<<<
+ *     for i in range(N-1):
+ *         j = i + 1
+ */
+  __pyx_t_10 = 0;
+  __pyx_t_9 = -1;
+  if (__pyx_t_10 < 0) {
+    __pyx_t_10 += __pyx_pybuffernd_S.diminfo[0].shape;
+    if (unlikely(__pyx_t_10 < 0)) __pyx_t_9 = 0;
+  } else if (unlikely(__pyx_t_10 >= __pyx_pybuffernd_S.diminfo[0].shape)) __pyx_t_9 = 0;
+  if (unlikely(__pyx_t_9 != -1)) {
+    __Pyx_RaiseBufferIndexError(__pyx_t_9);
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  __pyx_t_11 = 0;
+  __pyx_t_12 = 1;
+  __pyx_t_9 = -1;
+  if (__pyx_t_11 < 0) {
+    __pyx_t_11 += __pyx_pybuffernd_cumm_i.diminfo[0].shape;
+    if (unlikely(__pyx_t_11 < 0)) __pyx_t_9 = 0;
+  } else if (unlikely(__pyx_t_11 >= __pyx_pybuffernd_cumm_i.diminfo[0].shape)) __pyx_t_9 = 0;
+  if (__pyx_t_12 < 0) {
+    __pyx_t_12 += __pyx_pybuffernd_cumm_i.diminfo[1].shape;
+    if (unlikely(__pyx_t_12 < 0)) __pyx_t_9 = 1;
+  } else if (unlikely(__pyx_t_12 >= __pyx_pybuffernd_cumm_i.diminfo[1].shape)) __pyx_t_9 = 1;
+  if (unlikely(__pyx_t_9 != -1)) {
+    __Pyx_RaiseBufferIndexError(__pyx_t_9);
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  *__Pyx_BufPtrStrided2d(__pyx_t_5numpy_int64_t *, __pyx_pybuffernd_cumm_i.rcbuffer->pybuffer.buf, __pyx_t_11, __pyx_pybuffernd_cumm_i.diminfo[0].strides, __pyx_t_12, __pyx_pybuffernd_cumm_i.diminfo[1].strides) = (*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_int64_t *, __pyx_pybuffernd_S.rcbuffer->pybuffer.buf, __pyx_t_10, __pyx_pybuffernd_S.diminfo[0].strides));
+
+  /* "bx/align/_epo.pyx":177
+ *     cumm_i[0,0] = 0
+ *     cumm_i[0,1] = S[0]
+ *     for i in range(N-1):             # <<<<<<<<<<<<<<
+ *         j = i + 1
+ *         cumm_i[j,0] = cumm_i[i, 1] + D[i]
+ */
+  __pyx_t_13 = (__pyx_v_N - 1);
+  for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_13; __pyx_t_9+=1) {
+    __pyx_v_i = __pyx_t_9;
+
+    /* "bx/align/_epo.pyx":178
+ *     cumm_i[0,1] = S[0]
+ *     for i in range(N-1):
+ *         j = i + 1             # <<<<<<<<<<<<<<
+ *         cumm_i[j,0] = cumm_i[i, 1] + D[i]
+ *         cumm_i[j,1] = cumm_i[j,0] + S[j]
+ */
+    __pyx_v_j = (__pyx_v_i + 1);
+
+    /* "bx/align/_epo.pyx":179
+ *     for i in range(N-1):
+ *         j = i + 1
+ *         cumm_i[j,0] = cumm_i[i, 1] + D[i]             # <<<<<<<<<<<<<<
+ *         cumm_i[j,1] = cumm_i[j,0] + S[j]
+ *     return cumm_i
+ */
+    __pyx_t_14 = __pyx_v_i;
+    __pyx_t_15 = 1;
+    __pyx_t_16 = -1;
+    if (__pyx_t_14 < 0) {
+      __pyx_t_14 += __pyx_pybuffernd_cumm_i.diminfo[0].shape;
+      if (unlikely(__pyx_t_14 < 0)) __pyx_t_16 = 0;
+    } else if (unlikely(__pyx_t_14 >= __pyx_pybuffernd_cumm_i.diminfo[0].shape)) __pyx_t_16 = 0;
+    if (__pyx_t_15 < 0) {
+      __pyx_t_15 += __pyx_pybuffernd_cumm_i.diminfo[1].shape;
+      if (unlikely(__pyx_t_15 < 0)) __pyx_t_16 = 1;
+    } else if (unlikely(__pyx_t_15 >= __pyx_pybuffernd_cumm_i.diminfo[1].shape)) __pyx_t_16 = 1;
+    if (unlikely(__pyx_t_16 != -1)) {
+      __Pyx_RaiseBufferIndexError(__pyx_t_16);
+      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 179; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+    __pyx_t_16 = __pyx_v_i;
+    __pyx_t_17 = -1;
+    if (__pyx_t_16 < 0) {
+      __pyx_t_16 += __pyx_pybuffernd_D.diminfo[0].shape;
+      if (unlikely(__pyx_t_16 < 0)) __pyx_t_17 = 0;
+    } else if (unlikely(__pyx_t_16 >= __pyx_pybuffernd_D.diminfo[0].shape)) __pyx_t_17 = 0;
+    if (unlikely(__pyx_t_17 != -1)) {
+      __Pyx_RaiseBufferIndexError(__pyx_t_17);
+      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 179; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+    __pyx_t_17 = __pyx_v_j;
+    __pyx_t_18 = 0;
+    __pyx_t_19 = -1;
+    if (__pyx_t_17 < 0) {
+      __pyx_t_17 += __pyx_pybuffernd_cumm_i.diminfo[0].shape;
+      if (unlikely(__pyx_t_17 < 0)) __pyx_t_19 = 0;
+    } else if (unlikely(__pyx_t_17 >= __pyx_pybuffernd_cumm_i.diminfo[0].shape)) __pyx_t_19 = 0;
+    if (__pyx_t_18 < 0) {
+      __pyx_t_18 += __pyx_pybuffernd_cumm_i.diminfo[1].shape;
+      if (unlikely(__pyx_t_18 < 0)) __pyx_t_19 = 1;
+    } else if (unlikely(__pyx_t_18 >= __pyx_pybuffernd_cumm_i.diminfo[1].shape)) __pyx_t_19 = 1;
+    if (unlikely(__pyx_t_19 != -1)) {
+      __Pyx_RaiseBufferIndexError(__pyx_t_19);
+      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 179; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+    *__Pyx_BufPtrStrided2d(__pyx_t_5numpy_int64_t *, __pyx_pybuffernd_cumm_i.rcbuffer->pybuffer.buf, __pyx_t_17, __pyx_pybuffernd_cumm_i.diminfo[0].strides, __pyx_t_18, __pyx_pybuffernd_cumm_i.diminfo[1].strides) = ((*__Pyx_BufPtrStrided2d(__pyx_t_5numpy_int64_t *, __pyx_pybuffernd_cumm_i.rcbuffer->pybuffer.buf, __pyx_t_14, __pyx_pybuffernd_cumm_i.diminfo[0].strides, __pyx_t_15, __pyx_pybuffernd_cumm_i.diminfo[1].strides)) + (*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_int64_t *, __pyx_pybuffe [...]
+
+    /* "bx/align/_epo.pyx":180
+ *         j = i + 1
+ *         cumm_i[j,0] = cumm_i[i, 1] + D[i]
+ *         cumm_i[j,1] = cumm_i[j,0] + S[j]             # <<<<<<<<<<<<<<
+ *     return cumm_i
+ * 
+ */
+    __pyx_t_19 = __pyx_v_j;
+    __pyx_t_20 = 0;
+    __pyx_t_21 = -1;
+    if (__pyx_t_19 < 0) {
+      __pyx_t_19 += __pyx_pybuffernd_cumm_i.diminfo[0].shape;
+      if (unlikely(__pyx_t_19 < 0)) __pyx_t_21 = 0;
+    } else if (unlikely(__pyx_t_19 >= __pyx_pybuffernd_cumm_i.diminfo[0].shape)) __pyx_t_21 = 0;
+    if (__pyx_t_20 < 0) {
+      __pyx_t_20 += __pyx_pybuffernd_cumm_i.diminfo[1].shape;
+      if (unlikely(__pyx_t_20 < 0)) __pyx_t_21 = 1;
+    } else if (unlikely(__pyx_t_20 >= __pyx_pybuffernd_cumm_i.diminfo[1].shape)) __pyx_t_21 = 1;
+    if (unlikely(__pyx_t_21 != -1)) {
+      __Pyx_RaiseBufferIndexError(__pyx_t_21);
+      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 180; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+    __pyx_t_21 = __pyx_v_j;
+    __pyx_t_22 = -1;
+    if (__pyx_t_21 < 0) {
+      __pyx_t_21 += __pyx_pybuffernd_S.diminfo[0].shape;
+      if (unlikely(__pyx_t_21 < 0)) __pyx_t_22 = 0;
+    } else if (unlikely(__pyx_t_21 >= __pyx_pybuffernd_S.diminfo[0].shape)) __pyx_t_22 = 0;
+    if (unlikely(__pyx_t_22 != -1)) {
+      __Pyx_RaiseBufferIndexError(__pyx_t_22);
+      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 180; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+    __pyx_t_22 = __pyx_v_j;
+    __pyx_t_23 = 1;
+    __pyx_t_24 = -1;
+    if (__pyx_t_22 < 0) {
+      __pyx_t_22 += __pyx_pybuffernd_cumm_i.diminfo[0].shape;
+      if (unlikely(__pyx_t_22 < 0)) __pyx_t_24 = 0;
+    } else if (unlikely(__pyx_t_22 >= __pyx_pybuffernd_cumm_i.diminfo[0].shape)) __pyx_t_24 = 0;
+    if (__pyx_t_23 < 0) {
+      __pyx_t_23 += __pyx_pybuffernd_cumm_i.diminfo[1].shape;
+      if (unlikely(__pyx_t_23 < 0)) __pyx_t_24 = 1;
+    } else if (unlikely(__pyx_t_23 >= __pyx_pybuffernd_cumm_i.diminfo[1].shape)) __pyx_t_24 = 1;
+    if (unlikely(__pyx_t_24 != -1)) {
+      __Pyx_RaiseBufferIndexError(__pyx_t_24);
+      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 180; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+    *__Pyx_BufPtrStrided2d(__pyx_t_5numpy_int64_t *, __pyx_pybuffernd_cumm_i.rcbuffer->pybuffer.buf, __pyx_t_22, __pyx_pybuffernd_cumm_i.diminfo[0].strides, __pyx_t_23, __pyx_pybuffernd_cumm_i.diminfo[1].strides) = ((*__Pyx_BufPtrStrided2d(__pyx_t_5numpy_int64_t *, __pyx_pybuffernd_cumm_i.rcbuffer->pybuffer.buf, __pyx_t_19, __pyx_pybuffernd_cumm_i.diminfo[0].strides, __pyx_t_20, __pyx_pybuffernd_cumm_i.diminfo[1].strides)) + (*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_int64_t *, __pyx_pybuffe [...]
+  }
+
+  /* "bx/align/_epo.pyx":181
+ *         cumm_i[j,0] = cumm_i[i, 1] + D[i]
+ *         cumm_i[j,1] = cumm_i[j,0] + S[j]
+ *     return cumm_i             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+  __Pyx_XDECREF(((PyObject *)__pyx_r));
+  __Pyx_INCREF(((PyObject *)__pyx_v_cumm_i));
+  __pyx_r = ((PyArrayObject *)__pyx_v_cumm_i);
+  goto __pyx_L0;
+
+  __pyx_r = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_XDECREF(__pyx_t_5);
+  { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
+    __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
+    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_D.rcbuffer->pybuffer);
+    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_S.rcbuffer->pybuffer);
+    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_cumm_i.rcbuffer->pybuffer);
+  __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}
+  __Pyx_AddTraceback("bx.align._epo.cummulative_intervals", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  goto __pyx_L2;
+  __pyx_L0:;
+  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_D.rcbuffer->pybuffer);
+  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_S.rcbuffer->pybuffer);
+  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_cumm_i.rcbuffer->pybuffer);
+  __pyx_L2:;
+  __Pyx_XDECREF((PyObject *)__pyx_v_cumm_i);
+  __Pyx_XGIVEREF((PyObject *)__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_5align_4_epo_7cummulative_intervals(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_2bx_5align_4_epo_6cummulative_intervals[] = "compute cummulative intervals for this side of an aligmnent. S and D are one side of\n    the alignment as described in the chain file format";
+static PyObject *__pyx_pw_2bx_5align_4_epo_7cummulative_intervals(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyArrayObject *__pyx_v_S = 0;
+  PyArrayObject *__pyx_v_D = 0;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("cummulative_intervals (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__S,&__pyx_n_s__D,0};
+    PyObject* values[2] = {0,0};
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__S)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__D)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("cummulative_intervals", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 165; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "cummulative_intervals") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 165; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
+      goto __pyx_L5_argtuple_error;
+    } else {
+      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+    }
+    __pyx_v_S = ((PyArrayObject *)values[0]);
+    __pyx_v_D = ((PyArrayObject *)values[1]);
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("cummulative_intervals", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 165; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.align._epo.cummulative_intervals", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_S), __pyx_ptype_5numpy_ndarray, 1, "S", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 165; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_D), __pyx_ptype_5numpy_ndarray, 1, "D", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 166; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_r = __pyx_pf_2bx_5align_4_epo_6cummulative_intervals(__pyx_self, __pyx_v_S, __pyx_v_D);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/align/_epo.pyx":165
+ * #@cython.wraparound(False)
+ * #@cython.boundscheck(False)
+ * cpdef numpy.ndarray[numpy.int64_t, ndim=2] cummulative_intervals(numpy.ndarray[numpy.int64_t, ndim=1] S,             # <<<<<<<<<<<<<<
+ *         numpy.ndarray[numpy.int64_t, ndim=1] D ):
+ *     """compute cummulative intervals for this side of an aligmnent. S and D are one side of
+ */
+
+static PyObject *__pyx_pf_2bx_5align_4_epo_6cummulative_intervals(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_S, PyArrayObject *__pyx_v_D) {
+  __Pyx_LocalBuf_ND __pyx_pybuffernd_D;
+  __Pyx_Buffer __pyx_pybuffer_D;
+  __Pyx_LocalBuf_ND __pyx_pybuffernd_S;
+  __Pyx_Buffer __pyx_pybuffer_S;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("cummulative_intervals", 0);
+  __pyx_pybuffer_S.pybuffer.buf = NULL;
+  __pyx_pybuffer_S.refcount = 0;
+  __pyx_pybuffernd_S.data = NULL;
+  __pyx_pybuffernd_S.rcbuffer = &__pyx_pybuffer_S;
+  __pyx_pybuffer_D.pybuffer.buf = NULL;
+  __pyx_pybuffer_D.refcount = 0;
+  __pyx_pybuffernd_D.data = NULL;
+  __pyx_pybuffernd_D.rcbuffer = &__pyx_pybuffer_D;
+  {
+    __Pyx_BufFmt_StackElem __pyx_stack[1];
+    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_S.rcbuffer->pybuffer, (PyObject*)__pyx_v_S, &__Pyx_TypeInfo_nn___pyx_t_5numpy_int64_t, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 165; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  __pyx_pybuffernd_S.diminfo[0].strides = __pyx_pybuffernd_S.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_S.diminfo[0].shape = __pyx_pybuffernd_S.rcbuffer->pybuffer.shape[0];
+  {
+    __Pyx_BufFmt_StackElem __pyx_stack[1];
+    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_D.rcbuffer->pybuffer, (PyObject*)__pyx_v_D, &__Pyx_TypeInfo_nn___pyx_t_5numpy_int64_t, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 165; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  __pyx_pybuffernd_D.diminfo[0].strides = __pyx_pybuffernd_D.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_D.diminfo[0].shape = __pyx_pybuffernd_D.rcbuffer->pybuffer.shape[0];
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = ((PyObject *)__pyx_f_2bx_5align_4_epo_cummulative_intervals(__pyx_v_S, __pyx_v_D, 0)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 165; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
+    __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
+    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_D.rcbuffer->pybuffer);
+    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_S.rcbuffer->pybuffer);
+  __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}
+  __Pyx_AddTraceback("bx.align._epo.cummulative_intervals", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  goto __pyx_L2;
+  __pyx_L0:;
+  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_D.rcbuffer->pybuffer);
+  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_S.rcbuffer->pybuffer);
+  __pyx_L2:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static CYTHON_UNUSED int __pyx_pw_5numpy_7ndarray_1__getbuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /*proto*/
+static CYTHON_UNUSED int __pyx_pw_5numpy_7ndarray_1__getbuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__getbuffer__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_5numpy_7ndarray___getbuffer__(((PyArrayObject *)__pyx_v_self), ((Py_buffer *)__pyx_v_info), ((int)__pyx_v_flags));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "numpy.pxd":194
+ *         # experimental exception made for __getbuffer__ and __releasebuffer__
+ *         # -- the details of this may change.
+ *         def __getbuffer__(ndarray self, Py_buffer* info, int flags):             # <<<<<<<<<<<<<<
+ *             # This implementation of getbuffer is geared towards Cython
+ *             # requirements, and does not yet fullfill the PEP.
+ */
+
+static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) {
+  int __pyx_v_copy_shape;
+  int __pyx_v_i;
+  int __pyx_v_ndim;
+  int __pyx_v_endian_detector;
+  int __pyx_v_little_endian;
+  int __pyx_v_t;
+  char *__pyx_v_f;
+  PyArray_Descr *__pyx_v_descr = 0;
+  int __pyx_v_offset;
+  int __pyx_v_hasfields;
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  int __pyx_t_2;
+  int __pyx_t_3;
+  PyObject *__pyx_t_4 = NULL;
+  int __pyx_t_5;
+  int __pyx_t_6;
+  int __pyx_t_7;
+  PyObject *__pyx_t_8 = NULL;
+  char *__pyx_t_9;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__getbuffer__", 0);
+  if (__pyx_v_info != NULL) {
+    __pyx_v_info->obj = Py_None; __Pyx_INCREF(Py_None);
+    __Pyx_GIVEREF(__pyx_v_info->obj);
+  }
+
+  /* "numpy.pxd":200
+ *             # of flags
+ * 
+ *             if info == NULL: return             # <<<<<<<<<<<<<<
+ * 
+ *             cdef int copy_shape, i, ndim
+ */
+  __pyx_t_1 = (__pyx_v_info == NULL);
+  if (__pyx_t_1) {
+    __pyx_r = 0;
+    goto __pyx_L0;
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  /* "numpy.pxd":203
+ * 
+ *             cdef int copy_shape, i, ndim
+ *             cdef int endian_detector = 1             # <<<<<<<<<<<<<<
+ *             cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)
+ * 
+ */
+  __pyx_v_endian_detector = 1;
+
+  /* "numpy.pxd":204
+ *             cdef int copy_shape, i, ndim
+ *             cdef int endian_detector = 1
+ *             cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)             # <<<<<<<<<<<<<<
+ * 
+ *             ndim = PyArray_NDIM(self)
+ */
+  __pyx_v_little_endian = ((((char *)(&__pyx_v_endian_detector))[0]) != 0);
+
+  /* "numpy.pxd":206
+ *             cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)
+ * 
+ *             ndim = PyArray_NDIM(self)             # <<<<<<<<<<<<<<
+ * 
+ *             if sizeof(npy_intp) != sizeof(Py_ssize_t):
+ */
+  __pyx_v_ndim = PyArray_NDIM(__pyx_v_self);
+
+  /* "numpy.pxd":208
+ *             ndim = PyArray_NDIM(self)
+ * 
+ *             if sizeof(npy_intp) != sizeof(Py_ssize_t):             # <<<<<<<<<<<<<<
+ *                 copy_shape = 1
+ *             else:
+ */
+  __pyx_t_1 = ((sizeof(npy_intp)) != (sizeof(Py_ssize_t)));
+  if (__pyx_t_1) {
+
+    /* "numpy.pxd":209
+ * 
+ *             if sizeof(npy_intp) != sizeof(Py_ssize_t):
+ *                 copy_shape = 1             # <<<<<<<<<<<<<<
+ *             else:
+ *                 copy_shape = 0
+ */
+    __pyx_v_copy_shape = 1;
+    goto __pyx_L4;
+  }
+  /*else*/ {
+
+    /* "numpy.pxd":211
+ *                 copy_shape = 1
+ *             else:
+ *                 copy_shape = 0             # <<<<<<<<<<<<<<
+ * 
+ *             if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)
+ */
+    __pyx_v_copy_shape = 0;
+  }
+  __pyx_L4:;
+
+  /* "numpy.pxd":213
+ *                 copy_shape = 0
+ * 
+ *             if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)             # <<<<<<<<<<<<<<
+ *                 and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)):
+ *                 raise ValueError(u"ndarray is not C contiguous")
+ */
+  __pyx_t_1 = ((__pyx_v_flags & PyBUF_C_CONTIGUOUS) == PyBUF_C_CONTIGUOUS);
+  if (__pyx_t_1) {
+
+    /* "numpy.pxd":214
+ * 
+ *             if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)
+ *                 and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)):             # <<<<<<<<<<<<<<
+ *                 raise ValueError(u"ndarray is not C contiguous")
+ * 
+ */
+    __pyx_t_2 = (!PyArray_CHKFLAGS(__pyx_v_self, NPY_C_CONTIGUOUS));
+    __pyx_t_3 = __pyx_t_2;
+  } else {
+    __pyx_t_3 = __pyx_t_1;
+  }
+  if (__pyx_t_3) {
+
+    /* "numpy.pxd":215
+ *             if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)
+ *                 and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)):
+ *                 raise ValueError(u"ndarray is not C contiguous")             # <<<<<<<<<<<<<<
+ * 
+ *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
+ */
+    __pyx_t_4 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_k_tuple_20), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 215; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    __Pyx_Raise(__pyx_t_4, 0, 0, 0);
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    {__pyx_filename = __pyx_f[1]; __pyx_lineno = 215; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    goto __pyx_L5;
+  }
+  __pyx_L5:;
+
+  /* "numpy.pxd":217
+ *                 raise ValueError(u"ndarray is not C contiguous")
+ * 
+ *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)             # <<<<<<<<<<<<<<
+ *                 and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)):
+ *                 raise ValueError(u"ndarray is not Fortran contiguous")
+ */
+  __pyx_t_3 = ((__pyx_v_flags & PyBUF_F_CONTIGUOUS) == PyBUF_F_CONTIGUOUS);
+  if (__pyx_t_3) {
+
+    /* "numpy.pxd":218
+ * 
+ *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
+ *                 and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)):             # <<<<<<<<<<<<<<
+ *                 raise ValueError(u"ndarray is not Fortran contiguous")
+ * 
+ */
+    __pyx_t_1 = (!PyArray_CHKFLAGS(__pyx_v_self, NPY_F_CONTIGUOUS));
+    __pyx_t_2 = __pyx_t_1;
+  } else {
+    __pyx_t_2 = __pyx_t_3;
+  }
+  if (__pyx_t_2) {
+
+    /* "numpy.pxd":219
+ *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
+ *                 and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)):
+ *                 raise ValueError(u"ndarray is not Fortran contiguous")             # <<<<<<<<<<<<<<
+ * 
+ *             info.buf = PyArray_DATA(self)
+ */
+    __pyx_t_4 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_k_tuple_22), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 219; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    __Pyx_Raise(__pyx_t_4, 0, 0, 0);
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    {__pyx_filename = __pyx_f[1]; __pyx_lineno = 219; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    goto __pyx_L6;
+  }
+  __pyx_L6:;
+
+  /* "numpy.pxd":221
+ *                 raise ValueError(u"ndarray is not Fortran contiguous")
+ * 
+ *             info.buf = PyArray_DATA(self)             # <<<<<<<<<<<<<<
+ *             info.ndim = ndim
+ *             if copy_shape:
+ */
+  __pyx_v_info->buf = PyArray_DATA(__pyx_v_self);
+
+  /* "numpy.pxd":222
+ * 
+ *             info.buf = PyArray_DATA(self)
+ *             info.ndim = ndim             # <<<<<<<<<<<<<<
+ *             if copy_shape:
+ *                 # Allocate new buffer for strides and shape info.
+ */
+  __pyx_v_info->ndim = __pyx_v_ndim;
+
+  /* "numpy.pxd":223
+ *             info.buf = PyArray_DATA(self)
+ *             info.ndim = ndim
+ *             if copy_shape:             # <<<<<<<<<<<<<<
+ *                 # Allocate new buffer for strides and shape info.
+ *                 # This is allocated as one block, strides first.
+ */
+  if (__pyx_v_copy_shape) {
+
+    /* "numpy.pxd":226
+ *                 # Allocate new buffer for strides and shape info.
+ *                 # This is allocated as one block, strides first.
+ *                 info.strides = <Py_ssize_t*>stdlib.malloc(sizeof(Py_ssize_t) * <size_t>ndim * 2)             # <<<<<<<<<<<<<<
+ *                 info.shape = info.strides + ndim
+ *                 for i in range(ndim):
+ */
+    __pyx_v_info->strides = ((Py_ssize_t *)malloc((((sizeof(Py_ssize_t)) * ((size_t)__pyx_v_ndim)) * 2)));
+
+    /* "numpy.pxd":227
+ *                 # This is allocated as one block, strides first.
+ *                 info.strides = <Py_ssize_t*>stdlib.malloc(sizeof(Py_ssize_t) * <size_t>ndim * 2)
+ *                 info.shape = info.strides + ndim             # <<<<<<<<<<<<<<
+ *                 for i in range(ndim):
+ *                     info.strides[i] = PyArray_STRIDES(self)[i]
+ */
+    __pyx_v_info->shape = (__pyx_v_info->strides + __pyx_v_ndim);
+
+    /* "numpy.pxd":228
+ *                 info.strides = <Py_ssize_t*>stdlib.malloc(sizeof(Py_ssize_t) * <size_t>ndim * 2)
+ *                 info.shape = info.strides + ndim
+ *                 for i in range(ndim):             # <<<<<<<<<<<<<<
+ *                     info.strides[i] = PyArray_STRIDES(self)[i]
+ *                     info.shape[i] = PyArray_DIMS(self)[i]
+ */
+    __pyx_t_5 = __pyx_v_ndim;
+    for (__pyx_t_6 = 0; __pyx_t_6 < __pyx_t_5; __pyx_t_6+=1) {
+      __pyx_v_i = __pyx_t_6;
+
+      /* "numpy.pxd":229
+ *                 info.shape = info.strides + ndim
+ *                 for i in range(ndim):
+ *                     info.strides[i] = PyArray_STRIDES(self)[i]             # <<<<<<<<<<<<<<
+ *                     info.shape[i] = PyArray_DIMS(self)[i]
+ *             else:
+ */
+      (__pyx_v_info->strides[__pyx_v_i]) = (PyArray_STRIDES(__pyx_v_self)[__pyx_v_i]);
+
+      /* "numpy.pxd":230
+ *                 for i in range(ndim):
+ *                     info.strides[i] = PyArray_STRIDES(self)[i]
+ *                     info.shape[i] = PyArray_DIMS(self)[i]             # <<<<<<<<<<<<<<
+ *             else:
+ *                 info.strides = <Py_ssize_t*>PyArray_STRIDES(self)
+ */
+      (__pyx_v_info->shape[__pyx_v_i]) = (PyArray_DIMS(__pyx_v_self)[__pyx_v_i]);
+    }
+    goto __pyx_L7;
+  }
+  /*else*/ {
+
+    /* "numpy.pxd":232
+ *                     info.shape[i] = PyArray_DIMS(self)[i]
+ *             else:
+ *                 info.strides = <Py_ssize_t*>PyArray_STRIDES(self)             # <<<<<<<<<<<<<<
+ *                 info.shape = <Py_ssize_t*>PyArray_DIMS(self)
+ *             info.suboffsets = NULL
+ */
+    __pyx_v_info->strides = ((Py_ssize_t *)PyArray_STRIDES(__pyx_v_self));
+
+    /* "numpy.pxd":233
+ *             else:
+ *                 info.strides = <Py_ssize_t*>PyArray_STRIDES(self)
+ *                 info.shape = <Py_ssize_t*>PyArray_DIMS(self)             # <<<<<<<<<<<<<<
+ *             info.suboffsets = NULL
+ *             info.itemsize = PyArray_ITEMSIZE(self)
+ */
+    __pyx_v_info->shape = ((Py_ssize_t *)PyArray_DIMS(__pyx_v_self));
+  }
+  __pyx_L7:;
+
+  /* "numpy.pxd":234
+ *                 info.strides = <Py_ssize_t*>PyArray_STRIDES(self)
+ *                 info.shape = <Py_ssize_t*>PyArray_DIMS(self)
+ *             info.suboffsets = NULL             # <<<<<<<<<<<<<<
+ *             info.itemsize = PyArray_ITEMSIZE(self)
+ *             info.readonly = not PyArray_ISWRITEABLE(self)
+ */
+  __pyx_v_info->suboffsets = NULL;
+
+  /* "numpy.pxd":235
+ *                 info.shape = <Py_ssize_t*>PyArray_DIMS(self)
+ *             info.suboffsets = NULL
+ *             info.itemsize = PyArray_ITEMSIZE(self)             # <<<<<<<<<<<<<<
+ *             info.readonly = not PyArray_ISWRITEABLE(self)
+ * 
+ */
+  __pyx_v_info->itemsize = PyArray_ITEMSIZE(__pyx_v_self);
+
+  /* "numpy.pxd":236
+ *             info.suboffsets = NULL
+ *             info.itemsize = PyArray_ITEMSIZE(self)
+ *             info.readonly = not PyArray_ISWRITEABLE(self)             # <<<<<<<<<<<<<<
+ * 
+ *             cdef int t
+ */
+  __pyx_v_info->readonly = (!PyArray_ISWRITEABLE(__pyx_v_self));
+
+  /* "numpy.pxd":239
+ * 
+ *             cdef int t
+ *             cdef char* f = NULL             # <<<<<<<<<<<<<<
+ *             cdef dtype descr = self.descr
+ *             cdef list stack
+ */
+  __pyx_v_f = NULL;
+
+  /* "numpy.pxd":240
+ *             cdef int t
+ *             cdef char* f = NULL
+ *             cdef dtype descr = self.descr             # <<<<<<<<<<<<<<
+ *             cdef list stack
+ *             cdef int offset
+ */
+  __pyx_t_4 = ((PyObject *)__pyx_v_self->descr);
+  __Pyx_INCREF(__pyx_t_4);
+  __pyx_v_descr = ((PyArray_Descr *)__pyx_t_4);
+  __pyx_t_4 = 0;
+
+  /* "numpy.pxd":244
+ *             cdef int offset
+ * 
+ *             cdef bint hasfields = PyDataType_HASFIELDS(descr)             # <<<<<<<<<<<<<<
+ * 
+ *             if not hasfields and not copy_shape:
+ */
+  __pyx_v_hasfields = PyDataType_HASFIELDS(__pyx_v_descr);
+
+  /* "numpy.pxd":246
+ *             cdef bint hasfields = PyDataType_HASFIELDS(descr)
+ * 
+ *             if not hasfields and not copy_shape:             # <<<<<<<<<<<<<<
+ *                 # do not call releasebuffer
+ *                 info.obj = None
+ */
+  __pyx_t_2 = (!__pyx_v_hasfields);
+  if (__pyx_t_2) {
+    __pyx_t_3 = (!__pyx_v_copy_shape);
+    __pyx_t_1 = __pyx_t_3;
+  } else {
+    __pyx_t_1 = __pyx_t_2;
+  }
+  if (__pyx_t_1) {
+
+    /* "numpy.pxd":248
+ *             if not hasfields and not copy_shape:
+ *                 # do not call releasebuffer
+ *                 info.obj = None             # <<<<<<<<<<<<<<
+ *             else:
+ *                 # need to call releasebuffer
+ */
+    __Pyx_INCREF(Py_None);
+    __Pyx_GIVEREF(Py_None);
+    __Pyx_GOTREF(__pyx_v_info->obj);
+    __Pyx_DECREF(__pyx_v_info->obj);
+    __pyx_v_info->obj = Py_None;
+    goto __pyx_L10;
+  }
+  /*else*/ {
+
+    /* "numpy.pxd":251
+ *             else:
+ *                 # need to call releasebuffer
+ *                 info.obj = self             # <<<<<<<<<<<<<<
+ * 
+ *             if not hasfields:
+ */
+    __Pyx_INCREF(((PyObject *)__pyx_v_self));
+    __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
+    __Pyx_GOTREF(__pyx_v_info->obj);
+    __Pyx_DECREF(__pyx_v_info->obj);
+    __pyx_v_info->obj = ((PyObject *)__pyx_v_self);
+  }
+  __pyx_L10:;
+
+  /* "numpy.pxd":253
+ *                 info.obj = self
+ * 
+ *             if not hasfields:             # <<<<<<<<<<<<<<
+ *                 t = descr.type_num
+ *                 if ((descr.byteorder == c'>' and little_endian) or
+ */
+  __pyx_t_1 = (!__pyx_v_hasfields);
+  if (__pyx_t_1) {
+
+    /* "numpy.pxd":254
+ * 
+ *             if not hasfields:
+ *                 t = descr.type_num             # <<<<<<<<<<<<<<
+ *                 if ((descr.byteorder == c'>' and little_endian) or
+ *                     (descr.byteorder == c'<' and not little_endian)):
+ */
+    __pyx_t_5 = __pyx_v_descr->type_num;
+    __pyx_v_t = __pyx_t_5;
+
+    /* "numpy.pxd":255
+ *             if not hasfields:
+ *                 t = descr.type_num
+ *                 if ((descr.byteorder == c'>' and little_endian) or             # <<<<<<<<<<<<<<
+ *                     (descr.byteorder == c'<' and not little_endian)):
+ *                     raise ValueError(u"Non-native byte order not supported")
+ */
+    __pyx_t_1 = (__pyx_v_descr->byteorder == '>');
+    if (__pyx_t_1) {
+      __pyx_t_2 = __pyx_v_little_endian;
+    } else {
+      __pyx_t_2 = __pyx_t_1;
+    }
+    if (!__pyx_t_2) {
+
+      /* "numpy.pxd":256
+ *                 t = descr.type_num
+ *                 if ((descr.byteorder == c'>' and little_endian) or
+ *                     (descr.byteorder == c'<' and not little_endian)):             # <<<<<<<<<<<<<<
+ *                     raise ValueError(u"Non-native byte order not supported")
+ *                 if   t == NPY_BYTE:        f = "b"
+ */
+      __pyx_t_1 = (__pyx_v_descr->byteorder == '<');
+      if (__pyx_t_1) {
+        __pyx_t_3 = (!__pyx_v_little_endian);
+        __pyx_t_7 = __pyx_t_3;
+      } else {
+        __pyx_t_7 = __pyx_t_1;
+      }
+      __pyx_t_1 = __pyx_t_7;
+    } else {
+      __pyx_t_1 = __pyx_t_2;
+    }
+    if (__pyx_t_1) {
+
+      /* "numpy.pxd":257
+ *                 if ((descr.byteorder == c'>' and little_endian) or
+ *                     (descr.byteorder == c'<' and not little_endian)):
+ *                     raise ValueError(u"Non-native byte order not supported")             # <<<<<<<<<<<<<<
+ *                 if   t == NPY_BYTE:        f = "b"
+ *                 elif t == NPY_UBYTE:       f = "B"
+ */
+      __pyx_t_4 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_k_tuple_24), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __Pyx_Raise(__pyx_t_4, 0, 0, 0);
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      {__pyx_filename = __pyx_f[1]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      goto __pyx_L12;
+    }
+    __pyx_L12:;
+
+    /* "numpy.pxd":258
+ *                     (descr.byteorder == c'<' and not little_endian)):
+ *                     raise ValueError(u"Non-native byte order not supported")
+ *                 if   t == NPY_BYTE:        f = "b"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_UBYTE:       f = "B"
+ *                 elif t == NPY_SHORT:       f = "h"
+ */
+    __pyx_t_1 = (__pyx_v_t == NPY_BYTE);
+    if (__pyx_t_1) {
+      __pyx_v_f = __pyx_k__b;
+      goto __pyx_L13;
+    }
+
+    /* "numpy.pxd":259
+ *                     raise ValueError(u"Non-native byte order not supported")
+ *                 if   t == NPY_BYTE:        f = "b"
+ *                 elif t == NPY_UBYTE:       f = "B"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_SHORT:       f = "h"
+ *                 elif t == NPY_USHORT:      f = "H"
+ */
+    __pyx_t_1 = (__pyx_v_t == NPY_UBYTE);
+    if (__pyx_t_1) {
+      __pyx_v_f = __pyx_k__B;
+      goto __pyx_L13;
+    }
+
+    /* "numpy.pxd":260
+ *                 if   t == NPY_BYTE:        f = "b"
+ *                 elif t == NPY_UBYTE:       f = "B"
+ *                 elif t == NPY_SHORT:       f = "h"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_USHORT:      f = "H"
+ *                 elif t == NPY_INT:         f = "i"
+ */
+    __pyx_t_1 = (__pyx_v_t == NPY_SHORT);
+    if (__pyx_t_1) {
+      __pyx_v_f = __pyx_k__h;
+      goto __pyx_L13;
+    }
+
+    /* "numpy.pxd":261
+ *                 elif t == NPY_UBYTE:       f = "B"
+ *                 elif t == NPY_SHORT:       f = "h"
+ *                 elif t == NPY_USHORT:      f = "H"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_INT:         f = "i"
+ *                 elif t == NPY_UINT:        f = "I"
+ */
+    __pyx_t_1 = (__pyx_v_t == NPY_USHORT);
+    if (__pyx_t_1) {
+      __pyx_v_f = __pyx_k__H;
+      goto __pyx_L13;
+    }
+
+    /* "numpy.pxd":262
+ *                 elif t == NPY_SHORT:       f = "h"
+ *                 elif t == NPY_USHORT:      f = "H"
+ *                 elif t == NPY_INT:         f = "i"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_UINT:        f = "I"
+ *                 elif t == NPY_LONG:        f = "l"
+ */
+    __pyx_t_1 = (__pyx_v_t == NPY_INT);
+    if (__pyx_t_1) {
+      __pyx_v_f = __pyx_k__i;
+      goto __pyx_L13;
+    }
+
+    /* "numpy.pxd":263
+ *                 elif t == NPY_USHORT:      f = "H"
+ *                 elif t == NPY_INT:         f = "i"
+ *                 elif t == NPY_UINT:        f = "I"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_LONG:        f = "l"
+ *                 elif t == NPY_ULONG:       f = "L"
+ */
+    __pyx_t_1 = (__pyx_v_t == NPY_UINT);
+    if (__pyx_t_1) {
+      __pyx_v_f = __pyx_k__I;
+      goto __pyx_L13;
+    }
+
+    /* "numpy.pxd":264
+ *                 elif t == NPY_INT:         f = "i"
+ *                 elif t == NPY_UINT:        f = "I"
+ *                 elif t == NPY_LONG:        f = "l"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_ULONG:       f = "L"
+ *                 elif t == NPY_LONGLONG:    f = "q"
+ */
+    __pyx_t_1 = (__pyx_v_t == NPY_LONG);
+    if (__pyx_t_1) {
+      __pyx_v_f = __pyx_k__l;
+      goto __pyx_L13;
+    }
+
+    /* "numpy.pxd":265
+ *                 elif t == NPY_UINT:        f = "I"
+ *                 elif t == NPY_LONG:        f = "l"
+ *                 elif t == NPY_ULONG:       f = "L"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_LONGLONG:    f = "q"
+ *                 elif t == NPY_ULONGLONG:   f = "Q"
+ */
+    __pyx_t_1 = (__pyx_v_t == NPY_ULONG);
+    if (__pyx_t_1) {
+      __pyx_v_f = __pyx_k__L;
+      goto __pyx_L13;
+    }
+
+    /* "numpy.pxd":266
+ *                 elif t == NPY_LONG:        f = "l"
+ *                 elif t == NPY_ULONG:       f = "L"
+ *                 elif t == NPY_LONGLONG:    f = "q"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_ULONGLONG:   f = "Q"
+ *                 elif t == NPY_FLOAT:       f = "f"
+ */
+    __pyx_t_1 = (__pyx_v_t == NPY_LONGLONG);
+    if (__pyx_t_1) {
+      __pyx_v_f = __pyx_k__q;
+      goto __pyx_L13;
+    }
+
+    /* "numpy.pxd":267
+ *                 elif t == NPY_ULONG:       f = "L"
+ *                 elif t == NPY_LONGLONG:    f = "q"
+ *                 elif t == NPY_ULONGLONG:   f = "Q"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_FLOAT:       f = "f"
+ *                 elif t == NPY_DOUBLE:      f = "d"
+ */
+    __pyx_t_1 = (__pyx_v_t == NPY_ULONGLONG);
+    if (__pyx_t_1) {
+      __pyx_v_f = __pyx_k__Q;
+      goto __pyx_L13;
+    }
+
+    /* "numpy.pxd":268
+ *                 elif t == NPY_LONGLONG:    f = "q"
+ *                 elif t == NPY_ULONGLONG:   f = "Q"
+ *                 elif t == NPY_FLOAT:       f = "f"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_DOUBLE:      f = "d"
+ *                 elif t == NPY_LONGDOUBLE:  f = "g"
+ */
+    __pyx_t_1 = (__pyx_v_t == NPY_FLOAT);
+    if (__pyx_t_1) {
+      __pyx_v_f = __pyx_k__f;
+      goto __pyx_L13;
+    }
+
+    /* "numpy.pxd":269
+ *                 elif t == NPY_ULONGLONG:   f = "Q"
+ *                 elif t == NPY_FLOAT:       f = "f"
+ *                 elif t == NPY_DOUBLE:      f = "d"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_LONGDOUBLE:  f = "g"
+ *                 elif t == NPY_CFLOAT:      f = "Zf"
+ */
+    __pyx_t_1 = (__pyx_v_t == NPY_DOUBLE);
+    if (__pyx_t_1) {
+      __pyx_v_f = __pyx_k__d;
+      goto __pyx_L13;
+    }
+
+    /* "numpy.pxd":270
+ *                 elif t == NPY_FLOAT:       f = "f"
+ *                 elif t == NPY_DOUBLE:      f = "d"
+ *                 elif t == NPY_LONGDOUBLE:  f = "g"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_CFLOAT:      f = "Zf"
+ *                 elif t == NPY_CDOUBLE:     f = "Zd"
+ */
+    __pyx_t_1 = (__pyx_v_t == NPY_LONGDOUBLE);
+    if (__pyx_t_1) {
+      __pyx_v_f = __pyx_k__g;
+      goto __pyx_L13;
+    }
+
+    /* "numpy.pxd":271
+ *                 elif t == NPY_DOUBLE:      f = "d"
+ *                 elif t == NPY_LONGDOUBLE:  f = "g"
+ *                 elif t == NPY_CFLOAT:      f = "Zf"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_CDOUBLE:     f = "Zd"
+ *                 elif t == NPY_CLONGDOUBLE: f = "Zg"
+ */
+    __pyx_t_1 = (__pyx_v_t == NPY_CFLOAT);
+    if (__pyx_t_1) {
+      __pyx_v_f = __pyx_k__Zf;
+      goto __pyx_L13;
+    }
+
+    /* "numpy.pxd":272
+ *                 elif t == NPY_LONGDOUBLE:  f = "g"
+ *                 elif t == NPY_CFLOAT:      f = "Zf"
+ *                 elif t == NPY_CDOUBLE:     f = "Zd"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_CLONGDOUBLE: f = "Zg"
+ *                 elif t == NPY_OBJECT:      f = "O"
+ */
+    __pyx_t_1 = (__pyx_v_t == NPY_CDOUBLE);
+    if (__pyx_t_1) {
+      __pyx_v_f = __pyx_k__Zd;
+      goto __pyx_L13;
+    }
+
+    /* "numpy.pxd":273
+ *                 elif t == NPY_CFLOAT:      f = "Zf"
+ *                 elif t == NPY_CDOUBLE:     f = "Zd"
+ *                 elif t == NPY_CLONGDOUBLE: f = "Zg"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_OBJECT:      f = "O"
+ *                 else:
+ */
+    __pyx_t_1 = (__pyx_v_t == NPY_CLONGDOUBLE);
+    if (__pyx_t_1) {
+      __pyx_v_f = __pyx_k__Zg;
+      goto __pyx_L13;
+    }
+
+    /* "numpy.pxd":274
+ *                 elif t == NPY_CDOUBLE:     f = "Zd"
+ *                 elif t == NPY_CLONGDOUBLE: f = "Zg"
+ *                 elif t == NPY_OBJECT:      f = "O"             # <<<<<<<<<<<<<<
+ *                 else:
+ *                     raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
+ */
+    __pyx_t_1 = (__pyx_v_t == NPY_OBJECT);
+    if (__pyx_t_1) {
+      __pyx_v_f = __pyx_k__O;
+      goto __pyx_L13;
+    }
+    /*else*/ {
+
+      /* "numpy.pxd":276
+ *                 elif t == NPY_OBJECT:      f = "O"
+ *                 else:
+ *                     raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)             # <<<<<<<<<<<<<<
+ *                 info.format = f
+ *                 return
+ */
+      __pyx_t_4 = PyInt_FromLong(__pyx_v_t); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __pyx_t_8 = PyNumber_Remainder(((PyObject *)__pyx_kp_u_25), __pyx_t_4); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(((PyObject *)__pyx_t_8));
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      PyTuple_SET_ITEM(__pyx_t_4, 0, ((PyObject *)__pyx_t_8));
+      __Pyx_GIVEREF(((PyObject *)__pyx_t_8));
+      __pyx_t_8 = 0;
+      __pyx_t_8 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_t_4), NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_8);
+      __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
+      __Pyx_Raise(__pyx_t_8, 0, 0, 0);
+      __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+      {__pyx_filename = __pyx_f[1]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+    __pyx_L13:;
+
+    /* "numpy.pxd":277
+ *                 else:
+ *                     raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
+ *                 info.format = f             # <<<<<<<<<<<<<<
+ *                 return
+ *             else:
+ */
+    __pyx_v_info->format = __pyx_v_f;
+
+    /* "numpy.pxd":278
+ *                     raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
+ *                 info.format = f
+ *                 return             # <<<<<<<<<<<<<<
+ *             else:
+ *                 info.format = <char*>stdlib.malloc(_buffer_format_string_len)
+ */
+    __pyx_r = 0;
+    goto __pyx_L0;
+    goto __pyx_L11;
+  }
+  /*else*/ {
+
+    /* "numpy.pxd":280
+ *                 return
+ *             else:
+ *                 info.format = <char*>stdlib.malloc(_buffer_format_string_len)             # <<<<<<<<<<<<<<
+ *                 info.format[0] = c'^' # Native data types, manual alignment
+ *                 offset = 0
+ */
+    __pyx_v_info->format = ((char *)malloc(255));
+
+    /* "numpy.pxd":281
+ *             else:
+ *                 info.format = <char*>stdlib.malloc(_buffer_format_string_len)
+ *                 info.format[0] = c'^' # Native data types, manual alignment             # <<<<<<<<<<<<<<
+ *                 offset = 0
+ *                 f = _util_dtypestring(descr, info.format + 1,
+ */
+    (__pyx_v_info->format[0]) = '^';
+
+    /* "numpy.pxd":282
+ *                 info.format = <char*>stdlib.malloc(_buffer_format_string_len)
+ *                 info.format[0] = c'^' # Native data types, manual alignment
+ *                 offset = 0             # <<<<<<<<<<<<<<
+ *                 f = _util_dtypestring(descr, info.format + 1,
+ *                                       info.format + _buffer_format_string_len,
+ */
+    __pyx_v_offset = 0;
+
+    /* "numpy.pxd":285
+ *                 f = _util_dtypestring(descr, info.format + 1,
+ *                                       info.format + _buffer_format_string_len,
+ *                                       &offset)             # <<<<<<<<<<<<<<
+ *                 f[0] = c'\0' # Terminate format string
+ * 
+ */
+    __pyx_t_9 = __pyx_f_5numpy__util_dtypestring(__pyx_v_descr, (__pyx_v_info->format + 1), (__pyx_v_info->format + 255), (&__pyx_v_offset)); if (unlikely(__pyx_t_9 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 283; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_v_f = __pyx_t_9;
+
+    /* "numpy.pxd":286
+ *                                       info.format + _buffer_format_string_len,
+ *                                       &offset)
+ *                 f[0] = c'\0' # Terminate format string             # <<<<<<<<<<<<<<
+ * 
+ *         def __releasebuffer__(ndarray self, Py_buffer* info):
+ */
+    (__pyx_v_f[0]) = '\x00';
+  }
+  __pyx_L11:;
+
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_XDECREF(__pyx_t_8);
+  __Pyx_AddTraceback("numpy.ndarray.__getbuffer__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = -1;
+  if (__pyx_v_info != NULL && __pyx_v_info->obj != NULL) {
+    __Pyx_GOTREF(__pyx_v_info->obj);
+    __Pyx_DECREF(__pyx_v_info->obj); __pyx_v_info->obj = NULL;
+  }
+  goto __pyx_L2;
+  __pyx_L0:;
+  if (__pyx_v_info != NULL && __pyx_v_info->obj == Py_None) {
+    __Pyx_GOTREF(Py_None);
+    __Pyx_DECREF(Py_None); __pyx_v_info->obj = NULL;
+  }
+  __pyx_L2:;
+  __Pyx_XDECREF((PyObject *)__pyx_v_descr);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static CYTHON_UNUSED void __pyx_pw_5numpy_7ndarray_3__releasebuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info); /*proto*/
+static CYTHON_UNUSED void __pyx_pw_5numpy_7ndarray_3__releasebuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info) {
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__releasebuffer__ (wrapper)", 0);
+  __pyx_pf_5numpy_7ndarray_2__releasebuffer__(((PyArrayObject *)__pyx_v_self), ((Py_buffer *)__pyx_v_info));
+  __Pyx_RefNannyFinishContext();
+}
+
+/* "numpy.pxd":288
+ *                 f[0] = c'\0' # Terminate format string
+ * 
+ *         def __releasebuffer__(ndarray self, Py_buffer* info):             # <<<<<<<<<<<<<<
+ *             if PyArray_HASFIELDS(self):
+ *                 stdlib.free(info.format)
+ */
+
+static void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info) {
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("__releasebuffer__", 0);
+
+  /* "numpy.pxd":289
+ * 
+ *         def __releasebuffer__(ndarray self, Py_buffer* info):
+ *             if PyArray_HASFIELDS(self):             # <<<<<<<<<<<<<<
+ *                 stdlib.free(info.format)
+ *             if sizeof(npy_intp) != sizeof(Py_ssize_t):
+ */
+  __pyx_t_1 = PyArray_HASFIELDS(__pyx_v_self);
+  if (__pyx_t_1) {
+
+    /* "numpy.pxd":290
+ *         def __releasebuffer__(ndarray self, Py_buffer* info):
+ *             if PyArray_HASFIELDS(self):
+ *                 stdlib.free(info.format)             # <<<<<<<<<<<<<<
+ *             if sizeof(npy_intp) != sizeof(Py_ssize_t):
+ *                 stdlib.free(info.strides)
+ */
+    free(__pyx_v_info->format);
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  /* "numpy.pxd":291
+ *             if PyArray_HASFIELDS(self):
+ *                 stdlib.free(info.format)
+ *             if sizeof(npy_intp) != sizeof(Py_ssize_t):             # <<<<<<<<<<<<<<
+ *                 stdlib.free(info.strides)
+ *                 # info.shape was stored after info.strides in the same block
+ */
+  __pyx_t_1 = ((sizeof(npy_intp)) != (sizeof(Py_ssize_t)));
+  if (__pyx_t_1) {
+
+    /* "numpy.pxd":292
+ *                 stdlib.free(info.format)
+ *             if sizeof(npy_intp) != sizeof(Py_ssize_t):
+ *                 stdlib.free(info.strides)             # <<<<<<<<<<<<<<
+ *                 # info.shape was stored after info.strides in the same block
+ * 
+ */
+    free(__pyx_v_info->strides);
+    goto __pyx_L4;
+  }
+  __pyx_L4:;
+
+  __Pyx_RefNannyFinishContext();
+}
+
+/* "numpy.pxd":768
+ * ctypedef npy_cdouble     complex_t
+ * 
+ * cdef inline object PyArray_MultiIterNew1(a):             # <<<<<<<<<<<<<<
+ *     return PyArray_MultiIterNew(1, <void*>a)
+ * 
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew1(PyObject *__pyx_v_a) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("PyArray_MultiIterNew1", 0);
+
+  /* "numpy.pxd":769
+ * 
+ * cdef inline object PyArray_MultiIterNew1(a):
+ *     return PyArray_MultiIterNew(1, <void*>a)             # <<<<<<<<<<<<<<
+ * 
+ * cdef inline object PyArray_MultiIterNew2(a, b):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = PyArray_MultiIterNew(1, ((void *)__pyx_v_a)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 769; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("numpy.PyArray_MultiIterNew1", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "numpy.pxd":771
+ *     return PyArray_MultiIterNew(1, <void*>a)
+ * 
+ * cdef inline object PyArray_MultiIterNew2(a, b):             # <<<<<<<<<<<<<<
+ *     return PyArray_MultiIterNew(2, <void*>a, <void*>b)
+ * 
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew2(PyObject *__pyx_v_a, PyObject *__pyx_v_b) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("PyArray_MultiIterNew2", 0);
+
+  /* "numpy.pxd":772
+ * 
+ * cdef inline object PyArray_MultiIterNew2(a, b):
+ *     return PyArray_MultiIterNew(2, <void*>a, <void*>b)             # <<<<<<<<<<<<<<
+ * 
+ * cdef inline object PyArray_MultiIterNew3(a, b, c):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = PyArray_MultiIterNew(2, ((void *)__pyx_v_a), ((void *)__pyx_v_b)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 772; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("numpy.PyArray_MultiIterNew2", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "numpy.pxd":774
+ *     return PyArray_MultiIterNew(2, <void*>a, <void*>b)
+ * 
+ * cdef inline object PyArray_MultiIterNew3(a, b, c):             # <<<<<<<<<<<<<<
+ *     return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)
+ * 
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew3(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("PyArray_MultiIterNew3", 0);
+
+  /* "numpy.pxd":775
+ * 
+ * cdef inline object PyArray_MultiIterNew3(a, b, c):
+ *     return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)             # <<<<<<<<<<<<<<
+ * 
+ * cdef inline object PyArray_MultiIterNew4(a, b, c, d):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = PyArray_MultiIterNew(3, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 775; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("numpy.PyArray_MultiIterNew3", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "numpy.pxd":777
+ *     return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)
+ * 
+ * cdef inline object PyArray_MultiIterNew4(a, b, c, d):             # <<<<<<<<<<<<<<
+ *     return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)
+ * 
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew4(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c, PyObject *__pyx_v_d) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("PyArray_MultiIterNew4", 0);
+
+  /* "numpy.pxd":778
+ * 
+ * cdef inline object PyArray_MultiIterNew4(a, b, c, d):
+ *     return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)             # <<<<<<<<<<<<<<
+ * 
+ * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = PyArray_MultiIterNew(4, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c), ((void *)__pyx_v_d)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 778; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("numpy.PyArray_MultiIterNew4", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "numpy.pxd":780
+ *     return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)
+ * 
+ * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e):             # <<<<<<<<<<<<<<
+ *     return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)
+ * 
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew5(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c, PyObject *__pyx_v_d, PyObject *__pyx_v_e) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("PyArray_MultiIterNew5", 0);
+
+  /* "numpy.pxd":781
+ * 
+ * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e):
+ *     return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)             # <<<<<<<<<<<<<<
+ * 
+ * cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL:
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = PyArray_MultiIterNew(5, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c), ((void *)__pyx_v_d), ((void *)__pyx_v_e)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 781; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("numpy.PyArray_MultiIterNew5", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "numpy.pxd":783
+ *     return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)
+ * 
+ * cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL:             # <<<<<<<<<<<<<<
+ *     # Recursive utility function used in __getbuffer__ to get format
+ *     # string. The new location in the format string is returned.
+ */
+
+static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx_v_descr, char *__pyx_v_f, char *__pyx_v_end, int *__pyx_v_offset) {
+  PyArray_Descr *__pyx_v_child = 0;
+  int __pyx_v_endian_detector;
+  int __pyx_v_little_endian;
+  PyObject *__pyx_v_fields = 0;
+  PyObject *__pyx_v_childname = NULL;
+  PyObject *__pyx_v_new_offset = NULL;
+  PyObject *__pyx_v_t = NULL;
+  char *__pyx_r;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  Py_ssize_t __pyx_t_2;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  PyObject *__pyx_t_5 = NULL;
+  PyObject *(*__pyx_t_6)(PyObject *);
+  int __pyx_t_7;
+  int __pyx_t_8;
+  int __pyx_t_9;
+  int __pyx_t_10;
+  long __pyx_t_11;
+  char *__pyx_t_12;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("_util_dtypestring", 0);
+
+  /* "numpy.pxd":790
+ *     cdef int delta_offset
+ *     cdef tuple i
+ *     cdef int endian_detector = 1             # <<<<<<<<<<<<<<
+ *     cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)
+ *     cdef tuple fields
+ */
+  __pyx_v_endian_detector = 1;
+
+  /* "numpy.pxd":791
+ *     cdef tuple i
+ *     cdef int endian_detector = 1
+ *     cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)             # <<<<<<<<<<<<<<
+ *     cdef tuple fields
+ * 
+ */
+  __pyx_v_little_endian = ((((char *)(&__pyx_v_endian_detector))[0]) != 0);
+
+  /* "numpy.pxd":794
+ *     cdef tuple fields
+ * 
+ *     for childname in descr.names:             # <<<<<<<<<<<<<<
+ *         fields = descr.fields[childname]
+ *         child, new_offset = fields
+ */
+  if (unlikely(((PyObject *)__pyx_v_descr->names) == Py_None)) {
+    PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable");
+    {__pyx_filename = __pyx_f[1]; __pyx_lineno = 794; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  __pyx_t_1 = ((PyObject *)__pyx_v_descr->names); __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0;
+  for (;;) {
+    if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
+    #if CYTHON_COMPILING_IN_CPYTHON
+    __pyx_t_3 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_3); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 794; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    #else
+    __pyx_t_3 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 794; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    #endif
+    __Pyx_XDECREF(__pyx_v_childname);
+    __pyx_v_childname = __pyx_t_3;
+    __pyx_t_3 = 0;
+
+    /* "numpy.pxd":795
+ * 
+ *     for childname in descr.names:
+ *         fields = descr.fields[childname]             # <<<<<<<<<<<<<<
+ *         child, new_offset = fields
+ * 
+ */
+    __pyx_t_3 = PyObject_GetItem(__pyx_v_descr->fields, __pyx_v_childname); if (!__pyx_t_3) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 795; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    if (!(likely(PyTuple_CheckExact(__pyx_t_3))||((__pyx_t_3) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected tuple, got %.200s", Py_TYPE(__pyx_t_3)->tp_name), 0))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 795; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_XDECREF(((PyObject *)__pyx_v_fields));
+    __pyx_v_fields = ((PyObject*)__pyx_t_3);
+    __pyx_t_3 = 0;
+
+    /* "numpy.pxd":796
+ *     for childname in descr.names:
+ *         fields = descr.fields[childname]
+ *         child, new_offset = fields             # <<<<<<<<<<<<<<
+ * 
+ *         if (end - f) - (new_offset - offset[0]) < 15:
+ */
+    if (likely(PyTuple_CheckExact(((PyObject *)__pyx_v_fields)))) {
+      PyObject* sequence = ((PyObject *)__pyx_v_fields);
+      #if CYTHON_COMPILING_IN_CPYTHON
+      Py_ssize_t size = Py_SIZE(sequence);
+      #else
+      Py_ssize_t size = PySequence_Size(sequence);
+      #endif
+      if (unlikely(size != 2)) {
+        if (size > 2) __Pyx_RaiseTooManyValuesError(2);
+        else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
+        {__pyx_filename = __pyx_f[1]; __pyx_lineno = 796; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      }
+      #if CYTHON_COMPILING_IN_CPYTHON
+      __pyx_t_3 = PyTuple_GET_ITEM(sequence, 0); 
+      __pyx_t_4 = PyTuple_GET_ITEM(sequence, 1); 
+      __Pyx_INCREF(__pyx_t_3);
+      __Pyx_INCREF(__pyx_t_4);
+      #else
+      __pyx_t_3 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 796; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_4 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 796; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      #endif
+    } else if (1) {
+      __Pyx_RaiseNoneNotIterableError(); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 796; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    } else
+    {
+      Py_ssize_t index = -1;
+      __pyx_t_5 = PyObject_GetIter(((PyObject *)__pyx_v_fields)); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 796; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_5);
+      __pyx_t_6 = Py_TYPE(__pyx_t_5)->tp_iternext;
+      index = 0; __pyx_t_3 = __pyx_t_6(__pyx_t_5); if (unlikely(!__pyx_t_3)) goto __pyx_L5_unpacking_failed;
+      __Pyx_GOTREF(__pyx_t_3);
+      index = 1; __pyx_t_4 = __pyx_t_6(__pyx_t_5); if (unlikely(!__pyx_t_4)) goto __pyx_L5_unpacking_failed;
+      __Pyx_GOTREF(__pyx_t_4);
+      if (__Pyx_IternextUnpackEndCheck(__pyx_t_6(__pyx_t_5), 2) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 796; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_6 = NULL;
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      goto __pyx_L6_unpacking_done;
+      __pyx_L5_unpacking_failed:;
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      __pyx_t_6 = NULL;
+      if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
+      {__pyx_filename = __pyx_f[1]; __pyx_lineno = 796; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_L6_unpacking_done:;
+    }
+    if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_ptype_5numpy_dtype))))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 796; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_XDECREF(((PyObject *)__pyx_v_child));
+    __pyx_v_child = ((PyArray_Descr *)__pyx_t_3);
+    __pyx_t_3 = 0;
+    __Pyx_XDECREF(__pyx_v_new_offset);
+    __pyx_v_new_offset = __pyx_t_4;
+    __pyx_t_4 = 0;
+
+    /* "numpy.pxd":798
+ *         child, new_offset = fields
+ * 
+ *         if (end - f) - (new_offset - offset[0]) < 15:             # <<<<<<<<<<<<<<
+ *             raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd")
+ * 
+ */
+    __pyx_t_4 = PyInt_FromLong((__pyx_v_end - __pyx_v_f)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 798; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    __pyx_t_3 = PyInt_FromLong((__pyx_v_offset[0])); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 798; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __pyx_t_5 = PyNumber_Subtract(__pyx_v_new_offset, __pyx_t_3); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 798; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_5);
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __pyx_t_3 = PyNumber_Subtract(__pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 798; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+    __pyx_t_5 = PyObject_RichCompare(__pyx_t_3, __pyx_int_15, Py_LT); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 798; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 798; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+    if (__pyx_t_7) {
+
+      /* "numpy.pxd":799
+ * 
+ *         if (end - f) - (new_offset - offset[0]) < 15:
+ *             raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd")             # <<<<<<<<<<<<<<
+ * 
+ *         if ((child.byteorder == c'>' and little_endian) or
+ */
+      __pyx_t_5 = PyObject_Call(__pyx_builtin_RuntimeError, ((PyObject *)__pyx_k_tuple_27), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_5);
+      __Pyx_Raise(__pyx_t_5, 0, 0, 0);
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      {__pyx_filename = __pyx_f[1]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      goto __pyx_L7;
+    }
+    __pyx_L7:;
+
+    /* "numpy.pxd":801
+ *             raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd")
+ * 
+ *         if ((child.byteorder == c'>' and little_endian) or             # <<<<<<<<<<<<<<
+ *             (child.byteorder == c'<' and not little_endian)):
+ *             raise ValueError(u"Non-native byte order not supported")
+ */
+    __pyx_t_7 = (__pyx_v_child->byteorder == '>');
+    if (__pyx_t_7) {
+      __pyx_t_8 = __pyx_v_little_endian;
+    } else {
+      __pyx_t_8 = __pyx_t_7;
+    }
+    if (!__pyx_t_8) {
+
+      /* "numpy.pxd":802
+ * 
+ *         if ((child.byteorder == c'>' and little_endian) or
+ *             (child.byteorder == c'<' and not little_endian)):             # <<<<<<<<<<<<<<
+ *             raise ValueError(u"Non-native byte order not supported")
+ *             # One could encode it in the format string and have Cython
+ */
+      __pyx_t_7 = (__pyx_v_child->byteorder == '<');
+      if (__pyx_t_7) {
+        __pyx_t_9 = (!__pyx_v_little_endian);
+        __pyx_t_10 = __pyx_t_9;
+      } else {
+        __pyx_t_10 = __pyx_t_7;
+      }
+      __pyx_t_7 = __pyx_t_10;
+    } else {
+      __pyx_t_7 = __pyx_t_8;
+    }
+    if (__pyx_t_7) {
+
+      /* "numpy.pxd":803
+ *         if ((child.byteorder == c'>' and little_endian) or
+ *             (child.byteorder == c'<' and not little_endian)):
+ *             raise ValueError(u"Non-native byte order not supported")             # <<<<<<<<<<<<<<
+ *             # One could encode it in the format string and have Cython
+ *             # complain instead, BUT: < and > in format strings also imply
+ */
+      __pyx_t_5 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_k_tuple_28), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 803; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_5);
+      __Pyx_Raise(__pyx_t_5, 0, 0, 0);
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      {__pyx_filename = __pyx_f[1]; __pyx_lineno = 803; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      goto __pyx_L8;
+    }
+    __pyx_L8:;
+
+    /* "numpy.pxd":813
+ * 
+ *         # Output padding bytes
+ *         while offset[0] < new_offset:             # <<<<<<<<<<<<<<
+ *             f[0] = 120 # "x"; pad byte
+ *             f += 1
+ */
+    while (1) {
+      __pyx_t_5 = PyInt_FromLong((__pyx_v_offset[0])); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 813; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_5);
+      __pyx_t_3 = PyObject_RichCompare(__pyx_t_5, __pyx_v_new_offset, Py_LT); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 813; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 813; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      if (!__pyx_t_7) break;
+
+      /* "numpy.pxd":814
+ *         # Output padding bytes
+ *         while offset[0] < new_offset:
+ *             f[0] = 120 # "x"; pad byte             # <<<<<<<<<<<<<<
+ *             f += 1
+ *             offset[0] += 1
+ */
+      (__pyx_v_f[0]) = 120;
+
+      /* "numpy.pxd":815
+ *         while offset[0] < new_offset:
+ *             f[0] = 120 # "x"; pad byte
+ *             f += 1             # <<<<<<<<<<<<<<
+ *             offset[0] += 1
+ * 
+ */
+      __pyx_v_f = (__pyx_v_f + 1);
+
+      /* "numpy.pxd":816
+ *             f[0] = 120 # "x"; pad byte
+ *             f += 1
+ *             offset[0] += 1             # <<<<<<<<<<<<<<
+ * 
+ *         offset[0] += child.itemsize
+ */
+      __pyx_t_11 = 0;
+      (__pyx_v_offset[__pyx_t_11]) = ((__pyx_v_offset[__pyx_t_11]) + 1);
+    }
+
+    /* "numpy.pxd":818
+ *             offset[0] += 1
+ * 
+ *         offset[0] += child.itemsize             # <<<<<<<<<<<<<<
+ * 
+ *         if not PyDataType_HASFIELDS(child):
+ */
+    __pyx_t_11 = 0;
+    (__pyx_v_offset[__pyx_t_11]) = ((__pyx_v_offset[__pyx_t_11]) + __pyx_v_child->elsize);
+
+    /* "numpy.pxd":820
+ *         offset[0] += child.itemsize
+ * 
+ *         if not PyDataType_HASFIELDS(child):             # <<<<<<<<<<<<<<
+ *             t = child.type_num
+ *             if end - f < 5:
+ */
+    __pyx_t_7 = (!PyDataType_HASFIELDS(__pyx_v_child));
+    if (__pyx_t_7) {
+
+      /* "numpy.pxd":821
+ * 
+ *         if not PyDataType_HASFIELDS(child):
+ *             t = child.type_num             # <<<<<<<<<<<<<<
+ *             if end - f < 5:
+ *                 raise RuntimeError(u"Format string allocated too short.")
+ */
+      __pyx_t_3 = PyInt_FromLong(__pyx_v_child->type_num); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 821; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __Pyx_XDECREF(__pyx_v_t);
+      __pyx_v_t = __pyx_t_3;
+      __pyx_t_3 = 0;
+
+      /* "numpy.pxd":822
+ *         if not PyDataType_HASFIELDS(child):
+ *             t = child.type_num
+ *             if end - f < 5:             # <<<<<<<<<<<<<<
+ *                 raise RuntimeError(u"Format string allocated too short.")
+ * 
+ */
+      __pyx_t_7 = ((__pyx_v_end - __pyx_v_f) < 5);
+      if (__pyx_t_7) {
+
+        /* "numpy.pxd":823
+ *             t = child.type_num
+ *             if end - f < 5:
+ *                 raise RuntimeError(u"Format string allocated too short.")             # <<<<<<<<<<<<<<
+ * 
+ *             # Until ticket #99 is fixed, use integers to avoid warnings
+ */
+        __pyx_t_3 = PyObject_Call(__pyx_builtin_RuntimeError, ((PyObject *)__pyx_k_tuple_30), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 823; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_3);
+        __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+        __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+        {__pyx_filename = __pyx_f[1]; __pyx_lineno = 823; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        goto __pyx_L12;
+      }
+      __pyx_L12:;
+
+      /* "numpy.pxd":826
+ * 
+ *             # Until ticket #99 is fixed, use integers to avoid warnings
+ *             if   t == NPY_BYTE:        f[0] =  98 #"b"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_UBYTE:       f[0] =  66 #"B"
+ *             elif t == NPY_SHORT:       f[0] = 104 #"h"
+ */
+      __pyx_t_3 = PyInt_FromLong(NPY_BYTE); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 826; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_5 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 826; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 826; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      if (__pyx_t_7) {
+        (__pyx_v_f[0]) = 98;
+        goto __pyx_L13;
+      }
+
+      /* "numpy.pxd":827
+ *             # Until ticket #99 is fixed, use integers to avoid warnings
+ *             if   t == NPY_BYTE:        f[0] =  98 #"b"
+ *             elif t == NPY_UBYTE:       f[0] =  66 #"B"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_SHORT:       f[0] = 104 #"h"
+ *             elif t == NPY_USHORT:      f[0] =  72 #"H"
+ */
+      __pyx_t_5 = PyInt_FromLong(NPY_UBYTE); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 827; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_5);
+      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_5, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 827; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 827; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      if (__pyx_t_7) {
+        (__pyx_v_f[0]) = 66;
+        goto __pyx_L13;
+      }
+
+      /* "numpy.pxd":828
+ *             if   t == NPY_BYTE:        f[0] =  98 #"b"
+ *             elif t == NPY_UBYTE:       f[0] =  66 #"B"
+ *             elif t == NPY_SHORT:       f[0] = 104 #"h"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_USHORT:      f[0] =  72 #"H"
+ *             elif t == NPY_INT:         f[0] = 105 #"i"
+ */
+      __pyx_t_3 = PyInt_FromLong(NPY_SHORT); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 828; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_5 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 828; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 828; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      if (__pyx_t_7) {
+        (__pyx_v_f[0]) = 104;
+        goto __pyx_L13;
+      }
+
+      /* "numpy.pxd":829
+ *             elif t == NPY_UBYTE:       f[0] =  66 #"B"
+ *             elif t == NPY_SHORT:       f[0] = 104 #"h"
+ *             elif t == NPY_USHORT:      f[0] =  72 #"H"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_INT:         f[0] = 105 #"i"
+ *             elif t == NPY_UINT:        f[0] =  73 #"I"
+ */
+      __pyx_t_5 = PyInt_FromLong(NPY_USHORT); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 829; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_5);
+      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_5, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 829; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 829; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      if (__pyx_t_7) {
+        (__pyx_v_f[0]) = 72;
+        goto __pyx_L13;
+      }
+
+      /* "numpy.pxd":830
+ *             elif t == NPY_SHORT:       f[0] = 104 #"h"
+ *             elif t == NPY_USHORT:      f[0] =  72 #"H"
+ *             elif t == NPY_INT:         f[0] = 105 #"i"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_UINT:        f[0] =  73 #"I"
+ *             elif t == NPY_LONG:        f[0] = 108 #"l"
+ */
+      __pyx_t_3 = PyInt_FromLong(NPY_INT); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 830; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_5 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 830; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 830; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      if (__pyx_t_7) {
+        (__pyx_v_f[0]) = 105;
+        goto __pyx_L13;
+      }
+
+      /* "numpy.pxd":831
+ *             elif t == NPY_USHORT:      f[0] =  72 #"H"
+ *             elif t == NPY_INT:         f[0] = 105 #"i"
+ *             elif t == NPY_UINT:        f[0] =  73 #"I"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_LONG:        f[0] = 108 #"l"
+ *             elif t == NPY_ULONG:       f[0] = 76  #"L"
+ */
+      __pyx_t_5 = PyInt_FromLong(NPY_UINT); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 831; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_5);
+      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_5, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 831; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 831; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      if (__pyx_t_7) {
+        (__pyx_v_f[0]) = 73;
+        goto __pyx_L13;
+      }
+
+      /* "numpy.pxd":832
+ *             elif t == NPY_INT:         f[0] = 105 #"i"
+ *             elif t == NPY_UINT:        f[0] =  73 #"I"
+ *             elif t == NPY_LONG:        f[0] = 108 #"l"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_ULONG:       f[0] = 76  #"L"
+ *             elif t == NPY_LONGLONG:    f[0] = 113 #"q"
+ */
+      __pyx_t_3 = PyInt_FromLong(NPY_LONG); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 832; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_5 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 832; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 832; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      if (__pyx_t_7) {
+        (__pyx_v_f[0]) = 108;
+        goto __pyx_L13;
+      }
+
+      /* "numpy.pxd":833
+ *             elif t == NPY_UINT:        f[0] =  73 #"I"
+ *             elif t == NPY_LONG:        f[0] = 108 #"l"
+ *             elif t == NPY_ULONG:       f[0] = 76  #"L"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_LONGLONG:    f[0] = 113 #"q"
+ *             elif t == NPY_ULONGLONG:   f[0] = 81  #"Q"
+ */
+      __pyx_t_5 = PyInt_FromLong(NPY_ULONG); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 833; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_5);
+      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_5, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 833; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 833; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      if (__pyx_t_7) {
+        (__pyx_v_f[0]) = 76;
+        goto __pyx_L13;
+      }
+
+      /* "numpy.pxd":834
+ *             elif t == NPY_LONG:        f[0] = 108 #"l"
+ *             elif t == NPY_ULONG:       f[0] = 76  #"L"
+ *             elif t == NPY_LONGLONG:    f[0] = 113 #"q"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_ULONGLONG:   f[0] = 81  #"Q"
+ *             elif t == NPY_FLOAT:       f[0] = 102 #"f"
+ */
+      __pyx_t_3 = PyInt_FromLong(NPY_LONGLONG); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 834; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_5 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 834; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 834; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      if (__pyx_t_7) {
+        (__pyx_v_f[0]) = 113;
+        goto __pyx_L13;
+      }
+
+      /* "numpy.pxd":835
+ *             elif t == NPY_ULONG:       f[0] = 76  #"L"
+ *             elif t == NPY_LONGLONG:    f[0] = 113 #"q"
+ *             elif t == NPY_ULONGLONG:   f[0] = 81  #"Q"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_FLOAT:       f[0] = 102 #"f"
+ *             elif t == NPY_DOUBLE:      f[0] = 100 #"d"
+ */
+      __pyx_t_5 = PyInt_FromLong(NPY_ULONGLONG); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 835; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_5);
+      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_5, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 835; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 835; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      if (__pyx_t_7) {
+        (__pyx_v_f[0]) = 81;
+        goto __pyx_L13;
+      }
+
+      /* "numpy.pxd":836
+ *             elif t == NPY_LONGLONG:    f[0] = 113 #"q"
+ *             elif t == NPY_ULONGLONG:   f[0] = 81  #"Q"
+ *             elif t == NPY_FLOAT:       f[0] = 102 #"f"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_DOUBLE:      f[0] = 100 #"d"
+ *             elif t == NPY_LONGDOUBLE:  f[0] = 103 #"g"
+ */
+      __pyx_t_3 = PyInt_FromLong(NPY_FLOAT); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 836; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_5 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 836; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 836; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      if (__pyx_t_7) {
+        (__pyx_v_f[0]) = 102;
+        goto __pyx_L13;
+      }
+
+      /* "numpy.pxd":837
+ *             elif t == NPY_ULONGLONG:   f[0] = 81  #"Q"
+ *             elif t == NPY_FLOAT:       f[0] = 102 #"f"
+ *             elif t == NPY_DOUBLE:      f[0] = 100 #"d"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_LONGDOUBLE:  f[0] = 103 #"g"
+ *             elif t == NPY_CFLOAT:      f[0] = 90; f[1] = 102; f += 1 # Zf
+ */
+      __pyx_t_5 = PyInt_FromLong(NPY_DOUBLE); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 837; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_5);
+      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_5, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 837; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 837; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      if (__pyx_t_7) {
+        (__pyx_v_f[0]) = 100;
+        goto __pyx_L13;
+      }
+
+      /* "numpy.pxd":838
+ *             elif t == NPY_FLOAT:       f[0] = 102 #"f"
+ *             elif t == NPY_DOUBLE:      f[0] = 100 #"d"
+ *             elif t == NPY_LONGDOUBLE:  f[0] = 103 #"g"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_CFLOAT:      f[0] = 90; f[1] = 102; f += 1 # Zf
+ *             elif t == NPY_CDOUBLE:     f[0] = 90; f[1] = 100; f += 1 # Zd
+ */
+      __pyx_t_3 = PyInt_FromLong(NPY_LONGDOUBLE); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 838; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_5 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 838; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 838; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      if (__pyx_t_7) {
+        (__pyx_v_f[0]) = 103;
+        goto __pyx_L13;
+      }
+
+      /* "numpy.pxd":839
+ *             elif t == NPY_DOUBLE:      f[0] = 100 #"d"
+ *             elif t == NPY_LONGDOUBLE:  f[0] = 103 #"g"
+ *             elif t == NPY_CFLOAT:      f[0] = 90; f[1] = 102; f += 1 # Zf             # <<<<<<<<<<<<<<
+ *             elif t == NPY_CDOUBLE:     f[0] = 90; f[1] = 100; f += 1 # Zd
+ *             elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg
+ */
+      __pyx_t_5 = PyInt_FromLong(NPY_CFLOAT); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 839; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_5);
+      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_5, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 839; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 839; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      if (__pyx_t_7) {
+        (__pyx_v_f[0]) = 90;
+        (__pyx_v_f[1]) = 102;
+        __pyx_v_f = (__pyx_v_f + 1);
+        goto __pyx_L13;
+      }
+
+      /* "numpy.pxd":840
+ *             elif t == NPY_LONGDOUBLE:  f[0] = 103 #"g"
+ *             elif t == NPY_CFLOAT:      f[0] = 90; f[1] = 102; f += 1 # Zf
+ *             elif t == NPY_CDOUBLE:     f[0] = 90; f[1] = 100; f += 1 # Zd             # <<<<<<<<<<<<<<
+ *             elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg
+ *             elif t == NPY_OBJECT:      f[0] = 79 #"O"
+ */
+      __pyx_t_3 = PyInt_FromLong(NPY_CDOUBLE); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 840; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_5 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 840; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 840; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      if (__pyx_t_7) {
+        (__pyx_v_f[0]) = 90;
+        (__pyx_v_f[1]) = 100;
+        __pyx_v_f = (__pyx_v_f + 1);
+        goto __pyx_L13;
+      }
+
+      /* "numpy.pxd":841
+ *             elif t == NPY_CFLOAT:      f[0] = 90; f[1] = 102; f += 1 # Zf
+ *             elif t == NPY_CDOUBLE:     f[0] = 90; f[1] = 100; f += 1 # Zd
+ *             elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg             # <<<<<<<<<<<<<<
+ *             elif t == NPY_OBJECT:      f[0] = 79 #"O"
+ *             else:
+ */
+      __pyx_t_5 = PyInt_FromLong(NPY_CLONGDOUBLE); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 841; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_5);
+      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_5, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 841; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 841; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      if (__pyx_t_7) {
+        (__pyx_v_f[0]) = 90;
+        (__pyx_v_f[1]) = 103;
+        __pyx_v_f = (__pyx_v_f + 1);
+        goto __pyx_L13;
+      }
+
+      /* "numpy.pxd":842
+ *             elif t == NPY_CDOUBLE:     f[0] = 90; f[1] = 100; f += 1 # Zd
+ *             elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg
+ *             elif t == NPY_OBJECT:      f[0] = 79 #"O"             # <<<<<<<<<<<<<<
+ *             else:
+ *                 raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
+ */
+      __pyx_t_3 = PyInt_FromLong(NPY_OBJECT); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 842; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_5 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 842; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 842; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      if (__pyx_t_7) {
+        (__pyx_v_f[0]) = 79;
+        goto __pyx_L13;
+      }
+      /*else*/ {
+
+        /* "numpy.pxd":844
+ *             elif t == NPY_OBJECT:      f[0] = 79 #"O"
+ *             else:
+ *                 raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)             # <<<<<<<<<<<<<<
+ *             f += 1
+ *         else:
+ */
+        __pyx_t_5 = PyNumber_Remainder(((PyObject *)__pyx_kp_u_25), __pyx_v_t); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 844; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(((PyObject *)__pyx_t_5));
+        __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 844; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_3);
+        PyTuple_SET_ITEM(__pyx_t_3, 0, ((PyObject *)__pyx_t_5));
+        __Pyx_GIVEREF(((PyObject *)__pyx_t_5));
+        __pyx_t_5 = 0;
+        __pyx_t_5 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 844; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_5);
+        __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
+        __Pyx_Raise(__pyx_t_5, 0, 0, 0);
+        __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+        {__pyx_filename = __pyx_f[1]; __pyx_lineno = 844; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      }
+      __pyx_L13:;
+
+      /* "numpy.pxd":845
+ *             else:
+ *                 raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
+ *             f += 1             # <<<<<<<<<<<<<<
+ *         else:
+ *             # Cython ignores struct boundary information ("T{...}"),
+ */
+      __pyx_v_f = (__pyx_v_f + 1);
+      goto __pyx_L11;
+    }
+    /*else*/ {
+
+      /* "numpy.pxd":849
+ *             # Cython ignores struct boundary information ("T{...}"),
+ *             # so don't output it
+ *             f = _util_dtypestring(child, f, end, offset)             # <<<<<<<<<<<<<<
+ *     return f
+ * 
+ */
+      __pyx_t_12 = __pyx_f_5numpy__util_dtypestring(__pyx_v_child, __pyx_v_f, __pyx_v_end, __pyx_v_offset); if (unlikely(__pyx_t_12 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 849; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_v_f = __pyx_t_12;
+    }
+    __pyx_L11:;
+  }
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "numpy.pxd":850
+ *             # so don't output it
+ *             f = _util_dtypestring(child, f, end, offset)
+ *     return f             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+  __pyx_r = __pyx_v_f;
+  goto __pyx_L0;
+
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_XDECREF(__pyx_t_5);
+  __Pyx_AddTraceback("numpy._util_dtypestring", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XDECREF((PyObject *)__pyx_v_child);
+  __Pyx_XDECREF(__pyx_v_fields);
+  __Pyx_XDECREF(__pyx_v_childname);
+  __Pyx_XDECREF(__pyx_v_new_offset);
+  __Pyx_XDECREF(__pyx_v_t);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "numpy.pxd":965
+ * 
+ * 
+ * cdef inline void set_array_base(ndarray arr, object base):             # <<<<<<<<<<<<<<
+ *      cdef PyObject* baseptr
+ *      if base is None:
+ */
+
+static CYTHON_INLINE void __pyx_f_5numpy_set_array_base(PyArrayObject *__pyx_v_arr, PyObject *__pyx_v_base) {
+  PyObject *__pyx_v_baseptr;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("set_array_base", 0);
+
+  /* "numpy.pxd":967
+ * cdef inline void set_array_base(ndarray arr, object base):
+ *      cdef PyObject* baseptr
+ *      if base is None:             # <<<<<<<<<<<<<<
+ *          baseptr = NULL
+ *      else:
+ */
+  __pyx_t_1 = (__pyx_v_base == Py_None);
+  if (__pyx_t_1) {
+
+    /* "numpy.pxd":968
+ *      cdef PyObject* baseptr
+ *      if base is None:
+ *          baseptr = NULL             # <<<<<<<<<<<<<<
+ *      else:
+ *          Py_INCREF(base) # important to do this before decref below!
+ */
+    __pyx_v_baseptr = NULL;
+    goto __pyx_L3;
+  }
+  /*else*/ {
+
+    /* "numpy.pxd":970
+ *          baseptr = NULL
+ *      else:
+ *          Py_INCREF(base) # important to do this before decref below!             # <<<<<<<<<<<<<<
+ *          baseptr = <PyObject*>base
+ *      Py_XDECREF(arr.base)
+ */
+    Py_INCREF(__pyx_v_base);
+
+    /* "numpy.pxd":971
+ *      else:
+ *          Py_INCREF(base) # important to do this before decref below!
+ *          baseptr = <PyObject*>base             # <<<<<<<<<<<<<<
+ *      Py_XDECREF(arr.base)
+ *      arr.base = baseptr
+ */
+    __pyx_v_baseptr = ((PyObject *)__pyx_v_base);
+  }
+  __pyx_L3:;
+
+  /* "numpy.pxd":972
+ *          Py_INCREF(base) # important to do this before decref below!
+ *          baseptr = <PyObject*>base
+ *      Py_XDECREF(arr.base)             # <<<<<<<<<<<<<<
+ *      arr.base = baseptr
+ * 
+ */
+  Py_XDECREF(__pyx_v_arr->base);
+
+  /* "numpy.pxd":973
+ *          baseptr = <PyObject*>base
+ *      Py_XDECREF(arr.base)
+ *      arr.base = baseptr             # <<<<<<<<<<<<<<
+ * 
+ * cdef inline object get_array_base(ndarray arr):
+ */
+  __pyx_v_arr->base = __pyx_v_baseptr;
+
+  __Pyx_RefNannyFinishContext();
+}
+
+/* "numpy.pxd":975
+ *      arr.base = baseptr
+ * 
+ * cdef inline object get_array_base(ndarray arr):             # <<<<<<<<<<<<<<
+ *     if arr.base is NULL:
+ *         return None
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_5numpy_get_array_base(PyArrayObject *__pyx_v_arr) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("get_array_base", 0);
+
+  /* "numpy.pxd":976
+ * 
+ * cdef inline object get_array_base(ndarray arr):
+ *     if arr.base is NULL:             # <<<<<<<<<<<<<<
+ *         return None
+ *     else:
+ */
+  __pyx_t_1 = (__pyx_v_arr->base == NULL);
+  if (__pyx_t_1) {
+
+    /* "numpy.pxd":977
+ * cdef inline object get_array_base(ndarray arr):
+ *     if arr.base is NULL:
+ *         return None             # <<<<<<<<<<<<<<
+ *     else:
+ *         return <object>arr.base
+ */
+    __Pyx_XDECREF(__pyx_r);
+    __Pyx_INCREF(Py_None);
+    __pyx_r = Py_None;
+    goto __pyx_L0;
+    goto __pyx_L3;
+  }
+  /*else*/ {
+
+    /* "numpy.pxd":979
+ *         return None
+ *     else:
+ *         return <object>arr.base             # <<<<<<<<<<<<<<
+ */
+    __Pyx_XDECREF(__pyx_r);
+    __Pyx_INCREF(((PyObject *)__pyx_v_arr->base));
+    __pyx_r = ((PyObject *)__pyx_v_arr->base);
+    goto __pyx_L0;
+  }
+  __pyx_L3:;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_tp_new_2bx_5align_4_epo___pyx_scope_struct__rem_dash(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) {
+  struct __pyx_obj_2bx_5align_4_epo___pyx_scope_struct__rem_dash *p;
+  PyObject *o = (*t->tp_alloc)(t, 0);
+  if (!o) return 0;
+  p = ((struct __pyx_obj_2bx_5align_4_epo___pyx_scope_struct__rem_dash *)o);
+  p->__pyx_v_P = 0;
+  p->__pyx_v_Q = 0;
+  p->__pyx_v_p = 0;
+  p->__pyx_v_q = 0;
+  return o;
+}
+
+static void __pyx_tp_dealloc_2bx_5align_4_epo___pyx_scope_struct__rem_dash(PyObject *o) {
+  struct __pyx_obj_2bx_5align_4_epo___pyx_scope_struct__rem_dash *p = (struct __pyx_obj_2bx_5align_4_epo___pyx_scope_struct__rem_dash *)o;
+  PyObject_GC_UnTrack(o);
+  Py_CLEAR(p->__pyx_v_P);
+  Py_CLEAR(p->__pyx_v_Q);
+  Py_CLEAR(p->__pyx_v_p);
+  Py_CLEAR(p->__pyx_v_q);
+  PyObject_GC_Track(o);
+  (*Py_TYPE(o)->tp_free)(o);
+}
+
+static int __pyx_tp_traverse_2bx_5align_4_epo___pyx_scope_struct__rem_dash(PyObject *o, visitproc v, void *a) {
+  int e;
+  struct __pyx_obj_2bx_5align_4_epo___pyx_scope_struct__rem_dash *p = (struct __pyx_obj_2bx_5align_4_epo___pyx_scope_struct__rem_dash *)o;
+  if (p->__pyx_v_P) {
+    e = (*v)(p->__pyx_v_P, a); if (e) return e;
+  }
+  if (p->__pyx_v_Q) {
+    e = (*v)(p->__pyx_v_Q, a); if (e) return e;
+  }
+  if (p->__pyx_v_p) {
+    e = (*v)(p->__pyx_v_p, a); if (e) return e;
+  }
+  if (p->__pyx_v_q) {
+    e = (*v)(p->__pyx_v_q, a); if (e) return e;
+  }
+  return 0;
+}
+
+static int __pyx_tp_clear_2bx_5align_4_epo___pyx_scope_struct__rem_dash(PyObject *o) {
+  struct __pyx_obj_2bx_5align_4_epo___pyx_scope_struct__rem_dash *p = (struct __pyx_obj_2bx_5align_4_epo___pyx_scope_struct__rem_dash *)o;
+  PyObject* tmp;
+  tmp = ((PyObject*)p->__pyx_v_P);
+  p->__pyx_v_P = Py_None; Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  tmp = ((PyObject*)p->__pyx_v_Q);
+  p->__pyx_v_Q = Py_None; Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  tmp = ((PyObject*)p->__pyx_v_p);
+  p->__pyx_v_p = Py_None; Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  tmp = ((PyObject*)p->__pyx_v_q);
+  p->__pyx_v_q = Py_None; Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  return 0;
+}
+
+static PyMethodDef __pyx_methods_2bx_5align_4_epo___pyx_scope_struct__rem_dash[] = {
+  {0, 0, 0, 0}
+};
+
+static PyNumberMethods __pyx_tp_as_number___pyx_scope_struct__rem_dash = {
+  0, /*nb_add*/
+  0, /*nb_subtract*/
+  0, /*nb_multiply*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_divide*/
+  #endif
+  0, /*nb_remainder*/
+  0, /*nb_divmod*/
+  0, /*nb_power*/
+  0, /*nb_negative*/
+  0, /*nb_positive*/
+  0, /*nb_absolute*/
+  0, /*nb_nonzero*/
+  0, /*nb_invert*/
+  0, /*nb_lshift*/
+  0, /*nb_rshift*/
+  0, /*nb_and*/
+  0, /*nb_xor*/
+  0, /*nb_or*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_coerce*/
+  #endif
+  0, /*nb_int*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_long*/
+  #else
+  0, /*reserved*/
+  #endif
+  0, /*nb_float*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_oct*/
+  #endif
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_hex*/
+  #endif
+  0, /*nb_inplace_add*/
+  0, /*nb_inplace_subtract*/
+  0, /*nb_inplace_multiply*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_inplace_divide*/
+  #endif
+  0, /*nb_inplace_remainder*/
+  0, /*nb_inplace_power*/
+  0, /*nb_inplace_lshift*/
+  0, /*nb_inplace_rshift*/
+  0, /*nb_inplace_and*/
+  0, /*nb_inplace_xor*/
+  0, /*nb_inplace_or*/
+  0, /*nb_floor_divide*/
+  0, /*nb_true_divide*/
+  0, /*nb_inplace_floor_divide*/
+  0, /*nb_inplace_true_divide*/
+  #if PY_VERSION_HEX >= 0x02050000
+  0, /*nb_index*/
+  #endif
+};
+
+static PySequenceMethods __pyx_tp_as_sequence___pyx_scope_struct__rem_dash = {
+  0, /*sq_length*/
+  0, /*sq_concat*/
+  0, /*sq_repeat*/
+  0, /*sq_item*/
+  0, /*sq_slice*/
+  0, /*sq_ass_item*/
+  0, /*sq_ass_slice*/
+  0, /*sq_contains*/
+  0, /*sq_inplace_concat*/
+  0, /*sq_inplace_repeat*/
+};
+
+static PyMappingMethods __pyx_tp_as_mapping___pyx_scope_struct__rem_dash = {
+  0, /*mp_length*/
+  0, /*mp_subscript*/
+  0, /*mp_ass_subscript*/
+};
+
+static PyBufferProcs __pyx_tp_as_buffer___pyx_scope_struct__rem_dash = {
+  #if PY_MAJOR_VERSION < 3
+  0, /*bf_getreadbuffer*/
+  #endif
+  #if PY_MAJOR_VERSION < 3
+  0, /*bf_getwritebuffer*/
+  #endif
+  #if PY_MAJOR_VERSION < 3
+  0, /*bf_getsegcount*/
+  #endif
+  #if PY_MAJOR_VERSION < 3
+  0, /*bf_getcharbuffer*/
+  #endif
+  #if PY_VERSION_HEX >= 0x02060000
+  0, /*bf_getbuffer*/
+  #endif
+  #if PY_VERSION_HEX >= 0x02060000
+  0, /*bf_releasebuffer*/
+  #endif
+};
+
+static PyTypeObject __pyx_type_2bx_5align_4_epo___pyx_scope_struct__rem_dash = {
+  PyVarObject_HEAD_INIT(0, 0)
+  __Pyx_NAMESTR("bx.align._epo.__pyx_scope_struct__rem_dash"), /*tp_name*/
+  sizeof(struct __pyx_obj_2bx_5align_4_epo___pyx_scope_struct__rem_dash), /*tp_basicsize*/
+  0, /*tp_itemsize*/
+  __pyx_tp_dealloc_2bx_5align_4_epo___pyx_scope_struct__rem_dash, /*tp_dealloc*/
+  0, /*tp_print*/
+  0, /*tp_getattr*/
+  0, /*tp_setattr*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*tp_compare*/
+  #else
+  0, /*reserved*/
+  #endif
+  0, /*tp_repr*/
+  &__pyx_tp_as_number___pyx_scope_struct__rem_dash, /*tp_as_number*/
+  &__pyx_tp_as_sequence___pyx_scope_struct__rem_dash, /*tp_as_sequence*/
+  &__pyx_tp_as_mapping___pyx_scope_struct__rem_dash, /*tp_as_mapping*/
+  0, /*tp_hash*/
+  0, /*tp_call*/
+  0, /*tp_str*/
+  0, /*tp_getattro*/
+  0, /*tp_setattro*/
+  &__pyx_tp_as_buffer___pyx_scope_struct__rem_dash, /*tp_as_buffer*/
+  Py_TPFLAGS_DEFAULT|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+  0, /*tp_doc*/
+  __pyx_tp_traverse_2bx_5align_4_epo___pyx_scope_struct__rem_dash, /*tp_traverse*/
+  __pyx_tp_clear_2bx_5align_4_epo___pyx_scope_struct__rem_dash, /*tp_clear*/
+  0, /*tp_richcompare*/
+  0, /*tp_weaklistoffset*/
+  0, /*tp_iter*/
+  0, /*tp_iternext*/
+  __pyx_methods_2bx_5align_4_epo___pyx_scope_struct__rem_dash, /*tp_methods*/
+  0, /*tp_members*/
+  0, /*tp_getset*/
+  0, /*tp_base*/
+  0, /*tp_dict*/
+  0, /*tp_descr_get*/
+  0, /*tp_descr_set*/
+  0, /*tp_dictoffset*/
+  0, /*tp_init*/
+  0, /*tp_alloc*/
+  __pyx_tp_new_2bx_5align_4_epo___pyx_scope_struct__rem_dash, /*tp_new*/
+  0, /*tp_free*/
+  0, /*tp_is_gc*/
+  0, /*tp_bases*/
+  0, /*tp_mro*/
+  0, /*tp_cache*/
+  0, /*tp_subclasses*/
+  0, /*tp_weaklist*/
+  0, /*tp_del*/
+  #if PY_VERSION_HEX >= 0x02060000
+  0, /*tp_version_tag*/
+  #endif
+};
+
+static PyMethodDef __pyx_methods[] = {
+  {__Pyx_NAMESTR("bed_union"), (PyCFunction)__pyx_pw_2bx_5align_4_epo_5bed_union, METH_O, __Pyx_DOCSTR(__pyx_doc_2bx_5align_4_epo_4bed_union)},
+  {__Pyx_NAMESTR("cummulative_intervals"), (PyCFunction)__pyx_pw_2bx_5align_4_epo_7cummulative_intervals, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(__pyx_doc_2bx_5align_4_epo_6cummulative_intervals)},
+  {0, 0, 0, 0}
+};
+
+#if PY_MAJOR_VERSION >= 3
+static struct PyModuleDef __pyx_moduledef = {
+  #if PY_VERSION_HEX < 0x03020000
+    { PyObject_HEAD_INIT(NULL) NULL, 0, NULL },
+  #else
+    PyModuleDef_HEAD_INIT,
+  #endif
+    __Pyx_NAMESTR("_epo"),
+    0, /* m_doc */
+    -1, /* m_size */
+    __pyx_methods /* m_methods */,
+    NULL, /* m_reload */
+    NULL, /* m_traverse */
+    NULL, /* m_clear */
+    NULL /* m_free */
+};
+#endif
+
+static __Pyx_StringTabEntry __pyx_string_tab[] = {
+  {&__pyx_kp_s_10, __pyx_k_10, sizeof(__pyx_k_10), 0, 0, 1, 0},
+  {&__pyx_kp_s_11, __pyx_k_11, sizeof(__pyx_k_11), 0, 0, 1, 0},
+  {&__pyx_kp_s_12, __pyx_k_12, sizeof(__pyx_k_12), 0, 0, 1, 0},
+  {&__pyx_kp_s_14, __pyx_k_14, sizeof(__pyx_k_14), 0, 0, 1, 0},
+  {&__pyx_kp_s_15, __pyx_k_15, sizeof(__pyx_k_15), 0, 0, 1, 0},
+  {&__pyx_kp_s_16, __pyx_k_16, sizeof(__pyx_k_16), 0, 0, 1, 0},
+  {&__pyx_kp_s_18, __pyx_k_18, sizeof(__pyx_k_18), 0, 0, 1, 0},
+  {&__pyx_kp_u_19, __pyx_k_19, sizeof(__pyx_k_19), 0, 1, 0, 0},
+  {&__pyx_kp_u_21, __pyx_k_21, sizeof(__pyx_k_21), 0, 1, 0, 0},
+  {&__pyx_kp_u_23, __pyx_k_23, sizeof(__pyx_k_23), 0, 1, 0, 0},
+  {&__pyx_kp_u_25, __pyx_k_25, sizeof(__pyx_k_25), 0, 1, 0, 0},
+  {&__pyx_kp_u_26, __pyx_k_26, sizeof(__pyx_k_26), 0, 1, 0, 0},
+  {&__pyx_kp_u_29, __pyx_k_29, sizeof(__pyx_k_29), 0, 1, 0, 0},
+  {&__pyx_kp_s_3, __pyx_k_3, sizeof(__pyx_k_3), 0, 0, 1, 0},
+  {&__pyx_n_s_4, __pyx_k_4, sizeof(__pyx_k_4), 0, 0, 1, 1},
+  {&__pyx_n_s_5, __pyx_k_5, sizeof(__pyx_k_5), 0, 0, 1, 1},
+  {&__pyx_n_s_8, __pyx_k_8, sizeof(__pyx_k_8), 0, 0, 1, 1},
+  {&__pyx_n_s_9, __pyx_k_9, sizeof(__pyx_k_9), 0, 0, 1, 1},
+  {&__pyx_n_s__D, __pyx_k__D, sizeof(__pyx_k__D), 0, 0, 1, 1},
+  {&__pyx_n_s__DTYPE, __pyx_k__DTYPE, sizeof(__pyx_k__DTYPE), 0, 0, 1, 1},
+  {&__pyx_n_s__N, __pyx_k__N, sizeof(__pyx_k__N), 0, 0, 1, 1},
+  {&__pyx_n_s__P, __pyx_k__P, sizeof(__pyx_k__P), 0, 0, 1, 1},
+  {&__pyx_n_s__P_card, __pyx_k__P_card, sizeof(__pyx_k__P_card), 0, 0, 1, 1},
+  {&__pyx_n_s__Q, __pyx_k__Q, sizeof(__pyx_k__Q), 0, 0, 1, 1},
+  {&__pyx_n_s__Q_card, __pyx_k__Q_card, sizeof(__pyx_k__Q_card), 0, 0, 1, 1},
+  {&__pyx_n_s__R, __pyx_k__R, sizeof(__pyx_k__R), 0, 0, 1, 1},
+  {&__pyx_n_s__RuntimeError, __pyx_k__RuntimeError, sizeof(__pyx_k__RuntimeError), 0, 0, 1, 1},
+  {&__pyx_n_s__S, __pyx_k__S, sizeof(__pyx_k__S), 0, 0, 1, 1},
+  {&__pyx_n_s__ValueError, __pyx_k__ValueError, sizeof(__pyx_k__ValueError), 0, 0, 1, 1},
+  {&__pyx_n_s____enter__, __pyx_k____enter__, sizeof(__pyx_k____enter__), 0, 0, 1, 1},
+  {&__pyx_n_s____exit__, __pyx_k____exit__, sizeof(__pyx_k____exit__), 0, 0, 1, 1},
+  {&__pyx_n_s____main__, __pyx_k____main__, sizeof(__pyx_k____main__), 0, 0, 1, 1},
+  {&__pyx_n_s____name__, __pyx_k____name__, sizeof(__pyx_k____name__), 0, 0, 1, 1},
+  {&__pyx_n_s____test__, __pyx_k____test__, sizeof(__pyx_k____test__), 0, 0, 1, 1},
+  {&__pyx_n_s__a, __pyx_k__a, sizeof(__pyx_k__a), 0, 0, 1, 1},
+  {&__pyx_n_s__adv, __pyx_k__adv, sizeof(__pyx_k__adv), 0, 0, 1, 1},
+  {&__pyx_n_s__array, __pyx_k__array, sizeof(__pyx_k__array), 0, 0, 1, 1},
+  {&__pyx_n_s__axis, __pyx_k__axis, sizeof(__pyx_k__axis), 0, 0, 1, 1},
+  {&__pyx_n_s__b, __pyx_k__b, sizeof(__pyx_k__b), 0, 0, 1, 1},
+  {&__pyx_n_s__collections, __pyx_k__collections, sizeof(__pyx_k__collections), 0, 0, 1, 1},
+  {&__pyx_n_s__d, __pyx_k__d, sizeof(__pyx_k__d), 0, 0, 1, 1},
+  {&__pyx_n_s__dash, __pyx_k__dash, sizeof(__pyx_k__dash), 0, 0, 1, 1},
+  {&__pyx_n_s__data, __pyx_k__data, sizeof(__pyx_k__data), 0, 0, 1, 1},
+  {&__pyx_n_s__dtype, __pyx_k__dtype, sizeof(__pyx_k__dtype), 0, 0, 1, 1},
+  {&__pyx_n_s__empty, __pyx_k__empty, sizeof(__pyx_k__empty), 0, 0, 1, 1},
+  {&__pyx_n_s__endswith, __pyx_k__endswith, sizeof(__pyx_k__endswith), 0, 0, 1, 1},
+  {&__pyx_n_s__fastLoadChain, __pyx_k__fastLoadChain, sizeof(__pyx_k__fastLoadChain), 0, 0, 1, 1},
+  {&__pyx_n_s__fd, __pyx_k__fd, sizeof(__pyx_k__fd), 0, 0, 1, 1},
+  {&__pyx_n_s__fname, __pyx_k__fname, sizeof(__pyx_k__fname), 0, 0, 1, 1},
+  {&__pyx_n_s__getLogger, __pyx_k__getLogger, sizeof(__pyx_k__getLogger), 0, 0, 1, 1},
+  {&__pyx_n_s__gzip, __pyx_k__gzip, sizeof(__pyx_k__gzip), 0, 0, 1, 1},
+  {&__pyx_n_s__hd, __pyx_k__hd, sizeof(__pyx_k__hd), 0, 0, 1, 1},
+  {&__pyx_n_s__hf, __pyx_k__hf, sizeof(__pyx_k__hf), 0, 0, 1, 1},
+  {&__pyx_n_s__i, __pyx_k__i, sizeof(__pyx_k__i), 0, 0, 1, 1},
+  {&__pyx_n_s__info, __pyx_k__info, sizeof(__pyx_k__info), 0, 0, 1, 1},
+  {&__pyx_n_s__int, __pyx_k__int, sizeof(__pyx_k__int), 0, 0, 1, 1},
+  {&__pyx_n_s__int64, __pyx_k__int64, sizeof(__pyx_k__int64), 0, 0, 1, 1},
+  {&__pyx_n_s__l, __pyx_k__l, sizeof(__pyx_k__l), 0, 0, 1, 1},
+  {&__pyx_n_s__line, __pyx_k__line, sizeof(__pyx_k__line), 0, 0, 1, 1},
+  {&__pyx_n_s__log, __pyx_k__log, sizeof(__pyx_k__log), 0, 0, 1, 1},
+  {&__pyx_n_s__logging, __pyx_k__logging, sizeof(__pyx_k__logging), 0, 0, 1, 1},
+  {&__pyx_n_s__map, __pyx_k__map, sizeof(__pyx_k__map), 0, 0, 1, 1},
+  {&__pyx_n_s__myp, __pyx_k__myp, sizeof(__pyx_k__myp), 0, 0, 1, 1},
+  {&__pyx_n_s__namedtuple, __pyx_k__namedtuple, sizeof(__pyx_k__namedtuple), 0, 0, 1, 1},
+  {&__pyx_n_s__numpy, __pyx_k__numpy, sizeof(__pyx_k__numpy), 0, 0, 1, 1},
+  {&__pyx_n_s__open, __pyx_k__open, sizeof(__pyx_k__open), 0, 0, 1, 1},
+  {&__pyx_n_s__open_f, __pyx_k__open_f, sizeof(__pyx_k__open_f), 0, 0, 1, 1},
+  {&__pyx_n_s__p, __pyx_k__p, sizeof(__pyx_k__p), 0, 0, 1, 1},
+  {&__pyx_n_s__p_card, __pyx_k__p_card, sizeof(__pyx_k__p_card), 0, 0, 1, 1},
+  {&__pyx_n_s__q, __pyx_k__q, sizeof(__pyx_k__q), 0, 0, 1, 1},
+  {&__pyx_n_s__qEnd, __pyx_k__qEnd, sizeof(__pyx_k__qEnd), 0, 0, 1, 1},
+  {&__pyx_n_s__qStart, __pyx_k__qStart, sizeof(__pyx_k__qStart), 0, 0, 1, 1},
+  {&__pyx_n_s__q_card, __pyx_k__q_card, sizeof(__pyx_k__q_card), 0, 0, 1, 1},
+  {&__pyx_n_s__queue, __pyx_k__queue, sizeof(__pyx_k__queue), 0, 0, 1, 1},
+  {&__pyx_n_s__r, __pyx_k__r, sizeof(__pyx_k__r), 0, 0, 1, 1},
+  {&__pyx_n_s__range, __pyx_k__range, sizeof(__pyx_k__range), 0, 0, 1, 1},
+  {&__pyx_n_s__readline, __pyx_k__readline, sizeof(__pyx_k__readline), 0, 0, 1, 1},
+  {&__pyx_n_s__rem_dash, __pyx_k__rem_dash, sizeof(__pyx_k__rem_dash), 0, 0, 1, 1},
+  {&__pyx_n_s__s, __pyx_k__s, sizeof(__pyx_k__s), 0, 0, 1, 1},
+  {&__pyx_n_s__shape, __pyx_k__shape, sizeof(__pyx_k__shape), 0, 0, 1, 1},
+  {&__pyx_n_s__shi, __pyx_k__shi, sizeof(__pyx_k__shi), 0, 0, 1, 1},
+  {&__pyx_n_s__sort, __pyx_k__sort, sizeof(__pyx_k__sort), 0, 0, 1, 1},
+  {&__pyx_n_s__split, __pyx_k__split, sizeof(__pyx_k__split), 0, 0, 1, 1},
+  {&__pyx_n_s__sum, __pyx_k__sum, sizeof(__pyx_k__sum), 0, 0, 1, 1},
+  {&__pyx_n_s__t, __pyx_k__t, sizeof(__pyx_k__t), 0, 0, 1, 1},
+  {&__pyx_n_s__tEnd, __pyx_k__tEnd, sizeof(__pyx_k__tEnd), 0, 0, 1, 1},
+  {&__pyx_n_s__tStart, __pyx_k__tStart, sizeof(__pyx_k__tStart), 0, 0, 1, 1},
+  {&__pyx_n_s__uint64, __pyx_k__uint64, sizeof(__pyx_k__uint64), 0, 0, 1, 1},
+  {&__pyx_n_s__zeros, __pyx_k__zeros, sizeof(__pyx_k__zeros), 0, 0, 1, 1},
+  {&__pyx_n_s__zip, __pyx_k__zip, sizeof(__pyx_k__zip), 0, 0, 1, 1},
+  {0, 0, 0, 0, 0, 0, 0}
+};
+static int __Pyx_InitCachedBuiltins(void) {
+  __pyx_builtin_sum = __Pyx_GetName(__pyx_b, __pyx_n_s__sum); if (!__pyx_builtin_sum) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 45; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_builtin_map = __Pyx_GetName(__pyx_b, __pyx_n_s__map); if (!__pyx_builtin_map) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 45; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_builtin_range = __Pyx_GetName(__pyx_b, __pyx_n_s__range); if (!__pyx_builtin_range) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 45; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_builtin_open = __Pyx_GetName(__pyx_b, __pyx_n_s__open); if (!__pyx_builtin_open) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 95; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_builtin_ValueError = __Pyx_GetName(__pyx_b, __pyx_n_s__ValueError); if (!__pyx_builtin_ValueError) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_builtin_zip = __Pyx_GetName(__pyx_b, __pyx_n_s__zip); if (!__pyx_builtin_zip) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_builtin_RuntimeError = __Pyx_GetName(__pyx_b, __pyx_n_s__RuntimeError); if (!__pyx_builtin_RuntimeError) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  return 0;
+  __pyx_L1_error:;
+  return -1;
+}
+
+static int __Pyx_InitCachedConstants(void) {
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0);
+
+  /* "bx/align/_epo.pyx":31
+ *     """
+ * 
+ *     def myp(l):             # <<<<<<<<<<<<<<
+ *         if l: return l.pop(0)
+ * 
+ */
+  __pyx_k_tuple_1 = PyTuple_Pack(1, ((PyObject *)__pyx_n_s__l)); if (unlikely(!__pyx_k_tuple_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 31; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_k_tuple_1);
+  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_1));
+  __pyx_k_codeobj_2 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_k_tuple_1, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_3, __pyx_n_s__myp, 31, __pyx_empty_bytes); if (unlikely(!__pyx_k_codeobj_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 31; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "bx/align/_epo.pyx":34
+ *         if l: return l.pop(0)
+ * 
+ *     def adv(queue, i, d):             # <<<<<<<<<<<<<<
+ *         # shifted interval
+ *         shi = i[0]-d, i[1]-d
+ */
+  __pyx_k_tuple_6 = PyTuple_Pack(4, ((PyObject *)__pyx_n_s__queue), ((PyObject *)__pyx_n_s__i), ((PyObject *)__pyx_n_s__d), ((PyObject *)__pyx_n_s__shi)); if (unlikely(!__pyx_k_tuple_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 34; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_k_tuple_6);
+  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_6));
+  __pyx_k_codeobj_7 = (PyObject*)__Pyx_PyCode_New(3, 0, 4, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_k_tuple_6, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_3, __pyx_n_s__adv, 34, __pyx_empty_bytes); if (unlikely(!__pyx_k_codeobj_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 34; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "bx/align/_epo.pyx":95
+ * def fastLoadChain(fname, hf):
+ *     data = []
+ *     open_f = (fname.endswith(".gz") and gzip.open or open)             # <<<<<<<<<<<<<<
+ *     with open_f(fname) as fd:
+ *         while True:
+ */
+  __pyx_k_tuple_13 = PyTuple_Pack(1, ((PyObject *)__pyx_kp_s_12)); if (unlikely(!__pyx_k_tuple_13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 95; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_k_tuple_13);
+  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_13));
+
+  /* "bx/align/_epo.pyx":96
+ *     data = []
+ *     open_f = (fname.endswith(".gz") and gzip.open or open)
+ *     with open_f(fname) as fd:             # <<<<<<<<<<<<<<
+ *         while True:
+ *             line = fd.readline()
+ */
+  __pyx_k_tuple_17 = PyTuple_Pack(3, Py_None, Py_None, Py_None); if (unlikely(!__pyx_k_tuple_17)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 96; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_k_tuple_17);
+  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_17));
+
+  /* "numpy.pxd":215
+ *             if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)
+ *                 and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)):
+ *                 raise ValueError(u"ndarray is not C contiguous")             # <<<<<<<<<<<<<<
+ * 
+ *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
+ */
+  __pyx_k_tuple_20 = PyTuple_Pack(1, ((PyObject *)__pyx_kp_u_19)); if (unlikely(!__pyx_k_tuple_20)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 215; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_k_tuple_20);
+  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_20));
+
+  /* "numpy.pxd":219
+ *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
+ *                 and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)):
+ *                 raise ValueError(u"ndarray is not Fortran contiguous")             # <<<<<<<<<<<<<<
+ * 
+ *             info.buf = PyArray_DATA(self)
+ */
+  __pyx_k_tuple_22 = PyTuple_Pack(1, ((PyObject *)__pyx_kp_u_21)); if (unlikely(!__pyx_k_tuple_22)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 219; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_k_tuple_22);
+  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_22));
+
+  /* "numpy.pxd":257
+ *                 if ((descr.byteorder == c'>' and little_endian) or
+ *                     (descr.byteorder == c'<' and not little_endian)):
+ *                     raise ValueError(u"Non-native byte order not supported")             # <<<<<<<<<<<<<<
+ *                 if   t == NPY_BYTE:        f = "b"
+ *                 elif t == NPY_UBYTE:       f = "B"
+ */
+  __pyx_k_tuple_24 = PyTuple_Pack(1, ((PyObject *)__pyx_kp_u_23)); if (unlikely(!__pyx_k_tuple_24)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_k_tuple_24);
+  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_24));
+
+  /* "numpy.pxd":799
+ * 
+ *         if (end - f) - (new_offset - offset[0]) < 15:
+ *             raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd")             # <<<<<<<<<<<<<<
+ * 
+ *         if ((child.byteorder == c'>' and little_endian) or
+ */
+  __pyx_k_tuple_27 = PyTuple_Pack(1, ((PyObject *)__pyx_kp_u_26)); if (unlikely(!__pyx_k_tuple_27)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_k_tuple_27);
+  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_27));
+
+  /* "numpy.pxd":803
+ *         if ((child.byteorder == c'>' and little_endian) or
+ *             (child.byteorder == c'<' and not little_endian)):
+ *             raise ValueError(u"Non-native byte order not supported")             # <<<<<<<<<<<<<<
+ *             # One could encode it in the format string and have Cython
+ *             # complain instead, BUT: < and > in format strings also imply
+ */
+  __pyx_k_tuple_28 = PyTuple_Pack(1, ((PyObject *)__pyx_kp_u_23)); if (unlikely(!__pyx_k_tuple_28)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 803; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_k_tuple_28);
+  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_28));
+
+  /* "numpy.pxd":823
+ *             t = child.type_num
+ *             if end - f < 5:
+ *                 raise RuntimeError(u"Format string allocated too short.")             # <<<<<<<<<<<<<<
+ * 
+ *             # Until ticket #99 is fixed, use integers to avoid warnings
+ */
+  __pyx_k_tuple_30 = PyTuple_Pack(1, ((PyObject *)__pyx_kp_u_29)); if (unlikely(!__pyx_k_tuple_30)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 823; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_k_tuple_30);
+  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_30));
+
+  /* "bx/align/_epo.pyx":26
+ * 
+ * 
+ * def rem_dash(p, q):             # <<<<<<<<<<<<<<
+ *     """remove dash columns and shift match intervals to the left. both iterables
+ *     are read on the same direction left-to-right.
+ */
+  __pyx_k_tuple_31 = PyTuple_Pack(18, ((PyObject *)__pyx_n_s__p), ((PyObject *)__pyx_n_s__q), ((PyObject *)__pyx_n_s__myp), ((PyObject *)__pyx_n_s__myp), ((PyObject *)__pyx_n_s__adv), ((PyObject *)__pyx_n_s__adv), ((PyObject *)__pyx_n_s__p_card), ((PyObject *)__pyx_n_s__q_card), ((PyObject *)__pyx_n_s__P), ((PyObject *)__pyx_n_s__Q), ((PyObject *)__pyx_n_s__dash), ((PyObject *)__pyx_n_s__a), ((PyObject *)__pyx_n_s__b), ((PyObject *)__pyx_n_s__i), ((PyObject *)__pyx_n_s__r), ((PyObject *) [...]
+  __Pyx_GOTREF(__pyx_k_tuple_31);
+  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_31));
+  __pyx_k_codeobj_32 = (PyObject*)__Pyx_PyCode_New(2, 0, 18, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_k_tuple_31, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_3, __pyx_n_s__rem_dash, 26, __pyx_empty_bytes); if (unlikely(!__pyx_k_codeobj_32)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 26; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "bx/align/_epo.pyx":93
+ *     return P, Q
+ * 
+ * def fastLoadChain(fname, hf):             # <<<<<<<<<<<<<<
+ *     data = []
+ *     open_f = (fname.endswith(".gz") and gzip.open or open)
+ */
+  __pyx_k_tuple_33 = PyTuple_Pack(11, ((PyObject *)__pyx_n_s__fname), ((PyObject *)__pyx_n_s__hf), ((PyObject *)__pyx_n_s__data), ((PyObject *)__pyx_n_s__open_f), ((PyObject *)__pyx_n_s__fd), ((PyObject *)__pyx_n_s__line), ((PyObject *)__pyx_n_s__hd), ((PyObject *)__pyx_n_s__N), ((PyObject *)__pyx_n_s__s), ((PyObject *)__pyx_n_s__t), ((PyObject *)__pyx_n_s__q)); if (unlikely(!__pyx_k_tuple_33)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 93; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_k_tuple_33);
+  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_33));
+  __pyx_k_codeobj_34 = (PyObject*)__Pyx_PyCode_New(2, 0, 11, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_k_tuple_33, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_3, __pyx_n_s__fastLoadChain, 93, __pyx_empty_bytes); if (unlikely(!__pyx_k_codeobj_34)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 93; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_RefNannyFinishContext();
+  return 0;
+  __pyx_L1_error:;
+  __Pyx_RefNannyFinishContext();
+  return -1;
+}
+
+static int __Pyx_InitGlobals(void) {
+  if (__Pyx_InitStrings(__pyx_string_tab) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  __pyx_int_0 = PyInt_FromLong(0); if (unlikely(!__pyx_int_0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  __pyx_int_1 = PyInt_FromLong(1); if (unlikely(!__pyx_int_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  __pyx_int_2 = PyInt_FromLong(2); if (unlikely(!__pyx_int_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  __pyx_int_15 = PyInt_FromLong(15); if (unlikely(!__pyx_int_15)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  return 0;
+  __pyx_L1_error:;
+  return -1;
+}
+
+#if PY_MAJOR_VERSION < 3
+PyMODINIT_FUNC init_epo(void); /*proto*/
+PyMODINIT_FUNC init_epo(void)
+#else
+PyMODINIT_FUNC PyInit__epo(void); /*proto*/
+PyMODINIT_FUNC PyInit__epo(void)
+#endif
+{
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  __Pyx_RefNannyDeclarations
+  #if CYTHON_REFNANNY
+  __Pyx_RefNanny = __Pyx_RefNannyImportAPI("refnanny");
+  if (!__Pyx_RefNanny) {
+      PyErr_Clear();
+      __Pyx_RefNanny = __Pyx_RefNannyImportAPI("Cython.Runtime.refnanny");
+      if (!__Pyx_RefNanny)
+          Py_FatalError("failed to import 'refnanny' module");
+  }
+  #endif
+  __Pyx_RefNannySetupContext("PyMODINIT_FUNC PyInit__epo(void)", 0);
+  if ( __Pyx_check_binary_version() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_bytes)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #ifdef __Pyx_CyFunction_USED
+  if (__Pyx_CyFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #endif
+  #ifdef __Pyx_FusedFunction_USED
+  if (__pyx_FusedFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #endif
+  #ifdef __Pyx_Generator_USED
+  if (__pyx_Generator_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #endif
+  /*--- Library function declarations ---*/
+  /*--- Threads initialization code ---*/
+  #if defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS
+  #ifdef WITH_THREAD /* Python build with threading support? */
+  PyEval_InitThreads();
+  #endif
+  #endif
+  /*--- Module creation code ---*/
+  #if PY_MAJOR_VERSION < 3
+  __pyx_m = Py_InitModule4(__Pyx_NAMESTR("_epo"), __pyx_methods, 0, 0, PYTHON_API_VERSION); Py_XINCREF(__pyx_m);
+  #else
+  __pyx_m = PyModule_Create(&__pyx_moduledef);
+  #endif
+  if (unlikely(!__pyx_m)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #if PY_MAJOR_VERSION >= 3
+  {
+    PyObject *modules = PyImport_GetModuleDict(); if (unlikely(!modules)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (!PyDict_GetItemString(modules, "bx.align._epo")) {
+      if (unlikely(PyDict_SetItemString(modules, "bx.align._epo", __pyx_m) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+  }
+  #endif
+  __pyx_b = PyImport_AddModule(__Pyx_NAMESTR(__Pyx_BUILTIN_MODULE_NAME)); if (unlikely(!__pyx_b)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #if CYTHON_COMPILING_IN_PYPY
+  Py_INCREF(__pyx_b);
+  #endif
+  if (__Pyx_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  /*--- Initialize various global constants etc. ---*/
+  if (unlikely(__Pyx_InitGlobals() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (__pyx_module_is_main_bx__align___epo) {
+    if (__Pyx_SetAttrString(__pyx_m, "__name__", __pyx_n_s____main__) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  }
+  /*--- Builtin init code ---*/
+  if (unlikely(__Pyx_InitCachedBuiltins() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  /*--- Constants init code ---*/
+  if (unlikely(__Pyx_InitCachedConstants() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  /*--- Global init code ---*/
+  /*--- Variable export code ---*/
+  /*--- Function export code ---*/
+  /*--- Type init code ---*/
+  if (PyType_Ready(&__pyx_type_2bx_5align_4_epo___pyx_scope_struct__rem_dash) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 26; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_2bx_5align_4_epo___pyx_scope_struct__rem_dash = &__pyx_type_2bx_5align_4_epo___pyx_scope_struct__rem_dash;
+  /*--- Type import code ---*/
+  __pyx_ptype_7cpython_4type_type = __Pyx_ImportType(__Pyx_BUILTIN_MODULE_NAME, "type", 
+  #if CYTHON_COMPILING_IN_PYPY
+  sizeof(PyTypeObject),
+  #else
+  sizeof(PyHeapTypeObject),
+  #endif
+  0); if (unlikely(!__pyx_ptype_7cpython_4type_type)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 9; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_5numpy_dtype = __Pyx_ImportType("numpy", "dtype", sizeof(PyArray_Descr), 0); if (unlikely(!__pyx_ptype_5numpy_dtype)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 155; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_5numpy_flatiter = __Pyx_ImportType("numpy", "flatiter", sizeof(PyArrayIterObject), 0); if (unlikely(!__pyx_ptype_5numpy_flatiter)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 165; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_5numpy_broadcast = __Pyx_ImportType("numpy", "broadcast", sizeof(PyArrayMultiIterObject), 0); if (unlikely(!__pyx_ptype_5numpy_broadcast)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_5numpy_ndarray = __Pyx_ImportType("numpy", "ndarray", sizeof(PyArrayObject), 0); if (unlikely(!__pyx_ptype_5numpy_ndarray)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 178; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_5numpy_ufunc = __Pyx_ImportType("numpy", "ufunc", sizeof(PyUFuncObject), 0); if (unlikely(!__pyx_ptype_5numpy_ufunc)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 861; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  /*--- Variable import code ---*/
+  /*--- Function import code ---*/
+  /*--- Execution code ---*/
+
+  /* "bx/align/_epo.pyx":3
+ * 
+ * 
+ * import logging, gzip             # <<<<<<<<<<<<<<
+ * from collections import namedtuple
+ * import numpy
+ */
+  __pyx_t_1 = __Pyx_Import(((PyObject *)__pyx_n_s__logging), 0, -1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s__logging, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_1 = __Pyx_Import(((PyObject *)__pyx_n_s__gzip), 0, -1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s__gzip, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "bx/align/_epo.pyx":4
+ * 
+ * import logging, gzip
+ * from collections import namedtuple             # <<<<<<<<<<<<<<
+ * import numpy
+ * cimport numpy
+ */
+  __pyx_t_1 = PyList_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 4; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_INCREF(((PyObject *)__pyx_n_s__namedtuple));
+  PyList_SET_ITEM(__pyx_t_1, 0, ((PyObject *)__pyx_n_s__namedtuple));
+  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__namedtuple));
+  __pyx_t_2 = __Pyx_Import(((PyObject *)__pyx_n_s__collections), ((PyObject *)__pyx_t_1), -1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 4; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+  __pyx_t_1 = PyObject_GetAttr(__pyx_t_2, __pyx_n_s__namedtuple);
+  if (__pyx_t_1 == NULL) {
+    if (PyErr_ExceptionMatches(PyExc_AttributeError)) __Pyx_RaiseImportError(__pyx_n_s__namedtuple);
+    if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 4; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s__namedtuple, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 4; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+  /* "bx/align/_epo.pyx":5
+ * import logging, gzip
+ * from collections import namedtuple
+ * import numpy             # <<<<<<<<<<<<<<
+ * cimport numpy
+ * 
+ */
+  __pyx_t_2 = __Pyx_Import(((PyObject *)__pyx_n_s__numpy), 0, -1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 5; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s__numpy, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 5; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+  /* "bx/align/_epo.pyx":8
+ * cimport numpy
+ * 
+ * log = logging.getLogger(__name__)             # <<<<<<<<<<<<<<
+ * 
+ * cimport cython
+ */
+  __pyx_t_2 = __Pyx_GetName(__pyx_m, __pyx_n_s__logging); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 8; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_1 = PyObject_GetAttr(__pyx_t_2, __pyx_n_s__getLogger); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 8; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_2 = __Pyx_GetName(__pyx_m, __pyx_n_s____name__); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 8; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 8; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_2);
+  __Pyx_GIVEREF(__pyx_t_2);
+  __pyx_t_2 = 0;
+  __pyx_t_2 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 8; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s__log, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 8; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+  /* "bx/align/_epo.pyx":12
+ * cimport cython
+ * 
+ * DTYPE = numpy.uint64             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+  __pyx_t_2 = __Pyx_GetName(__pyx_m, __pyx_n_s__numpy); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 12; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = PyObject_GetAttr(__pyx_t_2, __pyx_n_s__uint64); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 12; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s__DTYPE, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 12; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+  /* "bx/align/_epo.pyx":26
+ * 
+ * 
+ * def rem_dash(p, q):             # <<<<<<<<<<<<<<
+ *     """remove dash columns and shift match intervals to the left. both iterables
+ *     are read on the same direction left-to-right.
+ */
+  __pyx_t_3 = PyCFunction_NewEx(&__pyx_mdef_2bx_5align_4_epo_1rem_dash, NULL, __pyx_n_s_5); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 26; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s__rem_dash, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 26; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+  /* "bx/align/_epo.pyx":93
+ *     return P, Q
+ * 
+ * def fastLoadChain(fname, hf):             # <<<<<<<<<<<<<<
+ *     data = []
+ *     open_f = (fname.endswith(".gz") and gzip.open or open)
+ */
+  __pyx_t_3 = PyCFunction_NewEx(&__pyx_mdef_2bx_5align_4_epo_3fastLoadChain, NULL, __pyx_n_s_5); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 93; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s__fastLoadChain, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 93; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+  /* "bx/align/_epo.pyx":3
+ * 
+ * 
+ * import logging, gzip             # <<<<<<<<<<<<<<
+ * from collections import namedtuple
+ * import numpy
+ */
+  __pyx_t_3 = PyDict_New(); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(((PyObject *)__pyx_t_3));
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s____test__, ((PyObject *)__pyx_t_3)) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
+
+  /* "numpy.pxd":975
+ *      arr.base = baseptr
+ * 
+ * cdef inline object get_array_base(ndarray arr):             # <<<<<<<<<<<<<<
+ *     if arr.base is NULL:
+ *         return None
+ */
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  if (__pyx_m) {
+    __Pyx_AddTraceback("init bx.align._epo", __pyx_clineno, __pyx_lineno, __pyx_filename);
+    Py_DECREF(__pyx_m); __pyx_m = 0;
+  } else if (!PyErr_Occurred()) {
+    PyErr_SetString(PyExc_ImportError, "init bx.align._epo");
+  }
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  #if PY_MAJOR_VERSION < 3
+  return;
+  #else
+  return __pyx_m;
+  #endif
+}
+
+/* Runtime support code */
+#if CYTHON_REFNANNY
+static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) {
+    PyObject *m = NULL, *p = NULL;
+    void *r = NULL;
+    m = PyImport_ImportModule((char *)modname);
+    if (!m) goto end;
+    p = PyObject_GetAttrString(m, (char *)"RefNannyAPI");
+    if (!p) goto end;
+    r = PyLong_AsVoidPtr(p);
+end:
+    Py_XDECREF(p);
+    Py_XDECREF(m);
+    return (__Pyx_RefNannyAPIStruct *)r;
+}
+#endif /* CYTHON_REFNANNY */
+
+static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name) {
+    PyObject *result;
+    result = PyObject_GetAttr(dict, name);
+    if (!result) {
+        if (dict != __pyx_b) {
+            PyErr_Clear();
+            result = PyObject_GetAttr(__pyx_b, name);
+        }
+        if (!result) {
+            PyErr_SetObject(PyExc_NameError, name);
+        }
+    }
+    return result;
+}
+
+static void __Pyx_RaiseArgtupleInvalid(
+    const char* func_name,
+    int exact,
+    Py_ssize_t num_min,
+    Py_ssize_t num_max,
+    Py_ssize_t num_found)
+{
+    Py_ssize_t num_expected;
+    const char *more_or_less;
+    if (num_found < num_min) {
+        num_expected = num_min;
+        more_or_less = "at least";
+    } else {
+        num_expected = num_max;
+        more_or_less = "at most";
+    }
+    if (exact) {
+        more_or_less = "exactly";
+    }
+    PyErr_Format(PyExc_TypeError,
+                 "%s() takes %s %" CYTHON_FORMAT_SSIZE_T "d positional argument%s (%" CYTHON_FORMAT_SSIZE_T "d given)",
+                 func_name, more_or_less, num_expected,
+                 (num_expected == 1) ? "" : "s", num_found);
+}
+
+static void __Pyx_RaiseDoubleKeywordsError(
+    const char* func_name,
+    PyObject* kw_name)
+{
+    PyErr_Format(PyExc_TypeError,
+        #if PY_MAJOR_VERSION >= 3
+        "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
+        #else
+        "%s() got multiple values for keyword argument '%s'", func_name,
+        PyString_AsString(kw_name));
+        #endif
+}
+
+static int __Pyx_ParseOptionalKeywords(
+    PyObject *kwds,
+    PyObject **argnames[],
+    PyObject *kwds2,
+    PyObject *values[],
+    Py_ssize_t num_pos_args,
+    const char* function_name)
+{
+    PyObject *key = 0, *value = 0;
+    Py_ssize_t pos = 0;
+    PyObject*** name;
+    PyObject*** first_kw_arg = argnames + num_pos_args;
+    while (PyDict_Next(kwds, &pos, &key, &value)) {
+        name = first_kw_arg;
+        while (*name && (**name != key)) name++;
+        if (*name) {
+            values[name-argnames] = value;
+            continue;
+        }
+        name = first_kw_arg;
+        #if PY_MAJOR_VERSION < 3
+        if (likely(PyString_CheckExact(key)) || likely(PyString_Check(key))) {
+            while (*name) {
+                if ((CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**name) == PyString_GET_SIZE(key))
+                        && _PyString_Eq(**name, key)) {
+                    values[name-argnames] = value;
+                    break;
+                }
+                name++;
+            }
+            if (*name) continue;
+            else {
+                PyObject*** argname = argnames;
+                while (argname != first_kw_arg) {
+                    if ((**argname == key) || (
+                            (CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**argname) == PyString_GET_SIZE(key))
+                             && _PyString_Eq(**argname, key))) {
+                        goto arg_passed_twice;
+                    }
+                    argname++;
+                }
+            }
+        } else
+        #endif
+        if (likely(PyUnicode_Check(key))) {
+            while (*name) {
+                int cmp = (**name == key) ? 0 :
+                #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3
+                    (PyUnicode_GET_SIZE(**name) != PyUnicode_GET_SIZE(key)) ? 1 :
+                #endif
+                    PyUnicode_Compare(**name, key);
+                if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad;
+                if (cmp == 0) {
+                    values[name-argnames] = value;
+                    break;
+                }
+                name++;
+            }
+            if (*name) continue;
+            else {
+                PyObject*** argname = argnames;
+                while (argname != first_kw_arg) {
+                    int cmp = (**argname == key) ? 0 :
+                    #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3
+                        (PyUnicode_GET_SIZE(**argname) != PyUnicode_GET_SIZE(key)) ? 1 :
+                    #endif
+                        PyUnicode_Compare(**argname, key);
+                    if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad;
+                    if (cmp == 0) goto arg_passed_twice;
+                    argname++;
+                }
+            }
+        } else
+            goto invalid_keyword_type;
+        if (kwds2) {
+            if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
+        } else {
+            goto invalid_keyword;
+        }
+    }
+    return 0;
+arg_passed_twice:
+    __Pyx_RaiseDoubleKeywordsError(function_name, key);
+    goto bad;
+invalid_keyword_type:
+    PyErr_Format(PyExc_TypeError,
+        "%s() keywords must be strings", function_name);
+    goto bad;
+invalid_keyword:
+    PyErr_Format(PyExc_TypeError,
+    #if PY_MAJOR_VERSION < 3
+        "%s() got an unexpected keyword argument '%s'",
+        function_name, PyString_AsString(key));
+    #else
+        "%s() got an unexpected keyword argument '%U'",
+        function_name, key);
+    #endif
+bad:
+    return -1;
+}
+
+static CYTHON_INLINE void __Pyx_RaiseClosureNameError(const char *varname) {
+    PyErr_Format(PyExc_NameError, "free variable '%s' referenced before assignment in enclosing scope", varname);
+}
+
+static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    PyObject *tmp_type, *tmp_value, *tmp_tb;
+    PyThreadState *tstate = PyThreadState_GET();
+    tmp_type = tstate->curexc_type;
+    tmp_value = tstate->curexc_value;
+    tmp_tb = tstate->curexc_traceback;
+    tstate->curexc_type = type;
+    tstate->curexc_value = value;
+    tstate->curexc_traceback = tb;
+    Py_XDECREF(tmp_type);
+    Py_XDECREF(tmp_value);
+    Py_XDECREF(tmp_tb);
+#else
+    PyErr_Restore(type, value, tb);
+#endif
+}
+static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    PyThreadState *tstate = PyThreadState_GET();
+    *type = tstate->curexc_type;
+    *value = tstate->curexc_value;
+    *tb = tstate->curexc_traceback;
+    tstate->curexc_type = 0;
+    tstate->curexc_value = 0;
+    tstate->curexc_traceback = 0;
+#else
+    PyErr_Fetch(type, value, tb);
+#endif
+}
+
+#if PY_MAJOR_VERSION < 3
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb,
+                        CYTHON_UNUSED PyObject *cause) {
+    Py_XINCREF(type);
+    if (!value || value == Py_None)
+        value = NULL;
+    else
+        Py_INCREF(value);
+    if (!tb || tb == Py_None)
+        tb = NULL;
+    else {
+        Py_INCREF(tb);
+        if (!PyTraceBack_Check(tb)) {
+            PyErr_SetString(PyExc_TypeError,
+                "raise: arg 3 must be a traceback or None");
+            goto raise_error;
+        }
+    }
+    #if PY_VERSION_HEX < 0x02050000
+    if (PyClass_Check(type)) {
+    #else
+    if (PyType_Check(type)) {
+    #endif
+#if CYTHON_COMPILING_IN_PYPY
+        if (!value) {
+            Py_INCREF(Py_None);
+            value = Py_None;
+        }
+#endif
+        PyErr_NormalizeException(&type, &value, &tb);
+    } else {
+        if (value) {
+            PyErr_SetString(PyExc_TypeError,
+                "instance exception may not have a separate value");
+            goto raise_error;
+        }
+        value = type;
+        #if PY_VERSION_HEX < 0x02050000
+            if (PyInstance_Check(type)) {
+                type = (PyObject*) ((PyInstanceObject*)type)->in_class;
+                Py_INCREF(type);
+            }
+            else {
+                type = 0;
+                PyErr_SetString(PyExc_TypeError,
+                    "raise: exception must be an old-style class or instance");
+                goto raise_error;
+            }
+        #else
+            type = (PyObject*) Py_TYPE(type);
+            Py_INCREF(type);
+            if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
+                PyErr_SetString(PyExc_TypeError,
+                    "raise: exception class must be a subclass of BaseException");
+                goto raise_error;
+            }
+        #endif
+    }
+    __Pyx_ErrRestore(type, value, tb);
+    return;
+raise_error:
+    Py_XDECREF(value);
+    Py_XDECREF(type);
+    Py_XDECREF(tb);
+    return;
+}
+#else /* Python 3+ */
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause) {
+    PyObject* owned_instance = NULL;
+    if (tb == Py_None) {
+        tb = 0;
+    } else if (tb && !PyTraceBack_Check(tb)) {
+        PyErr_SetString(PyExc_TypeError,
+            "raise: arg 3 must be a traceback or None");
+        goto bad;
+    }
+    if (value == Py_None)
+        value = 0;
+    if (PyExceptionInstance_Check(type)) {
+        if (value) {
+            PyErr_SetString(PyExc_TypeError,
+                "instance exception may not have a separate value");
+            goto bad;
+        }
+        value = type;
+        type = (PyObject*) Py_TYPE(value);
+    } else if (PyExceptionClass_Check(type)) {
+        PyObject *args;
+        if (!value)
+            args = PyTuple_New(0);
+        else if (PyTuple_Check(value)) {
+            Py_INCREF(value);
+            args = value;
+        }
+        else
+            args = PyTuple_Pack(1, value);
+        if (!args)
+            goto bad;
+        owned_instance = PyEval_CallObject(type, args);
+        Py_DECREF(args);
+        if (!owned_instance)
+            goto bad;
+        value = owned_instance;
+        if (!PyExceptionInstance_Check(value)) {
+            PyErr_Format(PyExc_TypeError,
+                         "calling %R should have returned an instance of "
+                         "BaseException, not %R",
+                         type, Py_TYPE(value));
+            goto bad;
+        }
+    } else {
+        PyErr_SetString(PyExc_TypeError,
+            "raise: exception class must be a subclass of BaseException");
+        goto bad;
+    }
+    if (cause && cause != Py_None) {
+        PyObject *fixed_cause;
+        if (PyExceptionClass_Check(cause)) {
+            fixed_cause = PyObject_CallObject(cause, NULL);
+            if (fixed_cause == NULL)
+                goto bad;
+        }
+        else if (PyExceptionInstance_Check(cause)) {
+            fixed_cause = cause;
+            Py_INCREF(fixed_cause);
+        }
+        else {
+            PyErr_SetString(PyExc_TypeError,
+                            "exception causes must derive from "
+                            "BaseException");
+            goto bad;
+        }
+        PyException_SetCause(value, fixed_cause);
+    }
+    PyErr_SetObject(type, value);
+    if (tb) {
+        PyThreadState *tstate = PyThreadState_GET();
+        PyObject* tmp_tb = tstate->curexc_traceback;
+        if (tb != tmp_tb) {
+            Py_INCREF(tb);
+            tstate->curexc_traceback = tb;
+            Py_XDECREF(tmp_tb);
+        }
+    }
+bad:
+    Py_XDECREF(owned_instance);
+    return;
+}
+#endif
+
+static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected) {
+    PyErr_Format(PyExc_ValueError,
+                 "too many values to unpack (expected %" CYTHON_FORMAT_SSIZE_T "d)", expected);
+}
+
+static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index) {
+    PyErr_Format(PyExc_ValueError,
+                 "need more than %" CYTHON_FORMAT_SSIZE_T "d value%s to unpack",
+                 index, (index == 1) ? "" : "s");
+}
+
+static CYTHON_INLINE int __Pyx_IterFinish(void) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    PyThreadState *tstate = PyThreadState_GET();
+    PyObject* exc_type = tstate->curexc_type;
+    if (unlikely(exc_type)) {
+        if (likely(exc_type == PyExc_StopIteration) || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration)) {
+            PyObject *exc_value, *exc_tb;
+            exc_value = tstate->curexc_value;
+            exc_tb = tstate->curexc_traceback;
+            tstate->curexc_type = 0;
+            tstate->curexc_value = 0;
+            tstate->curexc_traceback = 0;
+            Py_DECREF(exc_type);
+            Py_XDECREF(exc_value);
+            Py_XDECREF(exc_tb);
+            return 0;
+        } else {
+            return -1;
+        }
+    }
+    return 0;
+#else
+    if (unlikely(PyErr_Occurred())) {
+        if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) {
+            PyErr_Clear();
+            return 0;
+        } else {
+            return -1;
+        }
+    }
+    return 0;
+#endif
+}
+
+static int __Pyx_IternextUnpackEndCheck(PyObject *retval, Py_ssize_t expected) {
+    if (unlikely(retval)) {
+        Py_DECREF(retval);
+        __Pyx_RaiseTooManyValuesError(expected);
+        return -1;
+    } else {
+        return __Pyx_IterFinish();
+    }
+    return 0;
+}
+
+static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) {
+    PyObject *local_type, *local_value, *local_tb;
+#if CYTHON_COMPILING_IN_CPYTHON
+    PyObject *tmp_type, *tmp_value, *tmp_tb;
+    PyThreadState *tstate = PyThreadState_GET();
+    local_type = tstate->curexc_type;
+    local_value = tstate->curexc_value;
+    local_tb = tstate->curexc_traceback;
+    tstate->curexc_type = 0;
+    tstate->curexc_value = 0;
+    tstate->curexc_traceback = 0;
+#else
+    PyErr_Fetch(&local_type, &local_value, &local_tb);
+#endif
+    PyErr_NormalizeException(&local_type, &local_value, &local_tb);
+#if CYTHON_COMPILING_IN_CPYTHON
+    if (unlikely(tstate->curexc_type))
+#else
+    if (unlikely(PyErr_Occurred()))
+#endif
+        goto bad;
+    #if PY_MAJOR_VERSION >= 3
+    if (unlikely(PyException_SetTraceback(local_value, local_tb) < 0))
+        goto bad;
+    #endif
+    Py_INCREF(local_type);
+    Py_INCREF(local_value);
+    Py_INCREF(local_tb);
+    *type = local_type;
+    *value = local_value;
+    *tb = local_tb;
+#if CYTHON_COMPILING_IN_CPYTHON
+    tmp_type = tstate->exc_type;
+    tmp_value = tstate->exc_value;
+    tmp_tb = tstate->exc_traceback;
+    tstate->exc_type = local_type;
+    tstate->exc_value = local_value;
+    tstate->exc_traceback = local_tb;
+    /* Make sure tstate is in a consistent state when we XDECREF
+       these objects (DECREF may run arbitrary code). */
+    Py_XDECREF(tmp_type);
+    Py_XDECREF(tmp_value);
+    Py_XDECREF(tmp_tb);
+#else
+    PyErr_SetExcInfo(local_type, local_value, local_tb);
+#endif
+    return 0;
+bad:
+    *type = 0;
+    *value = 0;
+    *tb = 0;
+    Py_XDECREF(local_type);
+    Py_XDECREF(local_value);
+    Py_XDECREF(local_tb);
+    return -1;
+}
+
+static CYTHON_INLINE int __Pyx_IsLittleEndian(void) {
+  unsigned int n = 1;
+  return *(unsigned char*)(&n) != 0;
+}
+static void __Pyx_BufFmt_Init(__Pyx_BufFmt_Context* ctx,
+                              __Pyx_BufFmt_StackElem* stack,
+                              __Pyx_TypeInfo* type) {
+  stack[0].field = &ctx->root;
+  stack[0].parent_offset = 0;
+  ctx->root.type = type;
+  ctx->root.name = "buffer dtype";
+  ctx->root.offset = 0;
+  ctx->head = stack;
+  ctx->head->field = &ctx->root;
+  ctx->fmt_offset = 0;
+  ctx->head->parent_offset = 0;
+  ctx->new_packmode = '@';
+  ctx->enc_packmode = '@';
+  ctx->new_count = 1;
+  ctx->enc_count = 0;
+  ctx->enc_type = 0;
+  ctx->is_complex = 0;
+  ctx->is_valid_array = 0;
+  ctx->struct_alignment = 0;
+  while (type->typegroup == 'S') {
+    ++ctx->head;
+    ctx->head->field = type->fields;
+    ctx->head->parent_offset = 0;
+    type = type->fields->type;
+  }
+}
+static int __Pyx_BufFmt_ParseNumber(const char** ts) {
+    int count;
+    const char* t = *ts;
+    if (*t < '0' || *t > '9') {
+      return -1;
+    } else {
+        count = *t++ - '0';
+        while (*t >= '0' && *t < '9') {
+            count *= 10;
+            count += *t++ - '0';
+        }
+    }
+    *ts = t;
+    return count;
+}
+static int __Pyx_BufFmt_ExpectNumber(const char **ts) {
+    int number = __Pyx_BufFmt_ParseNumber(ts);
+    if (number == -1) /* First char was not a digit */
+        PyErr_Format(PyExc_ValueError,\
+                     "Does not understand character buffer dtype format string ('%c')", **ts);
+    return number;
+}
+static void __Pyx_BufFmt_RaiseUnexpectedChar(char ch) {
+  PyErr_Format(PyExc_ValueError,
+               "Unexpected format string character: '%c'", ch);
+}
+static const char* __Pyx_BufFmt_DescribeTypeChar(char ch, int is_complex) {
+  switch (ch) {
+    case 'c': return "'char'";
+    case 'b': return "'signed char'";
+    case 'B': return "'unsigned char'";
+    case 'h': return "'short'";
+    case 'H': return "'unsigned short'";
+    case 'i': return "'int'";
+    case 'I': return "'unsigned int'";
+    case 'l': return "'long'";
+    case 'L': return "'unsigned long'";
+    case 'q': return "'long long'";
+    case 'Q': return "'unsigned long long'";
+    case 'f': return (is_complex ? "'complex float'" : "'float'");
+    case 'd': return (is_complex ? "'complex double'" : "'double'");
+    case 'g': return (is_complex ? "'complex long double'" : "'long double'");
+    case 'T': return "a struct";
+    case 'O': return "Python object";
+    case 'P': return "a pointer";
+    case 's': case 'p': return "a string";
+    case 0: return "end";
+    default: return "unparseable format string";
+  }
+}
+static size_t __Pyx_BufFmt_TypeCharToStandardSize(char ch, int is_complex) {
+  switch (ch) {
+    case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1;
+    case 'h': case 'H': return 2;
+    case 'i': case 'I': case 'l': case 'L': return 4;
+    case 'q': case 'Q': return 8;
+    case 'f': return (is_complex ? 8 : 4);
+    case 'd': return (is_complex ? 16 : 8);
+    case 'g': {
+      PyErr_SetString(PyExc_ValueError, "Python does not define a standard format string size for long double ('g')..");
+      return 0;
+    }
+    case 'O': case 'P': return sizeof(void*);
+    default:
+      __Pyx_BufFmt_RaiseUnexpectedChar(ch);
+      return 0;
+    }
+}
+static size_t __Pyx_BufFmt_TypeCharToNativeSize(char ch, int is_complex) {
+  switch (ch) {
+    case 'c': case 'b': case 'B': case 's': case 'p': return 1;
+    case 'h': case 'H': return sizeof(short);
+    case 'i': case 'I': return sizeof(int);
+    case 'l': case 'L': return sizeof(long);
+    #ifdef HAVE_LONG_LONG
+    case 'q': case 'Q': return sizeof(PY_LONG_LONG);
+    #endif
+    case 'f': return sizeof(float) * (is_complex ? 2 : 1);
+    case 'd': return sizeof(double) * (is_complex ? 2 : 1);
+    case 'g': return sizeof(long double) * (is_complex ? 2 : 1);
+    case 'O': case 'P': return sizeof(void*);
+    default: {
+      __Pyx_BufFmt_RaiseUnexpectedChar(ch);
+      return 0;
+    }
+  }
+}
+typedef struct { char c; short x; } __Pyx_st_short;
+typedef struct { char c; int x; } __Pyx_st_int;
+typedef struct { char c; long x; } __Pyx_st_long;
+typedef struct { char c; float x; } __Pyx_st_float;
+typedef struct { char c; double x; } __Pyx_st_double;
+typedef struct { char c; long double x; } __Pyx_st_longdouble;
+typedef struct { char c; void *x; } __Pyx_st_void_p;
+#ifdef HAVE_LONG_LONG
+typedef struct { char c; PY_LONG_LONG x; } __Pyx_st_longlong;
+#endif
+static size_t __Pyx_BufFmt_TypeCharToAlignment(char ch, CYTHON_UNUSED int is_complex) {
+  switch (ch) {
+    case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1;
+    case 'h': case 'H': return sizeof(__Pyx_st_short) - sizeof(short);
+    case 'i': case 'I': return sizeof(__Pyx_st_int) - sizeof(int);
+    case 'l': case 'L': return sizeof(__Pyx_st_long) - sizeof(long);
+#ifdef HAVE_LONG_LONG
+    case 'q': case 'Q': return sizeof(__Pyx_st_longlong) - sizeof(PY_LONG_LONG);
+#endif
+    case 'f': return sizeof(__Pyx_st_float) - sizeof(float);
+    case 'd': return sizeof(__Pyx_st_double) - sizeof(double);
+    case 'g': return sizeof(__Pyx_st_longdouble) - sizeof(long double);
+    case 'P': case 'O': return sizeof(__Pyx_st_void_p) - sizeof(void*);
+    default:
+      __Pyx_BufFmt_RaiseUnexpectedChar(ch);
+      return 0;
+    }
+}
+/* These are for computing the padding at the end of the struct to align
+   on the first member of the struct. This will probably the same as above,
+   but we don't have any guarantees.
+ */
+typedef struct { short x; char c; } __Pyx_pad_short;
+typedef struct { int x; char c; } __Pyx_pad_int;
+typedef struct { long x; char c; } __Pyx_pad_long;
+typedef struct { float x; char c; } __Pyx_pad_float;
+typedef struct { double x; char c; } __Pyx_pad_double;
+typedef struct { long double x; char c; } __Pyx_pad_longdouble;
+typedef struct { void *x; char c; } __Pyx_pad_void_p;
+#ifdef HAVE_LONG_LONG
+typedef struct { PY_LONG_LONG x; char c; } __Pyx_pad_longlong;
+#endif
+static size_t __Pyx_BufFmt_TypeCharToPadding(char ch, CYTHON_UNUSED int is_complex) {
+  switch (ch) {
+    case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1;
+    case 'h': case 'H': return sizeof(__Pyx_pad_short) - sizeof(short);
+    case 'i': case 'I': return sizeof(__Pyx_pad_int) - sizeof(int);
+    case 'l': case 'L': return sizeof(__Pyx_pad_long) - sizeof(long);
+#ifdef HAVE_LONG_LONG
+    case 'q': case 'Q': return sizeof(__Pyx_pad_longlong) - sizeof(PY_LONG_LONG);
+#endif
+    case 'f': return sizeof(__Pyx_pad_float) - sizeof(float);
+    case 'd': return sizeof(__Pyx_pad_double) - sizeof(double);
+    case 'g': return sizeof(__Pyx_pad_longdouble) - sizeof(long double);
+    case 'P': case 'O': return sizeof(__Pyx_pad_void_p) - sizeof(void*);
+    default:
+      __Pyx_BufFmt_RaiseUnexpectedChar(ch);
+      return 0;
+    }
+}
+static char __Pyx_BufFmt_TypeCharToGroup(char ch, int is_complex) {
+  switch (ch) {
+    case 'c':
+        return 'H';
+    case 'b': case 'h': case 'i':
+    case 'l': case 'q': case 's': case 'p':
+        return 'I';
+    case 'B': case 'H': case 'I': case 'L': case 'Q':
+        return 'U';
+    case 'f': case 'd': case 'g':
+        return (is_complex ? 'C' : 'R');
+    case 'O':
+        return 'O';
+    case 'P':
+        return 'P';
+    default: {
+      __Pyx_BufFmt_RaiseUnexpectedChar(ch);
+      return 0;
+    }
+  }
+}
+static void __Pyx_BufFmt_RaiseExpected(__Pyx_BufFmt_Context* ctx) {
+  if (ctx->head == NULL || ctx->head->field == &ctx->root) {
+    const char* expected;
+    const char* quote;
+    if (ctx->head == NULL) {
+      expected = "end";
+      quote = "";
+    } else {
+      expected = ctx->head->field->type->name;
+      quote = "'";
+    }
+    PyErr_Format(PyExc_ValueError,
+                 "Buffer dtype mismatch, expected %s%s%s but got %s",
+                 quote, expected, quote,
+                 __Pyx_BufFmt_DescribeTypeChar(ctx->enc_type, ctx->is_complex));
+  } else {
+    __Pyx_StructField* field = ctx->head->field;
+    __Pyx_StructField* parent = (ctx->head - 1)->field;
+    PyErr_Format(PyExc_ValueError,
+                 "Buffer dtype mismatch, expected '%s' but got %s in '%s.%s'",
+                 field->type->name, __Pyx_BufFmt_DescribeTypeChar(ctx->enc_type, ctx->is_complex),
+                 parent->type->name, field->name);
+  }
+}
+static int __Pyx_BufFmt_ProcessTypeChunk(__Pyx_BufFmt_Context* ctx) {
+  char group;
+  size_t size, offset, arraysize = 1;
+  if (ctx->enc_type == 0) return 0;
+  if (ctx->head->field->type->arraysize[0]) {
+    int i, ndim = 0;
+    if (ctx->enc_type == 's' || ctx->enc_type == 'p') {
+        ctx->is_valid_array = ctx->head->field->type->ndim == 1;
+        ndim = 1;
+        if (ctx->enc_count != ctx->head->field->type->arraysize[0]) {
+            PyErr_Format(PyExc_ValueError,
+                         "Expected a dimension of size %zu, got %zu",
+                         ctx->head->field->type->arraysize[0], ctx->enc_count);
+            return -1;
+        }
+    }
+    if (!ctx->is_valid_array) {
+      PyErr_Format(PyExc_ValueError, "Expected %d dimensions, got %d",
+                   ctx->head->field->type->ndim, ndim);
+      return -1;
+    }
+    for (i = 0; i < ctx->head->field->type->ndim; i++) {
+      arraysize *= ctx->head->field->type->arraysize[i];
+    }
+    ctx->is_valid_array = 0;
+    ctx->enc_count = 1;
+  }
+  group = __Pyx_BufFmt_TypeCharToGroup(ctx->enc_type, ctx->is_complex);
+  do {
+    __Pyx_StructField* field = ctx->head->field;
+    __Pyx_TypeInfo* type = field->type;
+    if (ctx->enc_packmode == '@' || ctx->enc_packmode == '^') {
+      size = __Pyx_BufFmt_TypeCharToNativeSize(ctx->enc_type, ctx->is_complex);
+    } else {
+      size = __Pyx_BufFmt_TypeCharToStandardSize(ctx->enc_type, ctx->is_complex);
+    }
+    if (ctx->enc_packmode == '@') {
+      size_t align_at = __Pyx_BufFmt_TypeCharToAlignment(ctx->enc_type, ctx->is_complex);
+      size_t align_mod_offset;
+      if (align_at == 0) return -1;
+      align_mod_offset = ctx->fmt_offset % align_at;
+      if (align_mod_offset > 0) ctx->fmt_offset += align_at - align_mod_offset;
+      if (ctx->struct_alignment == 0)
+          ctx->struct_alignment = __Pyx_BufFmt_TypeCharToPadding(ctx->enc_type,
+                                                                 ctx->is_complex);
+    }
+    if (type->size != size || type->typegroup != group) {
+      if (type->typegroup == 'C' && type->fields != NULL) {
+        size_t parent_offset = ctx->head->parent_offset + field->offset;
+        ++ctx->head;
+        ctx->head->field = type->fields;
+        ctx->head->parent_offset = parent_offset;
+        continue;
+      }
+      if ((type->typegroup == 'H' || group == 'H') && type->size == size) {
+      } else {
+          __Pyx_BufFmt_RaiseExpected(ctx);
+          return -1;
+      }
+    }
+    offset = ctx->head->parent_offset + field->offset;
+    if (ctx->fmt_offset != offset) {
+      PyErr_Format(PyExc_ValueError,
+                   "Buffer dtype mismatch; next field is at offset %" CYTHON_FORMAT_SSIZE_T "d but %" CYTHON_FORMAT_SSIZE_T "d expected",
+                   (Py_ssize_t)ctx->fmt_offset, (Py_ssize_t)offset);
+      return -1;
+    }
+    ctx->fmt_offset += size;
+    if (arraysize)
+      ctx->fmt_offset += (arraysize - 1) * size;
+    --ctx->enc_count; /* Consume from buffer string */
+    while (1) {
+      if (field == &ctx->root) {
+        ctx->head = NULL;
+        if (ctx->enc_count != 0) {
+          __Pyx_BufFmt_RaiseExpected(ctx);
+          return -1;
+        }
+        break; /* breaks both loops as ctx->enc_count == 0 */
+      }
+      ctx->head->field = ++field;
+      if (field->type == NULL) {
+        --ctx->head;
+        field = ctx->head->field;
+        continue;
+      } else if (field->type->typegroup == 'S') {
+        size_t parent_offset = ctx->head->parent_offset + field->offset;
+        if (field->type->fields->type == NULL) continue; /* empty struct */
+        field = field->type->fields;
+        ++ctx->head;
+        ctx->head->field = field;
+        ctx->head->parent_offset = parent_offset;
+        break;
+      } else {
+        break;
+      }
+    }
+  } while (ctx->enc_count);
+  ctx->enc_type = 0;
+  ctx->is_complex = 0;
+  return 0;
+}
+static CYTHON_INLINE PyObject *
+__pyx_buffmt_parse_array(__Pyx_BufFmt_Context* ctx, const char** tsp)
+{
+    const char *ts = *tsp;
+    int i = 0, number;
+    int ndim = ctx->head->field->type->ndim;
+;
+    ++ts;
+    if (ctx->new_count != 1) {
+        PyErr_SetString(PyExc_ValueError,
+                        "Cannot handle repeated arrays in format string");
+        return NULL;
+    }
+    if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
+    while (*ts && *ts != ')') {
+        if (isspace(*ts))
+            continue;
+        number = __Pyx_BufFmt_ExpectNumber(&ts);
+        if (number == -1) return NULL;
+        if (i < ndim && (size_t) number != ctx->head->field->type->arraysize[i])
+            return PyErr_Format(PyExc_ValueError,
+                        "Expected a dimension of size %zu, got %d",
+                        ctx->head->field->type->arraysize[i], number);
+        if (*ts != ',' && *ts != ')')
+            return PyErr_Format(PyExc_ValueError,
+                                "Expected a comma in format string, got '%c'", *ts);
+        if (*ts == ',') ts++;
+        i++;
+    }
+    if (i != ndim)
+        return PyErr_Format(PyExc_ValueError, "Expected %d dimension(s), got %d",
+                            ctx->head->field->type->ndim, i);
+    if (!*ts) {
+        PyErr_SetString(PyExc_ValueError,
+                        "Unexpected end of format string, expected ')'");
+        return NULL;
+    }
+    ctx->is_valid_array = 1;
+    ctx->new_count = 1;
+    *tsp = ++ts;
+    return Py_None;
+}
+static const char* __Pyx_BufFmt_CheckString(__Pyx_BufFmt_Context* ctx, const char* ts) {
+  int got_Z = 0;
+  while (1) {
+    switch(*ts) {
+      case 0:
+        if (ctx->enc_type != 0 && ctx->head == NULL) {
+          __Pyx_BufFmt_RaiseExpected(ctx);
+          return NULL;
+        }
+        if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
+        if (ctx->head != NULL) {
+          __Pyx_BufFmt_RaiseExpected(ctx);
+          return NULL;
+        }
+                return ts;
+      case ' ':
+      case 10:
+      case 13:
+        ++ts;
+        break;
+      case '<':
+        if (!__Pyx_IsLittleEndian()) {
+          PyErr_SetString(PyExc_ValueError, "Little-endian buffer not supported on big-endian compiler");
+          return NULL;
+        }
+        ctx->new_packmode = '=';
+        ++ts;
+        break;
+      case '>':
+      case '!':
+        if (__Pyx_IsLittleEndian()) {
+          PyErr_SetString(PyExc_ValueError, "Big-endian buffer not supported on little-endian compiler");
+          return NULL;
+        }
+        ctx->new_packmode = '=';
+        ++ts;
+        break;
+      case '=':
+      case '@':
+      case '^':
+        ctx->new_packmode = *ts++;
+        break;
+      case 'T': /* substruct */
+        {
+          const char* ts_after_sub;
+          size_t i, struct_count = ctx->new_count;
+          size_t struct_alignment = ctx->struct_alignment;
+          ctx->new_count = 1;
+          ++ts;
+          if (*ts != '{') {
+            PyErr_SetString(PyExc_ValueError, "Buffer acquisition: Expected '{' after 'T'");
+            return NULL;
+          }
+          if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
+          ctx->enc_type = 0; /* Erase processed last struct element */
+          ctx->enc_count = 0;
+          ctx->struct_alignment = 0;
+          ++ts;
+          ts_after_sub = ts;
+          for (i = 0; i != struct_count; ++i) {
+            ts_after_sub = __Pyx_BufFmt_CheckString(ctx, ts);
+            if (!ts_after_sub) return NULL;
+          }
+          ts = ts_after_sub;
+          if (struct_alignment) ctx->struct_alignment = struct_alignment;
+        }
+        break;
+      case '}': /* end of substruct; either repeat or move on */
+        {
+          size_t alignment = ctx->struct_alignment;
+          ++ts;
+          if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
+          ctx->enc_type = 0; /* Erase processed last struct element */
+          if (alignment && ctx->fmt_offset % alignment) {
+            ctx->fmt_offset += alignment - (ctx->fmt_offset % alignment);
+          }
+        }
+        return ts;
+      case 'x':
+        if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
+        ctx->fmt_offset += ctx->new_count;
+        ctx->new_count = 1;
+        ctx->enc_count = 0;
+        ctx->enc_type = 0;
+        ctx->enc_packmode = ctx->new_packmode;
+        ++ts;
+        break;
+      case 'Z':
+        got_Z = 1;
+        ++ts;
+        if (*ts != 'f' && *ts != 'd' && *ts != 'g') {
+          __Pyx_BufFmt_RaiseUnexpectedChar('Z');
+          return NULL;
+        }        /* fall through */
+      case 'c': case 'b': case 'B': case 'h': case 'H': case 'i': case 'I':
+      case 'l': case 'L': case 'q': case 'Q':
+      case 'f': case 'd': case 'g':
+      case 'O': case 's': case 'p':
+        if (ctx->enc_type == *ts && got_Z == ctx->is_complex &&
+            ctx->enc_packmode == ctx->new_packmode) {
+          ctx->enc_count += ctx->new_count;
+        } else {
+          if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
+          ctx->enc_count = ctx->new_count;
+          ctx->enc_packmode = ctx->new_packmode;
+          ctx->enc_type = *ts;
+          ctx->is_complex = got_Z;
+        }
+        ++ts;
+        ctx->new_count = 1;
+        got_Z = 0;
+        break;
+      case ':':
+        ++ts;
+        while(*ts != ':') ++ts;
+        ++ts;
+        break;
+      case '(':
+        if (!__pyx_buffmt_parse_array(ctx, &ts)) return NULL;
+        break;
+      default:
+        {
+          int number = __Pyx_BufFmt_ExpectNumber(&ts);
+          if (number == -1) return NULL;
+          ctx->new_count = (size_t)number;
+        }
+    }
+  }
+}
+static CYTHON_INLINE void __Pyx_ZeroBuffer(Py_buffer* buf) {
+  buf->buf = NULL;
+  buf->obj = NULL;
+  buf->strides = __Pyx_zeros;
+  buf->shape = __Pyx_zeros;
+  buf->suboffsets = __Pyx_minusones;
+}
+static CYTHON_INLINE int __Pyx_GetBufferAndValidate(
+        Py_buffer* buf, PyObject* obj,  __Pyx_TypeInfo* dtype, int flags,
+        int nd, int cast, __Pyx_BufFmt_StackElem* stack)
+{
+  if (obj == Py_None || obj == NULL) {
+    __Pyx_ZeroBuffer(buf);
+    return 0;
+  }
+  buf->buf = NULL;
+  if (__Pyx_GetBuffer(obj, buf, flags) == -1) goto fail;
+  if (buf->ndim != nd) {
+    PyErr_Format(PyExc_ValueError,
+                 "Buffer has wrong number of dimensions (expected %d, got %d)",
+                 nd, buf->ndim);
+    goto fail;
+  }
+  if (!cast) {
+    __Pyx_BufFmt_Context ctx;
+    __Pyx_BufFmt_Init(&ctx, stack, dtype);
+    if (!__Pyx_BufFmt_CheckString(&ctx, buf->format)) goto fail;
+  }
+  if ((unsigned)buf->itemsize != dtype->size) {
+    PyErr_Format(PyExc_ValueError,
+      "Item size of buffer (%" CYTHON_FORMAT_SSIZE_T "d byte%s) does not match size of '%s' (%" CYTHON_FORMAT_SSIZE_T "d byte%s)",
+      buf->itemsize, (buf->itemsize > 1) ? "s" : "",
+      dtype->name, (Py_ssize_t)dtype->size, (dtype->size > 1) ? "s" : "");
+    goto fail;
+  }
+  if (buf->suboffsets == NULL) buf->suboffsets = __Pyx_minusones;
+  return 0;
+fail:;
+  __Pyx_ZeroBuffer(buf);
+  return -1;
+}
+static CYTHON_INLINE void __Pyx_SafeReleaseBuffer(Py_buffer* info) {
+  if (info->buf == NULL) return;
+  if (info->suboffsets == __Pyx_minusones) info->suboffsets = NULL;
+  __Pyx_ReleaseBuffer(info);
+}
+
+static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type) {
+    if (unlikely(!type)) {
+        PyErr_Format(PyExc_SystemError, "Missing type object");
+        return 0;
+    }
+    if (likely(PyObject_TypeCheck(obj, type)))
+        return 1;
+    PyErr_Format(PyExc_TypeError, "Cannot convert %.200s to %.200s",
+                 Py_TYPE(obj)->tp_name, type->tp_name);
+    return 0;
+}
+
+static void __Pyx_RaiseBufferFallbackError(void) {
+  PyErr_Format(PyExc_ValueError,
+     "Buffer acquisition failed on assignment; and then reacquiring the old buffer failed too!");
+}
+
+static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
+    const char *name, int exact)
+{
+    if (!type) {
+        PyErr_Format(PyExc_SystemError, "Missing type object");
+        return 0;
+    }
+    if (none_allowed && obj == Py_None) return 1;
+    else if (exact) {
+        if (Py_TYPE(obj) == type) return 1;
+    }
+    else {
+        if (PyObject_TypeCheck(obj, type)) return 1;
+    }
+    PyErr_Format(PyExc_TypeError,
+        "Argument '%s' has incorrect type (expected %s, got %s)",
+        name, type->tp_name, Py_TYPE(obj)->tp_name);
+    return 0;
+}
+
+static void __Pyx_RaiseBufferIndexError(int axis) {
+  PyErr_Format(PyExc_IndexError,
+     "Out of bounds on buffer access (axis %d)", axis);
+}
+
+static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void) {
+    PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable");
+}
+
+static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    PyThreadState *tstate = PyThreadState_GET();
+    *type = tstate->exc_type;
+    *value = tstate->exc_value;
+    *tb = tstate->exc_traceback;
+    Py_XINCREF(*type);
+    Py_XINCREF(*value);
+    Py_XINCREF(*tb);
+#else
+    PyErr_GetExcInfo(type, value, tb);
+#endif
+}
+static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    PyObject *tmp_type, *tmp_value, *tmp_tb;
+    PyThreadState *tstate = PyThreadState_GET();
+    tmp_type = tstate->exc_type;
+    tmp_value = tstate->exc_value;
+    tmp_tb = tstate->exc_traceback;
+    tstate->exc_type = type;
+    tstate->exc_value = value;
+    tstate->exc_traceback = tb;
+    Py_XDECREF(tmp_type);
+    Py_XDECREF(tmp_value);
+    Py_XDECREF(tmp_tb);
+#else
+    PyErr_SetExcInfo(type, value, tb);
+#endif
+}
+
+#if PY_MAJOR_VERSION < 3
+static int __Pyx_GetBuffer(PyObject *obj, Py_buffer *view, int flags) {
+    CYTHON_UNUSED PyObject *getbuffer_cobj;
+  #if PY_VERSION_HEX >= 0x02060000
+    if (PyObject_CheckBuffer(obj)) return PyObject_GetBuffer(obj, view, flags);
+  #endif
+        if (PyObject_TypeCheck(obj, __pyx_ptype_5numpy_ndarray)) return __pyx_pw_5numpy_7ndarray_1__getbuffer__(obj, view, flags);
+  #if PY_VERSION_HEX < 0x02060000
+    if (obj->ob_type->tp_dict &&
+        (getbuffer_cobj = PyMapping_GetItemString(obj->ob_type->tp_dict,
+                                             "__pyx_getbuffer"))) {
+        getbufferproc func;
+      #if PY_VERSION_HEX >= 0x02070000 && !(PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION == 0)
+        func = (getbufferproc) PyCapsule_GetPointer(getbuffer_cobj, "getbuffer(obj, view, flags)");
+      #else
+        func = (getbufferproc) PyCObject_AsVoidPtr(getbuffer_cobj);
+      #endif
+        Py_DECREF(getbuffer_cobj);
+        if (!func)
+            goto fail;
+        return func(obj, view, flags);
+    } else {
+        PyErr_Clear();
+    }
+  #endif
+    PyErr_Format(PyExc_TypeError, "'%100s' does not have the buffer interface", Py_TYPE(obj)->tp_name);
+#if PY_VERSION_HEX < 0x02060000
+fail:
+#endif
+    return -1;
+}
+static void __Pyx_ReleaseBuffer(Py_buffer *view) {
+    PyObject *obj = view->obj;
+    CYTHON_UNUSED PyObject *releasebuffer_cobj;
+    if (!obj) return;
+  #if PY_VERSION_HEX >= 0x02060000
+    if (PyObject_CheckBuffer(obj)) {
+        PyBuffer_Release(view);
+        return;
+    }
+  #endif
+        if (PyObject_TypeCheck(obj, __pyx_ptype_5numpy_ndarray)) { __pyx_pw_5numpy_7ndarray_3__releasebuffer__(obj, view); return; }
+  #if PY_VERSION_HEX < 0x02060000
+    if (obj->ob_type->tp_dict &&
+        (releasebuffer_cobj = PyMapping_GetItemString(obj->ob_type->tp_dict,
+                                                      "__pyx_releasebuffer"))) {
+        releasebufferproc func;
+      #if PY_VERSION_HEX >= 0x02070000 && !(PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION == 0)
+        func = (releasebufferproc) PyCapsule_GetPointer(releasebuffer_cobj, "releasebuffer(obj, view)");
+      #else
+        func = (releasebufferproc) PyCObject_AsVoidPtr(releasebuffer_cobj);
+      #endif
+        Py_DECREF(releasebuffer_cobj);
+        if (!func)
+            goto fail;
+        func(obj, view);
+        return;
+    } else {
+        PyErr_Clear();
+    }
+  #endif
+    goto nofail;
+#if PY_VERSION_HEX < 0x02060000
+fail:
+#endif
+    PyErr_WriteUnraisable(obj);
+nofail:
+    Py_DECREF(obj);
+    view->obj = NULL;
+}
+#endif /*  PY_MAJOR_VERSION < 3 */
+
+
+    static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level) {
+    PyObject *empty_list = 0;
+    PyObject *module = 0;
+    PyObject *global_dict = 0;
+    PyObject *empty_dict = 0;
+    PyObject *list;
+    #if PY_VERSION_HEX < 0x03030000
+    PyObject *py_import = 0;
+    py_import = __Pyx_GetAttrString(__pyx_b, "__import__");
+    if (!py_import)
+        goto bad;
+    #endif
+    if (from_list)
+        list = from_list;
+    else {
+        empty_list = PyList_New(0);
+        if (!empty_list)
+            goto bad;
+        list = empty_list;
+    }
+    global_dict = PyModule_GetDict(__pyx_m);
+    if (!global_dict)
+        goto bad;
+    empty_dict = PyDict_New();
+    if (!empty_dict)
+        goto bad;
+    #if PY_VERSION_HEX >= 0x02050000
+    {
+        #if PY_MAJOR_VERSION >= 3
+        if (level == -1) {
+            if (strchr(__Pyx_MODULE_NAME, '.')) {
+                #if PY_VERSION_HEX < 0x03030000
+                PyObject *py_level = PyInt_FromLong(1);
+                if (!py_level)
+                    goto bad;
+                module = PyObject_CallFunctionObjArgs(py_import,
+                    name, global_dict, empty_dict, list, py_level, NULL);
+                Py_DECREF(py_level);
+                #else
+                module = PyImport_ImportModuleLevelObject(
+                    name, global_dict, empty_dict, list, 1);
+                #endif
+                if (!module) {
+                    if (!PyErr_ExceptionMatches(PyExc_ImportError))
+                        goto bad;
+                    PyErr_Clear();
+                }
+            }
+            level = 0; /* try absolute import on failure */
+        }
+        #endif
+        if (!module) {
+            #if PY_VERSION_HEX < 0x03030000
+            PyObject *py_level = PyInt_FromLong(level);
+            if (!py_level)
+                goto bad;
+            module = PyObject_CallFunctionObjArgs(py_import,
+                name, global_dict, empty_dict, list, py_level, NULL);
+            Py_DECREF(py_level);
+            #else
+            module = PyImport_ImportModuleLevelObject(
+                name, global_dict, empty_dict, list, level);
+            #endif
+        }
+    }
+    #else
+    if (level>0) {
+        PyErr_SetString(PyExc_RuntimeError, "Relative import is not supported for Python <=2.4.");
+        goto bad;
+    }
+    module = PyObject_CallFunctionObjArgs(py_import,
+        name, global_dict, empty_dict, list, NULL);
+    #endif
+bad:
+    #if PY_VERSION_HEX < 0x03030000
+    Py_XDECREF(py_import);
+    #endif
+    Py_XDECREF(empty_list);
+    Py_XDECREF(empty_dict);
+    return module;
+}
+
+static CYTHON_INLINE void __Pyx_RaiseImportError(PyObject *name) {
+#if PY_MAJOR_VERSION < 3
+    PyErr_Format(PyExc_ImportError, "cannot import name %.230s",
+                 PyString_AsString(name));
+#else
+    PyErr_Format(PyExc_ImportError, "cannot import name %S", name);
+#endif
+}
+
+static PyObject *
+__Pyx_CyFunction_get_doc(__pyx_CyFunctionObject *op, CYTHON_UNUSED void *closure)
+{
+    if (unlikely(op->func_doc == NULL)) {
+        if (op->func.m_ml->ml_doc) {
+#if PY_MAJOR_VERSION >= 3
+            op->func_doc = PyUnicode_FromString(op->func.m_ml->ml_doc);
+#else
+            op->func_doc = PyString_FromString(op->func.m_ml->ml_doc);
+#endif
+            if (unlikely(op->func_doc == NULL))
+                return NULL;
+        } else {
+            Py_INCREF(Py_None);
+            return Py_None;
+        }
+    }
+    Py_INCREF(op->func_doc);
+    return op->func_doc;
+}
+static int
+__Pyx_CyFunction_set_doc(__pyx_CyFunctionObject *op, PyObject *value)
+{
+    PyObject *tmp = op->func_doc;
+    if (value == NULL)
+        value = Py_None; /* Mark as deleted */
+    Py_INCREF(value);
+    op->func_doc = value;
+    Py_XDECREF(tmp);
+    return 0;
+}
+static PyObject *
+__Pyx_CyFunction_get_name(__pyx_CyFunctionObject *op)
+{
+    if (unlikely(op->func_name == NULL)) {
+#if PY_MAJOR_VERSION >= 3
+        op->func_name = PyUnicode_InternFromString(op->func.m_ml->ml_name);
+#else
+        op->func_name = PyString_InternFromString(op->func.m_ml->ml_name);
+#endif
+        if (unlikely(op->func_name == NULL))
+            return NULL;
+    }
+    Py_INCREF(op->func_name);
+    return op->func_name;
+}
+static int
+__Pyx_CyFunction_set_name(__pyx_CyFunctionObject *op, PyObject *value)
+{
+    PyObject *tmp;
+#if PY_MAJOR_VERSION >= 3
+    if (unlikely(value == NULL || !PyUnicode_Check(value))) {
+#else
+    if (unlikely(value == NULL || !PyString_Check(value))) {
+#endif
+        PyErr_SetString(PyExc_TypeError,
+                        "__name__ must be set to a string object");
+        return -1;
+    }
+    tmp = op->func_name;
+    Py_INCREF(value);
+    op->func_name = value;
+    Py_XDECREF(tmp);
+    return 0;
+}
+static PyObject *
+__Pyx_CyFunction_get_qualname(__pyx_CyFunctionObject *op)
+{
+    Py_INCREF(op->func_qualname);
+    return op->func_qualname;
+}
+static int
+__Pyx_CyFunction_set_qualname(__pyx_CyFunctionObject *op, PyObject *value)
+{
+    PyObject *tmp;
+#if PY_MAJOR_VERSION >= 3
+    if (unlikely(value == NULL || !PyUnicode_Check(value))) {
+#else
+    if (unlikely(value == NULL || !PyString_Check(value))) {
+#endif
+        PyErr_SetString(PyExc_TypeError,
+                        "__qualname__ must be set to a string object");
+        return -1;
+    }
+    tmp = op->func_qualname;
+    Py_INCREF(value);
+    op->func_qualname = value;
+    Py_XDECREF(tmp);
+    return 0;
+}
+static PyObject *
+__Pyx_CyFunction_get_self(__pyx_CyFunctionObject *m, CYTHON_UNUSED void *closure)
+{
+    PyObject *self;
+    self = m->func_closure;
+    if (self == NULL)
+        self = Py_None;
+    Py_INCREF(self);
+    return self;
+}
+static PyObject *
+__Pyx_CyFunction_get_dict(__pyx_CyFunctionObject *op)
+{
+    if (unlikely(op->func_dict == NULL)) {
+        op->func_dict = PyDict_New();
+        if (unlikely(op->func_dict == NULL))
+            return NULL;
+    }
+    Py_INCREF(op->func_dict);
+    return op->func_dict;
+}
+static int
+__Pyx_CyFunction_set_dict(__pyx_CyFunctionObject *op, PyObject *value)
+{
+    PyObject *tmp;
+    if (unlikely(value == NULL)) {
+        PyErr_SetString(PyExc_TypeError,
+               "function's dictionary may not be deleted");
+        return -1;
+    }
+    if (unlikely(!PyDict_Check(value))) {
+        PyErr_SetString(PyExc_TypeError,
+               "setting function's dictionary to a non-dict");
+        return -1;
+    }
+    tmp = op->func_dict;
+    Py_INCREF(value);
+    op->func_dict = value;
+    Py_XDECREF(tmp);
+    return 0;
+}
+static PyObject *
+__Pyx_CyFunction_get_globals(CYTHON_UNUSED __pyx_CyFunctionObject *op)
+{
+    PyObject* dict = PyModule_GetDict(__pyx_m);
+    Py_XINCREF(dict);
+    return dict;
+}
+static PyObject *
+__Pyx_CyFunction_get_closure(CYTHON_UNUSED __pyx_CyFunctionObject *op)
+{
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+static PyObject *
+__Pyx_CyFunction_get_code(__pyx_CyFunctionObject *op)
+{
+    PyObject* result = (op->func_code) ? op->func_code : Py_None;
+    Py_INCREF(result);
+    return result;
+}
+static PyObject *
+__Pyx_CyFunction_get_defaults(__pyx_CyFunctionObject *op)
+{
+    if (op->defaults_tuple) {
+        Py_INCREF(op->defaults_tuple);
+        return op->defaults_tuple;
+    }
+    if (op->defaults_getter) {
+        PyObject *res = op->defaults_getter((PyObject *) op);
+        if (likely(res)) {
+            Py_INCREF(res);
+            op->defaults_tuple = res;
+        }
+        return res;
+    }
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+static PyGetSetDef __pyx_CyFunction_getsets[] = {
+    {(char *) "func_doc", (getter)__Pyx_CyFunction_get_doc, (setter)__Pyx_CyFunction_set_doc, 0, 0},
+    {(char *) "__doc__",  (getter)__Pyx_CyFunction_get_doc, (setter)__Pyx_CyFunction_set_doc, 0, 0},
+    {(char *) "func_name", (getter)__Pyx_CyFunction_get_name, (setter)__Pyx_CyFunction_set_name, 0, 0},
+    {(char *) "__name__", (getter)__Pyx_CyFunction_get_name, (setter)__Pyx_CyFunction_set_name, 0, 0},
+    {(char *) "__qualname__", (getter)__Pyx_CyFunction_get_qualname, (setter)__Pyx_CyFunction_set_qualname, 0, 0},
+    {(char *) "__self__", (getter)__Pyx_CyFunction_get_self, 0, 0, 0},
+    {(char *) "func_dict", (getter)__Pyx_CyFunction_get_dict, (setter)__Pyx_CyFunction_set_dict, 0, 0},
+    {(char *) "__dict__", (getter)__Pyx_CyFunction_get_dict, (setter)__Pyx_CyFunction_set_dict, 0, 0},
+    {(char *) "func_globals", (getter)__Pyx_CyFunction_get_globals, 0, 0, 0},
+    {(char *) "__globals__", (getter)__Pyx_CyFunction_get_globals, 0, 0, 0},
+    {(char *) "func_closure", (getter)__Pyx_CyFunction_get_closure, 0, 0, 0},
+    {(char *) "__closure__", (getter)__Pyx_CyFunction_get_closure, 0, 0, 0},
+    {(char *) "func_code", (getter)__Pyx_CyFunction_get_code, 0, 0, 0},
+    {(char *) "__code__", (getter)__Pyx_CyFunction_get_code, 0, 0, 0},
+    {(char *) "func_defaults", (getter)__Pyx_CyFunction_get_defaults, 0, 0, 0},
+    {(char *) "__defaults__", (getter)__Pyx_CyFunction_get_defaults, 0, 0, 0},
+    {0, 0, 0, 0, 0}
+};
+#ifndef PY_WRITE_RESTRICTED /* < Py2.5 */
+#define PY_WRITE_RESTRICTED WRITE_RESTRICTED
+#endif
+static PyMemberDef __pyx_CyFunction_members[] = {
+    {(char *) "__module__", T_OBJECT, offsetof(__pyx_CyFunctionObject, func.m_module), PY_WRITE_RESTRICTED, 0},
+    {0, 0, 0,  0, 0}
+};
+static PyObject *
+__Pyx_CyFunction_reduce(__pyx_CyFunctionObject *m, CYTHON_UNUSED PyObject *args)
+{
+#if PY_MAJOR_VERSION >= 3
+    return PyUnicode_FromString(m->func.m_ml->ml_name);
+#else
+    return PyString_FromString(m->func.m_ml->ml_name);
+#endif
+}
+static PyMethodDef __pyx_CyFunction_methods[] = {
+    {__Pyx_NAMESTR("__reduce__"), (PyCFunction)__Pyx_CyFunction_reduce, METH_VARARGS, 0},
+    {0, 0, 0, 0}
+};
+static PyObject *__Pyx_CyFunction_New(PyTypeObject *type, PyMethodDef *ml, int flags, PyObject* qualname,
+                                      PyObject *closure, PyObject *module, PyObject* code) {
+    __pyx_CyFunctionObject *op = PyObject_GC_New(__pyx_CyFunctionObject, type);
+    if (op == NULL)
+        return NULL;
+    op->flags = flags;
+    op->func_weakreflist = NULL;
+    op->func.m_ml = ml;
+    op->func.m_self = (PyObject *) op;
+    Py_XINCREF(closure);
+    op->func_closure = closure;
+    Py_XINCREF(module);
+    op->func.m_module = module;
+    op->func_dict = NULL;
+    op->func_name = NULL;
+    Py_INCREF(qualname);
+    op->func_qualname = qualname;
+    op->func_doc = NULL;
+    op->func_classobj = NULL;
+    Py_XINCREF(code);
+    op->func_code = code;
+    op->defaults_pyobjects = 0;
+    op->defaults = NULL;
+    op->defaults_tuple = NULL;
+    op->defaults_getter = NULL;
+    PyObject_GC_Track(op);
+    return (PyObject *) op;
+}
+static int
+__Pyx_CyFunction_clear(__pyx_CyFunctionObject *m)
+{
+    Py_CLEAR(m->func_closure);
+    Py_CLEAR(m->func.m_module);
+    Py_CLEAR(m->func_dict);
+    Py_CLEAR(m->func_name);
+    Py_CLEAR(m->func_qualname);
+    Py_CLEAR(m->func_doc);
+    Py_CLEAR(m->func_code);
+    Py_CLEAR(m->func_classobj);
+    Py_CLEAR(m->defaults_tuple);
+    if (m->defaults) {
+        PyObject **pydefaults = __Pyx_CyFunction_Defaults(PyObject *, m);
+        int i;
+        for (i = 0; i < m->defaults_pyobjects; i++)
+            Py_XDECREF(pydefaults[i]);
+        PyMem_Free(m->defaults);
+        m->defaults = NULL;
+    }
+    return 0;
+}
+static void __Pyx_CyFunction_dealloc(__pyx_CyFunctionObject *m)
+{
+    PyObject_GC_UnTrack(m);
+    if (m->func_weakreflist != NULL)
+        PyObject_ClearWeakRefs((PyObject *) m);
+    __Pyx_CyFunction_clear(m);
+    PyObject_GC_Del(m);
+}
+static int __Pyx_CyFunction_traverse(__pyx_CyFunctionObject *m, visitproc visit, void *arg)
+{
+    Py_VISIT(m->func_closure);
+    Py_VISIT(m->func.m_module);
+    Py_VISIT(m->func_dict);
+    Py_VISIT(m->func_name);
+    Py_VISIT(m->func_qualname);
+    Py_VISIT(m->func_doc);
+    Py_VISIT(m->func_code);
+    Py_VISIT(m->func_classobj);
+    Py_VISIT(m->defaults_tuple);
+    if (m->defaults) {
+        PyObject **pydefaults = __Pyx_CyFunction_Defaults(PyObject *, m);
+        int i;
+        for (i = 0; i < m->defaults_pyobjects; i++)
+            Py_VISIT(pydefaults[i]);
+    }
+    return 0;
+}
+static PyObject *__Pyx_CyFunction_descr_get(PyObject *func, PyObject *obj, PyObject *type)
+{
+    __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func;
+    if (m->flags & __Pyx_CYFUNCTION_STATICMETHOD) {
+        Py_INCREF(func);
+        return func;
+    }
+    if (m->flags & __Pyx_CYFUNCTION_CLASSMETHOD) {
+        if (type == NULL)
+            type = (PyObject *)(Py_TYPE(obj));
+        return PyMethod_New(func,
+                            type, (PyObject *)(Py_TYPE(type)));
+    }
+    if (obj == Py_None)
+        obj = NULL;
+    return PyMethod_New(func, obj, type);
+}
+static PyObject*
+__Pyx_CyFunction_repr(__pyx_CyFunctionObject *op)
+{
+#if PY_MAJOR_VERSION >= 3
+    return PyUnicode_FromFormat("<cyfunction %U at %p>",
+                                op->func_qualname, (void *)op);
+#else
+    return PyString_FromFormat("<cyfunction %s at %p>",
+                               PyString_AsString(op->func_qualname), (void *)op);
+#endif
+}
+#if CYTHON_COMPILING_IN_PYPY
+static PyObject * __Pyx_CyFunction_Call(PyObject *func, PyObject *arg, PyObject *kw) {
+    PyCFunctionObject* f = (PyCFunctionObject*)func;
+    PyCFunction meth = PyCFunction_GET_FUNCTION(func);
+    PyObject *self = PyCFunction_GET_SELF(func);
+    Py_ssize_t size;
+    switch (PyCFunction_GET_FLAGS(func) & ~(METH_CLASS | METH_STATIC | METH_COEXIST)) {
+    case METH_VARARGS:
+        if (likely(kw == NULL) || PyDict_Size(kw) == 0)
+            return (*meth)(self, arg);
+        break;
+    case METH_VARARGS | METH_KEYWORDS:
+        return (*(PyCFunctionWithKeywords)meth)(self, arg, kw);
+    case METH_NOARGS:
+        if (likely(kw == NULL) || PyDict_Size(kw) == 0) {
+            size = PyTuple_GET_SIZE(arg);
+            if (size == 0)
+                return (*meth)(self, NULL);
+            PyErr_Format(PyExc_TypeError,
+                "%.200s() takes no arguments (%zd given)",
+                f->m_ml->ml_name, size);
+            return NULL;
+        }
+        break;
+    case METH_O:
+        if (likely(kw == NULL) || PyDict_Size(kw) == 0) {
+            size = PyTuple_GET_SIZE(arg);
+            if (size == 1)
+                return (*meth)(self, PyTuple_GET_ITEM(arg, 0));
+            PyErr_Format(PyExc_TypeError,
+                "%.200s() takes exactly one argument (%zd given)",
+                f->m_ml->ml_name, size);
+            return NULL;
+        }
+        break;
+    default:
+        PyErr_SetString(PyExc_SystemError, "Bad call flags in "
+                        "__Pyx_CyFunction_Call. METH_OLDARGS is no "
+                        "longer supported!");
+        return NULL;
+    }
+    PyErr_Format(PyExc_TypeError, "%.200s() takes no keyword arguments",
+                 f->m_ml->ml_name);
+    return NULL;
+}
+#else
+static PyObject * __Pyx_CyFunction_Call(PyObject *func, PyObject *arg, PyObject *kw) {
+	return PyCFunction_Call(func, arg, kw);
+}
+#endif
+static PyTypeObject __pyx_CyFunctionType_type = {
+    PyVarObject_HEAD_INIT(0, 0)
+    __Pyx_NAMESTR("cython_function_or_method"), /*tp_name*/
+    sizeof(__pyx_CyFunctionObject),   /*tp_basicsize*/
+    0,                                  /*tp_itemsize*/
+    (destructor) __Pyx_CyFunction_dealloc, /*tp_dealloc*/
+    0,                                  /*tp_print*/
+    0,                                  /*tp_getattr*/
+    0,                                  /*tp_setattr*/
+#if PY_MAJOR_VERSION < 3
+    0,                                  /*tp_compare*/
+#else
+    0,                                  /*reserved*/
+#endif
+    (reprfunc) __Pyx_CyFunction_repr,   /*tp_repr*/
+    0,                                  /*tp_as_number*/
+    0,                                  /*tp_as_sequence*/
+    0,                                  /*tp_as_mapping*/
+    0,                                  /*tp_hash*/
+    __Pyx_CyFunction_Call,              /*tp_call*/
+    0,                                  /*tp_str*/
+    0,                                  /*tp_getattro*/
+    0,                                  /*tp_setattro*/
+    0,                                  /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags*/
+    0,                                  /*tp_doc*/
+    (traverseproc) __Pyx_CyFunction_traverse,   /*tp_traverse*/
+    (inquiry) __Pyx_CyFunction_clear,   /*tp_clear*/
+    0,                                  /*tp_richcompare*/
+    offsetof(__pyx_CyFunctionObject, func_weakreflist), /* tp_weaklistoffse */
+    0,                                  /*tp_iter*/
+    0,                                  /*tp_iternext*/
+    __pyx_CyFunction_methods,           /*tp_methods*/
+    __pyx_CyFunction_members,           /*tp_members*/
+    __pyx_CyFunction_getsets,           /*tp_getset*/
+    0,                                  /*tp_base*/
+    0,                                  /*tp_dict*/
+    __Pyx_CyFunction_descr_get,         /*tp_descr_get*/
+    0,                                  /*tp_descr_set*/
+    offsetof(__pyx_CyFunctionObject, func_dict),/*tp_dictoffset*/
+    0,                                  /*tp_init*/
+    0,                                  /*tp_alloc*/
+    0,                                  /*tp_new*/
+    0,                                  /*tp_free*/
+    0,                                  /*tp_is_gc*/
+    0,                                  /*tp_bases*/
+    0,                                  /*tp_mro*/
+    0,                                  /*tp_cache*/
+    0,                                  /*tp_subclasses*/
+    0,                                  /*tp_weaklist*/
+    0,                                  /*tp_del*/
+#if PY_VERSION_HEX >= 0x02060000
+    0,                                  /*tp_version_tag*/
+#endif
+};
+static int __Pyx_CyFunction_init(void) {
+#if !CYTHON_COMPILING_IN_PYPY
+    __pyx_CyFunctionType_type.tp_call = PyCFunction_Call;
+#endif
+    if (PyType_Ready(&__pyx_CyFunctionType_type) < 0)
+        return -1;
+    __pyx_CyFunctionType = &__pyx_CyFunctionType_type;
+    return 0;
+}
+static CYTHON_INLINE void *__Pyx_CyFunction_InitDefaults(PyObject *func, size_t size, int pyobjects) {
+    __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func;
+    m->defaults = PyMem_Malloc(size);
+    if (!m->defaults)
+        return PyErr_NoMemory();
+    memset(m->defaults, 0, sizeof(size));
+    m->defaults_pyobjects = pyobjects;
+    return m->defaults;
+}
+static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsTuple(PyObject *func, PyObject *tuple) {
+    __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func;
+    m->defaults_tuple = tuple;
+    Py_INCREF(tuple);
+}
+
+static CYTHON_INLINE PyObject *__Pyx_PyInt_to_py_npy_uint64(npy_uint64 val) {
+    const npy_uint64 neg_one = (npy_uint64)-1, const_zero = (npy_uint64)0;
+    const int is_unsigned = const_zero < neg_one;
+    if ((sizeof(npy_uint64) == sizeof(char))  ||
+        (sizeof(npy_uint64) == sizeof(short))) {
+        return PyInt_FromLong((long)val);
+    } else if ((sizeof(npy_uint64) == sizeof(int)) ||
+               (sizeof(npy_uint64) == sizeof(long))) {
+        if (is_unsigned)
+            return PyLong_FromUnsignedLong((unsigned long)val);
+        else
+            return PyInt_FromLong((long)val);
+    } else if (sizeof(npy_uint64) == sizeof(PY_LONG_LONG)) {
+        if (is_unsigned)
+            return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG)val);
+        else
+            return PyLong_FromLongLong((PY_LONG_LONG)val);
+    } else {
+        int one = 1; int little = (int)*(unsigned char *)&one;
+        unsigned char *bytes = (unsigned char *)&val;
+        return _PyLong_FromByteArray(bytes, sizeof(npy_uint64),
+                                     little, !is_unsigned);
+    }
+}
+
+#if CYTHON_CCOMPLEX
+  #ifdef __cplusplus
+    static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float x, float y) {
+      return ::std::complex< float >(x, y);
+    }
+  #else
+    static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float x, float y) {
+      return x + y*(__pyx_t_float_complex)_Complex_I;
+    }
+  #endif
+#else
+    static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float x, float y) {
+      __pyx_t_float_complex z;
+      z.real = x;
+      z.imag = y;
+      return z;
+    }
+#endif
+
+#if CYTHON_CCOMPLEX
+#else
+    static CYTHON_INLINE int __Pyx_c_eqf(__pyx_t_float_complex a, __pyx_t_float_complex b) {
+       return (a.real == b.real) && (a.imag == b.imag);
+    }
+    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_sumf(__pyx_t_float_complex a, __pyx_t_float_complex b) {
+        __pyx_t_float_complex z;
+        z.real = a.real + b.real;
+        z.imag = a.imag + b.imag;
+        return z;
+    }
+    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_difff(__pyx_t_float_complex a, __pyx_t_float_complex b) {
+        __pyx_t_float_complex z;
+        z.real = a.real - b.real;
+        z.imag = a.imag - b.imag;
+        return z;
+    }
+    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_prodf(__pyx_t_float_complex a, __pyx_t_float_complex b) {
+        __pyx_t_float_complex z;
+        z.real = a.real * b.real - a.imag * b.imag;
+        z.imag = a.real * b.imag + a.imag * b.real;
+        return z;
+    }
+    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_quotf(__pyx_t_float_complex a, __pyx_t_float_complex b) {
+        __pyx_t_float_complex z;
+        float denom = b.real * b.real + b.imag * b.imag;
+        z.real = (a.real * b.real + a.imag * b.imag) / denom;
+        z.imag = (a.imag * b.real - a.real * b.imag) / denom;
+        return z;
+    }
+    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_negf(__pyx_t_float_complex a) {
+        __pyx_t_float_complex z;
+        z.real = -a.real;
+        z.imag = -a.imag;
+        return z;
+    }
+    static CYTHON_INLINE int __Pyx_c_is_zerof(__pyx_t_float_complex a) {
+       return (a.real == 0) && (a.imag == 0);
+    }
+    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_conjf(__pyx_t_float_complex a) {
+        __pyx_t_float_complex z;
+        z.real =  a.real;
+        z.imag = -a.imag;
+        return z;
+    }
+    #if 1
+        static CYTHON_INLINE float __Pyx_c_absf(__pyx_t_float_complex z) {
+          #if !defined(HAVE_HYPOT) || defined(_MSC_VER)
+            return sqrtf(z.real*z.real + z.imag*z.imag);
+          #else
+            return hypotf(z.real, z.imag);
+          #endif
+        }
+        static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_powf(__pyx_t_float_complex a, __pyx_t_float_complex b) {
+            __pyx_t_float_complex z;
+            float r, lnr, theta, z_r, z_theta;
+            if (b.imag == 0 && b.real == (int)b.real) {
+                if (b.real < 0) {
+                    float denom = a.real * a.real + a.imag * a.imag;
+                    a.real = a.real / denom;
+                    a.imag = -a.imag / denom;
+                    b.real = -b.real;
+                }
+                switch ((int)b.real) {
+                    case 0:
+                        z.real = 1;
+                        z.imag = 0;
+                        return z;
+                    case 1:
+                        return a;
+                    case 2:
+                        z = __Pyx_c_prodf(a, a);
+                        return __Pyx_c_prodf(a, a);
+                    case 3:
+                        z = __Pyx_c_prodf(a, a);
+                        return __Pyx_c_prodf(z, a);
+                    case 4:
+                        z = __Pyx_c_prodf(a, a);
+                        return __Pyx_c_prodf(z, z);
+                }
+            }
+            if (a.imag == 0) {
+                if (a.real == 0) {
+                    return a;
+                }
+                r = a.real;
+                theta = 0;
+            } else {
+                r = __Pyx_c_absf(a);
+                theta = atan2f(a.imag, a.real);
+            }
+            lnr = logf(r);
+            z_r = expf(lnr * b.real - theta * b.imag);
+            z_theta = theta * b.real + lnr * b.imag;
+            z.real = z_r * cosf(z_theta);
+            z.imag = z_r * sinf(z_theta);
+            return z;
+        }
+    #endif
+#endif
+
+#if CYTHON_CCOMPLEX
+  #ifdef __cplusplus
+    static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) {
+      return ::std::complex< double >(x, y);
+    }
+  #else
+    static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) {
+      return x + y*(__pyx_t_double_complex)_Complex_I;
+    }
+  #endif
+#else
+    static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) {
+      __pyx_t_double_complex z;
+      z.real = x;
+      z.imag = y;
+      return z;
+    }
+#endif
+
+#if CYTHON_CCOMPLEX
+#else
+    static CYTHON_INLINE int __Pyx_c_eq(__pyx_t_double_complex a, __pyx_t_double_complex b) {
+       return (a.real == b.real) && (a.imag == b.imag);
+    }
+    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_sum(__pyx_t_double_complex a, __pyx_t_double_complex b) {
+        __pyx_t_double_complex z;
+        z.real = a.real + b.real;
+        z.imag = a.imag + b.imag;
+        return z;
+    }
+    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_diff(__pyx_t_double_complex a, __pyx_t_double_complex b) {
+        __pyx_t_double_complex z;
+        z.real = a.real - b.real;
+        z.imag = a.imag - b.imag;
+        return z;
+    }
+    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_prod(__pyx_t_double_complex a, __pyx_t_double_complex b) {
+        __pyx_t_double_complex z;
+        z.real = a.real * b.real - a.imag * b.imag;
+        z.imag = a.real * b.imag + a.imag * b.real;
+        return z;
+    }
+    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_quot(__pyx_t_double_complex a, __pyx_t_double_complex b) {
+        __pyx_t_double_complex z;
+        double denom = b.real * b.real + b.imag * b.imag;
+        z.real = (a.real * b.real + a.imag * b.imag) / denom;
+        z.imag = (a.imag * b.real - a.real * b.imag) / denom;
+        return z;
+    }
+    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_neg(__pyx_t_double_complex a) {
+        __pyx_t_double_complex z;
+        z.real = -a.real;
+        z.imag = -a.imag;
+        return z;
+    }
+    static CYTHON_INLINE int __Pyx_c_is_zero(__pyx_t_double_complex a) {
+       return (a.real == 0) && (a.imag == 0);
+    }
+    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_conj(__pyx_t_double_complex a) {
+        __pyx_t_double_complex z;
+        z.real =  a.real;
+        z.imag = -a.imag;
+        return z;
+    }
+    #if 1
+        static CYTHON_INLINE double __Pyx_c_abs(__pyx_t_double_complex z) {
+          #if !defined(HAVE_HYPOT) || defined(_MSC_VER)
+            return sqrt(z.real*z.real + z.imag*z.imag);
+          #else
+            return hypot(z.real, z.imag);
+          #endif
+        }
+        static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_pow(__pyx_t_double_complex a, __pyx_t_double_complex b) {
+            __pyx_t_double_complex z;
+            double r, lnr, theta, z_r, z_theta;
+            if (b.imag == 0 && b.real == (int)b.real) {
+                if (b.real < 0) {
+                    double denom = a.real * a.real + a.imag * a.imag;
+                    a.real = a.real / denom;
+                    a.imag = -a.imag / denom;
+                    b.real = -b.real;
+                }
+                switch ((int)b.real) {
+                    case 0:
+                        z.real = 1;
+                        z.imag = 0;
+                        return z;
+                    case 1:
+                        return a;
+                    case 2:
+                        z = __Pyx_c_prod(a, a);
+                        return __Pyx_c_prod(a, a);
+                    case 3:
+                        z = __Pyx_c_prod(a, a);
+                        return __Pyx_c_prod(z, a);
+                    case 4:
+                        z = __Pyx_c_prod(a, a);
+                        return __Pyx_c_prod(z, z);
+                }
+            }
+            if (a.imag == 0) {
+                if (a.real == 0) {
+                    return a;
+                }
+                r = a.real;
+                theta = 0;
+            } else {
+                r = __Pyx_c_abs(a);
+                theta = atan2(a.imag, a.real);
+            }
+            lnr = log(r);
+            z_r = exp(lnr * b.real - theta * b.imag);
+            z_theta = theta * b.real + lnr * b.imag;
+            z.real = z_r * cos(z_theta);
+            z.imag = z_r * sin(z_theta);
+            return z;
+        }
+    #endif
+#endif
+
+static CYTHON_INLINE unsigned char __Pyx_PyInt_AsUnsignedChar(PyObject* x) {
+    const unsigned char neg_one = (unsigned char)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(unsigned char) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(unsigned char)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to unsigned char" :
+                    "value too large to convert to unsigned char");
+            }
+            return (unsigned char)-1;
+        }
+        return (unsigned char)val;
+    }
+    return (unsigned char)__Pyx_PyInt_AsUnsignedLong(x);
+}
+
+static CYTHON_INLINE unsigned short __Pyx_PyInt_AsUnsignedShort(PyObject* x) {
+    const unsigned short neg_one = (unsigned short)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(unsigned short) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(unsigned short)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to unsigned short" :
+                    "value too large to convert to unsigned short");
+            }
+            return (unsigned short)-1;
+        }
+        return (unsigned short)val;
+    }
+    return (unsigned short)__Pyx_PyInt_AsUnsignedLong(x);
+}
+
+static CYTHON_INLINE unsigned int __Pyx_PyInt_AsUnsignedInt(PyObject* x) {
+    const unsigned int neg_one = (unsigned int)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(unsigned int) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(unsigned int)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to unsigned int" :
+                    "value too large to convert to unsigned int");
+            }
+            return (unsigned int)-1;
+        }
+        return (unsigned int)val;
+    }
+    return (unsigned int)__Pyx_PyInt_AsUnsignedLong(x);
+}
+
+static CYTHON_INLINE char __Pyx_PyInt_AsChar(PyObject* x) {
+    const char neg_one = (char)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(char) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(char)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to char" :
+                    "value too large to convert to char");
+            }
+            return (char)-1;
+        }
+        return (char)val;
+    }
+    return (char)__Pyx_PyInt_AsLong(x);
+}
+
+static CYTHON_INLINE short __Pyx_PyInt_AsShort(PyObject* x) {
+    const short neg_one = (short)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(short) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(short)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to short" :
+                    "value too large to convert to short");
+            }
+            return (short)-1;
+        }
+        return (short)val;
+    }
+    return (short)__Pyx_PyInt_AsLong(x);
+}
+
+static CYTHON_INLINE int __Pyx_PyInt_AsInt(PyObject* x) {
+    const int neg_one = (int)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(int) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(int)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to int" :
+                    "value too large to convert to int");
+            }
+            return (int)-1;
+        }
+        return (int)val;
+    }
+    return (int)__Pyx_PyInt_AsLong(x);
+}
+
+static CYTHON_INLINE signed char __Pyx_PyInt_AsSignedChar(PyObject* x) {
+    const signed char neg_one = (signed char)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(signed char) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(signed char)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to signed char" :
+                    "value too large to convert to signed char");
+            }
+            return (signed char)-1;
+        }
+        return (signed char)val;
+    }
+    return (signed char)__Pyx_PyInt_AsSignedLong(x);
+}
+
+static CYTHON_INLINE signed short __Pyx_PyInt_AsSignedShort(PyObject* x) {
+    const signed short neg_one = (signed short)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(signed short) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(signed short)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to signed short" :
+                    "value too large to convert to signed short");
+            }
+            return (signed short)-1;
+        }
+        return (signed short)val;
+    }
+    return (signed short)__Pyx_PyInt_AsSignedLong(x);
+}
+
+static CYTHON_INLINE signed int __Pyx_PyInt_AsSignedInt(PyObject* x) {
+    const signed int neg_one = (signed int)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(signed int) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(signed int)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to signed int" :
+                    "value too large to convert to signed int");
+            }
+            return (signed int)-1;
+        }
+        return (signed int)val;
+    }
+    return (signed int)__Pyx_PyInt_AsSignedLong(x);
+}
+
+static CYTHON_INLINE int __Pyx_PyInt_AsLongDouble(PyObject* x) {
+    const int neg_one = (int)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(int) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(int)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to int" :
+                    "value too large to convert to int");
+            }
+            return (int)-1;
+        }
+        return (int)val;
+    }
+    return (int)__Pyx_PyInt_AsLong(x);
+}
+
+static CYTHON_INLINE unsigned long __Pyx_PyInt_AsUnsignedLong(PyObject* x) {
+    const unsigned long neg_one = (unsigned long)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to unsigned long");
+            return (unsigned long)-1;
+        }
+        return (unsigned long)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to unsigned long");
+                return (unsigned long)-1;
+            }
+            return (unsigned long)PyLong_AsUnsignedLong(x);
+        } else {
+            return (unsigned long)PyLong_AsLong(x);
+        }
+    } else {
+        unsigned long val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (unsigned long)-1;
+        val = __Pyx_PyInt_AsUnsignedLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE unsigned PY_LONG_LONG __Pyx_PyInt_AsUnsignedLongLong(PyObject* x) {
+    const unsigned PY_LONG_LONG neg_one = (unsigned PY_LONG_LONG)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to unsigned PY_LONG_LONG");
+            return (unsigned PY_LONG_LONG)-1;
+        }
+        return (unsigned PY_LONG_LONG)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to unsigned PY_LONG_LONG");
+                return (unsigned PY_LONG_LONG)-1;
+            }
+            return (unsigned PY_LONG_LONG)PyLong_AsUnsignedLongLong(x);
+        } else {
+            return (unsigned PY_LONG_LONG)PyLong_AsLongLong(x);
+        }
+    } else {
+        unsigned PY_LONG_LONG val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (unsigned PY_LONG_LONG)-1;
+        val = __Pyx_PyInt_AsUnsignedLongLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE long __Pyx_PyInt_AsLong(PyObject* x) {
+    const long neg_one = (long)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to long");
+            return (long)-1;
+        }
+        return (long)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to long");
+                return (long)-1;
+            }
+            return (long)PyLong_AsUnsignedLong(x);
+        } else {
+            return (long)PyLong_AsLong(x);
+        }
+    } else {
+        long val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (long)-1;
+        val = __Pyx_PyInt_AsLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE PY_LONG_LONG __Pyx_PyInt_AsLongLong(PyObject* x) {
+    const PY_LONG_LONG neg_one = (PY_LONG_LONG)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to PY_LONG_LONG");
+            return (PY_LONG_LONG)-1;
+        }
+        return (PY_LONG_LONG)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to PY_LONG_LONG");
+                return (PY_LONG_LONG)-1;
+            }
+            return (PY_LONG_LONG)PyLong_AsUnsignedLongLong(x);
+        } else {
+            return (PY_LONG_LONG)PyLong_AsLongLong(x);
+        }
+    } else {
+        PY_LONG_LONG val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (PY_LONG_LONG)-1;
+        val = __Pyx_PyInt_AsLongLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE signed long __Pyx_PyInt_AsSignedLong(PyObject* x) {
+    const signed long neg_one = (signed long)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to signed long");
+            return (signed long)-1;
+        }
+        return (signed long)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to signed long");
+                return (signed long)-1;
+            }
+            return (signed long)PyLong_AsUnsignedLong(x);
+        } else {
+            return (signed long)PyLong_AsLong(x);
+        }
+    } else {
+        signed long val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (signed long)-1;
+        val = __Pyx_PyInt_AsSignedLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE signed PY_LONG_LONG __Pyx_PyInt_AsSignedLongLong(PyObject* x) {
+    const signed PY_LONG_LONG neg_one = (signed PY_LONG_LONG)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to signed PY_LONG_LONG");
+            return (signed PY_LONG_LONG)-1;
+        }
+        return (signed PY_LONG_LONG)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to signed PY_LONG_LONG");
+                return (signed PY_LONG_LONG)-1;
+            }
+            return (signed PY_LONG_LONG)PyLong_AsUnsignedLongLong(x);
+        } else {
+            return (signed PY_LONG_LONG)PyLong_AsLongLong(x);
+        }
+    } else {
+        signed PY_LONG_LONG val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (signed PY_LONG_LONG)-1;
+        val = __Pyx_PyInt_AsSignedLongLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static int __Pyx_check_binary_version(void) {
+    char ctversion[4], rtversion[4];
+    PyOS_snprintf(ctversion, 4, "%d.%d", PY_MAJOR_VERSION, PY_MINOR_VERSION);
+    PyOS_snprintf(rtversion, 4, "%s", Py_GetVersion());
+    if (ctversion[0] != rtversion[0] || ctversion[2] != rtversion[2]) {
+        char message[200];
+        PyOS_snprintf(message, sizeof(message),
+                      "compiletime version %s of module '%.100s' "
+                      "does not match runtime version %s",
+                      ctversion, __Pyx_MODULE_NAME, rtversion);
+        #if PY_VERSION_HEX < 0x02050000
+        return PyErr_Warn(NULL, message);
+        #else
+        return PyErr_WarnEx(NULL, message, 1);
+        #endif
+    }
+    return 0;
+}
+
+#ifndef __PYX_HAVE_RT_ImportModule
+#define __PYX_HAVE_RT_ImportModule
+static PyObject *__Pyx_ImportModule(const char *name) {
+    PyObject *py_name = 0;
+    PyObject *py_module = 0;
+    py_name = __Pyx_PyIdentifier_FromString(name);
+    if (!py_name)
+        goto bad;
+    py_module = PyImport_Import(py_name);
+    Py_DECREF(py_name);
+    return py_module;
+bad:
+    Py_XDECREF(py_name);
+    return 0;
+}
+#endif
+
+#ifndef __PYX_HAVE_RT_ImportType
+#define __PYX_HAVE_RT_ImportType
+static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name,
+    size_t size, int strict)
+{
+    PyObject *py_module = 0;
+    PyObject *result = 0;
+    PyObject *py_name = 0;
+    char warning[200];
+    Py_ssize_t basicsize;
+#ifdef Py_LIMITED_API
+    PyObject *py_basicsize;
+#endif
+    py_module = __Pyx_ImportModule(module_name);
+    if (!py_module)
+        goto bad;
+    py_name = __Pyx_PyIdentifier_FromString(class_name);
+    if (!py_name)
+        goto bad;
+    result = PyObject_GetAttr(py_module, py_name);
+    Py_DECREF(py_name);
+    py_name = 0;
+    Py_DECREF(py_module);
+    py_module = 0;
+    if (!result)
+        goto bad;
+    if (!PyType_Check(result)) {
+        PyErr_Format(PyExc_TypeError,
+            "%s.%s is not a type object",
+            module_name, class_name);
+        goto bad;
+    }
+#ifndef Py_LIMITED_API
+    basicsize = ((PyTypeObject *)result)->tp_basicsize;
+#else
+    py_basicsize = PyObject_GetAttrString(result, "__basicsize__");
+    if (!py_basicsize)
+        goto bad;
+    basicsize = PyLong_AsSsize_t(py_basicsize);
+    Py_DECREF(py_basicsize);
+    py_basicsize = 0;
+    if (basicsize == (Py_ssize_t)-1 && PyErr_Occurred())
+        goto bad;
+#endif
+    if (!strict && (size_t)basicsize > size) {
+        PyOS_snprintf(warning, sizeof(warning),
+            "%s.%s size changed, may indicate binary incompatibility",
+            module_name, class_name);
+        #if PY_VERSION_HEX < 0x02050000
+        if (PyErr_Warn(NULL, warning) < 0) goto bad;
+        #else
+        if (PyErr_WarnEx(NULL, warning, 0) < 0) goto bad;
+        #endif
+    }
+    else if ((size_t)basicsize != size) {
+        PyErr_Format(PyExc_ValueError,
+            "%s.%s has the wrong size, try recompiling",
+            module_name, class_name);
+        goto bad;
+    }
+    return (PyTypeObject *)result;
+bad:
+    Py_XDECREF(py_module);
+    Py_XDECREF(result);
+    return NULL;
+}
+#endif
+
+static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) {
+    int start = 0, mid = 0, end = count - 1;
+    if (end >= 0 && code_line > entries[end].code_line) {
+        return count;
+    }
+    while (start < end) {
+        mid = (start + end) / 2;
+        if (code_line < entries[mid].code_line) {
+            end = mid;
+        } else if (code_line > entries[mid].code_line) {
+             start = mid + 1;
+        } else {
+            return mid;
+        }
+    }
+    if (code_line <= entries[mid].code_line) {
+        return mid;
+    } else {
+        return mid + 1;
+    }
+}
+static PyCodeObject *__pyx_find_code_object(int code_line) {
+    PyCodeObject* code_object;
+    int pos;
+    if (unlikely(!code_line) || unlikely(!__pyx_code_cache.entries)) {
+        return NULL;
+    }
+    pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line);
+    if (unlikely(pos >= __pyx_code_cache.count) || unlikely(__pyx_code_cache.entries[pos].code_line != code_line)) {
+        return NULL;
+    }
+    code_object = __pyx_code_cache.entries[pos].code_object;
+    Py_INCREF(code_object);
+    return code_object;
+}
+static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) {
+    int pos, i;
+    __Pyx_CodeObjectCacheEntry* entries = __pyx_code_cache.entries;
+    if (unlikely(!code_line)) {
+        return;
+    }
+    if (unlikely(!entries)) {
+        entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Malloc(64*sizeof(__Pyx_CodeObjectCacheEntry));
+        if (likely(entries)) {
+            __pyx_code_cache.entries = entries;
+            __pyx_code_cache.max_count = 64;
+            __pyx_code_cache.count = 1;
+            entries[0].code_line = code_line;
+            entries[0].code_object = code_object;
+            Py_INCREF(code_object);
+        }
+        return;
+    }
+    pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line);
+    if ((pos < __pyx_code_cache.count) && unlikely(__pyx_code_cache.entries[pos].code_line == code_line)) {
+        PyCodeObject* tmp = entries[pos].code_object;
+        entries[pos].code_object = code_object;
+        Py_DECREF(tmp);
+        return;
+    }
+    if (__pyx_code_cache.count == __pyx_code_cache.max_count) {
+        int new_max = __pyx_code_cache.max_count + 64;
+        entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Realloc(
+            __pyx_code_cache.entries, new_max*sizeof(__Pyx_CodeObjectCacheEntry));
+        if (unlikely(!entries)) {
+            return;
+        }
+        __pyx_code_cache.entries = entries;
+        __pyx_code_cache.max_count = new_max;
+    }
+    for (i=__pyx_code_cache.count; i>pos; i--) {
+        entries[i] = entries[i-1];
+    }
+    entries[pos].code_line = code_line;
+    entries[pos].code_object = code_object;
+    __pyx_code_cache.count++;
+    Py_INCREF(code_object);
+}
+
+#include "compile.h"
+#include "frameobject.h"
+#include "traceback.h"
+static PyCodeObject* __Pyx_CreateCodeObjectForTraceback(
+            const char *funcname, int c_line,
+            int py_line, const char *filename) {
+    PyCodeObject *py_code = 0;
+    PyObject *py_srcfile = 0;
+    PyObject *py_funcname = 0;
+    #if PY_MAJOR_VERSION < 3
+    py_srcfile = PyString_FromString(filename);
+    #else
+    py_srcfile = PyUnicode_FromString(filename);
+    #endif
+    if (!py_srcfile) goto bad;
+    if (c_line) {
+        #if PY_MAJOR_VERSION < 3
+        py_funcname = PyString_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line);
+        #else
+        py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line);
+        #endif
+    }
+    else {
+        #if PY_MAJOR_VERSION < 3
+        py_funcname = PyString_FromString(funcname);
+        #else
+        py_funcname = PyUnicode_FromString(funcname);
+        #endif
+    }
+    if (!py_funcname) goto bad;
+    py_code = __Pyx_PyCode_New(
+        0,            /*int argcount,*/
+        0,            /*int kwonlyargcount,*/
+        0,            /*int nlocals,*/
+        0,            /*int stacksize,*/
+        0,            /*int flags,*/
+        __pyx_empty_bytes, /*PyObject *code,*/
+        __pyx_empty_tuple, /*PyObject *consts,*/
+        __pyx_empty_tuple, /*PyObject *names,*/
+        __pyx_empty_tuple, /*PyObject *varnames,*/
+        __pyx_empty_tuple, /*PyObject *freevars,*/
+        __pyx_empty_tuple, /*PyObject *cellvars,*/
+        py_srcfile,   /*PyObject *filename,*/
+        py_funcname,  /*PyObject *name,*/
+        py_line,      /*int firstlineno,*/
+        __pyx_empty_bytes  /*PyObject *lnotab*/
+    );
+    Py_DECREF(py_srcfile);
+    Py_DECREF(py_funcname);
+    return py_code;
+bad:
+    Py_XDECREF(py_srcfile);
+    Py_XDECREF(py_funcname);
+    return NULL;
+}
+static void __Pyx_AddTraceback(const char *funcname, int c_line,
+                               int py_line, const char *filename) {
+    PyCodeObject *py_code = 0;
+    PyObject *py_globals = 0;
+    PyFrameObject *py_frame = 0;
+    py_code = __pyx_find_code_object(c_line ? c_line : py_line);
+    if (!py_code) {
+        py_code = __Pyx_CreateCodeObjectForTraceback(
+            funcname, c_line, py_line, filename);
+        if (!py_code) goto bad;
+        __pyx_insert_code_object(c_line ? c_line : py_line, py_code);
+    }
+    py_globals = PyModule_GetDict(__pyx_m);
+    if (!py_globals) goto bad;
+    py_frame = PyFrame_New(
+        PyThreadState_GET(), /*PyThreadState *tstate,*/
+        py_code,             /*PyCodeObject *code,*/
+        py_globals,          /*PyObject *globals,*/
+        0                    /*PyObject *locals*/
+    );
+    if (!py_frame) goto bad;
+    py_frame->f_lineno = py_line;
+    PyTraceBack_Here(py_frame);
+bad:
+    Py_XDECREF(py_code);
+    Py_XDECREF(py_frame);
+}
+
+static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
+    while (t->p) {
+        #if PY_MAJOR_VERSION < 3
+        if (t->is_unicode) {
+            *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
+        } else if (t->intern) {
+            *t->p = PyString_InternFromString(t->s);
+        } else {
+            *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
+        }
+        #else  /* Python 3+ has unicode identifiers */
+        if (t->is_unicode | t->is_str) {
+            if (t->intern) {
+                *t->p = PyUnicode_InternFromString(t->s);
+            } else if (t->encoding) {
+                *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL);
+            } else {
+                *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
+            }
+        } else {
+            *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
+        }
+        #endif
+        if (!*t->p)
+            return -1;
+        ++t;
+    }
+    return 0;
+}
+
+static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) {
+   int is_true = x == Py_True;
+   if (is_true | (x == Py_False) | (x == Py_None)) return is_true;
+   else return PyObject_IsTrue(x);
+}
+static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x) {
+  PyNumberMethods *m;
+  const char *name = NULL;
+  PyObject *res = NULL;
+#if PY_VERSION_HEX < 0x03000000
+  if (PyInt_Check(x) || PyLong_Check(x))
+#else
+  if (PyLong_Check(x))
+#endif
+    return Py_INCREF(x), x;
+  m = Py_TYPE(x)->tp_as_number;
+#if PY_VERSION_HEX < 0x03000000
+  if (m && m->nb_int) {
+    name = "int";
+    res = PyNumber_Int(x);
+  }
+  else if (m && m->nb_long) {
+    name = "long";
+    res = PyNumber_Long(x);
+  }
+#else
+  if (m && m->nb_int) {
+    name = "int";
+    res = PyNumber_Long(x);
+  }
+#endif
+  if (res) {
+#if PY_VERSION_HEX < 0x03000000
+    if (!PyInt_Check(res) && !PyLong_Check(res)) {
+#else
+    if (!PyLong_Check(res)) {
+#endif
+      PyErr_Format(PyExc_TypeError,
+                   "__%s__ returned non-%s (type %.200s)",
+                   name, name, Py_TYPE(res)->tp_name);
+      Py_DECREF(res);
+      return NULL;
+    }
+  }
+  else if (!PyErr_Occurred()) {
+    PyErr_SetString(PyExc_TypeError,
+                    "an integer is required");
+  }
+  return res;
+}
+static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) {
+  Py_ssize_t ival;
+  PyObject* x = PyNumber_Index(b);
+  if (!x) return -1;
+  ival = PyInt_AsSsize_t(x);
+  Py_DECREF(x);
+  return ival;
+}
+static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) {
+#if PY_VERSION_HEX < 0x02050000
+   if (ival <= LONG_MAX)
+       return PyInt_FromLong((long)ival);
+   else {
+       unsigned char *bytes = (unsigned char *) &ival;
+       int one = 1; int little = (int)*(unsigned char*)&one;
+       return _PyLong_FromByteArray(bytes, sizeof(size_t), little, 0);
+   }
+#else
+   return PyInt_FromSize_t(ival);
+#endif
+}
+static CYTHON_INLINE size_t __Pyx_PyInt_AsSize_t(PyObject* x) {
+   unsigned PY_LONG_LONG val = __Pyx_PyInt_AsUnsignedLongLong(x);
+   if (unlikely(val == (unsigned PY_LONG_LONG)-1 && PyErr_Occurred())) {
+       return (size_t)-1;
+   } else if (unlikely(val != (unsigned PY_LONG_LONG)(size_t)val)) {
+       PyErr_SetString(PyExc_OverflowError,
+                       "value too large to convert to size_t");
+       return (size_t)-1;
+   }
+   return (size_t)val;
+}
+
+
+#endif /* Py_PYTHON_H */
diff --git a/lib/bx/align/_epo.pyx b/lib/bx/align/_epo.pyx
new file mode 100644
index 0000000..f5352c9
--- /dev/null
+++ b/lib/bx/align/_epo.pyx
@@ -0,0 +1,184 @@
+
+
+import logging, gzip
+from collections import namedtuple
+import numpy
+cimport numpy
+
+log = logging.getLogger(__name__)
+
+cimport cython
+
+DTYPE = numpy.uint64
+
+
+cdef inline int max2( int a, int b ):
+    if b > a:
+        return b
+    return a
+
+cdef inline int min2( int a, int b ):
+    if b < a:
+        return b
+    return a
+
+
+def rem_dash(p, q):
+    """remove dash columns and shift match intervals to the left. both iterables
+    are read on the same direction left-to-right.
+    """
+
+    def myp(l):
+        if l: return l.pop(0)
+
+    def adv(queue, i, d):
+        # shifted interval
+        shi = i[0]-d, i[1]-d
+        assert shi[0] >= 0
+        if queue and queue[-1][1] == shi[0]:
+            # join to the preceeding one
+            queue[-1] = (queue[-1][0], shi[1])
+        else:
+            queue.append( shi )
+        return queue
+
+    p_card = sum( map(lambda i: p[i][1] - p[i][0], range(len(p))) )
+    q_card = sum( map(lambda i: q[i][1] - q[i][0], range(len(q))) )
+
+    P, Q = [], []
+    dash = 0 # dash (on both cigars) count so far
+    a, b = p.pop(0), q.pop(0)
+    #while p or q:
+    while a and b:
+        assert dash <= min(a[0], b[0])
+        i = max(a[0], b[0]) - min(a[1], b[1])
+        if i >= 0: # no intersection
+            if a[1] <= b[0]:
+                if p:
+                    i = min(i, p[0][0] - a[1])
+                P = adv(P, a, dash)
+                a = myp(p)
+            else:
+                if q:
+                    i = min(i, q[0][0] - b[1])
+                Q = adv(Q, b, dash)
+                b = myp(q)
+            dash += i
+        else: # intersection
+            if a[1] >= b[1]:
+                Q = adv(Q, b, dash); b = myp(q)
+            elif a[1] < b[1]:
+                P = adv(P, a, dash); a = myp(p)
+        #if not a or not b: # no more matchings
+        #    break
+    assert (not p) or (not q), "one or both should be empty: p=%s, q=%s" % (str(p), str(q))
+
+    if a: P = adv(P, a, dash)
+    if b: Q = adv(Q, b, dash)
+
+    # remaining intervals (in q or p)
+    r, R = p, P
+    if q: r, R = q, Q
+    # just extend the last inteval by the remaining bases
+    R[-1] = (R[-1][0], R[-1][1] + sum( map(lambda i: i[1]-i[0], r) ))
+
+    P_card = sum( map(lambda i: P[i][1] - P[i][0], range(len(P))) )
+    Q_card = sum( map(lambda i: Q[i][1] - Q[i][0], range(len(Q))) )
+
+    assert p_card == P_card, "%d != %d" % (p_card, P_card)
+    assert q_card == Q_card, "%d != %d" % (q_card, Q_card)
+
+    return P, Q
+
+def fastLoadChain(fname, hf):
+    data = []
+    open_f = (fname.endswith(".gz") and gzip.open or open)
+    with open_f(fname) as fd:
+        while True:
+            line = fd.readline()
+            if line == "":
+                break
+            hd = hf(line)
+            N = []
+            line = fd.readline().split()
+            while len(line) == 3:
+                N.append( (int(line[0]), int(line[1]), int(line[2])) )
+                line = fd.readline().split()
+            if len(line) != 1:
+                raise ValueError("last matching block expected (found %s)" % str(line))
+            N.append( (int(line[0]), 0, 0) )
+            s, t, q = zip( *N )
+            data.append( (hd,
+                numpy.array(s, dtype=numpy.int),
+                numpy.array(t, dtype=numpy.int),
+                numpy.array(q, dtype=numpy.int)) )
+            assert hd.tEnd - hd.tStart == sum(s) + sum(t)
+            assert hd.qEnd - hd.qStart == sum(s) + sum(q)
+            fd.readline() # a blank line
+        log.info("parsed %d elements from %s" % (len(data), fname))
+    return data
+
+
+
+ at cython.wraparound(False)
+ at cython.boundscheck(False)
+cpdef numpy.ndarray[numpy.uint64_t, ndim=2] bed_union( numpy.ndarray[numpy.uint64_t, ndim=2] elements ):
+    """compute the union of these elements. simply walk the sorted elements and join the intersecting ones
+    works on half-open intervals, i.e., [a, b), [b, c) ---> [a, c)
+
+    @param elements: 2-dim numpy array of unsigned64 ints
+    @return: 2-dim numpy array of unsigned64 ints"""
+
+    assert numpy.shape(elements)[0] > 0
+
+    cdef Py_ssize_t cst, cen, i, j
+    cdef numpy.ndarray[numpy.uint64_t, ndim=2] tmp_elems, final_elems
+
+    elements.sort(axis=0)
+    assert elements[0][0] <= elements[numpy.shape(elements)[0]-1][0]
+    tmp_elems = numpy.zeros((numpy.shape(elements)[0], 2), dtype=DTYPE)
+    cst = elements[0, 0]
+    cen = elements[0, 1]
+    j = 0
+
+    for i in range(1, numpy.shape(elements)[0]):
+        if elements[i, 0] <= cen: # overlaps with the last one
+            cen = max2(cen, elements[i, 1])
+        else:
+            tmp_elems[j, 0] = cst
+            tmp_elems[j, 1] = cen
+            j += 1
+            cst = elements[i, 0]
+            cen = elements[i, 1]
+    tmp_elems[j, 0] = cst
+    tmp_elems[j, 1] = cen
+    j += 1
+    final_elems = numpy.empty((j, 2), dtype=DTYPE)
+    for i in range(j):
+        final_elems[i, 0] = tmp_elems[i, 0]
+        final_elems[i, 1] = tmp_elems[i, 1]
+    assert final_elems[0, 0] == elements[0, 0], "fe=%d, e=%d" % (final_elems[0,0], elements[0,0])
+    return final_elems
+
+#@cython.wraparound(False)
+#@cython.boundscheck(False)
+cpdef numpy.ndarray[numpy.int64_t, ndim=2] cummulative_intervals(numpy.ndarray[numpy.int64_t, ndim=1] S,
+        numpy.ndarray[numpy.int64_t, ndim=1] D ):
+    """compute cummulative intervals for this side of an aligmnent. S and D are one side of
+    the alignment as described in the chain file format"""
+
+    cdef int N = S.shape[0]
+    cdef int i = 0, j = 0
+    assert N  == D.shape[0]
+    cdef numpy.ndarray[numpy.int64_t, ndim=2] cumm_i = numpy.empty((N, 2), dtype=numpy.int64)
+
+    cumm_i[0,0] = 0
+    cumm_i[0,1] = S[0]
+    for i in range(N-1):
+        j = i + 1
+        cumm_i[j,0] = cumm_i[i, 1] + D[i]
+        cumm_i[j,1] = cumm_i[j,0] + S[j]
+    return cumm_i
+
+
+
diff --git a/lib/bx/align/axt.py b/lib/bx/align/axt.py
new file mode 100644
index 0000000..4458f38
--- /dev/null
+++ b/lib/bx/align/axt.py
@@ -0,0 +1,193 @@
+"""
+Support for reading and writing the `AXT`_ format used for pairwise
+alignments.
+
+.. _AXT: http://genome.ucsc.edu/goldenPath/help/axt.html
+"""
+
+from bx.align import *
+
+import itertools
+from bx import interval_index_file
+
+# Tools for dealing with pairwise alignments in AXT format
+
+class MultiIndexed( object ):
+    """Similar to 'indexed' but wraps more than one axt_file"""
+    def __init__( self, axt_filenames, keep_open=False ):
+        self.indexes = [ Indexed( axt_file, axt_file + ".index" ) for axt_file in axt_filenames ]
+    def get( self, src, start, end ):
+        blocks = []
+        for index in self.indexes: blocks += index.get( src, start, end )
+        return blocks
+
+
+class Indexed( object ):
+    """Indexed access to a axt using overlap queries, requires an index file"""
+
+    def __init__( self, axt_filename, index_filename=None, keep_open=False, species1 = None, species2=None, species_to_lengths=None, support_ids=False ):
+        if index_filename is None: index_filename = axt_filename + ".index"
+        self.indexes = interval_index_file.Indexes( filename=index_filename )
+        self.axt_filename = axt_filename
+        # nota bene: (self.species1 = species1 or "species1") is incorrect if species1=""
+        self.species1 = species1
+        if (self.species1 == None): self.species1 = "species1"
+        self.species2 = species2
+        if (self.species2 == None): self.species2 = "species2"
+        self.species_to_lengths = species_to_lengths
+        self.support_ids        = support_ids            # for extra text at end of axt header lines
+        if keep_open:
+            self.f = open( axt_filename )
+        else:
+            self.f = None
+
+    def get( self, src, start, end ):
+        intersections = self.indexes.find( src, start, end )
+        return itertools.imap( self.get_axt_at_offset, [ val for start, end, val in intersections ] )
+
+    def get_axt_at_offset( self, offset ):
+        if self.f:
+            self.f.seek( offset )
+            return read_next_axt( self.f, self.species1, self.species2, self.species_to_lengths, self.support_ids )
+        else:
+            f = open( self.axt_filename )
+            try:
+                f.seek( offset )
+                return read_next_axt( f, self.species1, self.species2, self.species_to_lengths, self.support_ids )
+            finally:
+                f.close()
+
+class Reader( object ):
+    """Iterate over all axt blocks in a file in order"""
+
+    def __init__( self, file, species1 = None, species2=None, species_to_lengths=None, support_ids=False ):
+        self.file = file
+        # nota bene: (self.species1 = species1 or "species1") is incorrect if species1=""
+        self.species1 = species1
+        if (self.species1 == None): self.species1 = "species1"
+        self.species2 = species2
+        if (self.species2 == None): self.species2 = "species2"
+        self.species_to_lengths = species_to_lengths
+        self.support_ids        = support_ids            # for extra text at end of axt header lines
+        self.attributes = {}
+
+    def next( self ):
+        return read_next_axt( self.file, self.species1, self.species2, self.species_to_lengths, self.support_ids )
+
+    def __iter__( self ):
+        return ReaderIter( self )
+
+    def close( self ):
+        self.file.close()
+
+class ReaderIter( object ):
+    def __init__( self, reader ):
+        self.reader = reader
+    def __iter__( self ):
+        return self
+    def next( self ):
+        v = self.reader.next()
+        if not v: raise StopIteration
+        return v
+
+class Writer( object ):
+
+    def __init__( self, file, attributes={} ):
+        self.file = file
+        self.block = 0
+        self.src_split = True
+        if ("src_split" in attributes):
+            self.src_split = attributes["src_split"]
+
+    def write( self, alignment ):
+        if (len(alignment.components) != 2):
+            raise ValueError("%d-component alignment is not compatible with axt" % \
+                   len(alignment.components))
+        c1 = alignment.components[0]
+        c2 = alignment.components[1]
+
+        if c1.strand != "+":
+            c1 = c1.reverse_complement()
+            c2 = c2.reverse_complement()
+
+        if (self.src_split):
+            spec1,chr1 = src_split( c1.src )
+            spec2,chr2 = src_split( c2.src )
+        else:
+            chr1,chr2 = c1.src,c2.src
+
+        self.file.write( "%d %s %d %d %s %d %d %s %s\n" % \
+              (self.block,chr1,c1.start+1,c1.start+c1.size,
+               chr2,c2.start+1,c2.start+c2.size,c2.strand,
+               alignment.score))
+        self.file.write( "%s\n" % c1.text )
+        self.file.write( "%s\n" % c2.text )
+        self.file.write( "\n" )
+        self.block += 1
+
+    def close( self ):
+        self.file.close()
+
+# ---- Helper methods ---------------------------------------------------------
+
+# typical axt block:
+#   0 chr19 3001012 3001075 chr11 70568380 70568443 - 3500 [optional text]
+#   TCAGCTCATAAATCACCTCCTGCCACAAGCCTGGCCTGGTCCCAGGAGAGTGTCCAGGCTCAGA
+#   TCTGTTCATAAACCACCTGCCATGACAAGCCTGGCCTGTTCCCAAGACAATGTCCAGGCTCAGA
+# start and stop are origin-1, inclusive
+# first species is always on plus strand
+# when second species is on minus strand, start and stop are counted from sequence end
+
+def read_next_axt( file, species1, species2, species_to_lengths=None, support_ids=False ):
+    line = readline( file, skip_blank=True )
+    if not line: return
+    fields = line.split()
+    if (len(fields) < 9) or ((not support_ids) and (len(fields) > 9)):
+        raise ValueError("bad axt-block header: %s" % line)
+    attributes = {}
+    if (len(fields) > 9):
+        attributes["id"] = "_".join(fields[9:])
+    seq1 = readline( file )
+    if not line or line.isspace(): raise ValueError("incomplete axt-block; header: %s" % line)
+    seq2 = readline( file )
+    if not line or line.isspace(): raise ValueError("incomplete axt-block; header: %s" % line)
+    # Build 2 component alignment
+    alignment = Alignment(attributes=attributes,species_to_lengths=species_to_lengths)
+    # Build component for species 1
+    component = Component()
+    component.src = fields[1]
+    if (species1 != ""): component.src = species1 + "." + component.src
+    component.start = int( fields[2] ) - 1    # (axt intervals are origin-1
+    end = int( fields[3] )                    #  and inclusive on both ends)
+    component.size = end - component.start
+    component.strand = "+"
+    component.text = seq1.strip()
+    alignment.add_component( component )
+    # Build component for species 2
+    component = Component()
+    component.src = fields[4]
+    if (species2 != ""): component.src = species2 + "." + component.src
+    component.start = int( fields[5] ) - 1
+    end = int( fields[6] )
+    component.size = end - component.start
+    component.strand = fields[7]
+    component.text = seq2.strip()
+    alignment.add_component( component )
+    # add score
+    try:
+        alignment.score = int( fields[8] )
+    except:
+        try:
+            alignment.score = float( fields[8] )
+        except:
+            alignment.score = fields[8]
+    return alignment
+
+def readline( file, skip_blank=False ):
+    """Read a line from provided file, skipping any blank or comment lines"""
+    while 1:
+        line = file.readline()
+        if not line: return None
+        if line[0] != '#' and not ( skip_blank and line.isspace() ):
+            return line
+
diff --git a/lib/bx/align/core.py b/lib/bx/align/core.py
new file mode 100644
index 0000000..3e37868
--- /dev/null
+++ b/lib/bx/align/core.py
@@ -0,0 +1,426 @@
+"""
+Classes that represent alignments between multiple sequences.
+"""
+
+import random
+import string
+import weakref
+from bx.misc.readlengths import read_lengths_file
+
+# DNA reverse complement table
+## DNA_COMP = "                                             -                  " \
+##            " TVGH  CD  M KN   YSA BWXR       tvgh  cd  m kn   ysa bwxr      " \
+##            "                                                                " \
+##            "                                                                "
+
+DNA_COMP = string.maketrans( "ACGTacgt", "TGCAtgca" )
+
+class Alignment( object ):
+
+    def __init__( self, score=0, attributes={}, species_to_lengths=None ):
+        # species_to_lengths is needed only for file formats that don't provide
+        # chromosome lengths;  it maps each species name to one of these:
+        #   - the name of a file that contains a list of chromosome length pairs
+        #   - a dict mapping chromosome names to their length
+        #   - a single length value (useful when we just have one sequence and no chromosomes)
+        # internally a file name is replaced by a dict, but only on an "as
+        # needed" basis
+        self.score = score
+        self.text_size = 0
+        self.attributes = attributes
+        if species_to_lengths == None: self.species_to_lengths = {}
+        else: self.species_to_lengths = species_to_lengths
+        self.components = []
+
+    def add_component( self, component ):
+        component._alignment = weakref.ref( self )
+        self.components.append( component )
+        if component.text is not None:
+            if self.text_size == 0:
+                self.text_size = len( component.text )
+            elif self.text_size != len( component.text ):
+                raise Exception( "Components must have same text length" )
+
+    def get_score( self ):
+        return self.__score
+    def set_score( self,score ):
+        if type( score ) == str:
+            try:
+                score = int(score)
+            except:
+                try:
+                    score = float(score)
+                except:
+                    pass
+        self.__score = score
+    score = property( fget=get_score,fset=set_score )
+
+    def __str__( self ):
+        s = "a score=" + str( self.score )
+        for key in self.attributes:
+            s += " %s=%s" % ( key, self.attributes[key] )
+        s += "\n"
+        # Components
+        for c in self.components:
+            s += str( c )
+            s += "\n"
+        return s
+
+    def src_size( self, src ):
+        species,chrom = src_split( src )
+        if species in self.species_to_lengths:
+            chrom_to_length = self.species_to_lengths[species]
+        elif chrom in self.species_to_lengths:
+            chrom_to_length = self.species_to_lengths
+        else:
+            raise ValueError("no src_size (no length file for %s)" % species)
+        if type( chrom_to_length ) == int:         # (if it's a single length)
+            return chrom_to_length
+        if type( chrom_to_length ) == type( "" ):  # (if it's a file name)
+            chrom_to_length = read_lengths_file( chrom_to_length )
+            self.species_to_lengths[species] = chrom_to_length
+        if chrom not in chrom_to_length: raise ValueError("no src_size (%s has no length for %s)" % ( species, chrom ))
+        return chrom_to_length[chrom]
+
+    def get_component_by_src( self, src ):
+        for c in self.components:
+            if c.src == src: return c
+        return None
+
+    def get_components_by_src( self, src ):
+        for c in self.components:
+            if c.src == src: yield c
+
+    def get_component_by_src_start( self, src ):
+        for c in self.components:
+            if c.src.startswith( src ): return c
+        return None
+
+    def slice( self, start, end ):
+        new = Alignment( score=self.score, attributes=self.attributes )
+        for component in self.components:
+            # FIXME: Is this the right solution?
+            if component.empty:
+                continue
+            new.components.append( component.slice( start, end ) )
+        new.text_size = end - start
+        return new
+
+    def reverse_complement( self ):
+        new = Alignment( score=self.score, attributes=self.attributes )
+        for component in self.components:
+            new.components.append( component.reverse_complement() )
+        new.text_size = self.text_size
+        return new
+
+    def slice_by_component( self, component_index, start, end ):
+        """
+        Return a slice of the alignment, corresponding to an coordinate interval in a specific component.
+
+        component_index is one of
+            an integer offset into the components list
+            a string indicating the src of the desired component
+            a component
+
+        start and end are relative to the + strand, regardless of the component's strand.
+
+        """
+        if type( component_index ) == type( 0 ):
+            ref = self.components[ component_index ]
+        elif type( component_index ) == type( "" ):
+            ref = self.get_component_by_src( component_index )
+        elif type( component_index ) == Component:
+            ref = component_index
+        else:
+            raise ValueError( "can't figure out what to do" )
+        start_col = ref.coord_to_col( start )
+        end_col = ref.coord_to_col( end )
+        if (ref.strand == '-'):
+            (start_col,end_col) = (end_col,start_col)
+        return self.slice( start_col, end_col )
+
+    def column_iter( self ):
+        for i in range( self.text_size ):
+            yield [ c.text[i] for c in self.components ]
+
+    def limit_to_species( self, species ):
+        new = Alignment( score=self.score, attributes=self.attributes )
+        new.text_size = self.text_size
+        for component in self.components:
+            if component.src.split('.')[0] in species:
+                new.add_component( component )
+        return new
+
+    def remove_all_gap_columns( self ):
+        """
+        Remove any columns containing only gaps from alignment components,
+        text of components is modified IN PLACE.
+        """
+        seqs = []
+        for c in self.components:
+            try:
+                seqs.append( list( c.text ) )
+            except TypeError:
+                seqs.append( None )
+        i = 0
+        text_size = self.text_size
+        while i < text_size:
+            all_gap = True
+            for seq in seqs:
+                if seq is None: continue
+                if seq[i] != '-': all_gap = False
+            if all_gap:
+                for seq in seqs:
+                    if seq is None: continue
+                    del seq[i]
+                text_size -= 1
+            else:
+                i += 1
+        for i in range( len( self.components ) ):
+            if seqs[i] is None: continue
+            self.components[i].text = ''.join( seqs[i] )
+        self.text_size = text_size
+
+    def __eq__( self, other ):
+        if other is None or type( other ) != type( self ):
+            return False
+        if self.score != other.score:
+            return False
+        if self.attributes != other.attributes:
+            return False
+        if len( self.components ) != len( other.components ):
+            return False
+        for c1, c2 in zip( self.components, other.components ):
+            if c1 != c2:
+                return False
+        return True
+
+    def __ne__( self, other ):
+        return not( self.__eq__( other ) )
+
+    def __deepcopy__( self, memo ):
+        from copy import deepcopy
+        new = Alignment( score=self.score, attributes=deepcopy( self.attributes ), species_to_lengths=deepcopy( self.species_to_lengths ) )
+        for component in self.components:
+            new.add_component( deepcopy( component ) )
+        return new
+
+class Component( object ):
+
+    def __init__( self, src='', start=0, size=0, strand=None, src_size=None, text='' ):
+        self._alignment = None
+        self.src = src
+        self.start = start          # Nota Bene:  start,size,strand are as they
+        self.size = size            # .. appear in a MAF file-- origin-zero, end
+        self.strand = strand        # .. excluded, and minus strand counts from
+        self._src_size = src_size   # .. end of sequence
+        self.text = text
+        self.quality = None
+        # Optional fields to keep track of synteny status (only makes sense
+        # when the alignment is part of an ordered set)
+        self.synteny_left = None
+        self.synteny_right = None
+        self.synteny_empty = None
+        # If true, this component actually represents a non-aligning region,
+        # and has no text.
+        self.empty = False
+        # Index maps a coordinate (distance along + strand from + start) to alignment column
+        self.index = None
+
+    def __str__( self ):
+        if self.empty:
+            rval = "e %s %d %d %s %d %s" % ( self.src, self.start,
+                                             self.size, self.strand,
+                                             self.src_size, self.synteny_empty )
+        else:
+            rval = "s %s %d %d %s %d %s" % ( self.src, self.start,
+                                             self.size, self.strand,
+                                             self.src_size, self.text )
+            if self.synteny_left and self.synteny_right:
+                rval += "\ni %s %s %d %s %d" % ( self.src,
+                                                 self.synteny_left[0], self.synteny_left[1],
+                                                 self.synteny_right[0], self.synteny_right[1] )
+        return rval
+
+    def get_end( self ):
+        return self.start + self.size
+    end = property( fget=get_end )
+
+    def get_src_size( self ):
+        if self._src_size == None:
+            if self._alignment == None:
+                raise Exception("component has no src_size")
+            self._src_size = self._alignment().src_size( self.src )
+        return self._src_size
+    def set_src_size( self,src_size ):
+        self._src_size = src_size
+    src_size = property( fget=get_src_size, fset=set_src_size )
+
+    def get_forward_strand_start( self ):
+        if self.strand == '-': return self.src_size - self.end
+        else: return self.start
+    forward_strand_start = property( fget=get_forward_strand_start )
+
+    def get_forward_strand_end( self ):
+        if self.strand == '-': return self.src_size - self.start
+        else: return self.end
+    forward_strand_end = property( fget=get_forward_strand_end)
+
+    def reverse_complement( self ):
+        start = self.src_size - self.end
+        if self.strand == "+": strand = "-"
+        else: strand = "+"
+        comp = [ch for ch in self.text.translate(DNA_COMP)]
+        comp.reverse()
+        text = "".join(comp)
+        new = Component( self.src, start, self.size, strand, self._src_size, text )
+        new._alignment = self._alignment
+        return new
+
+    def slice( self, start, end ):
+        new = Component( src=self.src, start=self.start, strand=self.strand, src_size=self._src_size )
+        new._alignment = self._alignment
+        new.text = self.text[start:end]
+
+        #for i in range( 0, start ):
+        #    if self.text[i] != '-': new.start += 1
+        #for c in new.text:
+        #    if c != '-': new.size += 1
+        new.start += start - self.text.count( '-', 0, start )
+        new.size = len( new.text ) - new.text.count( '-' )
+
+        # FIXME: This annotation probably means nothing after slicing if
+        # one of the ends changes. In general the 'i' rows of a MAF only
+        # make sense in context (relative to the previous and next alignments
+        # in a stream, slicing breaks that).
+        new.synteny_left = self.synteny_left
+        new.synteny_right = self.synteny_right
+
+        return new
+
+    def slice_by_coord( self, start, end ):
+        """
+        Return the slice of the component corresponding to a coordinate interval.
+
+        start and end are relative to the + strand, regardless of the component's strand.
+
+        """
+        start_col = self.coord_to_col( start )
+        end_col = self.coord_to_col( end )
+        if (self.strand == '-'):
+            (start_col,end_col) = (end_col,start_col)
+        return self.slice( start_col, end_col )
+
+    def coord_to_col( self, pos ):
+        """
+        Return the alignment column index corresponding to coordinate pos.
+
+        pos is relative to the + strand, regardless of the component's strand.
+
+        """
+        start,end = self.get_forward_strand_start(),self.get_forward_strand_end()
+        if pos < start or pos > end:
+            raise ValueError("Range error: %d not in %d-%d" % ( pos, start, end ))
+        if not self.index:
+            self.index = list()
+            if (self.strand == '-'):
+                # nota bene: for - strand self.index[x] maps to one column
+                # higher than is actually associated with the position;  thus
+                # when slice_by_component() and slice_by_coord() flip the ends,
+                # the resulting slice is correct
+                for x in range( len(self.text)-1,-1,-1 ):
+                    if not self.text[x] == '-':
+                        self.index.append( x + 1 )
+                self.index.append( 0 )
+            else:
+                for x in range( len(self.text) ):
+                    if not self.text[x] == '-':
+                        self.index.append(x)
+                self.index.append( len(self.text) )
+        x = None
+        try:
+            x = self.index[ pos - start ]
+        except:
+            raise Exception("Error in index.")
+        return x
+
+
+    def __eq__( self, other ):
+        if other is None or type( other ) != type( self ):
+            return False
+        return ( self.src == other.src
+                 and self.start == other.start
+                 and self.size == other.size
+                 and self.strand == other.strand
+                 and self._src_size == other._src_size
+                 and self.text == other.text
+                 and self.synteny_left == other.synteny_left
+                 and self.synteny_right == other.synteny_right
+                 and self.synteny_empty == other.synteny_empty
+                 and self.empty == other.empty )
+
+    def __ne__( self, other ):
+        return not( self.__eq__( other ) )
+
+    def __deepcopy__( self, memo ):
+        new = Component( src=self.src, start=self.start, size=self.size, strand=self.strand, src_size=self._src_size, text=self.text )
+        new._alignment = self._alignment
+        new.quality = self.quality
+        new.synteny_left = self.synteny_left
+        new.synteny_right = self.synteny_right
+        new.synteny_empty = self.synteny_empty
+        new.empty = self.empty
+        new.index = self.index
+        return new
+
+def get_reader( format, infile, species_to_lengths=None ):
+    import bx.align.maf, bx.align.axt, bx.align.lav
+    if format == "maf": return bx.align.maf.Reader( infile, species_to_lengths )
+    elif format == "axt": return bx.align.axt.Reader( infile, species_to_lengths )
+    elif format == "lav": return bx.align.lav.Reader( infile )
+    else: raise ValueError("Unknown alignment format %s" % format)
+
+def get_writer( format, outfile, attributes={} ):
+    import bx.align.maf, bx.align.axt, bx.align.lav
+    if format == "maf": return bx.align.maf.Writer( outfile, attributes )
+    elif format == "axt": return bx.align.axt.Writer( outfile, attributes )
+    elif format == "lav": return bx.align.lav.Writer( outfile, attributes )
+    else: raise ValueError("Unknown alignment format %s" % format)
+
+def get_indexed( format, filename, index_filename=None, keep_open=False, species_to_lengths=None ):
+    import bx.align.maf, bx.align.axt, bx.align.lav
+    if format == "maf": return bx.align.maf.Indexed( filename, index_filename, keep_open, species_to_lengths )
+    elif format == "axt": return bx.align.axt.Indexed( filename, index_filename, keep_open, species_to_lengths )
+    elif format == "lav": raise Exception("LAV support for Indexed has not been implemented")
+    else: raise ValueError("Unknown alignment format %s" % format)
+
+def shuffle_columns( a ):
+    """Randomize the columns of an alignment"""
+    mask = range( a.text_size )
+    random.shuffle( mask )
+    for c in a.components:
+        c.text = ''.join( [ c.text[i] for i in mask ] )
+
+def src_split( src ): # splits src into species,chrom
+    dot = src.rfind( "." )
+    if dot == -1: return None,src
+    else:         return src[:dot],src[dot+1:]
+
+def src_merge( species,chrom,contig=None ): # creates src (inverse of src_split)
+    if species == None: src = chrom
+    else:               src = species + "." + chrom
+    if contig != None: src += "[%s]" % contig
+    return src
+
+# ---- Read C extension if available ---------------------------------------
+
+try:
+    from _core import coord_to_col
+except:
+    def coord_to_col( start, text, pos ):
+        col = 0
+        while start < pos:
+            if text[col] != '-':
+                start += 1
+            col += 1
+        return col
diff --git a/lib/bx/align/epo.py b/lib/bx/align/epo.py
new file mode 100644
index 0000000..166e920
--- /dev/null
+++ b/lib/bx/align/epo.py
@@ -0,0 +1,278 @@
+
+"""Classes and utilities for mutliple alignments from the EPO pipeline"""
+
+from __future__ import with_statement
+
+import logging, re, cPickle, os
+from collections import namedtuple
+from itertools import imap
+
+from _epo import rem_dash, fastLoadChain, bed_union, cummulative_intervals
+
+
+log = logging.getLogger(__name__)
+
+class Chain( namedtuple('Chain', 'score tName tSize tStrand tStart tEnd qName qSize qStrand qStart qEnd id') ):
+    """A Chain header as in http://genome.ucsc.edu/goldenPath/help/chain.html
+
+    chain coordinates are with respect to the strand, so for example tStart on the + strand is the
+    distance from the leftmost position; tStart on the - strand is the distance from the rightmost position."""
+
+    __slots__ = ()
+
+    def __str__(self):
+        return "chain {score} {tName} {tSize} {tStrand} {tStart} {tEnd} {qName} {qSize} {qStrand} {qStart} {qEnd} {id}".format(**self._asdict())
+
+    @classmethod
+    def _strfactory(cls, line):
+        """factory class method for Chain
+
+        :param line: header of a chain (in .chain format)
+        """
+
+        assert type(line) == str, "this is a factory from string"
+
+        line = line.rstrip().split()[1:] # the first component is the keyword "chain"
+        tup = map(lambda t: t[0](t[1]),
+                zip([int, str, int, str, int, int, str, int, str, int, int, str], line))
+        return tuple.__new__(cls, tup)
+
+    @classmethod
+    def _make_from_epo(cls, trg_comp, qr_comp, trg_chrom_sizes, qr_chrom_sizes):
+        """crate a chain of collinear rings from the given  components.
+
+        The target of the chain will always be on the forward strand.
+        This is done to avoid confusion when mapping psl files. So,
+        if trg_comp.strand=-, qr_comp.strand=- (resp. +) the
+        chain header will have tStrand=+, qStrand=+ (resp. -). No strand
+        changes on the other cases.
+
+        :param trg_comp: target (i.e, the first) component
+        :type trg_comp: L{EPOitem}
+        :param qr_comp: query (i.e, the second) component
+        :type qr_comp: L{EPOitem}
+        :param trg_chrom_sizes: chromosome sizes of the target
+        :type trg_chrom_sizes: dictionary of the type (chrom) --> size
+        :param qr_chrom_sizes: chromosome sizes of the query
+        :type qr_chrom_sizes: dictionary of the type (chrom) --> size
+        :return: A L{Chain} instance"""
+
+        # size, target, query arrays
+        S, T, Q = [], [], []
+
+        #the target strand of the chain must be on the forward strand
+        trg_intervals = trg_comp.intervals(reverse = trg_comp.strand == '-')
+        qr_intervals = qr_comp.intervals(reverse = trg_comp.strand == '-')
+        if len(trg_intervals) == 0 or len(qr_intervals) == 0:
+            log.warning("deletion/insertion only intervals")
+            return None
+        A, B = rem_dash(trg_intervals, qr_intervals)
+        # correct for when cigar starts/ends with dashes (in number of bases)
+        tr_start_correction = max(B[0][0] - A[0][0], 0)
+        tr_end_correction = max(A[-1][1] - B[-1][1], 0)
+        qr_start_correction = max(A[0][0] - B[0][0], 0)
+        qr_end_correction = max(B[-1][1] - A[-1][1], 0)
+
+        a, b = A.pop(0), B.pop(0)
+
+        # intervals are 0-base, halfo-open => lengths = coordinate difference
+        while A or B:
+            if a[1] < b[1]:
+                T.append(0); Q.append( A[0][0] - a[1] ); S.append( min(a[1], b[1]) - max(a[0], b[0]) )
+                a = A.pop(0)
+            elif b[1] < a[1]:
+                Q.append(0); T.append( B[0][0] - b[1] ); S.append( min(a[1], b[1]) - max(a[0], b[0]) )
+                b = B.pop(0)
+            elif A and B:
+                assert 1 > 2, "there are dash columns"
+            else:
+                break
+        S.append( min(a[1], b[1]) - max(a[0], b[0]) )
+        assert len(T) == len(Q) == len(S) - 1, "(S, T, Q) = (%d, %d, %d)" % tuple(map(len, (S, T, Q)))
+
+        tSize = trg_chrom_sizes[trg_comp.chrom]
+        qSize = qr_chrom_sizes[qr_comp.chrom]
+        ## UCSC coordinates are 0-based, half-open and e! coordinates are 1-base, closed
+        ## chain_start = epo_start - 1 and chain_end = epo_end
+        if qr_comp.strand == '+':
+            chain = Chain(0,
+                    trg_comp.chrom, tSize, "+",
+                    (trg_comp.start - 1) + tr_start_correction, trg_comp.end  - tr_end_correction,
+                    qr_comp.chrom, qSize, (qr_comp.strand == trg_comp.strand and '+' or '-'),
+                    (qr_comp.start - 1) + qr_start_correction, qr_comp.end  - qr_end_correction,
+                    qr_comp.gabid)
+        else:
+            chain = Chain(0,
+                    trg_comp.chrom, tSize, "+",
+                    (trg_comp.start - 1) + tr_start_correction, trg_comp.end - tr_end_correction,
+                    qr_comp.chrom, qSize, (qr_comp.strand == trg_comp.strand and '+' or '-'),
+                    (qr_comp.start - 1) + qr_end_correction, qr_comp.end - qr_start_correction,
+                    qr_comp.gabid)
+
+        # strand correction. in UCSC coordinates this is: size - coord
+        if chain.qStrand == '-':
+            chain = chain._replace(qEnd = chain.qSize - chain.qStart,
+                    qStart = chain.qSize - chain.qEnd)
+
+        assert chain.tEnd - chain.tStart  == sum(S) + sum(T), "[%s] %d != %d" % (str(chain),
+                chain.tEnd - chain.tStart, sum(S) + sum(T))
+        assert chain.qEnd - chain.qStart == sum(S) + sum(Q), "[%s] %d != %d" % (str(chain),
+                chain.qEnd - chain.qStart, sum(S) + sum(Q))
+        return chain, S, T, Q
+
+    def slice(self, who):
+        "return the slice entry (in a bed6 format), AS IS in the chain header"
+
+        assert who in ('t', 'q'), "who should be 't' or 'q'"
+
+        if who == 't':
+            return (self.tName, self.tStart, self.tEnd, self.id, self.score, self.tStrand)
+        else:
+            return (self.qName, self.qStart, self.qEnd, self.id, self.score, self.qStrand)
+
+    def bedInterval(self, who):
+        "return a BED6 entry, thus DOES coordinate conversion for minus strands"
+
+        if who == 't':
+            st, en = self.tStart, self.tEnd
+            if self.tStrand == '-':
+                st, en = self.tSize-en, self.tSize-st
+            return (self.tName, st, en, self.id, self.score, self.tStrand)
+        else:
+            st, en = self.qStart, self.qEnd
+            if self.qStrand == '-':
+                st, en = self.qSize-en, self.qSize-st
+                assert en-st == self.qEnd - self.qStart
+            return (self.qName, st, en, self.id, self.score, self.qStrand)
+
+    @classmethod
+    def _parse_file(cls, path, pickle=False):
+        """parse a .chain file into a list of the type [(L{Chain}, arr, arr, arr) ...]
+
+        :param fname: name of the file"""
+
+        fname = path
+        if fname.endswith(".gz"):
+            fname = path[:-3]
+
+        if fname.endswith('.pkl'):
+            #you asked for the pickled file. I'll give it to you
+            log.debug("loading pickled file %s ..." % fname)
+            return cPickle.load( open(fname) )
+        elif os.path.isfile("%s.pkl" % fname):
+            #there is a cached version I can give to you
+            log.info("loading pickled file %s.pkl ..." % fname)
+            if os.stat(path).st_mtime > os.stat("%s.pkl" % fname).st_mtime:
+                log.critical("*** pickled file %s.pkl is not up to date ***" % (path))
+            return cPickle.load( open("%s.pkl" % fname) )
+
+        data = fastLoadChain(path, cls._strfactory)
+        if pickle and not os.path.isfile('%s.pkl' % fname):
+            log.info("pckling to %s.pkl" % (fname))
+            with open('%s.pkl' % fname, 'wb') as fd:
+                cPickle.dump(data, fd)
+        return data
+
+class EPOitem(namedtuple('Epo_item', 'species gabid chrom start end strand cigar')):
+    "this format is how alignments are delivered from e!"
+
+    __slots__ = ()
+
+    cigar_pattern = re.compile("(\d*)([MD])")
+
+    def __repr__(self): return str(self)
+
+    def __str__(self):
+        c = self.cigar[:5] + "..." + self.cigar[-5:]
+        return "(%s %s %s %d %d %s %s)" % tuple(self[:6] + (c,))
+
+    @classmethod
+    def _strfactory(cls, line):
+        """factory method for an EPOitem
+
+        :param line: a line of input"""
+
+        cmp = line.rstrip().split()
+        chrom = cmp[2]
+        if not chrom.startswith("chr"):
+            chrom = "chr%s" % chrom
+        instance =  tuple.__new__(cls,
+                (cmp[0], cmp[1],
+                    chrom, int(cmp[3]), int(cmp[4]),
+                    {'1' : '+', '-1' : '-'}[cmp[5]], cmp[6]))
+        span = instance.end - instance.start + 1
+        m_num = sum( map(lambda t: (t[1] == "M" and [t[0]] or [0])[0] , instance.cigar_iter(False)) )
+        if span != m_num:
+            log.warning("[{gabid}] {species}.{chrom}:{start}-{end}.".format(**instance._asdict()) + "(span) %d != %d (matches)" % (span, m_num))
+            return None
+        return instance
+
+    @classmethod
+    def _parse_epo(cls, fname):
+        """Load an entire file in the EPO format into a dictionary of the type {gab_id => [Epoitem, ...]}
+
+        :param fname: file name"""
+
+        data = {}
+        with open(fname) as fd:
+            for el in imap(cls._strfactory, fd):
+                if el:
+                    data.setdefault(el.gabid, []).append( el )
+        log.info("parsed %d elements from %s" % (len(data), fname))
+        return data
+
+    def cigar_iter(self, reverse):
+        """self.cigar => [(length, type) ... ] iterate the cigar
+
+        :param reverse: whether to iterate in the reverse direction (right-to-left)
+        :type reverse: boolean
+
+        :return a list of pairs of the type [(length, M/D) ..]
+        """
+
+        l = 0
+        P = self.cigar_pattern
+
+        data = []
+        cigar = self.cigar
+        parsed_cigar = re.findall(P, cigar)
+        if reverse:
+            parsed_cigar = parsed_cigar[::-1]
+        for _l, t in parsed_cigar:
+            # 1M is encoded as M
+            l = (_l and int(_l) or 1) # int(_l) cannot be 0
+            data.append( (l, t) )
+        return data
+
+    def intervals(self, reverse, thr=0):
+        """return a list of (0-based half-open) intervals representing the match regions of the cigar
+
+        for example 4MD4M2DM with reverse=False will produce [(0,4), (5,9), (11,12)]
+        4MD4M2DM with reverse=True will produce [(0,1), (3,7), (8,12)] (= 12 - previous interval)
+
+        :param reverse: whether to iterate in the reverse direction (right-to-left) (this is passed as is to self.cigar_iter)
+        :type reverse: boolean
+        :param thr: shift all intervals by this much
+        :type thr: integer
+
+        :return: list of pairs"""
+
+        d = [(thr,thr)]
+        dl = 0
+        for tup in self.cigar_iter(reverse):
+            if tup[1] == "D":
+                dl = tup[0]
+            else:
+                s = d[-1][1] + dl
+                d.append( (s, s+tup[0]) )
+
+        assert d[0] == (thr, thr)
+        # assert that nr. of Ms in the interval == sum of produced intervals
+        assert sum( map(lambda t: t[0], filter(lambda t: t[1] == "M", self.cigar_iter(False))) ) == sum( map(lambda t: t[1]-t[0], d) )
+
+        d_sum = sum( map(lambda t: t[1]-t[0], d) )
+        assert self.end - self.start + 1 == d_sum, "[ (%d, %d) = %d ] != %d" % (self.start, self.end,
+                self.end-self.start+1, d_sum)
+        return d[1:] #clip the (thr, thr) entry
+
+
diff --git a/lib/bx/align/epo_tests.py b/lib/bx/align/epo_tests.py
new file mode 100644
index 0000000..c066aba
--- /dev/null
+++ b/lib/bx/align/epo_tests.py
@@ -0,0 +1,234 @@
+"tests for bx.align.epo"
+
+import unittest, logging, pdb
+import random
+import numpy as np
+
+from bx.align._epo import cummulative_intervals, bed_union
+from bx.align.epo import *
+
+class TestBed( unittest.TestCase ):
+    def setUp(self):
+        self.N = random.randint(1, 1000)
+
+    def test_ci(self):
+        S, D = [], []
+        for i in range(self.N):
+            S.append( random.randint(10, 50) )
+            D.append( random.randint(10, 50) )
+        D[-1] = 0
+        C = cummulative_intervals(np.array(S, dtype=np.int64),
+                np.array(D, dtype=np.int64))
+        for i in range(self.N):
+            assert C[i,1] - C[i,0] == S[i]
+        for i in range(1, self.N):
+            assert C[i,0] - C[i-1,1] == D[i-1], "[%d] %d != %d" % (i, C[i,0] - C[i-1,1], D[i-1])
+
+    def test_elem_u(self):
+        # back to back, so should return a single interval
+        EL = []
+        th = 0
+        for i in range(self.N):
+            size = random.randint(1, 20)
+            EL.append( (th, th+size) )
+            th += size
+        U = bed_union( np.array(EL, dtype=np.uint64) )
+        assert U[0,0] == 0 and U[0,1] == th
+
+        # disjoint
+        EL = []
+        th = 0
+        for i in range(self.N):
+            size = random.randint(1, 20)
+            EL.append( (th, th+size) )
+            th += (size + 1)
+        U = bed_union( np.array(EL, dtype=np.uint64) )
+        for i in range(U.shape[0]):
+            assert (U[i,0], U[i,1]) == EL[i]
+
+        # random with some empty elements
+        EL = []
+        th = 0
+        for i in range(self.N):
+            size = random.randint(1, 20)
+            EL.append( (th, th+size) )
+            th += random.randint(1, size+size) #50% of overlapping
+        U = bed_union( np.array(EL, dtype=np.uint64) )
+
+        assert U[0,1] > U[0,0]
+        for i in range(1, U.shape[0]):
+            assert U[i,1] > U[i,0]
+            assert U[i,0] > U[i-1,1]
+
+cigar_pairs = [
+("GGACCTGGAGAGATCAG---------------------------GACTTCAACTGTGTG-------------TCTTAGACTGGG--------AGGGTGTTA",
+ "AGGCCAGGAGAGATCAGGTAAGTCTTAATTTAATAAAGAGATAGGACCTGAACTGTGTCTAACAATAGGTAATATTAGACTGGGGGAGAGAGAAGACTTTC"),
+
+("TTT--------------------------------------------------------------------------------------------------------------------T",
+ "CTTGTACCAAGGACAGTACTGGCAGCCTAATTGCTAACACTTTGTGGTGGATTGGTCCACTCAATATTTGTTCCCACCTCTTTTCAGTCCAGTTCTATAAAGGACAGAAAGTTGAAAACT"),
+
+("A-------------------------------------------------ACACTGGACACAGCACTAACACGATTACTTA",
+ "ACATTTCCCACACTCCCTTGCAGCTAGGTTTCTAGATATAATTTAGATTCCA----------------------------A"),
+
+("TTTGGTCCTCTGGA------CGAGCAGCCAGTGCT---------------------------------------------------------------------------AAAAAAAA",
+ "T---CATTCTAGCAGGTGCTGCAGCAGCAGGTAGCCCTGGAGCCAACAGTTGTGGCTATGATTCTTGATCATCAGATTTGGCTCAAGTGATGTGTTCCTCTAGCATGCACTTGAGATA"),
+
+("G-----------------------C----------------------------------------------------------------------------------------A",
+ "GGCCTGCACTGCCAGTAATTTTAACAAATTTTTAGGCACTGAATTCCCTGTATTAAATCTGTTTTCCTTAGCGTAAACAGATCTCTGTTAAATGAAACTAAACCCTGACTGATA"),
+
+("TATT----------------------------------T",
+ "TCCTTCATTTTATTTCTCCCTTAAAATTTTTTTTATTACT"),
+
+("TAAAAA--A------A------------------------------------------------------------TTTTTTTTTTT",
+ "T---AATTATTTTGCAGCAGGTCCTTGATAACATATCATCTATAAATATTTCAGCAAGAATCTCTAAAAGGCAAGAACCTCCTTCTT"),
+
+("AAACAA---------------------------------------TT---T",
+ "AAACAATACCACTGCATCACTATCAAACCCAAAAAATAACAAAAATTGGGT"),
+
+("TCTTAAC---TGCTGAGCCATCCCTCCAGCTCCTGTTTTATTTTTATTATGAAGTAATAATA--ATAG--TAATAATAATGATG",
+ "TACACTTAATTCTAAAACTTGTTATGAATCATCA----------TTGG--TTTTTTATTGTGAAGAACTAATATAATCAGA--G"),
+
+("ATGATAATGGTATCCTAGCTCAACACCTG-GAGTTCACCCCAACAGTTAACTAA----GTTTGAGGAAGTGTTAACAAGCCTA---ACAAAGAGGACATGCCAATAGCTGACAGAGTCAC",
+ "A-------CCTCTGCTAGCTCAACTCCTGAGAATCAATTATATAAGCTAGGTCAGTGGTTTTGAGAAAGTATTAGTAGACATTTCTCCAAAGAATACATAAAAATGGCC-A--CAAGTAT")
+]
+
+def toCigar(species, id, s):
+    I = [(0,0)]
+    L = map(len, s.split("-"))
+    NZ = filter(lambda _: _, L)
+
+    if L[0] > 0:
+        I.append( (0, L[0]) )
+        NZ = NZ[1:]
+        L = L[1:]
+
+    for i in range(len(NZ)):
+        L.insert(0, 0)
+        size = NZ[i]
+        start = L.index(size)
+        I.append( (I[-1][1] + start, I[-1][1]+start+size) )
+        L = L[start+1:]
+    if len(L):
+        I.append((I[-1][1] + len(L), I[-1][1] + len(L)))
+    #print I[1:]
+    C = []
+    for i in range(1,len(I)):
+        dl = I[i][0] - I[i-1][1]
+        ml = I[i][1] - I[i][0]
+
+        dc = ""
+        if dl:
+            dc = (dl > 1 and str(dl) or "") + "D"
+
+        mc = ""
+        if ml:
+            mc = (ml > 1 and str(ml) or "") + "M"
+
+        C.append( dc+mc )
+    MSUM = sum(map(lambda i: i[1]-i[0], I))
+    start = random.randint(50, 10000)
+    return "%s\t%d\t1\t%d\t%d\t%d\t%s" % (species, id, start, start+MSUM-1,
+            random.choice((-1,1)), "".join(C))
+
+
+
+class TestEpo( unittest.TestCase ):
+    def setUp(self):
+        self.epo_records = []
+        for i, (t,q) in enumerate(cigar_pairs):
+            gab_pair = (toCigar("homo_sapiens", i, t), toCigar("mus_musculus", i, q))
+            A = EPOitem._strfactory(gab_pair[0])
+            B = EPOitem._strfactory(gab_pair[1])
+            if A and B:
+                self.epo_records.append( (A,B) )
+
+    def test_out(self):
+        def ch(c, ci):
+            th = 0
+            for l,t in ci:
+                if t == 'M':
+                    assert c[th:th+l].find('-') == -1
+                else:
+                    assert c[th:th+l] == '-' * l
+                th += l
+
+        for (a,b) in self.epo_records:
+            ca, cb = cigar_pairs[int(a.gabid)]
+            #if a.strand == '-': ca = ca[::-1]
+            #if b.strand == '-': cb = cb[::-1]
+            ch(ca, a.cigar_iter(False))
+            ch(cb, b.cigar_iter(False))
+
+    def test_make_chain(self):
+        def cch(cigar, s, e):
+            return cigar[s:e].find('-') == -1
+
+        for p in self.epo_records:
+            chain  = Chain._make_from_epo(p[0], p[1], {"chr1" : 500}, {"chr1" : 800})
+            if not chain:
+                continue
+            ch, S, T, Q = chain
+            i = int( ch.id )
+            c1, c2 = cigar_pairs[i]
+            if p[0].strand == '-':
+                c1 = c1[::-1]
+                c2 = c2[::-1]
+            th = 0
+            for s, t, q in zip(S, T, Q):
+                if not (cch(c1, th, th+s) and cch(c2, th, th+s)):
+                    pdb.set_trace()
+                assert cch(c1, th, th+s) and cch(c2, th, th+s), "%s and %s" % (c1[th:th+s], c2[th:th+s])
+                if t > q:
+                    cch(c1, th+s, th+s+t) and c1[th+s:th+s+t] == '-'*t
+                else:
+                    cch(c2, th+s, th+s+q) and c1[th+s:th+s+q] == '-'*q
+                th = th + s + max(t,q)
+
+    def test_rem_dash(self):
+        # ****--****-------****  4M2D4M7D4M
+        # *******-------*******  7M7D7M
+        # has 4 dash columns and should become
+        # ****--****---****      4M2D4M3D4M
+        # *******---*******      7M3D7M
+
+        for i in range(100):
+            dash_cols = random.randint(0, 10)
+            tStart = random.randint(0, 1000)
+            qStart = random.randint(0, 1000)
+            epo_pair = (EPOitem._strfactory("homo_sapiens\t0\t1\t%d\t%d\t1\t%s" % (tStart, tStart+12-1, "4M2D4M%dD4M" % (dash_cols+3))),
+                    EPOitem._strfactory("mus_musculus\t0\t1\t%d\t%d\t1\t%s" % (qStart, qStart+14-1, "7M%dD7M" % (dash_cols+3))))
+            chain = Chain._make_from_epo(epo_pair[0], epo_pair[1], {"chr1":500}, {"chr1":800})
+            ti = epo_pair[0].intervals(False)
+            qi = epo_pair[1].intervals(False)
+            assert ti[2][0] - ti[1][1] - dash_cols == chain[2][1]
+            assert qi[1][0] - qi[0][1] - dash_cols == chain[2][1]
+
+        # ----*****
+        # *-------*
+        # has 3 dash cols and should become
+        # *
+        # *
+        # with the qStart += 1 and tStart += 4
+
+        for i in range(100):
+            dash_cols = random.randint(0, 10)
+            tm = random.randint(6, 10)
+            qm = random.randint(1, 5)
+
+            tStart = random.randint(0, 1000)
+            qStart = random.randint(0, 1000)
+
+            epo_pair = (EPOitem._strfactory("homo_sapiens\t0\t1\t%d\t%d\t1\t%s" % (tStart, tStart+tm-1,
+                    "%dD%dM" % (dash_cols+1, tm))),
+                EPOitem._strfactory("mus_musculus\t0\t1\t%d\t%d\t1\t%s" % (qStart, qStart+qm+1-1,
+                    "M%dD%dM" % (dash_cols+tm-qm, qm))))
+            chain = Chain._make_from_epo(epo_pair[0], epo_pair[1], {"chr1":500}, {"chr1":800})
+            if chain[1][-1] != qm:
+                pdb.set_trace()
+            assert chain[1][-1] == qm
+            # correct also for coordinate interpretation differences between UCSC and EPO
+            assert (qStart + 1) - 1 == chain[0].qStart, "%d != %d" % (qStart + 1, chain[0].qStart)
+
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/lib/bx/align/lav.py b/lib/bx/align/lav.py
new file mode 100644
index 0000000..b225ef4
--- /dev/null
+++ b/lib/bx/align/lav.py
@@ -0,0 +1,571 @@
+"""
+Support for reading and writing the LAV format produced by the `blastz`_
+pairwise aligner.
+
+.. _blastz: http://www.bx.psu.edu/miller_lab/
+"""
+
+from bx.align import *
+import bx.seq
+
+import sys,math,StringIO
+import itertools
+from bx import interval_index_file
+
+class Reader(object):
+	"""Iterate over all lav blocks in a file in order"""
+
+	def __init__(self,file,path_subs=None,fail_to_ns=False):
+		self.file = file
+		self.lineNumber = 0
+		self.path_subs  = path_subs   # list of (prefix,replacement) to allow
+		if (self.path_subs == None):  # .. redirection of sequence file paths
+			self.path_subs = []       # .. on different machines
+		self.fail_to_ns = fail_to_ns  # True => if sequences fail to open,
+		                              #         create a fake file of all Ns
+
+		self.d_stanza_text = None
+
+		self.seq1_filename = None
+		self.seq1_file     = None
+		self.seq1_header   = None
+		self.seq1_start    = None
+		self.seq1_end      = None
+		self.seq1_strand   = None
+		self.seq1_contig   = None
+		self.seq1_src      = None
+		self.seq1_gap      = None
+
+		self.seq2_filename = None
+		self.seq2_file     = None
+		self.seq2_header   = None
+		self.seq2_start    = None
+		self.seq2_end      = None
+		self.seq2_strand   = None
+		self.seq2_contig   = None
+		self.seq2_src      = None
+		self.seq2_gap      = None
+
+	def next(self):
+		while (True):
+			line = self.fetch_line(strip=None,requireLine=False)
+			assert (line), "unexpected end of file (missing #:eof)"
+			line = line.rstrip()
+			if (line == ""):	# (allow blank lines between stanzas)
+				continue
+			if (line == "#:eof"):
+				line = self.file.readline().rstrip()
+				assert (not line), "extra line after #:eof (line %d, \"%s\")" \
+				                 % (self.lineNumber,line)
+				return None
+			if (line == "#:lav"):
+				continue
+			if (line.startswith("d {")):
+				self.d_stanza_text = self.parse_unknown_stanza()
+				continue
+			if (line.startswith("s {")):
+				self.parse_s_stanza()
+				continue
+			if (line.startswith("h {")):
+				self.parse_h_stanza()
+				continue
+			if (line.startswith("a {")):
+				(score,pieces) = self.parse_a_stanza()
+				break
+			if (line.endswith("{")):
+				self.parse_unknown_stanza()
+				continue
+			assert (False), "incomprehensible line (line %d, \"%s\")" \
+			              % (self.lineNumber,line)
+		return self.build_alignment(score,pieces)
+
+	def __iter__(self):
+		return ReaderIter(self)
+
+	def close(self):
+		self.file.close()
+
+	def open_seqs(self):
+		if (self.seq1_file != None) and (self.seq2_file != None):
+			return
+
+		if (self.seq1_file == None):
+			if (self.seq1_strand == "+"): revcomp = False
+			else:                         revcomp = "-5'"
+			if (self.seq1_contig == 1): contig = None
+			else:                       contig = self.seq1_contig
+			try:
+				f = file(self.seq1_filename,"rb")
+			except:
+				if (self.fail_to_ns):
+					f = StringIO.StringIO(">seq1\n" + ("n" * (self.seq1_end - self.seq1_start)))
+					revcomp = False
+					contig  = 1
+				else:
+					assert (False), "failed to open %s" % self.seq1_filename
+			self.seq1_file = bx.seq.seq_file(f,revcomp=revcomp,contig=contig)
+			self.seq1_gap  = self.seq1_file.gap
+			try:
+				name1 = self.header_to_src_name(self.seq1_header)
+			except ValueError:
+				try:
+					name1 = self.path_to_src_name(self.seq1_filename)
+				except ValueError:
+					name1 = "seq1"
+			(species1,chrom1) = src_split(name1)
+			self.seq1_src = src_merge(species1,chrom1,contig)
+			if (contig != None): chrom1 += "[%s]" % contig
+
+		if (self.seq2_file == None):
+			if (self.seq2_strand == "+"): revcomp = False
+			else:                         revcomp = "-5'"
+			if (self.seq2_contig == 1): contig = None
+			else:                       contig = self.seq2_contig
+			try:
+				f = file(self.seq2_filename,"rb")
+			except:
+				if (self.fail_to_ns):
+					f = StringIO.StringIO(">seq2\n" + ("n" * (self.seq2_end - self.seq2_start)))
+					revcomp = False
+					contig  = 1
+				else:
+					assert (False), "failed to open %s" % self.seq1_filename
+			self.seq2_file = bx.seq.seq_file(f,revcomp=revcomp,contig=contig)
+			self.seq2_gap  = self.seq2_file.gap
+			try:
+				name2 = self.header_to_src_name(self.seq2_header)
+			except ValueError:
+				try:
+					name2 = self.path_to_src_name(self.seq2_filename)
+				except ValueError:
+					name2 = "seq2"
+			(species2,chrom2) = src_split(name2)
+			self.seq2_src = src_merge(species2,chrom2,contig)
+			if (contig != None): chrom2 += "[%s]" % contig
+
+		length1 = self.seq1_file.length
+		length2 = self.seq2_file.length
+		assert (species1 != species2) or (chrom1 != chrom2) or (length1 == length2), \
+		       "conflicting lengths for %s (%d and %d)" % (self.seq1_src,length1,length2)
+
+		self.species_to_lengths = {}
+		self.species_to_lengths[species1] = {}
+		self.species_to_lengths[species2] = {}  # (OK if it clobbers line above)
+		self.species_to_lengths[species1][chrom1] = self.seq1_file.length
+		self.species_to_lengths[species2][chrom2] = self.seq2_file.length
+
+	def close_seqs(self):
+		if (self.seq1_file != None):
+			self.seq1_file.close()
+			self.seq1_file = None
+		if (self.seq2_file != None):
+			self.seq2_file.close()
+			self.seq2_file = None
+
+	def parse_s_stanza(self):
+		self.close_seqs()
+		line = self.fetch_line(report=" in s-stanza")
+		(self.seq1_filename,
+		 self.seq1_start,
+		 self.seq1_end,
+		 self.seq1_strand,
+		 self.seq1_contig) = self.parse_s_seq(line)
+
+		line = self.fetch_line(report=" in s-stanza")
+		(self.seq2_filename,
+		 self.seq2_start,
+		 self.seq2_end,
+		 self.seq2_strand,
+		 self.seq2_contig) = self.parse_s_seq(line)
+
+		line = self.fetch_line(report=" in s-stanza")
+		assert (line == "}"), "improper s-stanza terminator (line %d, \"%s\")" \
+							% (self.lineNumber,line)
+
+	def parse_s_seq(self,line):
+		fields = line.split()
+		filename = fields[0].strip('"')
+		start    = int(fields[1]) - 1
+		end      = int(fields[2])
+		contig   = int(fields[4])
+		if (fields[3] == "1"): strand = "-"
+		else:                  strand = "+"
+		if (filename.endswith("-")):
+			assert (strand == "-"), "strand mismatch in \"%s\"" % line
+			filename = filename[:-1]
+		filename = do_path_subs(filename,self.path_subs)
+		return (filename,start,end,strand,contig)
+
+
+	def parse_h_stanza(self):
+		line = self.fetch_line(strip='"',report=" in h-stanza")
+		self.seq1_header = line
+		self.seq1_header_prefix = ""
+		if (line.startswith(">")):
+			self.seq1_header = line[1:].strip()
+			self.seq1_header_prefix = ">"
+		self.seq1_header = self.seq1_header.split(None,1)
+		if (len(self.seq1_header) > 0): self.seq1_header = self.seq1_header[0]
+		else:                           self.seq1_header = "seq1"
+
+		line = self.fetch_line(strip='"',report=" in h-stanza")
+		self.seq2_header = line
+		self.seq2_header_prefix = ""
+		if (line.startswith(">")):
+			self.seq2_header = line[1:].strip()
+			self.seq2_header_prefix = ">"
+		self.seq2_header = self.seq2_header.split(None,1)
+		if (len(self.seq2_header) > 0): self.seq2_header = self.seq2_header[0]
+		else:                           self.seq2_header = "seq2"
+
+		line = self.fetch_line(report=" in h-stanza")
+		assert (line == "}"), "improper h-stanza terminator (line %d, \"%s\")" \
+							% (self.lineNumber,line)
+
+
+	def parse_a_stanza(self):
+		"""returns the pair (score,pieces)
+		   where pieces is a list of ungapped segments (start1,start2,length,pctId)
+		   with start1,start2 origin-0"""
+		# 's' line -- score, 1 field
+		line = self.fetch_line(report=" in a-stanza")
+		fields = line.split()
+		assert (fields[0] == "s"), "s line expected in a-stanza (line %d, \"%s\")" \
+								 % (self.lineNumber,line)
+		try:    score = int(fields[1])
+		except: score = float(fields[1])
+
+		# 'b' line -- begin positions in seqs, 2 fields
+		line = self.fetch_line(report=" in a-stanza")
+		fields = line.split()
+		assert (fields[0] == "b"), "b line expected in a-stanza (line %d, \"%s\")" \
+								 % (self.lineNumber,line)
+		beg1 = int(fields[1]) - 1
+		beg2 = int(fields[2]) - 1
+
+		# 'e' line -- end positions in seqs, 2 fields
+		line = self.fetch_line(report=" in a-stanza")
+		fields = line.split()
+		assert (fields[0] == "e"), "e line expected in a-stanza (line %d, \"%s\")" \
+								 % (self.lineNumber,line)
+		len1 = int(fields[1]) - beg1
+		len2 = int(fields[2]) - beg2
+
+		# 'l' lines
+		pieces = []
+		while (True):
+			line = self.fetch_line(report=" in a-stanza")
+			fields = line.split()
+			if (fields[0] != "l"):
+				break
+			start1  = int(fields[1]) - 1
+			start2  = int(fields[2]) - 1
+			length  = int(fields[3]) - start1
+			length2 = int(fields[4]) - start2
+			try:    pctId = int(fields[5])
+			except: pctId = float(fields[5])
+			assert (length2 == length), "length mismatch in a-stanza"
+			pieces.append((start1+self.seq1_start,start2+self.seq2_start,length,pctId))
+		assert (line == "}"), "improper a-stanza terminator (line %d, \"%s\")" \
+							% (self.lineNumber,line)
+		return (score,pieces)
+
+	def parse_unknown_stanza(self):
+		lines = []
+		while (True):
+			line = self.fetch_line()
+			assert (line), "unexpected end of file (missing #:eof)"
+			if (line == "}"): break
+			lines.append(line)
+		return "  " + "\n  ".join(lines) + "\n"
+
+	def fetch_line(self,strip=True,requireLine=True,report=""):
+		if   (strip == None): line = self.file.readline()
+		elif (strip == True): line = self.file.readline().strip()
+		else:                 line = self.file.readline().strip().strip(strip)
+		self.lineNumber += 1
+		if (requireLine):
+			assert (line), \
+			       "unexpected blank line or end of file%s (line %d)" \
+			     % (report,self.lineNumber)
+		return line
+
+
+	def d_stanza(self):
+		if (self.d_stanza_text == None): return ""
+		return "d {\n%s}" % self.d_stanza_text
+
+	def s_stanza(self):
+		if (self.seq1_filename == None): return ""
+
+		if (self.seq1_strand == "-"): seq1_strand = "1"
+		else:                         seq1_strand = "0"
+		if (self.seq2_strand == "-"): seq2_strand = "1"
+		else:                         seq2_strand = "0"
+
+		s =  "  \"%s\" %d %d %s %d\n"\
+		   % (self.seq1_filename,self.seq2_start+1,self.seq1_end,
+			  seq1_strand,self.seq1_contig)
+		s += "  \"%s\" %d %d %s %d\n"\
+		   % (self.seq2_filename,self.seq2_start+1,self.seq2_end,
+			  seq2_strand,self.seq2_contig)
+
+		return "s {\n%s}" % s
+
+	def h_stanza(self):
+		if (self.seq1_header == None): return ""
+		s =  "  \"%s%s\"\n" % (self.seq1_header_prefix,self.seq1_header)
+		s += "  \"%s%s\"\n" % (self.seq2_header_prefix,self.seq2_header)
+		return "h {\n%s}" % s
+
+	def build_alignment(self,score,pieces):
+		"""converts a score and pieces to an alignment"""
+	 	# build text
+		self.open_seqs()
+		text1 = text2 = ""
+		end1  = end2  = None
+		for (start1,start2,length,pctId) in pieces:
+			if (end1 != None):
+				if (start1 == end1): # insertion in sequence 2
+					text1 += self.seq1_gap * (start2-end2)
+					text2 += self.seq2_file.get(end2,start2-end2)
+				else: # insertion in sequence 1
+					text1 += self.seq1_file.get(end1,start1-end1)
+					text2 += self.seq2_gap * (start1-end1)
+
+			text1 += self.seq1_file.get(start1,length)
+			text2 += self.seq2_file.get(start2,length)
+			end1 = start1 + length
+			end2 = start2 + length
+		# create alignment
+		start1 = pieces[0][0]
+		start2 = pieces[0][1]
+		end1   = pieces[-1][0] + pieces[-1][2]
+		end2   = pieces[-1][1] + pieces[-1][2]
+		size1  = end1 - start1
+		size2  = end2 - start2
+		a = Alignment(score=score,species_to_lengths=self.species_to_lengths)
+		#if (self.seq1_strand == "-"): start1 = self.seq1_file.length - end1
+		a.add_component(Component(self.seq1_src,start1,size1,self.seq1_strand,text=text1))
+		#if (self.seq2_strand == "-"): start2 = self.seq2_file.length - end2
+		a.add_component(Component(self.seq2_src,start2,size2,self.seq2_strand,text=text2))
+		return a
+
+	def path_to_src_name(self,path_name):
+		# converts, e.g. ".../hg18/seq/chr13.nib" to "hg18.chr13"
+		if (path_name == None) or (path_name == ""): raise ValueError
+		if (path_name.endswith(".nib")):   path_name = path_name[:-4]
+		if (path_name.endswith(".fa")):    path_name = path_name[:-3]
+		if (path_name.endswith(".fasta")): path_name = path_name[:-6]
+		slash = path_name.rfind("/")
+		if (slash == -1): return path_name
+		name      = path_name[slash+1:]
+		path_name = path_name[:slash]
+		if (path_name.endswith("/seq")):   path_name = path_name[:-4]
+		slash = path_name.rfind("/")
+		if (slash != -1): path_name = path_name[slash+1:]
+		return path_name + "." + name
+
+	def header_to_src_name(self,header):
+		# converts, e.g. "hg18.chr13:115404472-117281897" to "hg18.chr13"
+		if (header == None) or (header == ""): raise ValueError
+		colon = header.rfind(":")
+		if (colon != -1): header = header[:colon]
+		if ("/" in header): raise ValueError
+		if (header.count(".") == 0):
+			return header
+		header = header.split(".")
+		if (header[0] == "") or (header[1] == ""): raise ValueError
+		return ".".join(header)
+
+class ReaderIter(object):
+	def __init__(self,reader):
+		self.reader = reader
+	def __iter__(self):
+		return self
+	def next(self):
+		v = self.reader.next()
+		if (not v): raise StopIteration
+		return v
+
+
+class LavAsPiecesReader(Reader):
+	"""Iterate over all lav blocks in a file in order, returning alignments
+	   as score and pieces, as returned by Reader.parse_a_stanza"""
+
+	def build_alignment(self,score,pieces):
+		return (score,pieces)
+
+
+class Writer(object):
+
+	# blockHash is a hash from (src1,strand1,src2,strand2) to a list of blocks;
+	# the blocks are collected on each call to write(), but the actual writing
+	# does not occur until close().
+
+	def __init__(self,file,attributes={}):
+		self.file   = file
+		self.fname1 = None
+		self.fname2 = None
+		self.block  = 0
+		self.blockHash = {}  #  (see note above)
+
+		if ("name_format_1" in attributes):
+			self.fname1 = attributes["name_format_1"]
+		if ("name_format_2" in attributes):
+			self.fname2 = attributes["name_format_2"]
+
+		if ("d_stanza" in attributes):
+			write_lav_marker(self)
+			print >>self.file,"d {"
+			print >>self.file,attributes["d_stanza"]
+			print >>self.file,"}"
+
+	def write(self,alignment):
+		if (len(alignment.components) != 2):
+			raise ValueError("%d-component alignment is not compatible with lav" % \
+				   len(alignment.components))
+
+		c1 = alignment.components[0]
+		c2 = alignment.components[1]
+
+		key = (c1.src,c1.strand,c2.src,c2.strand)
+		if (key not in self.blockHash): self.blockHash[key] = []
+		self.blockHash[key].append(alignment)
+		self.block += 1
+
+	def close(self):
+		keys = [key for key in self.blockHash]
+		keys = sort_keys_by_chrom (keys)
+		for key in keys:
+			(src1,strand1,src2,strand2) = key
+			alignment    = self.blockHash[key][0]
+			self.src1    = src1
+			self.strand1 = strand1
+			self.length1 = alignment.src_size(src1)
+			self.src2    = src2
+			self.strand2 = strand2
+			self.length2 = alignment.src_size(src2)
+			self.write_s_stanza()
+			self.write_h_stanza()
+			for alignment in self.blockHash[key]:
+				self.write_a_stanza(alignment)
+		self.write_trailer()
+		if (self.file != sys.stdout): self.file.close()
+
+	def write_s_stanza(self):
+		self.write_lav_marker()
+		(strand1,flag1) = minus_or_nothing(self.strand1)
+		(strand2,flag2) = minus_or_nothing(self.strand2)
+		fname1 = build_filename(self.fname1,self.src1)
+		fname2 = build_filename(self.fname2,self.src2)
+		print >>self.file,"s {"
+		print >>self.file,"  \"%s%s\" 1 %d %d 1" \
+		                % (fname1,strand1,self.length1,flag1)
+		print >>self.file,"  \"%s%s\" 1 %d %d 1" \
+		                % (fname2,strand2,self.length2,flag2)
+		print >>self.file,"}"
+
+	def write_h_stanza(self):
+		strand1 = rc_or_nothing(self.strand1)
+		strand2 = rc_or_nothing(self.strand2)
+		print >>self.file,"h {"
+		print >>self.file,"  \"> %s%s\"" % (self.src1,strand1)
+		print >>self.file,"  \"> %s%s\"" % (self.src2,strand2)
+		print >>self.file,"}"
+
+	def write_a_stanza(self,alignment):
+		c1 = alignment.components[0]
+		pos1  = c1.start
+		text1 = c1.text.upper()
+		c2 = alignment.components[1]
+		pos2  = c2.start
+		text2 = c2.text.upper()
+
+		# collect ungapped pieces
+
+		pieces = []
+		piece1 = None
+
+		for ix in range(len(text1)):
+			ch1 = text1[ix]
+			ch2 = text2[ix]
+
+			nonGap = (ch1 != "-") and (ch2 != "-")
+			if (nonGap):
+				if (piece1 == None): # new piece starts
+					(piece1,piece2,idCount) = (pos1,pos2,0)
+				if (ch1 == ch2): idCount += 1
+			elif (piece1 != None): # new gap starts
+				size  = pos1 - piece1
+				pctId = (200*idCount + size) / (2*size)
+				pieces.append((piece1,piece2,size,pctId))
+				piece1 = None
+
+			if (ch1 != "-"): pos1 += 1
+			if (ch2 != "-"): pos2 += 1
+
+		if (piece1 != None):
+			size  = pos1 - piece1
+			pctId = (200*idCount + size) / (2*size)
+			pieces.append((piece1,piece2,size,pctId))
+
+		# write the block
+
+		(start1,start2,size,pctId) = pieces[-1]  # get end of final piece
+		end1 = start1 + size
+		end2 = start2 + size
+
+		(start1,start2,size,pctId) = pieces[0]   # get start of first piece
+
+		score = int(round(alignment.score))
+
+		print >>self.file,"a {"
+		print >>self.file,"  s %s"    % score
+		print >>self.file,"  b %d %d" % (start1+1,start2+1)
+		print >>self.file,"  e %d %d" % (end1,    end2)
+		for (start1,start2,size,pctId) in pieces:
+			print >>self.file,"  l %d %d %d %d %d" \
+							% (start1+1,start2+1,start1+size,start2+size,pctId)
+		print >>self.file,"}"
+
+	def write_lav_marker(self):
+		print >>self.file,"#:lav"
+
+	def write_trailer(self):
+		print >>self.file,"#:eof"
+
+def	sort_keys_by_chrom (keys):
+	decorated = [(chrom_key(src1),strand1,chrom_key(src2),strand2,(src1,strand1,src2,strand2)) \
+	             for (src1,strand1,src2,strand2) in keys]
+	decorated.sort()
+	return [key for (src1,strand1,src2,strand2,key) in decorated]
+
+def	chrom_key (src):
+	(species,chrom) = src_split(src)
+	if (chrom.startswith("chr")): chrom = chrom[3:]
+	try:                          chrom = int(chrom)
+	except ValueError: pass
+	return chrom
+
+def build_filename(fmt,src):
+	if (fmt == None): return src
+	num = fmt.count("%s")
+	if (num == 0): return fmt
+	(species,chrom) = src_split(src)
+	if (num == 1): return fmt % chrom
+	return fmt % (species,chrom)
+
+def minus_or_nothing(strand):
+	if (strand == "-"): return ("-",1)
+	else:               return ("",0)
+
+def rc_or_nothing(strand):
+	if (strand == "-"): return " (reverse complement)"
+	else:               return ""
+
+def do_path_subs(path,path_subs):
+	for (prefix,replacement) in path_subs:
+		if (path.startswith(prefix)):
+			return replacement + path[len(prefix):]
+	return path
diff --git a/lib/bx/align/lav_tests.py b/lib/bx/align/lav_tests.py
new file mode 100644
index 0000000..dad0861
--- /dev/null
+++ b/lib/bx/align/lav_tests.py
@@ -0,0 +1,45 @@
+"""
+Tests for `bx.align.lav`.
+"""
+
+import unittest
+import sys
+import bx.align as align
+import bx.align.lav as lav
+
+test_lav = "test_data/lav_tests/apple_orange.lav"
+
+class lavTestCase(unittest.TestCase):
+
+    def testReader(self):
+
+        reader = lav.Reader(file(test_lav))
+
+        a = reader.next()
+        assert a.score == 10286, "a.score is wrong: %s" % a.score
+        assert len(a.components) == 2
+        check_component(a.components[0], "apple",            106, 252, "+", 411, "GTCCGGCCGGCTGAGAGCTACAATACACATGCACGCAGTTTGGCCACTCACATTAAGTATATGAGGAAGGGTTAGCATGAGTTGTACTATAAGGCAGCGGATAGCAGGTTGTGGAAAAATATCCTCCCGATTCAAATCCCCAGGTGCCTAAA----------------GTAGGGCCGGTAGTTGAATGCTTGCCTGTCAGACTGGATGACCAAGTTCAGTATCAACACAATATAGTGCCAGGAGCTAATTGTTCCCCAGCAGCGTGAC")
+        check_component(a.components[1], "lav_tests.orange",  53, 252, "+", 361, "GTCCGGCCGGCTGTGTGCTACAATACACGTTCACGCAGTTTGGCCAATCACTTTAAGTATATACGAAATGGTTACCATGAGTTGTACTGTAAGGCAGCGGAAAGC---TTGTTAA--------CTCCTGGGCGACATT----GGGGCTGCAACATCGTTTATCCTCCTCTACAACCAATAGCTG-TTGCTTCTTGGTTCAAGTATATCCCATGGATTAGTATCAACACGATATAGTGTCAGGAGCTAATTGTTCCCCAGCAGCGTGAC")
+
+        a = reader.next()
+        assert a.score == 3586, "a.score is wrong: %s" % a.score
+        assert len(a.components) == 2
+        check_component(a.components[0], "apple",             52,  72, "+", 411, "TGCATATCGACTATTACAGCCACGCGAGTTACATTCCTCTTTTTTTTTGCTGGCGTCCGGCCGGCTGAGAGC")
+        check_component(a.components[1], "lav_tests.orange",   2,  72, "-", 361, "TGCATATCGACTAGTACAGCCTCTCGAGTTACCCCCCCCATTCCTCTTGCTGACGTCACGCTGCTGGGGAAC")
+
+        a = reader.next()
+        assert a is None
+
+        reader.close()
+
+def check_component( c, src, start, size, strand, src_size, text ):
+    #..print "\"%s\" == \"%s\"" % (c.src,src)
+    assert c.src      == src,      "c.src = %s (expected %s)"          % (c.src,     src)
+    assert c.start    == start,    "c.start = %s (expected %s)"        % (c.start,   start)
+    assert c.size     == size,     "c.size = %s (expected %s)"         % (c.size,    size)
+    assert c.strand   == strand,   "c.strand = %s (expected %s)"       % (c.strand,  strand)
+    assert c.src_size == src_size, "c.src_size = %s (expected %s)"     % (c.src_size,src_size)
+    assert c.text     == text,     "c.text = \"%s\" (expected \"%s\")" % (c.text,    text)
+
+test_classes = [ lavTestCase ]
+suite = unittest.TestSuite([ unittest.makeSuite(c) for c in test_classes ])
diff --git a/lib/bx/align/maf.py b/lib/bx/align/maf.py
new file mode 100644
index 0000000..3414aeb
--- /dev/null
+++ b/lib/bx/align/maf.py
@@ -0,0 +1,231 @@
+"""
+Support for the `MAF`_ multiple sequence alignment format used by `multiz`_.
+
+.. _MAF: http://genome.ucsc.edu/FAQ/FAQformat.html#format5
+.. _multiz: http://www.bx.psu.edu/miller_lab/
+"""
+
+from bx.align import *
+
+from StringIO import StringIO
+import os
+
+import itertools
+from bx import interval_index_file
+
+from bx.misc.seekbzip2 import SeekableBzip2File
+
+MAF_INVERSE_STATUS = 'V'
+MAF_INSERT_STATUS = 'I'
+MAF_CONTIG_STATUS = 'C'
+MAF_CONTIG_NESTED_STATUS = 'c'
+MAF_NEW_STATUS = 'N'
+MAF_NEW_NESTED_STATUS = 'n'
+MAF_MAYBE_NEW_STATUS = 'S'
+MAF_MAYBE_NEW_NESTED_STATUS = 's'
+MAF_MISSING_STATUS = 'M'
+
+class MAFIndexedAccess( interval_index_file.AbstractIndexedAccess ):
+    """
+    Indexed access to a MAF file.
+    """
+    def read_at_current_offset( self, file, **kwargs ):
+        """
+        Read the MAF block at the current position in `file` and return an
+        instance of `Alignment`.
+        """
+        return read_next_maf( file, **kwargs )
+
+class MAFMultiIndexedAccess( interval_index_file.AbstractMultiIndexedAccess ):
+    """
+    Indexed access to multiple MAF files.
+    """
+    indexed_access_class = MAFIndexedAccess
+      
+Indexed = MAFIndexedAccess
+"""Deprecated: `MAFIndexedAccess` is also available under the name `Indexed`."""
+
+MultiIndexed = MAFMultiIndexedAccess
+"""Deprecated: `MAFMultiIndexedAccess` is also available under the name `MultiIndexed`."""
+
+class Reader( object ):
+    """
+    Iterate over all maf blocks in a file in order
+    """
+    def __init__( self, file, **kwargs ):
+        self.file = file
+        self.maf_kwargs = kwargs
+        # Read and verify maf header, store any attributes
+        fields = self.file.readline().split()
+        if fields[0] != '##maf': raise Exception("File does not have MAF header")
+        self.attributes = parse_attributes( fields[1:] )
+
+    def next( self ):
+        return read_next_maf( self.file, **self.maf_kwargs )
+
+    def __iter__( self ):
+        return ReaderIter( self )
+
+    def close( self ):
+        self.file.close()
+
+class ReaderIter( object ):
+    """
+    Adapts a `Reader` to the iterator protocol.
+    """
+    def __init__( self, reader ):
+        self.reader = reader
+    def __iter__( self ): 
+        return self
+    def next( self ):
+        v = self.reader.next()
+        if not v: raise StopIteration
+        return v
+
+class Writer( object ):
+
+    def __init__( self, file, attributes={} ):
+        self.file = file
+        # Write header, Webb's maf code wants version first, we accomodate
+        if not attributes.has_key('version'): attributes['version'] = 1
+        self.file.write( "##maf version=%s" % attributes['version'] )
+        for key in attributes: 
+            if key == 'version': continue
+            self.file.writelines( " %s=%s" % ( key, attributes[key] ) )
+        self.file.write( "\n" )
+
+    def write( self, alignment ):
+        self.file.write( "a score=" + str( alignment.score ) )
+        for key in alignment.attributes:
+            self.file.write( " %s=%s" % ( key, alignment.attributes[key] ) )
+        self.file.write( "\n" )
+        # Components
+        rows = []
+        for c in alignment.components:
+            # "Empty component" generates an 'e' row
+            if c.empty:
+                rows.append( ( "e", c.src, str( c.start ), str( c.size ), c.strand, str( c.src_size ), c.synteny_empty ) )
+                continue
+            # Regular component
+            rows.append( ( "s", c.src, str( c.start ), str( c.size ), c.strand, str( c.src_size ), c.text ) )
+            # If component has quality, write a q row
+            if c.quality is not None:
+                rows.append( ( "q", c.src, "", "", "", "", c.quality ) )
+            # If component has synteny follow up with an 'i' row
+            if c.synteny_left and c.synteny_right:
+                rows.append( ( "i", c.src, "", "", "", "", " ".join( map( str, c.synteny_left + c.synteny_right ) ) ) )
+        self.file.write( format_tabular( rows, "llrrrrl" ) )
+        self.file.write( "\n" )
+
+    def close( self ):
+        self.file.close()
+
+# ---- Helper methods -------------------------------------------------------
+
+def from_string( string, **kwargs ):
+    return read_next_maf( StringIO( string ), **kwargs )
+
+def read_next_maf( file, species_to_lengths=None, parse_e_rows=False ):
+    """
+    Read the next MAF block from `file` and return as an `Alignment` 
+    instance. If `parse_i_rows` is true, empty components will be created 
+    when e rows are encountered.
+    """
+    alignment = Alignment(species_to_lengths=species_to_lengths)
+    # Attributes line
+    line = readline( file, skip_blank=True )
+    if not line: return None
+    fields = line.split() 
+    if fields[0] != 'a': raise Exception("Expected 'a ...' line")
+    alignment.attributes = parse_attributes( fields[1:] )
+    if 'score' in alignment.attributes:
+        alignment.score = alignment.attributes['score']
+        del alignment.attributes['score']
+    else:
+        alignment.score = 0
+    # Sequence lines
+    last_component = None
+    while 1:
+        line = readline( file )
+        # EOF or Blank line terminates alignment components
+        if not line or line.isspace(): break
+        if line.isspace(): break 
+        # Parse row
+        fields = line.split()
+        if fields[0] == 's':
+            # An 's' row contains sequence for a component
+            component = Component()
+            component.src = fields[1]
+            component.start = int( fields[2] )
+            component.size = int( fields[3] )
+            component.strand = fields[4]
+            component.src_size = int( fields[5] )
+            if len(fields) > 6: component.text = fields[6].strip()
+            # Add to set
+            alignment.add_component( component )
+            last_component = component
+        elif fields[0] == 'e':
+            # An 'e' row, when no bases align for a given species this tells
+            # us something about the synteny 
+            if parse_e_rows:
+                component = Component()
+                component.empty = True
+                component.src = fields[1]
+                component.start = int( fields[2] )
+                component.size = int( fields[3] )
+                component.strand = fields[4]
+                component.src_size = int( fields[5] )
+                component.text = None
+                synteny = fields[6].strip()
+                assert len( synteny ) == 1, \
+                    "Synteny status in 'e' rows should be denoted with a single character code"
+                component.synteny_empty = synteny
+                alignment.add_component( component )
+                last_component = component
+        elif fields[0] == 'i':
+            # An 'i' row, indicates left and right synteny status for the 
+            # previous component, we hope ;)
+            assert fields[1] == last_component.src, "'i' row does not follow matching 's' row"
+            last_component.synteny_left = ( fields[2], int( fields[3] ) )
+            last_component.synteny_right = ( fields[4], int( fields[5] ) )
+        elif fields[0] == 'q':
+            assert fields[1] == last_component.src, "'q' row does not follow matching 's' row"
+            # TODO: Should convert this to an integer array?
+            last_component.quality = fields[2]
+            
+    return alignment
+
+def readline( file, skip_blank=False ):
+    """Read a line from provided file, skipping any blank or comment lines"""
+    while 1:
+        line = file.readline()
+        #print "every line: %r" % line
+        if not line: return None 
+        if line[0] != '#' and not ( skip_blank and line.isspace() ):
+            return line
+
+def parse_attributes( fields ):
+    """Parse list of key=value strings into a dict"""
+    attributes = {}
+    for field in fields:
+        pair = field.split( '=' )
+        attributes[ pair[0] ] = pair[1]
+    return attributes
+
+def format_tabular( rows, align=None ):
+    if len( rows ) == 0: return ""
+    lengths = [ len( col ) for col in rows[ 0 ] ]
+    for row in rows[1:]:
+        for i in range( 0, len( row ) ):
+            lengths[ i ] = max( lengths[ i ], len( row[ i ] ) )
+    rval = ""
+    for row in rows:
+        for i in range( 0, len( row ) ):
+            if align and align[ i ] == "l":
+                rval += row[ i ].ljust( lengths[ i ] )
+            else:
+                rval += row[ i ].rjust( lengths[ i ] )
+            rval += " "
+        rval += "\n"
+    return rval
+        
diff --git a/lib/bx/align/maf_tests.py b/lib/bx/align/maf_tests.py
new file mode 100644
index 0000000..ca67c6c
--- /dev/null
+++ b/lib/bx/align/maf_tests.py
@@ -0,0 +1,190 @@
+"""
+Tests for `bx.align.maf`.
+"""
+
+import unittest
+import sys
+import bx.align as align
+import bx.align.maf as maf
+
+from StringIO import StringIO
+
+# A simple MAF from the rat paper days
+test_maf = """##maf version=1 scoring=humor.v4
+# humor.v4 R=30 M=10 /cluster/data/hg15/bed/blastz.mm3/axtNet300/chr1.maf
+# /cluster/data/hg15/bed/blastz.rn3/axtNet300/chr1.maf
+
+a score=0.128
+s human_hoxa 100  8 + 100257 ACA-TTACT
+s horse_hoxa 120  9 -  98892 ACAATTGCT
+s fugu_hoxa   88  7  + 90788 ACA--TGCT
+
+
+a score=0.071
+s human_unc 9077 8 + 10998 ACAGTATT
+# Comment
+s horse_unc 4555 6 -  5099 ACA--ATT
+s fugu_unc  4000 4 +  4038 AC----TT
+"""
+
+# A more complicated MAF with synteny annotation and such
+test_maf_2 = """##maf version=1 scoring=autoMZ.v1
+a score=3656.000000
+s hg17.chr1                   2005 34 + 245522847 TGTAACTTAATACCACAACCAGGCATAGGGG--AAA-------------
+s rheMac2.chr11            9625228 31 + 134511895 TGTAACCTCTTACTGCAACAAGGCACAGGGG------------------
+i rheMac2.chr11           C 0 I 1678
+s panTro1.chr1                2014 34 + 229575298 TGTAACTTAATACCACAACCAGGCATGGGGG--AAA-------------
+i panTro1.chr1            C 0 C 0
+s bosTau2.chr5            64972365 47 +  76426644 TCCAGCCATGTGTTGTGATCAG--CCAGGGGCTAAAGCCATGGCGGTAG
+i bosTau2.chr5            C 0 I 1462
+s canFam2.chr27           45129665 31 +  48908698 TTTGACTCTGTGCTCTTATCAGGCCCAAGGG------------------
+i canFam2.chr27           C 0 I 1664
+e danRer3.chr18            2360867 428 +  50308305 I
+e oryCun1.scaffold_139397      643 1271 -      4771 I
+e loxAfr1.scaffold_5603      58454 1915 +     68791 I
+e echTel1.scaffold_212365     4641 1430 +      9822 I
+e echTel1.scaffold_212365     4641 1430 +      9822 I
+e rn3.chr4                29161032 1524 - 187371129 I
+e mm7.chr6                28091695 3290 - 149646834 I
+
+"""
+
+# A MAF to test slicing upon
+test_maf_3 = """##maf version=1 scoring=none
+a score=0
+s apple  34 64 + 110 AGGGA---GTTCGTCACT------GTCGTAAGGGTTCAGA--CTGTCTATGTATACACAAGTTGTGTTGCA--ACCG
+s orange 19 61 - 100 AGGGATGCGTT--TCACTGCTATCGTCGTA----TTCAGACTTCG-CTATCT------GAGTTGT---GCATTACCG
+
+"""
+
+def test_reader():
+
+    reader = maf.Reader( StringIO( test_maf ) )
+    assert reader.attributes["version"] == "1" 
+    assert reader.attributes["scoring"] == "humor.v4" 
+
+    a = reader.next()
+    assert a.score == 0.128
+    assert len( a.components ) == 3
+    check_component( a.components[0], "human_hoxa", 100, 8,  "+", 100257, "ACA-TTACT" )
+    check_component( a.components[1], "horse_hoxa", 120, 9, "-",  98892, "ACAATTGCT" )
+    check_component( a.components[2], "fugu_hoxa",    88, 7,  "+",  90788, "ACA--TGCT" )
+    
+    a = reader.next()
+    assert a.score == 0.071
+    assert len( a.components ) == 3
+    check_component( a.components[0], "human_unc", 9077, 8, "+", 10998, "ACAGTATT" )
+    check_component( a.components[1], "horse_unc", 4555, 6, "-",  5099, "ACA--ATT" )
+    check_component( a.components[2], "fugu_unc",   4000, 4, "+",  4038, "AC----TT" )
+
+    a = reader.next()
+    assert a is None
+
+    reader.close()
+
+def test_writer():
+
+    val = StringIO()
+    writer = maf.Writer( val, { 'scoring':'foobar' } )
+    
+    a = align.Alignment()
+    a.score = 7009
+
+    a.components.append( align.Component( src="human_hoxa", start=100, size=9,  strand="+", src_size=1000257, text="ACA-TTACT" ) )
+    a.components.append( align.Component( src="horse_hoxa", start=120, size=10, strand="-",   src_size=98892, text="ACAATTGCT" ) )
+
+    check_component( a.components[0], "human_hoxa", 100, 9,  "+", 1000257, "ACA-TTACT" )
+    check_component( a.components[1], "horse_hoxa", 120, 10, "-",   98892, "ACAATTGCT" )
+
+    writer.write( a )
+
+    assert val.getvalue() == """##maf version=1 scoring=foobar
+a score=7009
+s human_hoxa 100  9 + 1000257 ACA-TTACT 
+s horse_hoxa 120 10 -   98892 ACAATTGCT 
+
+"""
+
+
+
+def test_slice():
+
+    a = align.Alignment()
+    a.score = "7009"
+    a.components.append( align.Component( src="human_hoxa", start=100, size=9,  strand="+", src_size=100257, text="ACA-TTACT" ) )
+    a.components.append( align.Component( src="horse_hoxa", start=120, size=10, strand="-",   src_size=98892, text="ACAATTGCT" ) )
+
+    b = a.slice_by_component( 0, 101, 105 )
+
+    check_component( b.components[0], src="human_hoxa", start=101, size=4, strand="+", src_size=100257, text="CA-TT" )
+    check_component( b.components[1], src="horse_hoxa", start=121, size=5, strand="-", src_size=98892, text ="CAATT" )
+
+	# test slicing with + strand src
+    reader = maf.Reader( StringIO( test_maf_3 ) )
+    a = reader.next()
+    b = a.slice_by_component( 0, 40, 62 )
+    check_component( b.components[0], src="apple",  start=40, size=22, strand="+", src_size=110, text="TTCGTCACT------GTCGTAAGGGTTC" )
+    check_component( b.components[1], src="orange", start=28, size=22, strand="-", src_size=100, text="TT--TCACTGCTATCGTCGTA----TTC" )
+
+	# test slicing with - strand src
+    b = a.slice_by_component( 1, 30, 68 )
+    check_component( b.components[0], src="apple",  start=46, size=41, strand="+", src_size=110, text="ACT------GTCGTAAGGGTTCAGA--CTGTCTATGTATACACAAGTTG" )
+    check_component( b.components[1], src="orange", start=32, size=38, strand="-", src_size=100, text="ACTGCTATCGTCGTA----TTCAGACTTCG-CTATCT------GAGTTG" )
+
+    a = reader.next()
+    assert a is None
+
+
+def test_with_synteny():
+    reader = maf.Reader( StringIO( test_maf_2 ), parse_e_rows=True )
+    
+    a = reader.next()
+    check_component( a.components[0], "hg17.chr1", 2005, 34, "+", 245522847, "TGTAACTTAATACCACAACCAGGCATAGGGG--AAA-------------")
+    check_component( a.components[1], "rheMac2.chr11", 9625228, 31, "+", 134511895, "TGTAACCTCTTACTGCAACAAGGCACAGGGG------------------")
+    print a.components[1].synteny_left
+    assert a.components[1].synteny_left == ( maf.MAF_CONTIG_STATUS, 0 )
+    assert a.components[1].synteny_right == ( maf.MAF_INSERT_STATUS, 1678 )
+
+    rat = a.get_component_by_src_start( "rn3." )
+    check_component( rat, "rn3.chr4", 29161032, 1524, "-", 187371129, None )
+    assert rat.synteny_empty == maf.MAF_INSERT_STATUS
+    
+def test_write_with_synteny():
+    reader = maf.Reader( StringIO( test_maf_2 ), parse_e_rows=True )
+    a = reader.next()
+    val = StringIO()
+    writer = maf.Writer( val, { 'scoring':'foobar' } )
+    writer.write( a )
+    actual = val.getvalue()
+    expected = """##maf version=1 scoring=foobar
+a score=3656.0
+s hg17.chr1                   2005   34 + 245522847 TGTAACTTAATACCACAACCAGGCATAGGGG--AAA------------- 
+s rheMac2.chr11            9625228   31 + 134511895 TGTAACCTCTTACTGCAACAAGGCACAGGGG------------------ 
+i rheMac2.chr11                                     C 0 I 1678                                        
+s panTro1.chr1                2014   34 + 229575298 TGTAACTTAATACCACAACCAGGCATGGGGG--AAA------------- 
+i panTro1.chr1                                      C 0 C 0                                           
+s bosTau2.chr5            64972365   47 +  76426644 TCCAGCCATGTGTTGTGATCAG--CCAGGGGCTAAAGCCATGGCGGTAG 
+i bosTau2.chr5                                      C 0 I 1462                                        
+s canFam2.chr27           45129665   31 +  48908698 TTTGACTCTGTGCTCTTATCAGGCCCAAGGG------------------ 
+i canFam2.chr27                                     C 0 I 1664                                        
+e danRer3.chr18            2360867  428 +  50308305 I                                                 
+e oryCun1.scaffold_139397      643 1271 -      4771 I                                                 
+e loxAfr1.scaffold_5603      58454 1915 +     68791 I                                                 
+e echTel1.scaffold_212365     4641 1430 +      9822 I                                                 
+e echTel1.scaffold_212365     4641 1430 +      9822 I                                                 
+e rn3.chr4                29161032 1524 - 187371129 I                                                 
+e mm7.chr6                28091695 3290 - 149646834 I                                                 
+
+"""
+    print actual
+    print "---"
+    print expected
+    assert actual == expected
+
+def check_component( c, src, start, size, strand, src_size, text ):
+    assert c.src == src
+    assert c.start == start 
+    assert c.size == size 
+    assert c.strand == strand 
+    assert c.src_size == src_size 
+    assert c.text == text
\ No newline at end of file
diff --git a/lib/bx/align/score.py b/lib/bx/align/score.py
new file mode 100644
index 0000000..fe23a4e
--- /dev/null
+++ b/lib/bx/align/score.py
@@ -0,0 +1,291 @@
+"""
+Support for scoring alignments using arbitrary scoring matrices, arbitrary
+alphabets, and affine gap penalties.
+"""
+
+from numpy import *
+
+class ScoringScheme( object ):
+	# note that gap_open and gap_extend are penalties, which means you should make them positive
+    def __init__( self, gap_open, gap_extend, default=-100, alphabet1="ACGT", alphabet2=None, gap1="-", gap2=None, text1_range=128, text2_range=None, typecode=int32 ):
+        if (text2_range == None): text2_range = text1_range
+        if (alphabet2 == None): alphabet2 = alphabet1
+        if (gap2 == None): gap2 = gap1 # (scheme with gap1=gap2=None is legit)
+        if type(alphabet1) == str: alphabet1 = [ch for ch in alphabet1]
+        if type(alphabet2) == str: alphabet2 = [ch for ch in alphabet2]
+        self.table = ones( (text1_range, text2_range), typecode )
+        self.table *= default
+        self.gap_open = gap_open
+        self.gap_extend = gap_extend
+        self.gap1 = gap1
+        self.gap2 = gap2
+        self.alphabet1 = alphabet1
+        self.alphabet2 = alphabet2
+	# private _set_score and _get_score allow subclasses to override them to
+	# implement a different underlying table object
+    def _set_score(self,(a,b),val):
+        self.table[a,b] = val
+    def _get_score(self,(a,b)):
+        return self.table[a,b]
+    def set_score( self, a, b, val, foldcase1=False, foldcase2=False ):
+        self._set_score((a,b),val)
+        if foldcase1:
+            aCh = chr(a)
+            if   (aCh.isupper()): aa = ord(aCh.lower())
+            elif (aCh.islower()): aa = ord(aCh.upper())
+            else:                 foldcase1 = False
+        if foldcase2:
+            bCh = chr(b)
+            if   (bCh.isupper()): bb = ord(bCh.lower())
+            elif (bCh.islower()): bb = ord(bCh.upper())
+            else:                 foldcase2 = False
+        if foldcase1 and foldcase2:
+            self._set_score((aa,b ),val)
+            self._set_score((a ,bb),val)
+            self._set_score((aa,bb),val)
+        elif foldcase1:
+            self._set_score((aa,b ),val)
+        elif foldcase2:
+            self._set_score((a ,bb),val)
+    def score_alignment( self, a ):
+        return score_alignment(self,a)
+    def score_texts( self, text1, text2 ):
+        return score_texts( self, text1, text2 )
+    def __str__ (self):
+        isDna1 = "".join( self.alphabet1 ) == "ACGT"
+        isDna2 = "".join( self.alphabet2 ) == "ACGT"
+        labelRows = not ( isDna1 and isDna2 )
+        width = 3
+        for a in self.alphabet1:
+            for b in self.alphabet2:
+                score = self._get_score((ord(a),ord(b)))
+                if (type(score) == float): s = "%8.6f" % score
+                else:                      s = "%s"    % score
+                if (len(s)+1 > width):
+                    width = len(s)+1
+        lines = []
+        line = []
+        if labelRows:
+            if isDna1: line.append(" ")
+            else:      line.append("  ")
+        for b in self.alphabet2:
+            if isDna2: s = b
+            else:      s = "%02X" % ord(b)
+            line.append("%*s" % (width,s))
+        lines.append(("".join(line))+"\n")
+        for a in self.alphabet1:
+            line = []
+            if labelRows:
+                if isDna1: line.append(a)
+                else:      line.append("%02X" % ord(a))
+            for b in self.alphabet2:
+                score = self._get_score((ord(a),ord(b)))
+                if (type(score) == float): s = "%8.6f" % score
+                else:                      s = "%s"    % score
+                line.append("%*s" % (width,s))
+            lines.append(("".join(line))+"\n")
+        return "".join(lines)
+
+def read_scoring_scheme( f, gap_open, gap_extend, gap1="-", gap2=None, **kwargs ):
+    """
+    Initialize scoring scheme from a file containint a blastz style text blob.
+    f can be either a file or the name of a file.
+    """
+    close_it = False
+    if (type(f) == str):
+        f = file(f,"rt")
+        close_it = True
+    ss = build_scoring_scheme("".join([line for line in f]),gap_open, gap_extend, gap1=gap1, gap2=gap2, **kwargs)
+    if (close_it):
+        f.close()
+    return ss
+
+def build_scoring_scheme( s, gap_open, gap_extend, gap1="-", gap2=None, **kwargs ):
+    """
+    Initialize scoring scheme from a blastz style text blob, first line
+    specifies the bases for each row/col, subsequent lines contain the
+    corresponding scores.  Slaw extensions allow for unusual and/or
+    asymmetric alphabets.  Symbols can be two digit hex, and each row
+    begins with symbol.  Note that a row corresponds to a symbol in text1
+    and a column to a symbol in text2.
+
+    examples:
+
+       blastz                       slaw
+
+          A    C    G    T               01   02    A    C    G    T
+         91 -114  -31 -123          01  200 -200  -50  100  -50  100
+       -114  100 -125  -31          02 -200  200  100  -50  100  -50
+        -31 -125  100 -114
+       -123  -31 -114   91
+    """
+    # perform initial parse to determine alphabets and locate scores
+    bad_matrix = "invalid scoring matrix"
+    s = s.rstrip( "\n" )
+    lines = s.split( "\n" )
+    rows  = []
+    symbols2 = lines.pop(0).split()
+    symbols1 = None
+    rows_have_syms = False
+    a_la_blastz = True
+    for i, line in enumerate( lines ):
+        row_scores = line.split()
+        if len( row_scores ) == len( symbols2 ):        # blastz-style row
+            if symbols1 == None:
+                if len( lines ) != len( symbols2 ):
+                    raise bad_matrix
+                symbols1 = symbols2
+            elif (rows_have_syms):
+                raise bad_matrix
+        elif len( row_scores ) == len( symbols2 ) + 1:  # row starts with symbol
+            if symbols1 == None:
+                symbols1 = []
+                rows_have_syms = True
+                a_la_blastz = False
+            elif not rows_have_syms:
+                raise bad_matrix
+            symbols1.append( row_scores.pop(0) )
+        else:
+            raise bad_matrix
+        rows.append( row_scores )
+    # convert alphabets from strings to characters
+    try:
+        alphabet1 = [sym_to_char( sym ) for sym in symbols1]
+        alphabet2 = [sym_to_char( sym ) for sym in symbols2]
+    except ValueError:
+        raise bad_matrix
+    if (alphabet1 != symbols1) or (alphabet2 != symbols2):
+        a_la_blastz = False
+    if a_la_blastz:
+        alphabet1 = [ch.upper() for ch in alphabet1]
+        alphabet2 = [ch.upper() for ch in alphabet2]
+    # decide if rows and/or columns should reflect case
+    if a_la_blastz:
+        foldcase1 = foldcase2 = True
+    else:
+        foldcase1 = "".join( alphabet1 ) == "ACGT"
+        foldcase2 = "".join( alphabet2 ) == "ACGT"
+    # create appropriately sized matrix
+    text1_range = text2_range = 128
+    if ord( max( alphabet1 ) ) >= 128: text1_range = 256
+    if ord( max( alphabet2 ) ) >= 128: text2_range = 256
+    typecode = int32
+    for i, row_scores in enumerate( rows ):
+        for j, score in enumerate( map( int_or_float, row_scores ) ):
+            if type( score ) == float: 
+                typecode = float32
+    if type( gap_open ) == float: 
+        typecode = float32
+    if type( gap_extend ) == float: 
+        typecode = float32
+    ss = ScoringScheme( gap_open, gap_extend, alphabet1=alphabet1, alphabet2=alphabet2, gap1=gap1, gap2=gap2, text1_range=text1_range, text2_range=text2_range, typecode=typecode, **kwargs )
+    # fill matrix
+    for i, row_scores in enumerate( rows ):
+        for j, score in enumerate( map( int_or_float, row_scores ) ):
+            ss.set_score( ord( alphabet1[i] ), ord( alphabet2[j] ), score )
+            if foldcase1 and foldcase2:
+                ss.set_score( ord( alphabet1[i].lower() ), ord( alphabet2[j].upper() ), score )
+                ss.set_score( ord( alphabet1[i].upper() ), ord( alphabet2[j].lower() ), score )
+                ss.set_score( ord( alphabet1[i].lower() ), ord( alphabet2[j].lower() ), score )
+            elif foldcase1:
+                ss.set_score( ord( alphabet1[i].lower() ), ord( alphabet2[j]         ), score )
+            elif foldcase2:
+                ss.set_score( ord( alphabet1[i]         ), ord( alphabet2[j].lower() ), score )
+    return ss
+
+def int_or_float( s ):
+    try:    return int( s )
+    except: return float( s )
+
+# convert possible two-char symbol to a single character
+def sym_to_char( sym ):
+    if   len( sym ) == 1: return sym
+    elif len( sym ) != 2: raise ValueError
+    else:                 return chr(int(sym,base=16))
+
+def score_alignment( scoring_scheme, a ):
+    score = 0
+    ncomps = len( a.components )
+    for i in range( ncomps ):
+        for j in range( i+1, ncomps ):
+            score += score_texts( scoring_scheme, a.components[i].text, a.components[j].text )
+    return score
+    
+def score_texts( scoring_scheme, text1, text2 ):
+    rval = 0
+    last_gap_a = last_gap_b = False
+    for i in range( len( text1 ) ):
+        a = text1[i]
+        b = text2[i]
+        # Ignore gap/gap pair
+        if a == scoring_scheme.gap1 and b == scoring_scheme.gap2: 
+            continue
+        # Gap in first species
+        elif a == scoring_scheme.gap1:
+            rval -= scoring_scheme.gap_extend
+            if not last_gap_a:
+               rval -= scoring_scheme.gap_open
+               last_gap_a = True
+               last_gap_b = False
+        # Gap in second species
+        elif b == scoring_scheme.gap2:
+            rval -= scoring_scheme.gap_extend
+            if not last_gap_b:
+               rval -= scoring_scheme.gap_open
+               last_gap_a = False
+               last_gap_b = True
+        # Aligned base
+        else:   
+            rval += scoring_scheme._get_score((ord(a),ord(b)))
+            last_gap_a = last_gap_b = False
+    return rval
+
+def accumulate_scores( scoring_scheme, text1, text2, skip_ref_gaps=False ):
+    """
+    Return cumulative scores for each position in alignment as a 1d array.
+    
+    If `skip_ref_gaps` is False positions in returned array correspond to each
+    column in alignment, if True they correspond to each non-gap position (each
+    base) in text1.
+    """
+    if skip_ref_gaps:
+        rval = zeros( len( text1 ) - text1.count( scoring_scheme.gap1 ) )
+    else:
+        rval = zeros( len( text1 ) )
+    score = 0
+    pos = 0
+    last_gap_a = last_gap_b = False
+    for i in range( len( text1 ) ):
+        a = text1[i]
+        b = text2[i]
+        # Ignore gap/gap pair
+        if a == scoring_scheme.gap1 and b == scoring_scheme.gap2: 
+            continue
+        # Gap in first species
+        elif a == scoring_scheme.gap1:
+            score -= scoring_scheme.gap_extend
+            if not last_gap_a:
+               score -= scoring_scheme.gap_open
+               last_gap_a = True
+               last_gap_b = False
+        # Gap in second species
+        elif b == scoring_scheme.gap2:
+            score -= scoring_scheme.gap_extend
+            if not last_gap_b:
+               score -= scoring_scheme.gap_open
+               last_gap_a = False
+               last_gap_b = True
+        # Aligned base
+        else:   
+            score += scoring_scheme._get_score((ord(a),ord(b)))
+            last_gap_a = last_gap_b = False
+        if not( skip_ref_gaps ) or a != scoring_scheme.gap1:
+            rval[pos] = score
+            pos += 1
+    return rval
+
+hox70 = build_scoring_scheme( """  A    C    G    T
+                                  91 -114  -31 -123
+                                -114  100 -125  -31
+                                 -31 -125  100 -114
+                                -123  -31 -114   91 """, 400, 30 )
diff --git a/lib/bx/align/score_tests.py b/lib/bx/align/score_tests.py
new file mode 100644
index 0000000..83c1e9e
--- /dev/null
+++ b/lib/bx/align/score_tests.py
@@ -0,0 +1,94 @@
+"""
+Tests for `bx.align.score`.
+"""
+
+import bx.align.score
+import bx.align.maf
+import StringIO
+import unittest
+import sys
+
+from numpy import array, cumsum, allclose
+
+aligns = [ ( "CCACTAGTTTTTAAATAATCTACTATCAAATAAAAGATTTGTTAATAATAAATTTTAAATCATTAACACTT",
+             "CCATTTGGGTTCAAAAATTGATCTATCA----------TGGTGGATTATTATTTAGCCATTAAGGACAAAT", 
+             -111 ),
+           ( "CCACTAGTTTTTAAATAATCTAC-----AATAAAAGATTTGTTAATAAT---AAATTTTAAATCATTAA-----CACTT",
+             "CCATTTGGGTTCAAAAATTGATCTATCA----------TGGTGGAT---TATTATTT-----AGCCATTAAGGACAAAT", 
+             -3626 ),
+           ( "CCACTAGTTTTTGATTC",
+             "CCATTTGGGTTC-----", 
+             -299 ),
+           ( "CTTAGTTTTTGATCACC",
+             "-----CTTGGGTTTACC", 
+             -299 ),
+           ( "gggaattgaacaatgagaacacatggacacaggaaggggaacatcacacacc----------ggggcctgttgtggggtggggggaag",
+             "ggaactagaacaagggagacacatacaaacaacaacaacaacaacacagcccttcccttcaaagagcttatagtctgatggaggagag",
+             1690 )
+         ]
+
+mafs = """##maf
+a score=2883.0
+s hg17.chr1             6734 30 + 245522847 CTACCTCAGTGTGGAAGGTGGGCAGTTCTG
+s rheMac1.SCAFFOLD71394 9319 30 -     13789 CTACCTCAGTGTGGAAGGTGGGCAGTTCTG
+
+a score=8167.0
+s hg17.chr1             41401 40 + 245522847 TGTGTGATTAATGCCTGAGACTGTGTGAAGTAAGAGATGG
+s panTro1.chr1          49673 40 + 229575298 TGCGTGATTAATGCCTGAGATTGTGTGAAGTAAAAGATGG
+s rheMac1.SCAFFOLD45837 26063 33 -     31516 TGTGTGATTAATGCCTGAGATTGTGTGAAGTAA-------
+"""
+
+nonsymm_scheme = bx.align.score.build_scoring_scheme ( """  A    C    G    T
+                                                           91    0  -31 -123
+                                                         -114  100 -125  -31
+                                                          -31 -125  100 -114
+                                                         -123  -31 -114   91 """, 400, 30 )
+
+aligns_for_nonsymm_scheme = [ ( "AAAACCCCGGGGTTTT",
+                                "ACGTACGTACGTACGT", 
+                                -580 )
+                            ]
+
+
+asymm_scheme = bx.align.score.build_scoring_scheme ( """    01   02    A    C    G    T
+                                                       01  200 -200  -50  100  -50  100
+                                                       02 -200  200  100  -50  100  -50 """,
+                                                       0, 0, gap1='\x00' )
+
+aligns_for_asymm_scheme = [ ( "\x01\x01\x01\x01\x01\x01",
+                              "ACGT\x01\x02", 
+                              100 )
+                          ]
+
+
+class BasicTests( unittest.TestCase ):
+
+    def test_scoring_text( self ):
+        ss = bx.align.score.hox70
+        for t1, t2, score in aligns:
+            self.assertEquals( bx.align.score.score_texts( ss, t1, t2 ), score )
+            
+    def test_align( self ):
+        ss = bx.align.score.hox70
+        for block in bx.align.maf.Reader( StringIO.StringIO( mafs ) ):
+            self.assertEquals( bx.align.score.score_alignment( ss, block ), float( block.score ) )
+            
+    def test_accumulate( self ):
+        ss = bx.align.score.hox70
+        self.assert_( allclose( bx.align.score.accumulate_scores( ss, "-----CTTT", "CTTAGTTTA"  ),
+                           cumsum( array( [ -430, -30, -30, -30, -30, -31, 91, 91, -123 ] ) ) ) )
+        self.assert_( allclose( bx.align.score.accumulate_scores( ss, "-----CTTT", "CTTAGTTTA", skip_ref_gaps=True ),
+                           cumsum( array( [ -581, 91, 91, -123 ] ) ) ) )
+
+    def test_nonsymm_scoring( self ):
+        ss = nonsymm_scheme
+        for t1, t2, score in aligns_for_nonsymm_scheme:
+            self.assertEquals( bx.align.score.score_texts( ss, t1, t2 ), score )
+
+    def test_asymm_scoring( self ):
+        ss = asymm_scheme
+        for t1, t2, score in aligns_for_asymm_scheme:
+            self.assertEquals( bx.align.score.score_texts( ss, t1, t2 ), score )
+   
+test_classes = [ BasicTests ]
+suite = unittest.TestSuite( [ unittest.makeSuite( c ) for c in test_classes ] )
diff --git a/lib/bx/align/sitemask/__init__.py b/lib/bx/align/sitemask/__init__.py
new file mode 100644
index 0000000..84772d6
--- /dev/null
+++ b/lib/bx/align/sitemask/__init__.py
@@ -0,0 +1,6 @@
+"""
+Tools for masking out specific sites in aligments by various criteria, for
+example masking CpG sites or sites with low sequence quality.
+"""
+
+from bx.align.sitemask.core import *
diff --git a/lib/bx/align/sitemask/_cpg.c b/lib/bx/align/sitemask/_cpg.c
new file mode 100644
index 0000000..db78fd4
--- /dev/null
+++ b/lib/bx/align/sitemask/_cpg.c
@@ -0,0 +1,3042 @@
+/* Generated by Cython 0.18 on Mon Jul 15 13:25:44 2013 */
+
+#define PY_SSIZE_T_CLEAN
+#include "Python.h"
+#ifndef Py_PYTHON_H
+    #error Python headers needed to compile C extensions, please install development version of Python.
+#elif PY_VERSION_HEX < 0x02040000
+    #error Cython requires Python 2.4+.
+#else
+#include <stddef.h> /* For offsetof */
+#ifndef offsetof
+#define offsetof(type, member) ( (size_t) & ((type*)0) -> member )
+#endif
+#if !defined(WIN32) && !defined(MS_WINDOWS)
+  #ifndef __stdcall
+    #define __stdcall
+  #endif
+  #ifndef __cdecl
+    #define __cdecl
+  #endif
+  #ifndef __fastcall
+    #define __fastcall
+  #endif
+#endif
+#ifndef DL_IMPORT
+  #define DL_IMPORT(t) t
+#endif
+#ifndef DL_EXPORT
+  #define DL_EXPORT(t) t
+#endif
+#ifndef PY_LONG_LONG
+  #define PY_LONG_LONG LONG_LONG
+#endif
+#ifndef Py_HUGE_VAL
+  #define Py_HUGE_VAL HUGE_VAL
+#endif
+#ifdef PYPY_VERSION
+#define CYTHON_COMPILING_IN_PYPY 1
+#define CYTHON_COMPILING_IN_CPYTHON 0
+#else
+#define CYTHON_COMPILING_IN_PYPY 0
+#define CYTHON_COMPILING_IN_CPYTHON 1
+#endif
+#if PY_VERSION_HEX < 0x02050000
+  typedef int Py_ssize_t;
+  #define PY_SSIZE_T_MAX INT_MAX
+  #define PY_SSIZE_T_MIN INT_MIN
+  #define PY_FORMAT_SIZE_T ""
+  #define CYTHON_FORMAT_SSIZE_T ""
+  #define PyInt_FromSsize_t(z) PyInt_FromLong(z)
+  #define PyInt_AsSsize_t(o)   __Pyx_PyInt_AsInt(o)
+  #define PyNumber_Index(o)    ((PyNumber_Check(o) && !PyFloat_Check(o)) ? PyNumber_Int(o) : \
+                                (PyErr_Format(PyExc_TypeError, \
+                                              "expected index value, got %.200s", Py_TYPE(o)->tp_name), \
+                                 (PyObject*)0))
+  #define __Pyx_PyIndex_Check(o) (PyNumber_Check(o) && !PyFloat_Check(o) && \
+                                  !PyComplex_Check(o))
+  #define PyIndex_Check __Pyx_PyIndex_Check
+  #define PyErr_WarnEx(category, message, stacklevel) PyErr_Warn(category, message)
+  #define __PYX_BUILD_PY_SSIZE_T "i"
+#else
+  #define __PYX_BUILD_PY_SSIZE_T "n"
+  #define CYTHON_FORMAT_SSIZE_T "z"
+  #define __Pyx_PyIndex_Check PyIndex_Check
+#endif
+#if PY_VERSION_HEX < 0x02060000
+  #define Py_REFCNT(ob) (((PyObject*)(ob))->ob_refcnt)
+  #define Py_TYPE(ob)   (((PyObject*)(ob))->ob_type)
+  #define Py_SIZE(ob)   (((PyVarObject*)(ob))->ob_size)
+  #define PyVarObject_HEAD_INIT(type, size) \
+          PyObject_HEAD_INIT(type) size,
+  #define PyType_Modified(t)
+  typedef struct {
+     void *buf;
+     PyObject *obj;
+     Py_ssize_t len;
+     Py_ssize_t itemsize;
+     int readonly;
+     int ndim;
+     char *format;
+     Py_ssize_t *shape;
+     Py_ssize_t *strides;
+     Py_ssize_t *suboffsets;
+     void *internal;
+  } Py_buffer;
+  #define PyBUF_SIMPLE 0
+  #define PyBUF_WRITABLE 0x0001
+  #define PyBUF_FORMAT 0x0004
+  #define PyBUF_ND 0x0008
+  #define PyBUF_STRIDES (0x0010 | PyBUF_ND)
+  #define PyBUF_C_CONTIGUOUS (0x0020 | PyBUF_STRIDES)
+  #define PyBUF_F_CONTIGUOUS (0x0040 | PyBUF_STRIDES)
+  #define PyBUF_ANY_CONTIGUOUS (0x0080 | PyBUF_STRIDES)
+  #define PyBUF_INDIRECT (0x0100 | PyBUF_STRIDES)
+  #define PyBUF_RECORDS (PyBUF_STRIDES | PyBUF_FORMAT | PyBUF_WRITABLE)
+  #define PyBUF_FULL (PyBUF_INDIRECT | PyBUF_FORMAT | PyBUF_WRITABLE)
+  typedef int (*getbufferproc)(PyObject *, Py_buffer *, int);
+  typedef void (*releasebufferproc)(PyObject *, Py_buffer *);
+#endif
+#if PY_MAJOR_VERSION < 3
+  #define __Pyx_BUILTIN_MODULE_NAME "__builtin__"
+  #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \
+          PyCode_New(a, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
+#else
+  #define __Pyx_BUILTIN_MODULE_NAME "builtins"
+  #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \
+          PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
+#endif
+#if PY_MAJOR_VERSION < 3 && PY_MINOR_VERSION < 6
+  #define PyUnicode_FromString(s) PyUnicode_Decode(s, strlen(s), "UTF-8", "strict")
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define Py_TPFLAGS_CHECKTYPES 0
+  #define Py_TPFLAGS_HAVE_INDEX 0
+#endif
+#if (PY_VERSION_HEX < 0x02060000) || (PY_MAJOR_VERSION >= 3)
+  #define Py_TPFLAGS_HAVE_NEWBUFFER 0
+#endif
+#if PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND)
+  #define CYTHON_PEP393_ENABLED 1
+  #define __Pyx_PyUnicode_READY(op)       (likely(PyUnicode_IS_READY(op)) ? \
+                                              0 : _PyUnicode_Ready((PyObject *)(op)))
+  #define __Pyx_PyUnicode_GET_LENGTH(u)   PyUnicode_GET_LENGTH(u)
+  #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_READ_CHAR(u, i)
+  #define __Pyx_PyUnicode_READ(k, d, i)   PyUnicode_READ(k, d, i)
+#else
+  #define CYTHON_PEP393_ENABLED 0
+  #define __Pyx_PyUnicode_READY(op)       (0)
+  #define __Pyx_PyUnicode_GET_LENGTH(u)   PyUnicode_GET_SIZE(u)
+  #define __Pyx_PyUnicode_READ_CHAR(u, i) ((Py_UCS4)(PyUnicode_AS_UNICODE(u)[i]))
+  #define __Pyx_PyUnicode_READ(k, d, i)   ((k=k), (Py_UCS4)(((Py_UNICODE*)d)[i]))
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define PyBaseString_Type            PyUnicode_Type
+  #define PyStringObject               PyUnicodeObject
+  #define PyString_Type                PyUnicode_Type
+  #define PyString_Check               PyUnicode_Check
+  #define PyString_CheckExact          PyUnicode_CheckExact
+#endif
+#if PY_VERSION_HEX < 0x02060000
+  #define PyBytesObject                PyStringObject
+  #define PyBytes_Type                 PyString_Type
+  #define PyBytes_Check                PyString_Check
+  #define PyBytes_CheckExact           PyString_CheckExact
+  #define PyBytes_FromString           PyString_FromString
+  #define PyBytes_FromStringAndSize    PyString_FromStringAndSize
+  #define PyBytes_FromFormat           PyString_FromFormat
+  #define PyBytes_DecodeEscape         PyString_DecodeEscape
+  #define PyBytes_AsString             PyString_AsString
+  #define PyBytes_AsStringAndSize      PyString_AsStringAndSize
+  #define PyBytes_Size                 PyString_Size
+  #define PyBytes_AS_STRING            PyString_AS_STRING
+  #define PyBytes_GET_SIZE             PyString_GET_SIZE
+  #define PyBytes_Repr                 PyString_Repr
+  #define PyBytes_Concat               PyString_Concat
+  #define PyBytes_ConcatAndDel         PyString_ConcatAndDel
+#endif
+#if PY_VERSION_HEX < 0x02060000
+  #define PySet_Check(obj)             PyObject_TypeCheck(obj, &PySet_Type)
+  #define PyFrozenSet_Check(obj)       PyObject_TypeCheck(obj, &PyFrozenSet_Type)
+#endif
+#ifndef PySet_CheckExact
+  #define PySet_CheckExact(obj)        (Py_TYPE(obj) == &PySet_Type)
+#endif
+#define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type)
+#if PY_MAJOR_VERSION >= 3
+  #define PyIntObject                  PyLongObject
+  #define PyInt_Type                   PyLong_Type
+  #define PyInt_Check(op)              PyLong_Check(op)
+  #define PyInt_CheckExact(op)         PyLong_CheckExact(op)
+  #define PyInt_FromString             PyLong_FromString
+  #define PyInt_FromUnicode            PyLong_FromUnicode
+  #define PyInt_FromLong               PyLong_FromLong
+  #define PyInt_FromSize_t             PyLong_FromSize_t
+  #define PyInt_FromSsize_t            PyLong_FromSsize_t
+  #define PyInt_AsLong                 PyLong_AsLong
+  #define PyInt_AS_LONG                PyLong_AS_LONG
+  #define PyInt_AsSsize_t              PyLong_AsSsize_t
+  #define PyInt_AsUnsignedLongMask     PyLong_AsUnsignedLongMask
+  #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define PyBoolObject                 PyLongObject
+#endif
+#if PY_VERSION_HEX < 0x03020000
+  typedef long Py_hash_t;
+  #define __Pyx_PyInt_FromHash_t PyInt_FromLong
+  #define __Pyx_PyInt_AsHash_t   PyInt_AsLong
+#else
+  #define __Pyx_PyInt_FromHash_t PyInt_FromSsize_t
+  #define __Pyx_PyInt_AsHash_t   PyInt_AsSsize_t
+#endif
+#if (PY_MAJOR_VERSION < 3) || (PY_VERSION_HEX >= 0x03010300)
+  #define __Pyx_PySequence_GetSlice(obj, a, b) PySequence_GetSlice(obj, a, b)
+  #define __Pyx_PySequence_SetSlice(obj, a, b, value) PySequence_SetSlice(obj, a, b, value)
+  #define __Pyx_PySequence_DelSlice(obj, a, b) PySequence_DelSlice(obj, a, b)
+#else
+  #define __Pyx_PySequence_GetSlice(obj, a, b) (unlikely(!(obj)) ? \
+        (PyErr_SetString(PyExc_SystemError, "null argument to internal routine"), (PyObject*)0) : \
+        (likely((obj)->ob_type->tp_as_mapping) ? (PySequence_GetSlice(obj, a, b)) : \
+            (PyErr_Format(PyExc_TypeError, "'%.200s' object is unsliceable", (obj)->ob_type->tp_name), (PyObject*)0)))
+  #define __Pyx_PySequence_SetSlice(obj, a, b, value) (unlikely(!(obj)) ? \
+        (PyErr_SetString(PyExc_SystemError, "null argument to internal routine"), -1) : \
+        (likely((obj)->ob_type->tp_as_mapping) ? (PySequence_SetSlice(obj, a, b, value)) : \
+            (PyErr_Format(PyExc_TypeError, "'%.200s' object doesn't support slice assignment", (obj)->ob_type->tp_name), -1)))
+  #define __Pyx_PySequence_DelSlice(obj, a, b) (unlikely(!(obj)) ? \
+        (PyErr_SetString(PyExc_SystemError, "null argument to internal routine"), -1) : \
+        (likely((obj)->ob_type->tp_as_mapping) ? (PySequence_DelSlice(obj, a, b)) : \
+            (PyErr_Format(PyExc_TypeError, "'%.200s' object doesn't support slice deletion", (obj)->ob_type->tp_name), -1)))
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define PyMethod_New(func, self, klass) ((self) ? PyMethod_New(func, self) : PyInstanceMethod_New(func))
+#endif
+#if PY_VERSION_HEX < 0x02050000
+  #define __Pyx_GetAttrString(o,n)   PyObject_GetAttrString((o),((char *)(n)))
+  #define __Pyx_SetAttrString(o,n,a) PyObject_SetAttrString((o),((char *)(n)),(a))
+  #define __Pyx_DelAttrString(o,n)   PyObject_DelAttrString((o),((char *)(n)))
+#else
+  #define __Pyx_GetAttrString(o,n)   PyObject_GetAttrString((o),(n))
+  #define __Pyx_SetAttrString(o,n,a) PyObject_SetAttrString((o),(n),(a))
+  #define __Pyx_DelAttrString(o,n)   PyObject_DelAttrString((o),(n))
+#endif
+#if PY_VERSION_HEX < 0x02050000
+  #define __Pyx_NAMESTR(n) ((char *)(n))
+  #define __Pyx_DOCSTR(n)  ((char *)(n))
+#else
+  #define __Pyx_NAMESTR(n) (n)
+  #define __Pyx_DOCSTR(n)  (n)
+#endif
+
+
+#if PY_MAJOR_VERSION >= 3
+  #define __Pyx_PyNumber_Divide(x,y)         PyNumber_TrueDivide(x,y)
+  #define __Pyx_PyNumber_InPlaceDivide(x,y)  PyNumber_InPlaceTrueDivide(x,y)
+#else
+  #define __Pyx_PyNumber_Divide(x,y)         PyNumber_Divide(x,y)
+  #define __Pyx_PyNumber_InPlaceDivide(x,y)  PyNumber_InPlaceDivide(x,y)
+#endif
+
+#ifndef __PYX_EXTERN_C
+  #ifdef __cplusplus
+    #define __PYX_EXTERN_C extern "C"
+  #else
+    #define __PYX_EXTERN_C extern
+  #endif
+#endif
+
+#if defined(WIN32) || defined(MS_WINDOWS)
+#define _USE_MATH_DEFINES
+#endif
+#include <math.h>
+#define __PYX_HAVE__bx__align__sitemask___cpg
+#define __PYX_HAVE_API__bx__align__sitemask___cpg
+#include "find_cpg.h"
+#ifdef _OPENMP
+#include <omp.h>
+#endif /* _OPENMP */
+
+#ifdef PYREX_WITHOUT_ASSERTIONS
+#define CYTHON_WITHOUT_ASSERTIONS
+#endif
+
+#ifndef CYTHON_INLINE
+  #if defined(__GNUC__)
+    #define CYTHON_INLINE __inline__
+  #elif defined(_MSC_VER)
+    #define CYTHON_INLINE __inline
+  #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+    #define CYTHON_INLINE inline
+  #else
+    #define CYTHON_INLINE
+  #endif
+#endif
+#ifndef CYTHON_UNUSED
+# if defined(__GNUC__)
+#   if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
+#     define CYTHON_UNUSED __attribute__ ((__unused__))
+#   else
+#     define CYTHON_UNUSED
+#   endif
+# elif defined(__ICC) || (defined(__INTEL_COMPILER) && !defined(_MSC_VER))
+#   define CYTHON_UNUSED __attribute__ ((__unused__))
+# else
+#   define CYTHON_UNUSED
+# endif
+#endif
+typedef struct {PyObject **p; char *s; const long n; const char* encoding; const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry; /*proto*/
+
+#define __Pyx_PyBytes_FromUString(s) PyBytes_FromString((char*)s)
+#define __Pyx_PyBytes_AsUString(s)   ((unsigned char*) PyBytes_AsString(s))
+#define __Pyx_Owned_Py_None(b) (Py_INCREF(Py_None), Py_None)
+#define __Pyx_PyBool_FromLong(b) ((b) ? (Py_INCREF(Py_True), Py_True) : (Py_INCREF(Py_False), Py_False))
+static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*);
+static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x);
+static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*);
+static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t);
+static CYTHON_INLINE size_t __Pyx_PyInt_AsSize_t(PyObject*);
+#if CYTHON_COMPILING_IN_CPYTHON
+#define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x))
+#else
+#define __pyx_PyFloat_AsDouble(x) PyFloat_AsDouble(x)
+#endif
+#define __pyx_PyFloat_AsFloat(x) ((float) __pyx_PyFloat_AsDouble(x))
+
+
+#ifdef __GNUC__
+  /* Test for GCC > 2.95 */
+  #if __GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))
+    #define likely(x)   __builtin_expect(!!(x), 1)
+    #define unlikely(x) __builtin_expect(!!(x), 0)
+  #else /* __GNUC__ > 2 ... */
+    #define likely(x)   (x)
+    #define unlikely(x) (x)
+  #endif /* __GNUC__ > 2 ... */
+#else /* __GNUC__ */
+  #define likely(x)   (x)
+  #define unlikely(x) (x)
+#endif /* __GNUC__ */
+    
+static PyObject *__pyx_m;
+static PyObject *__pyx_b;
+static PyObject *__pyx_empty_tuple;
+static PyObject *__pyx_empty_bytes;
+static int __pyx_lineno;
+static int __pyx_clineno = 0;
+static const char * __pyx_cfilenm= __FILE__;
+static const char *__pyx_filename;
+
+
+static const char *__pyx_f[] = {
+  "_cpg.pyx",
+};
+
+/*--- Type declarations ---*/
+#ifndef CYTHON_REFNANNY
+  #define CYTHON_REFNANNY 0
+#endif
+#if CYTHON_REFNANNY
+  typedef struct {
+    void (*INCREF)(void*, PyObject*, int);
+    void (*DECREF)(void*, PyObject*, int);
+    void (*GOTREF)(void*, PyObject*, int);
+    void (*GIVEREF)(void*, PyObject*, int);
+    void* (*SetupContext)(const char*, int, const char*);
+    void (*FinishContext)(void**);
+  } __Pyx_RefNannyAPIStruct;
+  static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL;
+  static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname); /*proto*/
+  #define __Pyx_RefNannyDeclarations void *__pyx_refnanny = NULL;
+#ifdef WITH_THREAD
+  #define __Pyx_RefNannySetupContext(name, acquire_gil) \
+          if (acquire_gil) { \
+              PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure(); \
+              __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__); \
+              PyGILState_Release(__pyx_gilstate_save); \
+          } else { \
+              __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__); \
+          }
+#else
+  #define __Pyx_RefNannySetupContext(name, acquire_gil) \
+          __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__)
+#endif
+  #define __Pyx_RefNannyFinishContext() \
+          __Pyx_RefNanny->FinishContext(&__pyx_refnanny)
+  #define __Pyx_INCREF(r)  __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_DECREF(r)  __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_GOTREF(r)  __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_XINCREF(r)  do { if((r) != NULL) {__Pyx_INCREF(r); }} while(0)
+  #define __Pyx_XDECREF(r)  do { if((r) != NULL) {__Pyx_DECREF(r); }} while(0)
+  #define __Pyx_XGOTREF(r)  do { if((r) != NULL) {__Pyx_GOTREF(r); }} while(0)
+  #define __Pyx_XGIVEREF(r) do { if((r) != NULL) {__Pyx_GIVEREF(r);}} while(0)
+#else
+  #define __Pyx_RefNannyDeclarations
+  #define __Pyx_RefNannySetupContext(name, acquire_gil)
+  #define __Pyx_RefNannyFinishContext()
+  #define __Pyx_INCREF(r) Py_INCREF(r)
+  #define __Pyx_DECREF(r) Py_DECREF(r)
+  #define __Pyx_GOTREF(r)
+  #define __Pyx_GIVEREF(r)
+  #define __Pyx_XINCREF(r) Py_XINCREF(r)
+  #define __Pyx_XDECREF(r) Py_XDECREF(r)
+  #define __Pyx_XGOTREF(r)
+  #define __Pyx_XGIVEREF(r)
+#endif /* CYTHON_REFNANNY */
+#define __Pyx_CLEAR(r)    do { PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);} while(0)
+#define __Pyx_XCLEAR(r)   do { if((r) != NULL) {PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);}} while(0)
+
+static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
+    Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/
+
+static void __Pyx_RaiseDoubleKeywordsError(const char* func_name, PyObject* kw_name); /*proto*/
+
+static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
+    PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
+    const char* function_name); /*proto*/
+
+static CYTHON_INLINE unsigned char __Pyx_PyInt_AsUnsignedChar(PyObject *);
+
+static CYTHON_INLINE unsigned short __Pyx_PyInt_AsUnsignedShort(PyObject *);
+
+static CYTHON_INLINE unsigned int __Pyx_PyInt_AsUnsignedInt(PyObject *);
+
+static CYTHON_INLINE char __Pyx_PyInt_AsChar(PyObject *);
+
+static CYTHON_INLINE short __Pyx_PyInt_AsShort(PyObject *);
+
+static CYTHON_INLINE int __Pyx_PyInt_AsInt(PyObject *);
+
+static CYTHON_INLINE signed char __Pyx_PyInt_AsSignedChar(PyObject *);
+
+static CYTHON_INLINE signed short __Pyx_PyInt_AsSignedShort(PyObject *);
+
+static CYTHON_INLINE signed int __Pyx_PyInt_AsSignedInt(PyObject *);
+
+static CYTHON_INLINE int __Pyx_PyInt_AsLongDouble(PyObject *);
+
+static CYTHON_INLINE unsigned long __Pyx_PyInt_AsUnsignedLong(PyObject *);
+
+static CYTHON_INLINE unsigned PY_LONG_LONG __Pyx_PyInt_AsUnsignedLongLong(PyObject *);
+
+static CYTHON_INLINE long __Pyx_PyInt_AsLong(PyObject *);
+
+static CYTHON_INLINE PY_LONG_LONG __Pyx_PyInt_AsLongLong(PyObject *);
+
+static CYTHON_INLINE signed long __Pyx_PyInt_AsSignedLong(PyObject *);
+
+static CYTHON_INLINE signed PY_LONG_LONG __Pyx_PyInt_AsSignedLongLong(PyObject *);
+
+static int __Pyx_check_binary_version(void);
+
+typedef struct {
+    int code_line;
+    PyCodeObject* code_object;
+} __Pyx_CodeObjectCacheEntry;
+struct __Pyx_CodeObjectCache {
+    int count;
+    int max_count;
+    __Pyx_CodeObjectCacheEntry* entries;
+};
+static struct __Pyx_CodeObjectCache __pyx_code_cache = {0,0,NULL};
+static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line);
+static PyCodeObject *__pyx_find_code_object(int code_line);
+static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object);
+
+static void __Pyx_AddTraceback(const char *funcname, int c_line,
+                               int py_line, const char *filename); /*proto*/
+
+static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
+
+
+/* Module declarations from 'bx.align.sitemask._cpg' */
+#define __Pyx_MODULE_NAME "bx.align.sitemask._cpg"
+int __pyx_module_is_main_bx__align__sitemask___cpg = 0;
+
+/* Implementation of 'bx.align.sitemask._cpg' */
+static PyObject *__pyx_pf_2bx_5align_8sitemask_4_cpg_find_cpg(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_sp1, PyObject *__pyx_v_sp2, PyObject *__pyx_v_start); /* proto */
+static PyObject *__pyx_pf_2bx_5align_8sitemask_4_cpg_2find_cpg_restricted(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_sp1, PyObject *__pyx_v_sp2, PyObject *__pyx_v_start); /* proto */
+static PyObject *__pyx_pf_2bx_5align_8sitemask_4_cpg_4find_non_cpg(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_sp1, PyObject *__pyx_v_sp2, PyObject *__pyx_v_start); /* proto */
+static PyObject *__pyx_pf_2bx_5align_8sitemask_4_cpg_6list_cpg(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_sp1, PyObject *__pyx_v_sp2); /* proto */
+static PyObject *__pyx_pf_2bx_5align_8sitemask_4_cpg_8list_cpg_restricted(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_sp1, PyObject *__pyx_v_sp2); /* proto */
+static PyObject *__pyx_pf_2bx_5align_8sitemask_4_cpg_10list_non_cpg(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_sp1, PyObject *__pyx_v_sp2); /* proto */
+static PyObject *__pyx_pf_2bx_5align_8sitemask_4_cpg_12remove_gaps(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_sp, PyObject *__pyx_v_cpglist); /* proto */
+static char __pyx_k_1[] = "-";
+static char __pyx_k_2[] = "\nPyrex/C extension for quickly finding potential CpG sites in pairs of \nsequences.\n";
+static char __pyx_k_5[] = "/aut/proj/odenas/software/bx-python/lib/bx/align/sitemask/_cpg.pyx";
+static char __pyx_k_6[] = "bx.align.sitemask._cpg";
+static char __pyx_k__a[] = "a";
+static char __pyx_k__b[] = "b";
+static char __pyx_k__sp[] = "sp";
+static char __pyx_k__pos[] = "pos";
+static char __pyx_k__sp1[] = "sp1";
+static char __pyx_k__sp2[] = "sp2";
+static char __pyx_k__item[] = "item";
+static char __pyx_k__start[] = "start";
+static char __pyx_k__remove[] = "remove";
+static char __pyx_k__cpglist[] = "cpglist";
+static char __pyx_k____main__[] = "__main__";
+static char __pyx_k____test__[] = "__test__";
+static char __pyx_k__find_cpg[] = "find_cpg";
+static char __pyx_k__list_cpg[] = "list_cpg";
+static char __pyx_k__remove_gaps[] = "remove_gaps";
+static char __pyx_k__find_non_cpg[] = "find_non_cpg";
+static char __pyx_k__list_non_cpg[] = "list_non_cpg";
+static char __pyx_k__find_cpg_restricted[] = "find_cpg_restricted";
+static char __pyx_k__list_cpg_restricted[] = "list_cpg_restricted";
+static PyObject *__pyx_kp_s_1;
+static PyObject *__pyx_kp_s_5;
+static PyObject *__pyx_n_s_6;
+static PyObject *__pyx_n_s____main__;
+static PyObject *__pyx_n_s____test__;
+static PyObject *__pyx_n_s__a;
+static PyObject *__pyx_n_s__b;
+static PyObject *__pyx_n_s__cpglist;
+static PyObject *__pyx_n_s__find_cpg;
+static PyObject *__pyx_n_s__find_cpg_restricted;
+static PyObject *__pyx_n_s__find_non_cpg;
+static PyObject *__pyx_n_s__item;
+static PyObject *__pyx_n_s__list_cpg;
+static PyObject *__pyx_n_s__list_cpg_restricted;
+static PyObject *__pyx_n_s__list_non_cpg;
+static PyObject *__pyx_n_s__pos;
+static PyObject *__pyx_n_s__remove;
+static PyObject *__pyx_n_s__remove_gaps;
+static PyObject *__pyx_n_s__sp;
+static PyObject *__pyx_n_s__sp1;
+static PyObject *__pyx_n_s__sp2;
+static PyObject *__pyx_n_s__start;
+static PyObject *__pyx_int_neg_1;
+static PyObject *__pyx_k_tuple_3;
+static PyObject *__pyx_k_tuple_7;
+static PyObject *__pyx_k_tuple_9;
+static PyObject *__pyx_k_tuple_11;
+static PyObject *__pyx_k_tuple_13;
+static PyObject *__pyx_k_tuple_15;
+static PyObject *__pyx_k_tuple_17;
+static PyObject *__pyx_k_codeobj_4;
+static PyObject *__pyx_k_codeobj_8;
+static PyObject *__pyx_k_codeobj_10;
+static PyObject *__pyx_k_codeobj_12;
+static PyObject *__pyx_k_codeobj_14;
+static PyObject *__pyx_k_codeobj_16;
+static PyObject *__pyx_k_codeobj_18;
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_5align_8sitemask_4_cpg_1find_cpg(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_mdef_2bx_5align_8sitemask_4_cpg_1find_cpg = {__Pyx_NAMESTR("find_cpg"), (PyCFunction)__pyx_pw_2bx_5align_8sitemask_4_cpg_1find_cpg, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(0)};
+static PyObject *__pyx_pw_2bx_5align_8sitemask_4_cpg_1find_cpg(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_sp1 = 0;
+  PyObject *__pyx_v_sp2 = 0;
+  PyObject *__pyx_v_start = 0;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("find_cpg (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__sp1,&__pyx_n_s__sp2,&__pyx_n_s__start,0};
+    PyObject* values[3] = {0,0,0};
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__sp1)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__sp2)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("find_cpg", 1, 3, 3, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 11; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+        case  2:
+        if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__start)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("find_cpg", 1, 3, 3, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 11; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "find_cpg") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 11; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else if (PyTuple_GET_SIZE(__pyx_args) != 3) {
+      goto __pyx_L5_argtuple_error;
+    } else {
+      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+      values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+    }
+    __pyx_v_sp1 = values[0];
+    __pyx_v_sp2 = values[1];
+    __pyx_v_start = values[2];
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("find_cpg", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 11; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.align.sitemask._cpg.find_cpg", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_5align_8sitemask_4_cpg_find_cpg(__pyx_self, __pyx_v_sp1, __pyx_v_sp2, __pyx_v_start);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/align/sitemask/_cpg.pyx":11
+ *     int next_non_cpg( char * sp1, char * sp2, int start)
+ * 
+ * def find_cpg( sp1, sp2, start ):             # <<<<<<<<<<<<<<
+ *     cdef char* a
+ *     cdef char* b
+ */
+
+static PyObject *__pyx_pf_2bx_5align_8sitemask_4_cpg_find_cpg(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_sp1, PyObject *__pyx_v_sp2, PyObject *__pyx_v_start) {
+  char *__pyx_v_a;
+  char *__pyx_v_b;
+  int __pyx_v_pos;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  char *__pyx_t_1;
+  int __pyx_t_2;
+  Py_ssize_t __pyx_t_3;
+  int __pyx_t_4;
+  PyObject *__pyx_t_5 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("find_cpg", 0);
+
+  /* "bx/align/sitemask/_cpg.pyx":15
+ *     cdef char* b
+ *     cdef int pos
+ *     a = sp1             # <<<<<<<<<<<<<<
+ *     b = sp2
+ *     pos = start
+ */
+  __pyx_t_1 = PyBytes_AsString(__pyx_v_sp1); if (unlikely((!__pyx_t_1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 15; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_v_a = __pyx_t_1;
+
+  /* "bx/align/sitemask/_cpg.pyx":16
+ *     cdef int pos
+ *     a = sp1
+ *     b = sp2             # <<<<<<<<<<<<<<
+ *     pos = start
+ *     if pos > len(sp1): return -1
+ */
+  __pyx_t_1 = PyBytes_AsString(__pyx_v_sp2); if (unlikely((!__pyx_t_1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 16; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_v_b = __pyx_t_1;
+
+  /* "bx/align/sitemask/_cpg.pyx":17
+ *     a = sp1
+ *     b = sp2
+ *     pos = start             # <<<<<<<<<<<<<<
+ *     if pos > len(sp1): return -1
+ *     return next_cpg( a, b, pos )
+ */
+  __pyx_t_2 = __Pyx_PyInt_AsInt(__pyx_v_start); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_v_pos = __pyx_t_2;
+
+  /* "bx/align/sitemask/_cpg.pyx":18
+ *     b = sp2
+ *     pos = start
+ *     if pos > len(sp1): return -1             # <<<<<<<<<<<<<<
+ *     return next_cpg( a, b, pos )
+ * 
+ */
+  __pyx_t_3 = PyObject_Length(__pyx_v_sp1); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 18; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_4 = (__pyx_v_pos > __pyx_t_3);
+  if (__pyx_t_4) {
+    __Pyx_XDECREF(__pyx_r);
+    __Pyx_INCREF(__pyx_int_neg_1);
+    __pyx_r = __pyx_int_neg_1;
+    goto __pyx_L0;
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  /* "bx/align/sitemask/_cpg.pyx":19
+ *     pos = start
+ *     if pos > len(sp1): return -1
+ *     return next_cpg( a, b, pos )             # <<<<<<<<<<<<<<
+ * 
+ * def find_cpg_restricted( sp1, sp2, start ):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_5 = PyInt_FromLong(next_cpg(__pyx_v_a, __pyx_v_b, __pyx_v_pos)); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 19; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __pyx_r = __pyx_t_5;
+  __pyx_t_5 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_5);
+  __Pyx_AddTraceback("bx.align.sitemask._cpg.find_cpg", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_5align_8sitemask_4_cpg_3find_cpg_restricted(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_mdef_2bx_5align_8sitemask_4_cpg_3find_cpg_restricted = {__Pyx_NAMESTR("find_cpg_restricted"), (PyCFunction)__pyx_pw_2bx_5align_8sitemask_4_cpg_3find_cpg_restricted, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(0)};
+static PyObject *__pyx_pw_2bx_5align_8sitemask_4_cpg_3find_cpg_restricted(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_sp1 = 0;
+  PyObject *__pyx_v_sp2 = 0;
+  PyObject *__pyx_v_start = 0;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("find_cpg_restricted (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__sp1,&__pyx_n_s__sp2,&__pyx_n_s__start,0};
+    PyObject* values[3] = {0,0,0};
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__sp1)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__sp2)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("find_cpg_restricted", 1, 3, 3, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 21; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+        case  2:
+        if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__start)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("find_cpg_restricted", 1, 3, 3, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 21; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "find_cpg_restricted") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 21; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else if (PyTuple_GET_SIZE(__pyx_args) != 3) {
+      goto __pyx_L5_argtuple_error;
+    } else {
+      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+      values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+    }
+    __pyx_v_sp1 = values[0];
+    __pyx_v_sp2 = values[1];
+    __pyx_v_start = values[2];
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("find_cpg_restricted", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 21; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.align.sitemask._cpg.find_cpg_restricted", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_5align_8sitemask_4_cpg_2find_cpg_restricted(__pyx_self, __pyx_v_sp1, __pyx_v_sp2, __pyx_v_start);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/align/sitemask/_cpg.pyx":21
+ *     return next_cpg( a, b, pos )
+ * 
+ * def find_cpg_restricted( sp1, sp2, start ):             # <<<<<<<<<<<<<<
+ *     cdef char* a
+ *     cdef char* b
+ */
+
+static PyObject *__pyx_pf_2bx_5align_8sitemask_4_cpg_2find_cpg_restricted(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_sp1, PyObject *__pyx_v_sp2, PyObject *__pyx_v_start) {
+  char *__pyx_v_a;
+  char *__pyx_v_b;
+  int __pyx_v_pos;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  char *__pyx_t_1;
+  int __pyx_t_2;
+  Py_ssize_t __pyx_t_3;
+  int __pyx_t_4;
+  PyObject *__pyx_t_5 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("find_cpg_restricted", 0);
+
+  /* "bx/align/sitemask/_cpg.pyx":25
+ *     cdef char* b
+ *     cdef int pos
+ *     a = sp1             # <<<<<<<<<<<<<<
+ *     b = sp2
+ *     pos = start
+ */
+  __pyx_t_1 = PyBytes_AsString(__pyx_v_sp1); if (unlikely((!__pyx_t_1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 25; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_v_a = __pyx_t_1;
+
+  /* "bx/align/sitemask/_cpg.pyx":26
+ *     cdef int pos
+ *     a = sp1
+ *     b = sp2             # <<<<<<<<<<<<<<
+ *     pos = start
+ *     if pos > len(sp1): return -1
+ */
+  __pyx_t_1 = PyBytes_AsString(__pyx_v_sp2); if (unlikely((!__pyx_t_1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 26; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_v_b = __pyx_t_1;
+
+  /* "bx/align/sitemask/_cpg.pyx":27
+ *     a = sp1
+ *     b = sp2
+ *     pos = start             # <<<<<<<<<<<<<<
+ *     if pos > len(sp1): return -1
+ *     return next_cpg_restricted( a, b, pos )
+ */
+  __pyx_t_2 = __Pyx_PyInt_AsInt(__pyx_v_start); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 27; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_v_pos = __pyx_t_2;
+
+  /* "bx/align/sitemask/_cpg.pyx":28
+ *     b = sp2
+ *     pos = start
+ *     if pos > len(sp1): return -1             # <<<<<<<<<<<<<<
+ *     return next_cpg_restricted( a, b, pos )
+ * 
+ */
+  __pyx_t_3 = PyObject_Length(__pyx_v_sp1); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 28; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_4 = (__pyx_v_pos > __pyx_t_3);
+  if (__pyx_t_4) {
+    __Pyx_XDECREF(__pyx_r);
+    __Pyx_INCREF(__pyx_int_neg_1);
+    __pyx_r = __pyx_int_neg_1;
+    goto __pyx_L0;
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  /* "bx/align/sitemask/_cpg.pyx":29
+ *     pos = start
+ *     if pos > len(sp1): return -1
+ *     return next_cpg_restricted( a, b, pos )             # <<<<<<<<<<<<<<
+ * 
+ * def find_non_cpg( sp1, sp2, start ):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_5 = PyInt_FromLong(next_cpg_restricted(__pyx_v_a, __pyx_v_b, __pyx_v_pos)); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 29; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __pyx_r = __pyx_t_5;
+  __pyx_t_5 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_5);
+  __Pyx_AddTraceback("bx.align.sitemask._cpg.find_cpg_restricted", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_5align_8sitemask_4_cpg_5find_non_cpg(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_mdef_2bx_5align_8sitemask_4_cpg_5find_non_cpg = {__Pyx_NAMESTR("find_non_cpg"), (PyCFunction)__pyx_pw_2bx_5align_8sitemask_4_cpg_5find_non_cpg, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(0)};
+static PyObject *__pyx_pw_2bx_5align_8sitemask_4_cpg_5find_non_cpg(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_sp1 = 0;
+  PyObject *__pyx_v_sp2 = 0;
+  PyObject *__pyx_v_start = 0;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("find_non_cpg (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__sp1,&__pyx_n_s__sp2,&__pyx_n_s__start,0};
+    PyObject* values[3] = {0,0,0};
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__sp1)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__sp2)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("find_non_cpg", 1, 3, 3, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 31; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+        case  2:
+        if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__start)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("find_non_cpg", 1, 3, 3, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 31; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "find_non_cpg") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 31; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else if (PyTuple_GET_SIZE(__pyx_args) != 3) {
+      goto __pyx_L5_argtuple_error;
+    } else {
+      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+      values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+    }
+    __pyx_v_sp1 = values[0];
+    __pyx_v_sp2 = values[1];
+    __pyx_v_start = values[2];
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("find_non_cpg", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 31; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.align.sitemask._cpg.find_non_cpg", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_5align_8sitemask_4_cpg_4find_non_cpg(__pyx_self, __pyx_v_sp1, __pyx_v_sp2, __pyx_v_start);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/align/sitemask/_cpg.pyx":31
+ *     return next_cpg_restricted( a, b, pos )
+ * 
+ * def find_non_cpg( sp1, sp2, start ):             # <<<<<<<<<<<<<<
+ *     cdef char* a
+ *     cdef char* b
+ */
+
+static PyObject *__pyx_pf_2bx_5align_8sitemask_4_cpg_4find_non_cpg(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_sp1, PyObject *__pyx_v_sp2, PyObject *__pyx_v_start) {
+  char *__pyx_v_a;
+  char *__pyx_v_b;
+  int __pyx_v_pos;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  char *__pyx_t_1;
+  int __pyx_t_2;
+  Py_ssize_t __pyx_t_3;
+  int __pyx_t_4;
+  PyObject *__pyx_t_5 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("find_non_cpg", 0);
+
+  /* "bx/align/sitemask/_cpg.pyx":35
+ *     cdef char* b
+ *     cdef int pos
+ *     a = sp1             # <<<<<<<<<<<<<<
+ *     b = sp2
+ *     pos = start
+ */
+  __pyx_t_1 = PyBytes_AsString(__pyx_v_sp1); if (unlikely((!__pyx_t_1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 35; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_v_a = __pyx_t_1;
+
+  /* "bx/align/sitemask/_cpg.pyx":36
+ *     cdef int pos
+ *     a = sp1
+ *     b = sp2             # <<<<<<<<<<<<<<
+ *     pos = start
+ *     if pos > len(sp1): return -1
+ */
+  __pyx_t_1 = PyBytes_AsString(__pyx_v_sp2); if (unlikely((!__pyx_t_1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 36; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_v_b = __pyx_t_1;
+
+  /* "bx/align/sitemask/_cpg.pyx":37
+ *     a = sp1
+ *     b = sp2
+ *     pos = start             # <<<<<<<<<<<<<<
+ *     if pos > len(sp1): return -1
+ *     return next_non_cpg( a, b, pos )
+ */
+  __pyx_t_2 = __Pyx_PyInt_AsInt(__pyx_v_start); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 37; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_v_pos = __pyx_t_2;
+
+  /* "bx/align/sitemask/_cpg.pyx":38
+ *     b = sp2
+ *     pos = start
+ *     if pos > len(sp1): return -1             # <<<<<<<<<<<<<<
+ *     return next_non_cpg( a, b, pos )
+ * 
+ */
+  __pyx_t_3 = PyObject_Length(__pyx_v_sp1); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 38; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_4 = (__pyx_v_pos > __pyx_t_3);
+  if (__pyx_t_4) {
+    __Pyx_XDECREF(__pyx_r);
+    __Pyx_INCREF(__pyx_int_neg_1);
+    __pyx_r = __pyx_int_neg_1;
+    goto __pyx_L0;
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  /* "bx/align/sitemask/_cpg.pyx":39
+ *     pos = start
+ *     if pos > len(sp1): return -1
+ *     return next_non_cpg( a, b, pos )             # <<<<<<<<<<<<<<
+ * 
+ * def list_cpg( sp1, sp2 ):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_5 = PyInt_FromLong(next_non_cpg(__pyx_v_a, __pyx_v_b, __pyx_v_pos)); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 39; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __pyx_r = __pyx_t_5;
+  __pyx_t_5 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_5);
+  __Pyx_AddTraceback("bx.align.sitemask._cpg.find_non_cpg", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_5align_8sitemask_4_cpg_7list_cpg(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_mdef_2bx_5align_8sitemask_4_cpg_7list_cpg = {__Pyx_NAMESTR("list_cpg"), (PyCFunction)__pyx_pw_2bx_5align_8sitemask_4_cpg_7list_cpg, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(0)};
+static PyObject *__pyx_pw_2bx_5align_8sitemask_4_cpg_7list_cpg(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_sp1 = 0;
+  PyObject *__pyx_v_sp2 = 0;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("list_cpg (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__sp1,&__pyx_n_s__sp2,0};
+    PyObject* values[2] = {0,0};
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__sp1)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__sp2)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("list_cpg", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 41; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "list_cpg") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 41; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
+      goto __pyx_L5_argtuple_error;
+    } else {
+      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+    }
+    __pyx_v_sp1 = values[0];
+    __pyx_v_sp2 = values[1];
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("list_cpg", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 41; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.align.sitemask._cpg.list_cpg", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_5align_8sitemask_4_cpg_6list_cpg(__pyx_self, __pyx_v_sp1, __pyx_v_sp2);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/align/sitemask/_cpg.pyx":41
+ *     return next_non_cpg( a, b, pos )
+ * 
+ * def list_cpg( sp1, sp2 ):             # <<<<<<<<<<<<<<
+ *     cdef char * a
+ *     cdef char * b
+ */
+
+static PyObject *__pyx_pf_2bx_5align_8sitemask_4_cpg_6list_cpg(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_sp1, PyObject *__pyx_v_sp2) {
+  char *__pyx_v_a;
+  char *__pyx_v_b;
+  int __pyx_v_start;
+  PyObject *__pyx_v_cpglist = NULL;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  char *__pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
+  int __pyx_t_3;
+  Py_ssize_t __pyx_t_4;
+  int __pyx_t_5;
+  int __pyx_t_6;
+  int __pyx_t_7;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("list_cpg", 0);
+
+  /* "bx/align/sitemask/_cpg.pyx":45
+ *     cdef char * b
+ *     cdef int start
+ *     a = sp1             # <<<<<<<<<<<<<<
+ *     b = sp2
+ *     start = 0
+ */
+  __pyx_t_1 = PyBytes_AsString(__pyx_v_sp1); if (unlikely((!__pyx_t_1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 45; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_v_a = __pyx_t_1;
+
+  /* "bx/align/sitemask/_cpg.pyx":46
+ *     cdef int start
+ *     a = sp1
+ *     b = sp2             # <<<<<<<<<<<<<<
+ *     start = 0
+ *     cpglist = list()
+ */
+  __pyx_t_1 = PyBytes_AsString(__pyx_v_sp2); if (unlikely((!__pyx_t_1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 46; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_v_b = __pyx_t_1;
+
+  /* "bx/align/sitemask/_cpg.pyx":47
+ *     a = sp1
+ *     b = sp2
+ *     start = 0             # <<<<<<<<<<<<<<
+ *     cpglist = list()
+ *     while start > -1 and start < len(sp1):
+ */
+  __pyx_v_start = 0;
+
+  /* "bx/align/sitemask/_cpg.pyx":48
+ *     b = sp2
+ *     start = 0
+ *     cpglist = list()             # <<<<<<<<<<<<<<
+ *     while start > -1 and start < len(sp1):
+ *         start = next_cpg( a, b, start )
+ */
+  __pyx_t_2 = PyList_New(0); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 48; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_v_cpglist = ((PyObject*)__pyx_t_2);
+  __pyx_t_2 = 0;
+
+  /* "bx/align/sitemask/_cpg.pyx":49
+ *     start = 0
+ *     cpglist = list()
+ *     while start > -1 and start < len(sp1):             # <<<<<<<<<<<<<<
+ *         start = next_cpg( a, b, start )
+ *         if start == -1: break
+ */
+  while (1) {
+    __pyx_t_3 = (__pyx_v_start > -1);
+    if (__pyx_t_3) {
+      __pyx_t_4 = PyObject_Length(__pyx_v_sp1); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 49; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_5 = (__pyx_v_start < __pyx_t_4);
+      __pyx_t_6 = __pyx_t_5;
+    } else {
+      __pyx_t_6 = __pyx_t_3;
+    }
+    if (!__pyx_t_6) break;
+
+    /* "bx/align/sitemask/_cpg.pyx":50
+ *     cpglist = list()
+ *     while start > -1 and start < len(sp1):
+ *         start = next_cpg( a, b, start )             # <<<<<<<<<<<<<<
+ *         if start == -1: break
+ *         cpglist.append(start)
+ */
+    __pyx_v_start = next_cpg(__pyx_v_a, __pyx_v_b, __pyx_v_start);
+
+    /* "bx/align/sitemask/_cpg.pyx":51
+ *     while start > -1 and start < len(sp1):
+ *         start = next_cpg( a, b, start )
+ *         if start == -1: break             # <<<<<<<<<<<<<<
+ *         cpglist.append(start)
+ *         start = start + 1
+ */
+    __pyx_t_6 = (__pyx_v_start == -1);
+    if (__pyx_t_6) {
+      goto __pyx_L4_break;
+      goto __pyx_L5;
+    }
+    __pyx_L5:;
+
+    /* "bx/align/sitemask/_cpg.pyx":52
+ *         start = next_cpg( a, b, start )
+ *         if start == -1: break
+ *         cpglist.append(start)             # <<<<<<<<<<<<<<
+ *         start = start + 1
+ *     return cpglist
+ */
+    __pyx_t_2 = PyInt_FromLong(__pyx_v_start); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 52; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_t_7 = PyList_Append(__pyx_v_cpglist, __pyx_t_2); if (unlikely(__pyx_t_7 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 52; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+    /* "bx/align/sitemask/_cpg.pyx":53
+ *         if start == -1: break
+ *         cpglist.append(start)
+ *         start = start + 1             # <<<<<<<<<<<<<<
+ *     return cpglist
+ * 
+ */
+    __pyx_v_start = (__pyx_v_start + 1);
+  }
+  __pyx_L4_break:;
+
+  /* "bx/align/sitemask/_cpg.pyx":54
+ *         cpglist.append(start)
+ *         start = start + 1
+ *     return cpglist             # <<<<<<<<<<<<<<
+ * 
+ * def list_cpg_restricted( sp1, sp2 ):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __Pyx_INCREF(((PyObject *)__pyx_v_cpglist));
+  __pyx_r = ((PyObject *)__pyx_v_cpglist);
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_AddTraceback("bx.align.sitemask._cpg.list_cpg", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_cpglist);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_5align_8sitemask_4_cpg_9list_cpg_restricted(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_mdef_2bx_5align_8sitemask_4_cpg_9list_cpg_restricted = {__Pyx_NAMESTR("list_cpg_restricted"), (PyCFunction)__pyx_pw_2bx_5align_8sitemask_4_cpg_9list_cpg_restricted, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(0)};
+static PyObject *__pyx_pw_2bx_5align_8sitemask_4_cpg_9list_cpg_restricted(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_sp1 = 0;
+  PyObject *__pyx_v_sp2 = 0;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("list_cpg_restricted (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__sp1,&__pyx_n_s__sp2,0};
+    PyObject* values[2] = {0,0};
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__sp1)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__sp2)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("list_cpg_restricted", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 56; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "list_cpg_restricted") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 56; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
+      goto __pyx_L5_argtuple_error;
+    } else {
+      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+    }
+    __pyx_v_sp1 = values[0];
+    __pyx_v_sp2 = values[1];
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("list_cpg_restricted", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 56; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.align.sitemask._cpg.list_cpg_restricted", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_5align_8sitemask_4_cpg_8list_cpg_restricted(__pyx_self, __pyx_v_sp1, __pyx_v_sp2);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/align/sitemask/_cpg.pyx":56
+ *     return cpglist
+ * 
+ * def list_cpg_restricted( sp1, sp2 ):             # <<<<<<<<<<<<<<
+ *     cdef char * a
+ *     cdef char * b
+ */
+
+static PyObject *__pyx_pf_2bx_5align_8sitemask_4_cpg_8list_cpg_restricted(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_sp1, PyObject *__pyx_v_sp2) {
+  char *__pyx_v_a;
+  char *__pyx_v_b;
+  int __pyx_v_start;
+  PyObject *__pyx_v_cpglist = NULL;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  char *__pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
+  int __pyx_t_3;
+  Py_ssize_t __pyx_t_4;
+  int __pyx_t_5;
+  int __pyx_t_6;
+  int __pyx_t_7;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("list_cpg_restricted", 0);
+
+  /* "bx/align/sitemask/_cpg.pyx":60
+ *     cdef char * b
+ *     cdef int start
+ *     a = sp1             # <<<<<<<<<<<<<<
+ *     b = sp2
+ *     start = 0
+ */
+  __pyx_t_1 = PyBytes_AsString(__pyx_v_sp1); if (unlikely((!__pyx_t_1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 60; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_v_a = __pyx_t_1;
+
+  /* "bx/align/sitemask/_cpg.pyx":61
+ *     cdef int start
+ *     a = sp1
+ *     b = sp2             # <<<<<<<<<<<<<<
+ *     start = 0
+ *     cpglist = list()
+ */
+  __pyx_t_1 = PyBytes_AsString(__pyx_v_sp2); if (unlikely((!__pyx_t_1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 61; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_v_b = __pyx_t_1;
+
+  /* "bx/align/sitemask/_cpg.pyx":62
+ *     a = sp1
+ *     b = sp2
+ *     start = 0             # <<<<<<<<<<<<<<
+ *     cpglist = list()
+ *     while start > -1 and start < len(sp1):
+ */
+  __pyx_v_start = 0;
+
+  /* "bx/align/sitemask/_cpg.pyx":63
+ *     b = sp2
+ *     start = 0
+ *     cpglist = list()             # <<<<<<<<<<<<<<
+ *     while start > -1 and start < len(sp1):
+ *         start = next_cpg_restricted( a, b, start )
+ */
+  __pyx_t_2 = PyList_New(0); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 63; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_v_cpglist = ((PyObject*)__pyx_t_2);
+  __pyx_t_2 = 0;
+
+  /* "bx/align/sitemask/_cpg.pyx":64
+ *     start = 0
+ *     cpglist = list()
+ *     while start > -1 and start < len(sp1):             # <<<<<<<<<<<<<<
+ *         start = next_cpg_restricted( a, b, start )
+ *         if start == -1: break
+ */
+  while (1) {
+    __pyx_t_3 = (__pyx_v_start > -1);
+    if (__pyx_t_3) {
+      __pyx_t_4 = PyObject_Length(__pyx_v_sp1); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 64; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_5 = (__pyx_v_start < __pyx_t_4);
+      __pyx_t_6 = __pyx_t_5;
+    } else {
+      __pyx_t_6 = __pyx_t_3;
+    }
+    if (!__pyx_t_6) break;
+
+    /* "bx/align/sitemask/_cpg.pyx":65
+ *     cpglist = list()
+ *     while start > -1 and start < len(sp1):
+ *         start = next_cpg_restricted( a, b, start )             # <<<<<<<<<<<<<<
+ *         if start == -1: break
+ *         cpglist.append(start)
+ */
+    __pyx_v_start = next_cpg_restricted(__pyx_v_a, __pyx_v_b, __pyx_v_start);
+
+    /* "bx/align/sitemask/_cpg.pyx":66
+ *     while start > -1 and start < len(sp1):
+ *         start = next_cpg_restricted( a, b, start )
+ *         if start == -1: break             # <<<<<<<<<<<<<<
+ *         cpglist.append(start)
+ *         start = start + 1
+ */
+    __pyx_t_6 = (__pyx_v_start == -1);
+    if (__pyx_t_6) {
+      goto __pyx_L4_break;
+      goto __pyx_L5;
+    }
+    __pyx_L5:;
+
+    /* "bx/align/sitemask/_cpg.pyx":67
+ *         start = next_cpg_restricted( a, b, start )
+ *         if start == -1: break
+ *         cpglist.append(start)             # <<<<<<<<<<<<<<
+ *         start = start + 1
+ *     return cpglist
+ */
+    __pyx_t_2 = PyInt_FromLong(__pyx_v_start); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 67; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_t_7 = PyList_Append(__pyx_v_cpglist, __pyx_t_2); if (unlikely(__pyx_t_7 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 67; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+    /* "bx/align/sitemask/_cpg.pyx":68
+ *         if start == -1: break
+ *         cpglist.append(start)
+ *         start = start + 1             # <<<<<<<<<<<<<<
+ *     return cpglist
+ * 
+ */
+    __pyx_v_start = (__pyx_v_start + 1);
+  }
+  __pyx_L4_break:;
+
+  /* "bx/align/sitemask/_cpg.pyx":69
+ *         cpglist.append(start)
+ *         start = start + 1
+ *     return cpglist             # <<<<<<<<<<<<<<
+ * 
+ * def list_non_cpg( sp1, sp2 ):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __Pyx_INCREF(((PyObject *)__pyx_v_cpglist));
+  __pyx_r = ((PyObject *)__pyx_v_cpglist);
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_AddTraceback("bx.align.sitemask._cpg.list_cpg_restricted", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_cpglist);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_5align_8sitemask_4_cpg_11list_non_cpg(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_mdef_2bx_5align_8sitemask_4_cpg_11list_non_cpg = {__Pyx_NAMESTR("list_non_cpg"), (PyCFunction)__pyx_pw_2bx_5align_8sitemask_4_cpg_11list_non_cpg, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(0)};
+static PyObject *__pyx_pw_2bx_5align_8sitemask_4_cpg_11list_non_cpg(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_sp1 = 0;
+  PyObject *__pyx_v_sp2 = 0;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("list_non_cpg (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__sp1,&__pyx_n_s__sp2,0};
+    PyObject* values[2] = {0,0};
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__sp1)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__sp2)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("list_non_cpg", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 71; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "list_non_cpg") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 71; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
+      goto __pyx_L5_argtuple_error;
+    } else {
+      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+    }
+    __pyx_v_sp1 = values[0];
+    __pyx_v_sp2 = values[1];
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("list_non_cpg", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 71; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.align.sitemask._cpg.list_non_cpg", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_5align_8sitemask_4_cpg_10list_non_cpg(__pyx_self, __pyx_v_sp1, __pyx_v_sp2);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/align/sitemask/_cpg.pyx":71
+ *     return cpglist
+ * 
+ * def list_non_cpg( sp1, sp2 ):             # <<<<<<<<<<<<<<
+ *     cdef char * a
+ *     cdef char * b
+ */
+
+static PyObject *__pyx_pf_2bx_5align_8sitemask_4_cpg_10list_non_cpg(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_sp1, PyObject *__pyx_v_sp2) {
+  char *__pyx_v_a;
+  char *__pyx_v_b;
+  int __pyx_v_start;
+  PyObject *__pyx_v_cpglist = NULL;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  char *__pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
+  int __pyx_t_3;
+  Py_ssize_t __pyx_t_4;
+  int __pyx_t_5;
+  int __pyx_t_6;
+  int __pyx_t_7;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("list_non_cpg", 0);
+
+  /* "bx/align/sitemask/_cpg.pyx":75
+ *     cdef char * b
+ *     cdef int start
+ *     a = sp1             # <<<<<<<<<<<<<<
+ *     b = sp2
+ *     start = 0
+ */
+  __pyx_t_1 = PyBytes_AsString(__pyx_v_sp1); if (unlikely((!__pyx_t_1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 75; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_v_a = __pyx_t_1;
+
+  /* "bx/align/sitemask/_cpg.pyx":76
+ *     cdef int start
+ *     a = sp1
+ *     b = sp2             # <<<<<<<<<<<<<<
+ *     start = 0
+ *     cpglist = list()
+ */
+  __pyx_t_1 = PyBytes_AsString(__pyx_v_sp2); if (unlikely((!__pyx_t_1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 76; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_v_b = __pyx_t_1;
+
+  /* "bx/align/sitemask/_cpg.pyx":77
+ *     a = sp1
+ *     b = sp2
+ *     start = 0             # <<<<<<<<<<<<<<
+ *     cpglist = list()
+ *     while start > -1 and start < len(sp1):
+ */
+  __pyx_v_start = 0;
+
+  /* "bx/align/sitemask/_cpg.pyx":78
+ *     b = sp2
+ *     start = 0
+ *     cpglist = list()             # <<<<<<<<<<<<<<
+ *     while start > -1 and start < len(sp1):
+ *         start = next_non_cpg( a, b, start )
+ */
+  __pyx_t_2 = PyList_New(0); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 78; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_v_cpglist = ((PyObject*)__pyx_t_2);
+  __pyx_t_2 = 0;
+
+  /* "bx/align/sitemask/_cpg.pyx":79
+ *     start = 0
+ *     cpglist = list()
+ *     while start > -1 and start < len(sp1):             # <<<<<<<<<<<<<<
+ *         start = next_non_cpg( a, b, start )
+ *         if start == -1: break
+ */
+  while (1) {
+    __pyx_t_3 = (__pyx_v_start > -1);
+    if (__pyx_t_3) {
+      __pyx_t_4 = PyObject_Length(__pyx_v_sp1); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 79; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_5 = (__pyx_v_start < __pyx_t_4);
+      __pyx_t_6 = __pyx_t_5;
+    } else {
+      __pyx_t_6 = __pyx_t_3;
+    }
+    if (!__pyx_t_6) break;
+
+    /* "bx/align/sitemask/_cpg.pyx":80
+ *     cpglist = list()
+ *     while start > -1 and start < len(sp1):
+ *         start = next_non_cpg( a, b, start )             # <<<<<<<<<<<<<<
+ *         if start == -1: break
+ *         cpglist.append(start)
+ */
+    __pyx_v_start = next_non_cpg(__pyx_v_a, __pyx_v_b, __pyx_v_start);
+
+    /* "bx/align/sitemask/_cpg.pyx":81
+ *     while start > -1 and start < len(sp1):
+ *         start = next_non_cpg( a, b, start )
+ *         if start == -1: break             # <<<<<<<<<<<<<<
+ *         cpglist.append(start)
+ *         start = start + 1
+ */
+    __pyx_t_6 = (__pyx_v_start == -1);
+    if (__pyx_t_6) {
+      goto __pyx_L4_break;
+      goto __pyx_L5;
+    }
+    __pyx_L5:;
+
+    /* "bx/align/sitemask/_cpg.pyx":82
+ *         start = next_non_cpg( a, b, start )
+ *         if start == -1: break
+ *         cpglist.append(start)             # <<<<<<<<<<<<<<
+ *         start = start + 1
+ *     return cpglist
+ */
+    __pyx_t_2 = PyInt_FromLong(__pyx_v_start); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 82; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_t_7 = PyList_Append(__pyx_v_cpglist, __pyx_t_2); if (unlikely(__pyx_t_7 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 82; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+    /* "bx/align/sitemask/_cpg.pyx":83
+ *         if start == -1: break
+ *         cpglist.append(start)
+ *         start = start + 1             # <<<<<<<<<<<<<<
+ *     return cpglist
+ * 
+ */
+    __pyx_v_start = (__pyx_v_start + 1);
+  }
+  __pyx_L4_break:;
+
+  /* "bx/align/sitemask/_cpg.pyx":84
+ *         cpglist.append(start)
+ *         start = start + 1
+ *     return cpglist             # <<<<<<<<<<<<<<
+ * 
+ * def remove_gaps( sp, cpglist ):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __Pyx_INCREF(((PyObject *)__pyx_v_cpglist));
+  __pyx_r = ((PyObject *)__pyx_v_cpglist);
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_AddTraceback("bx.align.sitemask._cpg.list_non_cpg", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_cpglist);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_5align_8sitemask_4_cpg_13remove_gaps(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_mdef_2bx_5align_8sitemask_4_cpg_13remove_gaps = {__Pyx_NAMESTR("remove_gaps"), (PyCFunction)__pyx_pw_2bx_5align_8sitemask_4_cpg_13remove_gaps, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(0)};
+static PyObject *__pyx_pw_2bx_5align_8sitemask_4_cpg_13remove_gaps(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_sp = 0;
+  PyObject *__pyx_v_cpglist = 0;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("remove_gaps (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__sp,&__pyx_n_s__cpglist,0};
+    PyObject* values[2] = {0,0};
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__sp)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__cpglist)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("remove_gaps", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 86; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "remove_gaps") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 86; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
+      goto __pyx_L5_argtuple_error;
+    } else {
+      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+    }
+    __pyx_v_sp = values[0];
+    __pyx_v_cpglist = values[1];
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("remove_gaps", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 86; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.align.sitemask._cpg.remove_gaps", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_5align_8sitemask_4_cpg_12remove_gaps(__pyx_self, __pyx_v_sp, __pyx_v_cpglist);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/align/sitemask/_cpg.pyx":86
+ *     return cpglist
+ * 
+ * def remove_gaps( sp, cpglist ):             # <<<<<<<<<<<<<<
+ *     for item in cpglist:
+ *         if sp[item] == '-':
+ */
+
+static PyObject *__pyx_pf_2bx_5align_8sitemask_4_cpg_12remove_gaps(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_sp, PyObject *__pyx_v_cpglist) {
+  PyObject *__pyx_v_item = NULL;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  Py_ssize_t __pyx_t_2;
+  PyObject *(*__pyx_t_3)(PyObject *);
+  PyObject *__pyx_t_4 = NULL;
+  PyObject *__pyx_t_5 = NULL;
+  int __pyx_t_6;
+  PyObject *__pyx_t_7 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("remove_gaps", 0);
+
+  /* "bx/align/sitemask/_cpg.pyx":87
+ * 
+ * def remove_gaps( sp, cpglist ):
+ *     for item in cpglist:             # <<<<<<<<<<<<<<
+ *         if sp[item] == '-':
+ *             cpglist.remove(item)
+ */
+  if (PyList_CheckExact(__pyx_v_cpglist) || PyTuple_CheckExact(__pyx_v_cpglist)) {
+    __pyx_t_1 = __pyx_v_cpglist; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0;
+    __pyx_t_3 = NULL;
+  } else {
+    __pyx_t_2 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_cpglist); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 87; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __pyx_t_3 = Py_TYPE(__pyx_t_1)->tp_iternext;
+  }
+  for (;;) {
+    if (!__pyx_t_3 && PyList_CheckExact(__pyx_t_1)) {
+      if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_1)) break;
+      #if CYTHON_COMPILING_IN_CPYTHON
+      __pyx_t_4 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_4); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 87; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      #else
+      __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 87; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      #endif
+    } else if (!__pyx_t_3 && PyTuple_CheckExact(__pyx_t_1)) {
+      if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
+      #if CYTHON_COMPILING_IN_CPYTHON
+      __pyx_t_4 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_4); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 87; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      #else
+      __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 87; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      #endif
+    } else {
+      __pyx_t_4 = __pyx_t_3(__pyx_t_1);
+      if (unlikely(!__pyx_t_4)) {
+        if (PyErr_Occurred()) {
+          if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
+          else {__pyx_filename = __pyx_f[0]; __pyx_lineno = 87; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        }
+        break;
+      }
+      __Pyx_GOTREF(__pyx_t_4);
+    }
+    __Pyx_XDECREF(__pyx_v_item);
+    __pyx_v_item = __pyx_t_4;
+    __pyx_t_4 = 0;
+
+    /* "bx/align/sitemask/_cpg.pyx":88
+ * def remove_gaps( sp, cpglist ):
+ *     for item in cpglist:
+ *         if sp[item] == '-':             # <<<<<<<<<<<<<<
+ *             cpglist.remove(item)
+ *     return cpglist
+ */
+    __pyx_t_4 = PyObject_GetItem(__pyx_v_sp, __pyx_v_item); if (!__pyx_t_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 88; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    __pyx_t_5 = PyObject_RichCompare(__pyx_t_4, ((PyObject *)__pyx_kp_s_1), Py_EQ); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 88; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 88; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+    if (__pyx_t_6) {
+
+      /* "bx/align/sitemask/_cpg.pyx":89
+ *     for item in cpglist:
+ *         if sp[item] == '-':
+ *             cpglist.remove(item)             # <<<<<<<<<<<<<<
+ *     return cpglist
+ */
+      __pyx_t_5 = PyObject_GetAttr(__pyx_v_cpglist, __pyx_n_s__remove); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 89; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_5);
+      __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 89; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __Pyx_INCREF(__pyx_v_item);
+      PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_v_item);
+      __Pyx_GIVEREF(__pyx_v_item);
+      __pyx_t_7 = PyObject_Call(__pyx_t_5, ((PyObject *)__pyx_t_4), NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 89; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_7);
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
+      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+      goto __pyx_L5;
+    }
+    __pyx_L5:;
+  }
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "bx/align/sitemask/_cpg.pyx":90
+ *         if sp[item] == '-':
+ *             cpglist.remove(item)
+ *     return cpglist             # <<<<<<<<<<<<<<
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __Pyx_INCREF(__pyx_v_cpglist);
+  __pyx_r = __pyx_v_cpglist;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_XDECREF(__pyx_t_5);
+  __Pyx_XDECREF(__pyx_t_7);
+  __Pyx_AddTraceback("bx.align.sitemask._cpg.remove_gaps", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_item);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyMethodDef __pyx_methods[] = {
+  {0, 0, 0, 0}
+};
+
+#if PY_MAJOR_VERSION >= 3
+static struct PyModuleDef __pyx_moduledef = {
+  #if PY_VERSION_HEX < 0x03020000
+    { PyObject_HEAD_INIT(NULL) NULL, 0, NULL },
+  #else
+    PyModuleDef_HEAD_INIT,
+  #endif
+    __Pyx_NAMESTR("_cpg"),
+    __Pyx_DOCSTR(__pyx_k_2), /* m_doc */
+    -1, /* m_size */
+    __pyx_methods /* m_methods */,
+    NULL, /* m_reload */
+    NULL, /* m_traverse */
+    NULL, /* m_clear */
+    NULL /* m_free */
+};
+#endif
+
+static __Pyx_StringTabEntry __pyx_string_tab[] = {
+  {&__pyx_kp_s_1, __pyx_k_1, sizeof(__pyx_k_1), 0, 0, 1, 0},
+  {&__pyx_kp_s_5, __pyx_k_5, sizeof(__pyx_k_5), 0, 0, 1, 0},
+  {&__pyx_n_s_6, __pyx_k_6, sizeof(__pyx_k_6), 0, 0, 1, 1},
+  {&__pyx_n_s____main__, __pyx_k____main__, sizeof(__pyx_k____main__), 0, 0, 1, 1},
+  {&__pyx_n_s____test__, __pyx_k____test__, sizeof(__pyx_k____test__), 0, 0, 1, 1},
+  {&__pyx_n_s__a, __pyx_k__a, sizeof(__pyx_k__a), 0, 0, 1, 1},
+  {&__pyx_n_s__b, __pyx_k__b, sizeof(__pyx_k__b), 0, 0, 1, 1},
+  {&__pyx_n_s__cpglist, __pyx_k__cpglist, sizeof(__pyx_k__cpglist), 0, 0, 1, 1},
+  {&__pyx_n_s__find_cpg, __pyx_k__find_cpg, sizeof(__pyx_k__find_cpg), 0, 0, 1, 1},
+  {&__pyx_n_s__find_cpg_restricted, __pyx_k__find_cpg_restricted, sizeof(__pyx_k__find_cpg_restricted), 0, 0, 1, 1},
+  {&__pyx_n_s__find_non_cpg, __pyx_k__find_non_cpg, sizeof(__pyx_k__find_non_cpg), 0, 0, 1, 1},
+  {&__pyx_n_s__item, __pyx_k__item, sizeof(__pyx_k__item), 0, 0, 1, 1},
+  {&__pyx_n_s__list_cpg, __pyx_k__list_cpg, sizeof(__pyx_k__list_cpg), 0, 0, 1, 1},
+  {&__pyx_n_s__list_cpg_restricted, __pyx_k__list_cpg_restricted, sizeof(__pyx_k__list_cpg_restricted), 0, 0, 1, 1},
+  {&__pyx_n_s__list_non_cpg, __pyx_k__list_non_cpg, sizeof(__pyx_k__list_non_cpg), 0, 0, 1, 1},
+  {&__pyx_n_s__pos, __pyx_k__pos, sizeof(__pyx_k__pos), 0, 0, 1, 1},
+  {&__pyx_n_s__remove, __pyx_k__remove, sizeof(__pyx_k__remove), 0, 0, 1, 1},
+  {&__pyx_n_s__remove_gaps, __pyx_k__remove_gaps, sizeof(__pyx_k__remove_gaps), 0, 0, 1, 1},
+  {&__pyx_n_s__sp, __pyx_k__sp, sizeof(__pyx_k__sp), 0, 0, 1, 1},
+  {&__pyx_n_s__sp1, __pyx_k__sp1, sizeof(__pyx_k__sp1), 0, 0, 1, 1},
+  {&__pyx_n_s__sp2, __pyx_k__sp2, sizeof(__pyx_k__sp2), 0, 0, 1, 1},
+  {&__pyx_n_s__start, __pyx_k__start, sizeof(__pyx_k__start), 0, 0, 1, 1},
+  {0, 0, 0, 0, 0, 0, 0}
+};
+static int __Pyx_InitCachedBuiltins(void) {
+  return 0;
+}
+
+static int __Pyx_InitCachedConstants(void) {
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0);
+
+  /* "bx/align/sitemask/_cpg.pyx":11
+ *     int next_non_cpg( char * sp1, char * sp2, int start)
+ * 
+ * def find_cpg( sp1, sp2, start ):             # <<<<<<<<<<<<<<
+ *     cdef char* a
+ *     cdef char* b
+ */
+  __pyx_k_tuple_3 = PyTuple_Pack(6, ((PyObject *)__pyx_n_s__sp1), ((PyObject *)__pyx_n_s__sp2), ((PyObject *)__pyx_n_s__start), ((PyObject *)__pyx_n_s__a), ((PyObject *)__pyx_n_s__b), ((PyObject *)__pyx_n_s__pos)); if (unlikely(!__pyx_k_tuple_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 11; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_k_tuple_3);
+  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_3));
+  __pyx_k_codeobj_4 = (PyObject*)__Pyx_PyCode_New(3, 0, 6, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_k_tuple_3, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_5, __pyx_n_s__find_cpg, 11, __pyx_empty_bytes); if (unlikely(!__pyx_k_codeobj_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 11; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "bx/align/sitemask/_cpg.pyx":21
+ *     return next_cpg( a, b, pos )
+ * 
+ * def find_cpg_restricted( sp1, sp2, start ):             # <<<<<<<<<<<<<<
+ *     cdef char* a
+ *     cdef char* b
+ */
+  __pyx_k_tuple_7 = PyTuple_Pack(6, ((PyObject *)__pyx_n_s__sp1), ((PyObject *)__pyx_n_s__sp2), ((PyObject *)__pyx_n_s__start), ((PyObject *)__pyx_n_s__a), ((PyObject *)__pyx_n_s__b), ((PyObject *)__pyx_n_s__pos)); if (unlikely(!__pyx_k_tuple_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 21; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_k_tuple_7);
+  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_7));
+  __pyx_k_codeobj_8 = (PyObject*)__Pyx_PyCode_New(3, 0, 6, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_k_tuple_7, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_5, __pyx_n_s__find_cpg_restricted, 21, __pyx_empty_bytes); if (unlikely(!__pyx_k_codeobj_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 21; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "bx/align/sitemask/_cpg.pyx":31
+ *     return next_cpg_restricted( a, b, pos )
+ * 
+ * def find_non_cpg( sp1, sp2, start ):             # <<<<<<<<<<<<<<
+ *     cdef char* a
+ *     cdef char* b
+ */
+  __pyx_k_tuple_9 = PyTuple_Pack(6, ((PyObject *)__pyx_n_s__sp1), ((PyObject *)__pyx_n_s__sp2), ((PyObject *)__pyx_n_s__start), ((PyObject *)__pyx_n_s__a), ((PyObject *)__pyx_n_s__b), ((PyObject *)__pyx_n_s__pos)); if (unlikely(!__pyx_k_tuple_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 31; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_k_tuple_9);
+  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_9));
+  __pyx_k_codeobj_10 = (PyObject*)__Pyx_PyCode_New(3, 0, 6, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_k_tuple_9, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_5, __pyx_n_s__find_non_cpg, 31, __pyx_empty_bytes); if (unlikely(!__pyx_k_codeobj_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 31; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "bx/align/sitemask/_cpg.pyx":41
+ *     return next_non_cpg( a, b, pos )
+ * 
+ * def list_cpg( sp1, sp2 ):             # <<<<<<<<<<<<<<
+ *     cdef char * a
+ *     cdef char * b
+ */
+  __pyx_k_tuple_11 = PyTuple_Pack(6, ((PyObject *)__pyx_n_s__sp1), ((PyObject *)__pyx_n_s__sp2), ((PyObject *)__pyx_n_s__a), ((PyObject *)__pyx_n_s__b), ((PyObject *)__pyx_n_s__start), ((PyObject *)__pyx_n_s__cpglist)); if (unlikely(!__pyx_k_tuple_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 41; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_k_tuple_11);
+  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_11));
+  __pyx_k_codeobj_12 = (PyObject*)__Pyx_PyCode_New(2, 0, 6, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_k_tuple_11, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_5, __pyx_n_s__list_cpg, 41, __pyx_empty_bytes); if (unlikely(!__pyx_k_codeobj_12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 41; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "bx/align/sitemask/_cpg.pyx":56
+ *     return cpglist
+ * 
+ * def list_cpg_restricted( sp1, sp2 ):             # <<<<<<<<<<<<<<
+ *     cdef char * a
+ *     cdef char * b
+ */
+  __pyx_k_tuple_13 = PyTuple_Pack(6, ((PyObject *)__pyx_n_s__sp1), ((PyObject *)__pyx_n_s__sp2), ((PyObject *)__pyx_n_s__a), ((PyObject *)__pyx_n_s__b), ((PyObject *)__pyx_n_s__start), ((PyObject *)__pyx_n_s__cpglist)); if (unlikely(!__pyx_k_tuple_13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 56; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_k_tuple_13);
+  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_13));
+  __pyx_k_codeobj_14 = (PyObject*)__Pyx_PyCode_New(2, 0, 6, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_k_tuple_13, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_5, __pyx_n_s__list_cpg_restricted, 56, __pyx_empty_bytes); if (unlikely(!__pyx_k_codeobj_14)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 56; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "bx/align/sitemask/_cpg.pyx":71
+ *     return cpglist
+ * 
+ * def list_non_cpg( sp1, sp2 ):             # <<<<<<<<<<<<<<
+ *     cdef char * a
+ *     cdef char * b
+ */
+  __pyx_k_tuple_15 = PyTuple_Pack(6, ((PyObject *)__pyx_n_s__sp1), ((PyObject *)__pyx_n_s__sp2), ((PyObject *)__pyx_n_s__a), ((PyObject *)__pyx_n_s__b), ((PyObject *)__pyx_n_s__start), ((PyObject *)__pyx_n_s__cpglist)); if (unlikely(!__pyx_k_tuple_15)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 71; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_k_tuple_15);
+  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_15));
+  __pyx_k_codeobj_16 = (PyObject*)__Pyx_PyCode_New(2, 0, 6, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_k_tuple_15, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_5, __pyx_n_s__list_non_cpg, 71, __pyx_empty_bytes); if (unlikely(!__pyx_k_codeobj_16)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 71; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "bx/align/sitemask/_cpg.pyx":86
+ *     return cpglist
+ * 
+ * def remove_gaps( sp, cpglist ):             # <<<<<<<<<<<<<<
+ *     for item in cpglist:
+ *         if sp[item] == '-':
+ */
+  __pyx_k_tuple_17 = PyTuple_Pack(3, ((PyObject *)__pyx_n_s__sp), ((PyObject *)__pyx_n_s__cpglist), ((PyObject *)__pyx_n_s__item)); if (unlikely(!__pyx_k_tuple_17)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 86; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_k_tuple_17);
+  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_17));
+  __pyx_k_codeobj_18 = (PyObject*)__Pyx_PyCode_New(2, 0, 3, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_k_tuple_17, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_5, __pyx_n_s__remove_gaps, 86, __pyx_empty_bytes); if (unlikely(!__pyx_k_codeobj_18)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 86; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_RefNannyFinishContext();
+  return 0;
+  __pyx_L1_error:;
+  __Pyx_RefNannyFinishContext();
+  return -1;
+}
+
+static int __Pyx_InitGlobals(void) {
+  if (__Pyx_InitStrings(__pyx_string_tab) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  __pyx_int_neg_1 = PyInt_FromLong(-1); if (unlikely(!__pyx_int_neg_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  return 0;
+  __pyx_L1_error:;
+  return -1;
+}
+
+#if PY_MAJOR_VERSION < 3
+PyMODINIT_FUNC init_cpg(void); /*proto*/
+PyMODINIT_FUNC init_cpg(void)
+#else
+PyMODINIT_FUNC PyInit__cpg(void); /*proto*/
+PyMODINIT_FUNC PyInit__cpg(void)
+#endif
+{
+  PyObject *__pyx_t_1 = NULL;
+  __Pyx_RefNannyDeclarations
+  #if CYTHON_REFNANNY
+  __Pyx_RefNanny = __Pyx_RefNannyImportAPI("refnanny");
+  if (!__Pyx_RefNanny) {
+      PyErr_Clear();
+      __Pyx_RefNanny = __Pyx_RefNannyImportAPI("Cython.Runtime.refnanny");
+      if (!__Pyx_RefNanny)
+          Py_FatalError("failed to import 'refnanny' module");
+  }
+  #endif
+  __Pyx_RefNannySetupContext("PyMODINIT_FUNC PyInit__cpg(void)", 0);
+  if ( __Pyx_check_binary_version() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_bytes)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #ifdef __Pyx_CyFunction_USED
+  if (__Pyx_CyFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #endif
+  #ifdef __Pyx_FusedFunction_USED
+  if (__pyx_FusedFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #endif
+  #ifdef __Pyx_Generator_USED
+  if (__pyx_Generator_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #endif
+  /*--- Library function declarations ---*/
+  /*--- Threads initialization code ---*/
+  #if defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS
+  #ifdef WITH_THREAD /* Python build with threading support? */
+  PyEval_InitThreads();
+  #endif
+  #endif
+  /*--- Module creation code ---*/
+  #if PY_MAJOR_VERSION < 3
+  __pyx_m = Py_InitModule4(__Pyx_NAMESTR("_cpg"), __pyx_methods, __Pyx_DOCSTR(__pyx_k_2), 0, PYTHON_API_VERSION); Py_XINCREF(__pyx_m);
+  #else
+  __pyx_m = PyModule_Create(&__pyx_moduledef);
+  #endif
+  if (unlikely(!__pyx_m)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #if PY_MAJOR_VERSION >= 3
+  {
+    PyObject *modules = PyImport_GetModuleDict(); if (unlikely(!modules)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (!PyDict_GetItemString(modules, "bx.align.sitemask._cpg")) {
+      if (unlikely(PyDict_SetItemString(modules, "bx.align.sitemask._cpg", __pyx_m) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+  }
+  #endif
+  __pyx_b = PyImport_AddModule(__Pyx_NAMESTR(__Pyx_BUILTIN_MODULE_NAME)); if (unlikely(!__pyx_b)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #if CYTHON_COMPILING_IN_PYPY
+  Py_INCREF(__pyx_b);
+  #endif
+  if (__Pyx_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  /*--- Initialize various global constants etc. ---*/
+  if (unlikely(__Pyx_InitGlobals() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (__pyx_module_is_main_bx__align__sitemask___cpg) {
+    if (__Pyx_SetAttrString(__pyx_m, "__name__", __pyx_n_s____main__) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  }
+  /*--- Builtin init code ---*/
+  if (unlikely(__Pyx_InitCachedBuiltins() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  /*--- Constants init code ---*/
+  if (unlikely(__Pyx_InitCachedConstants() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  /*--- Global init code ---*/
+  /*--- Variable export code ---*/
+  /*--- Function export code ---*/
+  /*--- Type init code ---*/
+  /*--- Type import code ---*/
+  /*--- Variable import code ---*/
+  /*--- Function import code ---*/
+  /*--- Execution code ---*/
+
+  /* "bx/align/sitemask/_cpg.pyx":11
+ *     int next_non_cpg( char * sp1, char * sp2, int start)
+ * 
+ * def find_cpg( sp1, sp2, start ):             # <<<<<<<<<<<<<<
+ *     cdef char* a
+ *     cdef char* b
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_2bx_5align_8sitemask_4_cpg_1find_cpg, NULL, __pyx_n_s_6); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 11; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s__find_cpg, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 11; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "bx/align/sitemask/_cpg.pyx":21
+ *     return next_cpg( a, b, pos )
+ * 
+ * def find_cpg_restricted( sp1, sp2, start ):             # <<<<<<<<<<<<<<
+ *     cdef char* a
+ *     cdef char* b
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_2bx_5align_8sitemask_4_cpg_3find_cpg_restricted, NULL, __pyx_n_s_6); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 21; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s__find_cpg_restricted, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 21; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "bx/align/sitemask/_cpg.pyx":31
+ *     return next_cpg_restricted( a, b, pos )
+ * 
+ * def find_non_cpg( sp1, sp2, start ):             # <<<<<<<<<<<<<<
+ *     cdef char* a
+ *     cdef char* b
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_2bx_5align_8sitemask_4_cpg_5find_non_cpg, NULL, __pyx_n_s_6); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 31; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s__find_non_cpg, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 31; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "bx/align/sitemask/_cpg.pyx":41
+ *     return next_non_cpg( a, b, pos )
+ * 
+ * def list_cpg( sp1, sp2 ):             # <<<<<<<<<<<<<<
+ *     cdef char * a
+ *     cdef char * b
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_2bx_5align_8sitemask_4_cpg_7list_cpg, NULL, __pyx_n_s_6); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 41; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s__list_cpg, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 41; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "bx/align/sitemask/_cpg.pyx":56
+ *     return cpglist
+ * 
+ * def list_cpg_restricted( sp1, sp2 ):             # <<<<<<<<<<<<<<
+ *     cdef char * a
+ *     cdef char * b
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_2bx_5align_8sitemask_4_cpg_9list_cpg_restricted, NULL, __pyx_n_s_6); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 56; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s__list_cpg_restricted, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 56; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "bx/align/sitemask/_cpg.pyx":71
+ *     return cpglist
+ * 
+ * def list_non_cpg( sp1, sp2 ):             # <<<<<<<<<<<<<<
+ *     cdef char * a
+ *     cdef char * b
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_2bx_5align_8sitemask_4_cpg_11list_non_cpg, NULL, __pyx_n_s_6); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 71; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s__list_non_cpg, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 71; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "bx/align/sitemask/_cpg.pyx":86
+ *     return cpglist
+ * 
+ * def remove_gaps( sp, cpglist ):             # <<<<<<<<<<<<<<
+ *     for item in cpglist:
+ *         if sp[item] == '-':
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_2bx_5align_8sitemask_4_cpg_13remove_gaps, NULL, __pyx_n_s_6); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 86; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s__remove_gaps, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 86; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "bx/align/sitemask/_cpg.pyx":1
+ * """             # <<<<<<<<<<<<<<
+ * Pyrex/C extension for quickly finding potential CpG sites in pairs of
+ * sequences.
+ */
+  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(((PyObject *)__pyx_t_1));
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s____test__, ((PyObject *)__pyx_t_1)) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  if (__pyx_m) {
+    __Pyx_AddTraceback("init bx.align.sitemask._cpg", __pyx_clineno, __pyx_lineno, __pyx_filename);
+    Py_DECREF(__pyx_m); __pyx_m = 0;
+  } else if (!PyErr_Occurred()) {
+    PyErr_SetString(PyExc_ImportError, "init bx.align.sitemask._cpg");
+  }
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  #if PY_MAJOR_VERSION < 3
+  return;
+  #else
+  return __pyx_m;
+  #endif
+}
+
+/* Runtime support code */
+#if CYTHON_REFNANNY
+static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) {
+    PyObject *m = NULL, *p = NULL;
+    void *r = NULL;
+    m = PyImport_ImportModule((char *)modname);
+    if (!m) goto end;
+    p = PyObject_GetAttrString(m, (char *)"RefNannyAPI");
+    if (!p) goto end;
+    r = PyLong_AsVoidPtr(p);
+end:
+    Py_XDECREF(p);
+    Py_XDECREF(m);
+    return (__Pyx_RefNannyAPIStruct *)r;
+}
+#endif /* CYTHON_REFNANNY */
+
+static void __Pyx_RaiseArgtupleInvalid(
+    const char* func_name,
+    int exact,
+    Py_ssize_t num_min,
+    Py_ssize_t num_max,
+    Py_ssize_t num_found)
+{
+    Py_ssize_t num_expected;
+    const char *more_or_less;
+    if (num_found < num_min) {
+        num_expected = num_min;
+        more_or_less = "at least";
+    } else {
+        num_expected = num_max;
+        more_or_less = "at most";
+    }
+    if (exact) {
+        more_or_less = "exactly";
+    }
+    PyErr_Format(PyExc_TypeError,
+                 "%s() takes %s %" CYTHON_FORMAT_SSIZE_T "d positional argument%s (%" CYTHON_FORMAT_SSIZE_T "d given)",
+                 func_name, more_or_less, num_expected,
+                 (num_expected == 1) ? "" : "s", num_found);
+}
+
+static void __Pyx_RaiseDoubleKeywordsError(
+    const char* func_name,
+    PyObject* kw_name)
+{
+    PyErr_Format(PyExc_TypeError,
+        #if PY_MAJOR_VERSION >= 3
+        "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
+        #else
+        "%s() got multiple values for keyword argument '%s'", func_name,
+        PyString_AsString(kw_name));
+        #endif
+}
+
+static int __Pyx_ParseOptionalKeywords(
+    PyObject *kwds,
+    PyObject **argnames[],
+    PyObject *kwds2,
+    PyObject *values[],
+    Py_ssize_t num_pos_args,
+    const char* function_name)
+{
+    PyObject *key = 0, *value = 0;
+    Py_ssize_t pos = 0;
+    PyObject*** name;
+    PyObject*** first_kw_arg = argnames + num_pos_args;
+    while (PyDict_Next(kwds, &pos, &key, &value)) {
+        name = first_kw_arg;
+        while (*name && (**name != key)) name++;
+        if (*name) {
+            values[name-argnames] = value;
+            continue;
+        }
+        name = first_kw_arg;
+        #if PY_MAJOR_VERSION < 3
+        if (likely(PyString_CheckExact(key)) || likely(PyString_Check(key))) {
+            while (*name) {
+                if ((CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**name) == PyString_GET_SIZE(key))
+                        && _PyString_Eq(**name, key)) {
+                    values[name-argnames] = value;
+                    break;
+                }
+                name++;
+            }
+            if (*name) continue;
+            else {
+                PyObject*** argname = argnames;
+                while (argname != first_kw_arg) {
+                    if ((**argname == key) || (
+                            (CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**argname) == PyString_GET_SIZE(key))
+                             && _PyString_Eq(**argname, key))) {
+                        goto arg_passed_twice;
+                    }
+                    argname++;
+                }
+            }
+        } else
+        #endif
+        if (likely(PyUnicode_Check(key))) {
+            while (*name) {
+                int cmp = (**name == key) ? 0 :
+                #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3
+                    (PyUnicode_GET_SIZE(**name) != PyUnicode_GET_SIZE(key)) ? 1 :
+                #endif
+                    PyUnicode_Compare(**name, key);
+                if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad;
+                if (cmp == 0) {
+                    values[name-argnames] = value;
+                    break;
+                }
+                name++;
+            }
+            if (*name) continue;
+            else {
+                PyObject*** argname = argnames;
+                while (argname != first_kw_arg) {
+                    int cmp = (**argname == key) ? 0 :
+                    #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3
+                        (PyUnicode_GET_SIZE(**argname) != PyUnicode_GET_SIZE(key)) ? 1 :
+                    #endif
+                        PyUnicode_Compare(**argname, key);
+                    if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad;
+                    if (cmp == 0) goto arg_passed_twice;
+                    argname++;
+                }
+            }
+        } else
+            goto invalid_keyword_type;
+        if (kwds2) {
+            if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
+        } else {
+            goto invalid_keyword;
+        }
+    }
+    return 0;
+arg_passed_twice:
+    __Pyx_RaiseDoubleKeywordsError(function_name, key);
+    goto bad;
+invalid_keyword_type:
+    PyErr_Format(PyExc_TypeError,
+        "%s() keywords must be strings", function_name);
+    goto bad;
+invalid_keyword:
+    PyErr_Format(PyExc_TypeError,
+    #if PY_MAJOR_VERSION < 3
+        "%s() got an unexpected keyword argument '%s'",
+        function_name, PyString_AsString(key));
+    #else
+        "%s() got an unexpected keyword argument '%U'",
+        function_name, key);
+    #endif
+bad:
+    return -1;
+}
+
+static CYTHON_INLINE unsigned char __Pyx_PyInt_AsUnsignedChar(PyObject* x) {
+    const unsigned char neg_one = (unsigned char)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(unsigned char) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(unsigned char)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to unsigned char" :
+                    "value too large to convert to unsigned char");
+            }
+            return (unsigned char)-1;
+        }
+        return (unsigned char)val;
+    }
+    return (unsigned char)__Pyx_PyInt_AsUnsignedLong(x);
+}
+
+static CYTHON_INLINE unsigned short __Pyx_PyInt_AsUnsignedShort(PyObject* x) {
+    const unsigned short neg_one = (unsigned short)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(unsigned short) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(unsigned short)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to unsigned short" :
+                    "value too large to convert to unsigned short");
+            }
+            return (unsigned short)-1;
+        }
+        return (unsigned short)val;
+    }
+    return (unsigned short)__Pyx_PyInt_AsUnsignedLong(x);
+}
+
+static CYTHON_INLINE unsigned int __Pyx_PyInt_AsUnsignedInt(PyObject* x) {
+    const unsigned int neg_one = (unsigned int)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(unsigned int) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(unsigned int)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to unsigned int" :
+                    "value too large to convert to unsigned int");
+            }
+            return (unsigned int)-1;
+        }
+        return (unsigned int)val;
+    }
+    return (unsigned int)__Pyx_PyInt_AsUnsignedLong(x);
+}
+
+static CYTHON_INLINE char __Pyx_PyInt_AsChar(PyObject* x) {
+    const char neg_one = (char)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(char) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(char)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to char" :
+                    "value too large to convert to char");
+            }
+            return (char)-1;
+        }
+        return (char)val;
+    }
+    return (char)__Pyx_PyInt_AsLong(x);
+}
+
+static CYTHON_INLINE short __Pyx_PyInt_AsShort(PyObject* x) {
+    const short neg_one = (short)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(short) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(short)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to short" :
+                    "value too large to convert to short");
+            }
+            return (short)-1;
+        }
+        return (short)val;
+    }
+    return (short)__Pyx_PyInt_AsLong(x);
+}
+
+static CYTHON_INLINE int __Pyx_PyInt_AsInt(PyObject* x) {
+    const int neg_one = (int)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(int) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(int)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to int" :
+                    "value too large to convert to int");
+            }
+            return (int)-1;
+        }
+        return (int)val;
+    }
+    return (int)__Pyx_PyInt_AsLong(x);
+}
+
+static CYTHON_INLINE signed char __Pyx_PyInt_AsSignedChar(PyObject* x) {
+    const signed char neg_one = (signed char)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(signed char) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(signed char)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to signed char" :
+                    "value too large to convert to signed char");
+            }
+            return (signed char)-1;
+        }
+        return (signed char)val;
+    }
+    return (signed char)__Pyx_PyInt_AsSignedLong(x);
+}
+
+static CYTHON_INLINE signed short __Pyx_PyInt_AsSignedShort(PyObject* x) {
+    const signed short neg_one = (signed short)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(signed short) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(signed short)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to signed short" :
+                    "value too large to convert to signed short");
+            }
+            return (signed short)-1;
+        }
+        return (signed short)val;
+    }
+    return (signed short)__Pyx_PyInt_AsSignedLong(x);
+}
+
+static CYTHON_INLINE signed int __Pyx_PyInt_AsSignedInt(PyObject* x) {
+    const signed int neg_one = (signed int)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(signed int) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(signed int)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to signed int" :
+                    "value too large to convert to signed int");
+            }
+            return (signed int)-1;
+        }
+        return (signed int)val;
+    }
+    return (signed int)__Pyx_PyInt_AsSignedLong(x);
+}
+
+static CYTHON_INLINE int __Pyx_PyInt_AsLongDouble(PyObject* x) {
+    const int neg_one = (int)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(int) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(int)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to int" :
+                    "value too large to convert to int");
+            }
+            return (int)-1;
+        }
+        return (int)val;
+    }
+    return (int)__Pyx_PyInt_AsLong(x);
+}
+
+static CYTHON_INLINE unsigned long __Pyx_PyInt_AsUnsignedLong(PyObject* x) {
+    const unsigned long neg_one = (unsigned long)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to unsigned long");
+            return (unsigned long)-1;
+        }
+        return (unsigned long)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to unsigned long");
+                return (unsigned long)-1;
+            }
+            return (unsigned long)PyLong_AsUnsignedLong(x);
+        } else {
+            return (unsigned long)PyLong_AsLong(x);
+        }
+    } else {
+        unsigned long val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (unsigned long)-1;
+        val = __Pyx_PyInt_AsUnsignedLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE unsigned PY_LONG_LONG __Pyx_PyInt_AsUnsignedLongLong(PyObject* x) {
+    const unsigned PY_LONG_LONG neg_one = (unsigned PY_LONG_LONG)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to unsigned PY_LONG_LONG");
+            return (unsigned PY_LONG_LONG)-1;
+        }
+        return (unsigned PY_LONG_LONG)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to unsigned PY_LONG_LONG");
+                return (unsigned PY_LONG_LONG)-1;
+            }
+            return (unsigned PY_LONG_LONG)PyLong_AsUnsignedLongLong(x);
+        } else {
+            return (unsigned PY_LONG_LONG)PyLong_AsLongLong(x);
+        }
+    } else {
+        unsigned PY_LONG_LONG val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (unsigned PY_LONG_LONG)-1;
+        val = __Pyx_PyInt_AsUnsignedLongLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE long __Pyx_PyInt_AsLong(PyObject* x) {
+    const long neg_one = (long)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to long");
+            return (long)-1;
+        }
+        return (long)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to long");
+                return (long)-1;
+            }
+            return (long)PyLong_AsUnsignedLong(x);
+        } else {
+            return (long)PyLong_AsLong(x);
+        }
+    } else {
+        long val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (long)-1;
+        val = __Pyx_PyInt_AsLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE PY_LONG_LONG __Pyx_PyInt_AsLongLong(PyObject* x) {
+    const PY_LONG_LONG neg_one = (PY_LONG_LONG)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to PY_LONG_LONG");
+            return (PY_LONG_LONG)-1;
+        }
+        return (PY_LONG_LONG)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to PY_LONG_LONG");
+                return (PY_LONG_LONG)-1;
+            }
+            return (PY_LONG_LONG)PyLong_AsUnsignedLongLong(x);
+        } else {
+            return (PY_LONG_LONG)PyLong_AsLongLong(x);
+        }
+    } else {
+        PY_LONG_LONG val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (PY_LONG_LONG)-1;
+        val = __Pyx_PyInt_AsLongLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE signed long __Pyx_PyInt_AsSignedLong(PyObject* x) {
+    const signed long neg_one = (signed long)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to signed long");
+            return (signed long)-1;
+        }
+        return (signed long)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to signed long");
+                return (signed long)-1;
+            }
+            return (signed long)PyLong_AsUnsignedLong(x);
+        } else {
+            return (signed long)PyLong_AsLong(x);
+        }
+    } else {
+        signed long val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (signed long)-1;
+        val = __Pyx_PyInt_AsSignedLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE signed PY_LONG_LONG __Pyx_PyInt_AsSignedLongLong(PyObject* x) {
+    const signed PY_LONG_LONG neg_one = (signed PY_LONG_LONG)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to signed PY_LONG_LONG");
+            return (signed PY_LONG_LONG)-1;
+        }
+        return (signed PY_LONG_LONG)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to signed PY_LONG_LONG");
+                return (signed PY_LONG_LONG)-1;
+            }
+            return (signed PY_LONG_LONG)PyLong_AsUnsignedLongLong(x);
+        } else {
+            return (signed PY_LONG_LONG)PyLong_AsLongLong(x);
+        }
+    } else {
+        signed PY_LONG_LONG val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (signed PY_LONG_LONG)-1;
+        val = __Pyx_PyInt_AsSignedLongLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static int __Pyx_check_binary_version(void) {
+    char ctversion[4], rtversion[4];
+    PyOS_snprintf(ctversion, 4, "%d.%d", PY_MAJOR_VERSION, PY_MINOR_VERSION);
+    PyOS_snprintf(rtversion, 4, "%s", Py_GetVersion());
+    if (ctversion[0] != rtversion[0] || ctversion[2] != rtversion[2]) {
+        char message[200];
+        PyOS_snprintf(message, sizeof(message),
+                      "compiletime version %s of module '%.100s' "
+                      "does not match runtime version %s",
+                      ctversion, __Pyx_MODULE_NAME, rtversion);
+        #if PY_VERSION_HEX < 0x02050000
+        return PyErr_Warn(NULL, message);
+        #else
+        return PyErr_WarnEx(NULL, message, 1);
+        #endif
+    }
+    return 0;
+}
+
+static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) {
+    int start = 0, mid = 0, end = count - 1;
+    if (end >= 0 && code_line > entries[end].code_line) {
+        return count;
+    }
+    while (start < end) {
+        mid = (start + end) / 2;
+        if (code_line < entries[mid].code_line) {
+            end = mid;
+        } else if (code_line > entries[mid].code_line) {
+             start = mid + 1;
+        } else {
+            return mid;
+        }
+    }
+    if (code_line <= entries[mid].code_line) {
+        return mid;
+    } else {
+        return mid + 1;
+    }
+}
+static PyCodeObject *__pyx_find_code_object(int code_line) {
+    PyCodeObject* code_object;
+    int pos;
+    if (unlikely(!code_line) || unlikely(!__pyx_code_cache.entries)) {
+        return NULL;
+    }
+    pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line);
+    if (unlikely(pos >= __pyx_code_cache.count) || unlikely(__pyx_code_cache.entries[pos].code_line != code_line)) {
+        return NULL;
+    }
+    code_object = __pyx_code_cache.entries[pos].code_object;
+    Py_INCREF(code_object);
+    return code_object;
+}
+static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) {
+    int pos, i;
+    __Pyx_CodeObjectCacheEntry* entries = __pyx_code_cache.entries;
+    if (unlikely(!code_line)) {
+        return;
+    }
+    if (unlikely(!entries)) {
+        entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Malloc(64*sizeof(__Pyx_CodeObjectCacheEntry));
+        if (likely(entries)) {
+            __pyx_code_cache.entries = entries;
+            __pyx_code_cache.max_count = 64;
+            __pyx_code_cache.count = 1;
+            entries[0].code_line = code_line;
+            entries[0].code_object = code_object;
+            Py_INCREF(code_object);
+        }
+        return;
+    }
+    pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line);
+    if ((pos < __pyx_code_cache.count) && unlikely(__pyx_code_cache.entries[pos].code_line == code_line)) {
+        PyCodeObject* tmp = entries[pos].code_object;
+        entries[pos].code_object = code_object;
+        Py_DECREF(tmp);
+        return;
+    }
+    if (__pyx_code_cache.count == __pyx_code_cache.max_count) {
+        int new_max = __pyx_code_cache.max_count + 64;
+        entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Realloc(
+            __pyx_code_cache.entries, new_max*sizeof(__Pyx_CodeObjectCacheEntry));
+        if (unlikely(!entries)) {
+            return;
+        }
+        __pyx_code_cache.entries = entries;
+        __pyx_code_cache.max_count = new_max;
+    }
+    for (i=__pyx_code_cache.count; i>pos; i--) {
+        entries[i] = entries[i-1];
+    }
+    entries[pos].code_line = code_line;
+    entries[pos].code_object = code_object;
+    __pyx_code_cache.count++;
+    Py_INCREF(code_object);
+}
+
+#include "compile.h"
+#include "frameobject.h"
+#include "traceback.h"
+static PyCodeObject* __Pyx_CreateCodeObjectForTraceback(
+            const char *funcname, int c_line,
+            int py_line, const char *filename) {
+    PyCodeObject *py_code = 0;
+    PyObject *py_srcfile = 0;
+    PyObject *py_funcname = 0;
+    #if PY_MAJOR_VERSION < 3
+    py_srcfile = PyString_FromString(filename);
+    #else
+    py_srcfile = PyUnicode_FromString(filename);
+    #endif
+    if (!py_srcfile) goto bad;
+    if (c_line) {
+        #if PY_MAJOR_VERSION < 3
+        py_funcname = PyString_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line);
+        #else
+        py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line);
+        #endif
+    }
+    else {
+        #if PY_MAJOR_VERSION < 3
+        py_funcname = PyString_FromString(funcname);
+        #else
+        py_funcname = PyUnicode_FromString(funcname);
+        #endif
+    }
+    if (!py_funcname) goto bad;
+    py_code = __Pyx_PyCode_New(
+        0,            /*int argcount,*/
+        0,            /*int kwonlyargcount,*/
+        0,            /*int nlocals,*/
+        0,            /*int stacksize,*/
+        0,            /*int flags,*/
+        __pyx_empty_bytes, /*PyObject *code,*/
+        __pyx_empty_tuple, /*PyObject *consts,*/
+        __pyx_empty_tuple, /*PyObject *names,*/
+        __pyx_empty_tuple, /*PyObject *varnames,*/
+        __pyx_empty_tuple, /*PyObject *freevars,*/
+        __pyx_empty_tuple, /*PyObject *cellvars,*/
+        py_srcfile,   /*PyObject *filename,*/
+        py_funcname,  /*PyObject *name,*/
+        py_line,      /*int firstlineno,*/
+        __pyx_empty_bytes  /*PyObject *lnotab*/
+    );
+    Py_DECREF(py_srcfile);
+    Py_DECREF(py_funcname);
+    return py_code;
+bad:
+    Py_XDECREF(py_srcfile);
+    Py_XDECREF(py_funcname);
+    return NULL;
+}
+static void __Pyx_AddTraceback(const char *funcname, int c_line,
+                               int py_line, const char *filename) {
+    PyCodeObject *py_code = 0;
+    PyObject *py_globals = 0;
+    PyFrameObject *py_frame = 0;
+    py_code = __pyx_find_code_object(c_line ? c_line : py_line);
+    if (!py_code) {
+        py_code = __Pyx_CreateCodeObjectForTraceback(
+            funcname, c_line, py_line, filename);
+        if (!py_code) goto bad;
+        __pyx_insert_code_object(c_line ? c_line : py_line, py_code);
+    }
+    py_globals = PyModule_GetDict(__pyx_m);
+    if (!py_globals) goto bad;
+    py_frame = PyFrame_New(
+        PyThreadState_GET(), /*PyThreadState *tstate,*/
+        py_code,             /*PyCodeObject *code,*/
+        py_globals,          /*PyObject *globals,*/
+        0                    /*PyObject *locals*/
+    );
+    if (!py_frame) goto bad;
+    py_frame->f_lineno = py_line;
+    PyTraceBack_Here(py_frame);
+bad:
+    Py_XDECREF(py_code);
+    Py_XDECREF(py_frame);
+}
+
+static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
+    while (t->p) {
+        #if PY_MAJOR_VERSION < 3
+        if (t->is_unicode) {
+            *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
+        } else if (t->intern) {
+            *t->p = PyString_InternFromString(t->s);
+        } else {
+            *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
+        }
+        #else  /* Python 3+ has unicode identifiers */
+        if (t->is_unicode | t->is_str) {
+            if (t->intern) {
+                *t->p = PyUnicode_InternFromString(t->s);
+            } else if (t->encoding) {
+                *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL);
+            } else {
+                *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
+            }
+        } else {
+            *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
+        }
+        #endif
+        if (!*t->p)
+            return -1;
+        ++t;
+    }
+    return 0;
+}
+
+static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) {
+   int is_true = x == Py_True;
+   if (is_true | (x == Py_False) | (x == Py_None)) return is_true;
+   else return PyObject_IsTrue(x);
+}
+static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x) {
+  PyNumberMethods *m;
+  const char *name = NULL;
+  PyObject *res = NULL;
+#if PY_VERSION_HEX < 0x03000000
+  if (PyInt_Check(x) || PyLong_Check(x))
+#else
+  if (PyLong_Check(x))
+#endif
+    return Py_INCREF(x), x;
+  m = Py_TYPE(x)->tp_as_number;
+#if PY_VERSION_HEX < 0x03000000
+  if (m && m->nb_int) {
+    name = "int";
+    res = PyNumber_Int(x);
+  }
+  else if (m && m->nb_long) {
+    name = "long";
+    res = PyNumber_Long(x);
+  }
+#else
+  if (m && m->nb_int) {
+    name = "int";
+    res = PyNumber_Long(x);
+  }
+#endif
+  if (res) {
+#if PY_VERSION_HEX < 0x03000000
+    if (!PyInt_Check(res) && !PyLong_Check(res)) {
+#else
+    if (!PyLong_Check(res)) {
+#endif
+      PyErr_Format(PyExc_TypeError,
+                   "__%s__ returned non-%s (type %.200s)",
+                   name, name, Py_TYPE(res)->tp_name);
+      Py_DECREF(res);
+      return NULL;
+    }
+  }
+  else if (!PyErr_Occurred()) {
+    PyErr_SetString(PyExc_TypeError,
+                    "an integer is required");
+  }
+  return res;
+}
+static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) {
+  Py_ssize_t ival;
+  PyObject* x = PyNumber_Index(b);
+  if (!x) return -1;
+  ival = PyInt_AsSsize_t(x);
+  Py_DECREF(x);
+  return ival;
+}
+static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) {
+#if PY_VERSION_HEX < 0x02050000
+   if (ival <= LONG_MAX)
+       return PyInt_FromLong((long)ival);
+   else {
+       unsigned char *bytes = (unsigned char *) &ival;
+       int one = 1; int little = (int)*(unsigned char*)&one;
+       return _PyLong_FromByteArray(bytes, sizeof(size_t), little, 0);
+   }
+#else
+   return PyInt_FromSize_t(ival);
+#endif
+}
+static CYTHON_INLINE size_t __Pyx_PyInt_AsSize_t(PyObject* x) {
+   unsigned PY_LONG_LONG val = __Pyx_PyInt_AsUnsignedLongLong(x);
+   if (unlikely(val == (unsigned PY_LONG_LONG)-1 && PyErr_Occurred())) {
+       return (size_t)-1;
+   } else if (unlikely(val != (unsigned PY_LONG_LONG)(size_t)val)) {
+       PyErr_SetString(PyExc_OverflowError,
+                       "value too large to convert to size_t");
+       return (size_t)-1;
+   }
+   return (size_t)val;
+}
+
+
+#endif /* Py_PYTHON_H */
diff --git a/lib/bx/align/sitemask/_cpg.pyx b/lib/bx/align/sitemask/_cpg.pyx
new file mode 100644
index 0000000..1133cfc
--- /dev/null
+++ b/lib/bx/align/sitemask/_cpg.pyx
@@ -0,0 +1,90 @@
+"""
+Pyrex/C extension for quickly finding potential CpG sites in pairs of 
+sequences.
+"""
+
+cdef extern from "find_cpg.h":
+    int next_cpg( char * sp1, char * sp2, int start)
+    int next_cpg_restricted( char * sp1, char *sp2, int start)
+    int next_non_cpg( char * sp1, char * sp2, int start)
+
+def find_cpg( sp1, sp2, start ):
+    cdef char* a
+    cdef char* b
+    cdef int pos
+    a = sp1
+    b = sp2
+    pos = start
+    if pos > len(sp1): return -1
+    return next_cpg( a, b, pos )
+
+def find_cpg_restricted( sp1, sp2, start ):
+    cdef char* a
+    cdef char* b
+    cdef int pos
+    a = sp1
+    b = sp2
+    pos = start
+    if pos > len(sp1): return -1
+    return next_cpg_restricted( a, b, pos )
+
+def find_non_cpg( sp1, sp2, start ):
+    cdef char* a
+    cdef char* b
+    cdef int pos
+    a = sp1
+    b = sp2
+    pos = start
+    if pos > len(sp1): return -1
+    return next_non_cpg( a, b, pos )
+
+def list_cpg( sp1, sp2 ):
+    cdef char * a
+    cdef char * b
+    cdef int start
+    a = sp1
+    b = sp2
+    start = 0
+    cpglist = list()
+    while start > -1 and start < len(sp1):
+        start = next_cpg( a, b, start )
+        if start == -1: break
+        cpglist.append(start)
+        start = start + 1
+    return cpglist
+
+def list_cpg_restricted( sp1, sp2 ):
+    cdef char * a
+    cdef char * b
+    cdef int start
+    a = sp1
+    b = sp2
+    start = 0
+    cpglist = list()
+    while start > -1 and start < len(sp1):
+        start = next_cpg_restricted( a, b, start )
+        if start == -1: break
+        cpglist.append(start)
+        start = start + 1
+    return cpglist
+
+def list_non_cpg( sp1, sp2 ):
+    cdef char * a
+    cdef char * b
+    cdef int start
+    a = sp1
+    b = sp2
+    start = 0
+    cpglist = list()
+    while start > -1 and start < len(sp1):
+        start = next_non_cpg( a, b, start )
+        if start == -1: break
+        cpglist.append(start)
+        start = start + 1
+    return cpglist
+
+def remove_gaps( sp, cpglist ):
+    for item in cpglist:
+        if sp[item] == '-':
+            cpglist.remove(item)
+    return cpglist
diff --git a/lib/bx/align/sitemask/core.py b/lib/bx/align/sitemask/core.py
new file mode 100644
index 0000000..e6c9800
--- /dev/null
+++ b/lib/bx/align/sitemask/core.py
@@ -0,0 +1,35 @@
+"""
+Base classes for site maskers.
+"""
+
+from bx.filter import *
+
+class Masker( Filter ):
+    def __init__( self, **kwargs ):
+        self.masked = 0
+        self.total = 0
+        Exception("Abstract class")
+
+class MaskPipeline( Pipeline ):
+    """
+    MaskPipeline implements a Pipeline through which alignments can be
+    pushed and masked.  Pipelines can be aggregated.
+    """
+    def get_masked( self ):
+        masked = 0
+        for function in self.pipeline:
+            try: masked += masker.masked
+            except AttributeError: pass
+        return masked
+    masked = property( fget=get_masked )
+    
+    def __call__( self, block ):
+        if not block: return
+        # push alignment block through all filters
+        self.total += len( block.components[0].text )
+        for masker in self.filters:
+            if not block: return
+            try: m_filter = masker.__call__
+            except AttributeError:
+                raise Exception("Masker in pipeline does not implement \"filter( self, block )\".")
+            masker( block )
diff --git a/lib/bx/align/sitemask/cpg.py b/lib/bx/align/sitemask/cpg.py
new file mode 100644
index 0000000..d7d6a53
--- /dev/null
+++ b/lib/bx/align/sitemask/cpg.py
@@ -0,0 +1,91 @@
+"""
+Support for masking potential CpG sites in *pairwise* alignments. 
+"""
+
+from _cpg import *
+from bx.align.sitemask import Masker
+from bx.filter import *
+import string
+
+# Restricted.  Only mask out sites that are defitely CpG
+class Restricted( Masker ):
+    def __init__( self, mask = '?' ):
+        self.mask = mask
+        self.masked = 0
+        self.total = 0
+        
+    def __call__( self, block ):
+        if not block: return block
+        if len(block.components) < 2:
+            return
+        cpglist = list_cpg_restricted( \
+            string.upper(block.components[0].text), \
+            string.upper(block.components[1].text) )
+
+        # now we have a fast list of CpG columns, iterate/mask
+        self.masked += len(cpglist)
+        self.total += len(block.components[0].text)
+        for component in block.components:
+            component.text = mask_columns( cpglist, component.text, self.mask )
+            
+        return block
+    
+# Inclusive. Mask out all sites that are not non-CpG sites.
+class Inclusive( Masker ):
+    def __init__( self, mask = '?' ):
+        self.mask = mask
+        self.masked = 0
+        self.total = 0
+        
+    def __call__( self, block ):
+        if not block: return block
+        if len(block.components) < 2:
+            return
+        cpglist = list_cpg( \
+            string.upper(block.components[0].text), \
+            string.upper(block.components[1].text) )
+        
+        self.masked += len( cpglist )
+        self.total += len( block.components[0].text )
+        for component in block.components:
+            component.text = mask_columns( cpglist, component.text, self.mask)
+            
+        return block
+
+#Mak nonCpG sites
+class nonCpG( Masker ):
+    def __init__( self, mask = '?' ):
+        self.mask = mask
+        self.masked = 0
+        self.total = 0
+        
+    def __call__( self, block ):
+        if not block: return block
+        if len(block.components) < 2:
+            return
+        noncpglist = list_non_cpg( \
+            string.upper(block.components[0].text), \
+            string.upper(block.components[1].text) )
+
+        # now we have a fast list of non-CpG columns, iterate/mask
+        self.masked += len(noncpglist)
+        self.total += len(block.components[0].text)
+        for component in block.components:
+            component.text = mask_columns( noncpglist, component.text, self.mask )
+            
+        return block
+    
+def mask_columns( masklist, text, mask ):
+    templist = list()
+    for position in masklist:
+        if text[position] != "-":
+            templist.append(position)
+    templist.append(len(text)) # Add the end of the text
+    #cut string
+    newtext = list()
+    c = 0
+    for position in templist:
+        newtext.append(text[c:position])
+        c = position + 1 # Gaps have len = 1
+    joinedtext = mask.join(newtext)
+    return joinedtext
diff --git a/lib/bx/align/sitemask/find_cpg.c b/lib/bx/align/sitemask/find_cpg.c
new file mode 100644
index 0000000..fb6e2b0
--- /dev/null
+++ b/lib/bx/align/sitemask/find_cpg.c
@@ -0,0 +1,66 @@
+#include <stdlib.h>
+/*
+  Author: Ian N Schenck
+  Version: 7/21/2006
+
+  Most of this was ripped out of James Taylor's never-released code,
+  and plugged in here for use in Python.  Slight modifications were
+  made where I saw fit.
+
+  It looks as if CpG's are typically not next to gaps.
+*/
+
+static inline int is_cpg( char * sp1, char * sp2, int pos)
+{
+  if ( pos < 1 ) return 0;
+  if ( sp1[pos + 1] == '\0' ) return 0;
+  if ( sp1[pos - 1] != 'C' && sp2[pos - 1] != 'C' &&
+       sp1[pos + 1] == 'G' && sp2[pos + 1] == 'G' &&
+       (sp1[pos] == 'C' || sp2[pos] == 'C') ) return 1;
+  if ( sp1[pos + 1] != 'G' && sp2[pos + 1] != 'G' &&
+       sp1[pos - 1] == 'C' && sp2[pos - 1] == 'C' &&
+       (sp1[pos] == 'G' || sp2[pos] == 'G') ) return 1;
+  return 0;
+}
+
+static inline int is_non_cpg( char * sp1, char * sp2, int pos)
+{
+  // first one can't assuredly be cpg
+  if ( pos < 1 ) return 1;
+  if ( sp1[pos + 1] == '\0' ) return 0;
+  return
+    ( sp1[pos - 1] != 'C' && sp2[pos - 1] != 'C' &&
+      sp1[pos + 1] != 'G' && sp2[pos + 1] != 'G' );
+}
+
+static inline int is_cpg_restricted( char * sp1, char * sp2, int pos )
+{
+  return !is_non_cpg( sp1, sp2, pos );
+}
+
+int next( char * sp1, char * sp2, int start, int (*func)(char*,char*,int))
+{
+  while( sp1[start+1] != '\0')
+    {
+      if( func(sp1, sp2, start) )
+	return start;
+      start++;
+    }
+  // nothing found
+  return -1;
+}
+
+int next_cpg( char * sp1, char * sp2, int start)
+{
+  return next( sp1, sp2, start, &is_cpg);
+}
+
+int next_cpg_restricted( char * sp1, char *sp2, int start)
+{
+  return next( sp1, sp2, start, &is_cpg_restricted );
+}
+
+int next_non_cpg( char * sp1, char * sp2, int start)
+{
+  return next( sp1, sp2, start, &is_non_cpg);
+}
diff --git a/lib/bx/align/sitemask/find_cpg.h b/lib/bx/align/sitemask/find_cpg.h
new file mode 100644
index 0000000..1e91dba
--- /dev/null
+++ b/lib/bx/align/sitemask/find_cpg.h
@@ -0,0 +1,7 @@
+#ifndef __find_cpg__
+#define __find_cpg__
+int next( char * sp1, char * sp2, int start, int (*func)(char*,char*,int));
+int next_cpg( char * sp1, char * sp2, int start);
+int next_cpg_restricted( char * sp1, char *sp2, int start);
+int next_non_cpg( char * sp1, char * sp2, int start);
+#endif
diff --git a/lib/bx/align/sitemask/quality.py b/lib/bx/align/sitemask/quality.py
new file mode 100644
index 0000000..b6cd002
--- /dev/null
+++ b/lib/bx/align/sitemask/quality.py
@@ -0,0 +1,130 @@
+"""
+Support for masking out sites in alignments based on sequence quality. Both 
+simple masking of regions below some threshold and masking using the 
+neighborhood quality standard (NQS) are supported. Uses sequence quality
+values stored in a `bx.binned_array.FileBinnedArray`.
+"""
+
+from bx.align.sitemask import Masker
+from bx.align import *
+from bx.binned_array import FileBinnedArray
+
+# This class implements simple rules for masking quality, if base <
+# minqual, mask
+class Simple( Masker ):
+    # keys should be:
+    # qualspecies: dictionary of species as key, lengths
+    #              dict by chromosome or chromosome list as value
+    # qualfiles: prefix for quality file for each species in qualspecies
+    # mask: mask character (default is '?')
+    # minqual: minimum quality
+    # cache: optional, but sets the number of megabytes allowed in cache per quality masked species
+    def __init__( self, qualfiles = None, qualspecies = None, minqual = None, mask = "?", cache=100):
+        if not qualfiles:
+            raise Exception("No quality files.")
+        if not qualspecies:
+            raise Exception("No species dictionary.")
+        if not minqual:
+            raise Exception("No minimum quality specified.")
+        self.mask = "?"
+        self.minqual = minqual
+        self.mask = mask
+        self.total = 0
+        self.masked = 0
+        
+        self.qualfiles = qualfiles
+        self.qualspecies = qualspecies
+        self.cache = cache * 2 # typical bin size is 512K
+        # load quality files into FileBinnedArray
+        self.qualities = {}
+        for species, qualfile in self.qualfiles.items():
+            specdict = {}
+            for chrom in self.qualspecies[species]:
+                specdict[chrom] = FileBinnedArray( \
+                    open(qualfile + "." + chrom + ".bqv", "rb"), \
+                    cache = self.cache/len(qualfiles) )
+            self.qualities[species] = specdict
+        
+    def __call__( self, block ):
+        if not block: return
+        for qualspec in self.qualities:
+            comp = block.get_component_by_src_start(qualspec)
+            if not comp: continue
+            chrom = comp.src.split(".")[1]
+            start, end = comp.get_forward_strand_start(), comp.get_forward_strand_end()
+            # get quality slice, for + strand
+            qual = self.qualities[qualspec][chrom][start:end]
+            x = 0
+            while start+x < end:
+                self.total += 1
+                # got the column in the alignment for this particular base
+                if qual[x] < self.minqual:
+                    col = comp.coord_to_col(start+x)
+                    self.masked += 1
+                    for component in block.components:
+                        if component.text[col] != "-":
+                            component.text = component.text[0:col] + \
+                                             self.mask + \
+                                             component.text[col+1:len(component.text)]
+                # iterate through quality
+                x += 1
+        return block
+    
+class NQS( Masker ):
+    # keys should be:
+    # qualspecies: dictionary of species as key, lengths
+    #              dict by chromosome or chromosome list as value
+    # qualfiles: prefix for quality file for each species in qualspecies
+    # mask: mask character (default is '?')
+    # minqual: minimum quality
+    # neighborqual: neighborhood minimum quality (bases within 5 bps are masked)
+    # cache: optional, but sets the number of megabytes allowed in cache per quality masked species
+    def __init__( self, qualfiles = None, qualspecies = None, minqual = None, mask = "?", cache=100):
+        if not qualfiles:
+            raise Exception("No quality files.")
+        if not qualspecies:
+            raise Exception("No species dictionary.")
+        if not minqual:
+            raise Exception("No minimum quality specified.")
+        self.mask = "?"
+        self.minqual = minqual
+        self.mask = mask
+        self.total = 0
+        self.masked = 0
+        
+        self.qualfiles = qualfiles
+        self.qualspecies = qualspecies
+        self.cache = cache * 2 # typical bin size is 512K
+        # load quality files into FileBinnedArray
+        self.qualities = {}
+        for species, qualfile in self.qualfiles.items():
+            specdict = {}
+            for chrom in self.qualspecies[species]:
+                specdict[chrom] = FileBinnedArray( \
+                    open(qualfile + "." + chrom + ".bqv", "rb"), \
+                    cache = self.cache/len(qualfiles) )
+            self.qualities[species] = specdict
+        
+    def __call__( self, block ):
+        if not block: return
+        for qualspec in self.qualities:
+            comp = block.get_component_by_src_start(qualspec)
+            chrom = comp.src.split(".")[1]
+            start, end = comp.get_forward_strand_start(), comp.get_forward_strand_end()
+            # get quality slice, for + strand
+            qual = self.qualities[qualspec][chrom][start:end]
+            x = 0
+            while start+x < end:
+                self.total += 1
+                # got the column in the alignment for this particular base
+                if qual[x] < self.minqual:
+                    col = comp.coord_to_col(start+x)
+                    self.masked += 1
+                    for component in block.components:
+                        if component.text[col] != "-":
+                            component.text = component.text[0:col] + \
+                                             self.mask + \
+                                             component.text[col+1:len(component.text)]
+                # iterate through quality
+                x += 1
+        return block
diff --git a/lib/bx/align/sitemask/sitemask_tests.py b/lib/bx/align/sitemask/sitemask_tests.py
new file mode 100644
index 0000000..f2886a9
--- /dev/null
+++ b/lib/bx/align/sitemask/sitemask_tests.py
@@ -0,0 +1,82 @@
+"""
+Tests for `bx.align.maf.sitemask`.
+"""
+
+import sys,tempfile
+import unittest
+from StringIO import StringIO
+import cpg
+import bx.align.maf
+
+test_maf_cpg = """##maf version=1 scoring=none
+a score=0
+s apple  34 64 + 110 AGGGA---GTTCGTCACT------GTCGTAAGGGTTCAGA--CTGTCTATGTATACACAAGTTGTGTTGCA--ACCG
+s orange 19 61 - 100 AGGGATGCGTT--TCACTGCTATCGTCGTA----TTCAGACTTCG-CTATCT------GAGTTGT---GCATTACCG
+"""
+
+cpg_inclusive_result = [
+"##maf,version=1",
+"a,score=0",
+"s,apple,34,64,+,110,AGGGA---GTTCGTCACT------GT##TAAGGGTTCAGA--CTGTCTATGTATACACAAGTTGTGTTGCA--ACCG", 
+"s,orange,19,61,-,100,AGGGATG#GTT--TCACTGCTAT#GT##TA----TTCAGACTTCG-CTATCT------GAGTTGT---GCATTACCG" 
+]
+
+cpg_restricted_result = [
+"##maf,version=1",
+"a,score=0",
+"s,apple,34,64,+,110,A##GA---#TT##TC#C#------#T##TA###GTTC#GA--C##TC#A#G#ATAC####GT#G#GT#GC#--AC#G", 
+"s,orange,19,61,-,100,A##GA#G##TT--TC#C#GC#AT##T##TA----TTC#GAC#T##-C#A#C#------##GT#G#---GC#TTAC#G"                          
+]
+
+noncpg_result = [
+"##maf,version=1",
+"a,score=0",
+"s,apple,34,64,+,110,#GG##---G##CG##A#T------G#CG##AGG####A##--#TG##T#T#T####ACAA##T#T##T##A--##CG", 
+"s,orange,19,61,-,100,#GG##T#CG##--##A#T##T##CG#CG##----###A###T#CG-#T#T#T------GA##T#T---##A####CG" 
+]
+
+def test_cpg_inclusive():
+    reader = bx.align.maf.Reader( StringIO( test_maf_cpg ) )
+    out = tempfile.NamedTemporaryFile('w')
+    writer = bx.align.maf.Writer( out )
+    cpgfilter = cpg.Inclusive( mask='#' )
+    cpgfilter.run( reader, writer.write )
+    out.seek(0)
+    j=0
+    for line in file(out.name):
+        line = line.strip()
+        if not(line):
+            continue
+        assert cpg_inclusive_result[j] == ",".join(line.split())
+        j+=1
+    
+def test_cpg_restricted():
+    reader = bx.align.maf.Reader( StringIO( test_maf_cpg ) )
+    out = tempfile.NamedTemporaryFile('w')
+    writer = bx.align.maf.Writer( out )
+    cpgfilter = cpg.Restricted( mask='#' )
+    cpgfilter.run( reader, writer.write )
+    out.seek(0)
+    j=0
+    for line in file(out.name):
+        line = line.strip()
+        if not(line):
+            continue
+        assert cpg_restricted_result[j] == ",".join(line.split())
+        j+=1
+
+def test_non_cpg():
+    reader = bx.align.maf.Reader( StringIO( test_maf_cpg ) )
+    out = tempfile.NamedTemporaryFile('w')
+    writer = bx.align.maf.Writer( out )
+    cpgfilter = cpg.nonCpG( mask='#' )
+    cpgfilter.run( reader, writer.write )
+    out.seek(0)
+    j=0
+    for line in file(out.name):
+        line = line.strip()
+        if not(line):
+            continue
+        assert noncpg_result[j] == ",".join(line.split())
+        j+=1
+
diff --git a/lib/bx/align/tools/__init__.py b/lib/bx/align/tools/__init__.py
new file mode 100644
index 0000000..6fbda99
--- /dev/null
+++ b/lib/bx/align/tools/__init__.py
@@ -0,0 +1,8 @@
+"""
+Various utilities for working with `bx.align.Alignment` objects.
+"""
+
+from fuse import *
+from thread import *
+from chop import *
+from tile import *
\ No newline at end of file
diff --git a/lib/bx/align/tools/chop.py b/lib/bx/align/tools/chop.py
new file mode 100644
index 0000000..560c39f
--- /dev/null
+++ b/lib/bx/align/tools/chop.py
@@ -0,0 +1,29 @@
+"""
+Support for chopping a list of alignment blocks to only the portion that
+intersects a particular interval.
+"""
+
+def chop_list( blocks, src, start, end ):
+    """
+    For each alignment block in the sequence `blocks`, chop out the portion
+    of the block that overlaps the interval [`start`,`end`) in the
+    component/species named `src`.
+    """
+    new_blocks = []
+    for block in blocks: 
+        ref = block.get_component_by_src( src )
+        # If the reference component is on the '-' strand we should complement the interval
+        if ref.strand == '-':
+            slice_start = max( ref.src_size - end, ref.start )
+            slice_end = max( ref.src_size - start, ref.end )
+        else:
+            slice_start = max( start, ref.start )
+            slice_end = min( end, ref.end )
+        sliced = block.slice_by_component( ref, slice_start, slice_end ) 
+        good = True
+        for c in sliced.components: 
+            if c.size < 1: 
+                good = False
+        if good:
+            new_blocks.append( sliced )
+    return new_blocks
diff --git a/lib/bx/align/tools/fuse.py b/lib/bx/align/tools/fuse.py
new file mode 100644
index 0000000..af6cb82
--- /dev/null
+++ b/lib/bx/align/tools/fuse.py
@@ -0,0 +1,88 @@
+"""
+Tools for fusing contiguous alignment blocks together.
+"""
+
+from itertools import *
+from copy import deepcopy
+
+def fuse_list( mafs ):
+    """
+    Try to fuse a list of blocks by progressively fusing each adjacent pair.
+    """
+    last = None
+    for m in mafs:
+        if last is None:
+            last = m
+        else:
+            fused = fuse( last, m )
+            if fused:
+                last = fused
+            else:
+                yield last
+                last = m
+    if last:
+        yield last
+
+def fuse( m1, m2 ):
+    """
+    Attempt to fuse two blocks. If they can be fused returns a new block, 
+    otherwise returns None.
+      
+    Example:
+      
+    >>> import bx.align.maf
+      
+    >>> block1 = bx.align.maf.from_string( '''
+    ... a score=0.0
+    ... s hg18.chr10 52686 44 + 135374737 GTGCTAACTTACTGCTCCACAGAAAACATCAATTCTGCTCATGC
+    ... s panTro1.chrUn_random 208115356 44 - 240967748 GTGCTAACTGACTGCTCCAGAGAAAACATCAATTCTGTTCATGT
+    ... ''' )
+    
+    >>> block2 = bx.align.maf.from_string( '''
+    ... a score=0.0
+    ... s hg18.chr10 52730 69 + 135374737 GCAGGTACAATTCATCAAGAAAGGAATTACAACTTCAGAAATGTGTTCAAAATATATCCATACTTTGAC
+    ... s panTro1.chrUn_random 208115400 69 - 240967748 GCAGCTACTATTCATCAAGAAAGGGATTACAACTTCAGAAATGTGTTCAAAGTGTATCCATACTTTGAT
+    ... ''' )
+    
+    >>> fused = fuse( block1, block2 )
+    
+    >>> print fused
+    a score=0.0
+    s hg18.chr10 52686 113 + 135374737 GTGCTAACTTACTGCTCCACAGAAAACATCAATTCTGCTCATGCGCAGGTACAATTCATCAAGAAAGGAATTACAACTTCAGAAATGTGTTCAAAATATATCCATACTTTGAC
+    s panTro1.chrUn_random 208115356 113 - 240967748 GTGCTAACTGACTGCTCCAGAGAAAACATCAATTCTGTTCATGTGCAGCTACTATTCATCAAGAAAGGGATTACAACTTCAGAAATGTGTTCAAAGTGTATCCATACTTTGAT
+    <BLANKLINE>
+    """
+    # Check if the blocks are adjacent, return none if not.
+    if len( m1.components ) != len( m2.components ): return None
+    for c1, c2 in izip( m1.components, m2.components ):
+        if c1.src != c2.src: return None
+        if c1.strand != c2.strand: return None
+        if c1.end != c2.start: return None
+    # Try to fuse:
+    n = deepcopy( m1 )
+    for c1, c2 in izip( n.components, m2.components ):
+        c1.text += c2.text
+        c1.size += c2.size
+    n.text_size = len( n.components[0].text )
+    return n
+    
+class FusingAlignmentWriter( object ):
+    """
+    Wrapper for an alignment Writer which attempts to fuse adjacent blocks
+    """
+    def __init__( self, maf_writer ):
+        self.maf_writer = maf_writer
+        self.last = None
+    def write( self, m ):
+        if not self.last:
+            self.last = m
+        else:
+            fused = fuse( self.last, m )
+            if fused:
+                self.last = fused
+            else:
+                self.maf_writer.write( self.last )
+                self.last = m
+    def close( self ):
+        if self.last: self.maf_writer.write( self.last )
+        self.maf_writer.close()
diff --git a/lib/bx/align/tools/thread.py b/lib/bx/align/tools/thread.py
new file mode 100644
index 0000000..86636c5
--- /dev/null
+++ b/lib/bx/align/tools/thread.py
@@ -0,0 +1,98 @@
+"""
+Tools for "threading" out specific species from alignments (removing other
+species and fixing alignment text).
+"""
+
+import sys
+from itertools import *
+from copy import deepcopy
+
+def thread( mafs, species ):
+    """
+    Restrict an list of alignments to a given list of species by:
+    
+        1) Removing components for any other species 
+        2) Remove any columns containing all gaps
+      
+    Example:
+      
+    >>> import bx.align.maf
+      
+    >>> block1 = bx.align.maf.from_string( '''
+    ... a score=4964.0
+    ... s hg18.chr10                  52686 44 + 135374737 GTGCTAACTTACTGCTCCACAGAAAACATCAATTCTGCTCATGC
+    ... s rheMac2.chr20            58163346 43 -  88221753 ATATTATCTTAACATTAAAGA-AGAACAGTAATTCTGGTCATAA
+    ... s panTro1.chrUn_random    208115356 44 - 240967748 GTGCTAACTGACTGCTCCAGAGAAAACATCAATTCTGTTCATGT
+    ... s oryCun1.scaffold_175207     85970 22 +    212797 ----------------------AAAATATTAGTTATCACCATAT
+    ... s bosTau2.chr23            23894492 43 +  41602928 AAACTACCTTAATGTCACAGG-AAACAATGTATgctgctgctgc
+    ... ''' )
+    
+    >>> block2 = bx.align.maf.from_string( '''
+    ... a score=9151.0
+    ... s hg18.chr10                  52730 69 + 135374737 GCAGGTACAATTCATCAAGAAAG-GAATTACAACTTCAGAAATGTGTTCAAAATATATCCATACTT-TGAC
+    ... s oryCun1.scaffold_175207     85992 71 +    212797 TCTAGTGCTCTCCAATAATATAATAGATTATAACTTCATATAATTATGTGAAATATAAGATTATTTATCAG
+    ... s panTro1.chrUn_random    208115400 69 - 240967748 GCAGCTACTATTCATCAAGAAAG-GGATTACAACTTCAGAAATGTGTTCAAAGTGTATCCATACTT-TGAT
+    ... s rheMac2.chr20            58163389 69 -  88221753 ACACATATTATTTCTTAACATGGAGGATTATATCTT-AAACATGTGTGCaaaatataaatatatat-tcaa
+    ... ''' )
+    
+    >>> mafs = [ block1, block2 ]
+    
+    >>> threaded = [ t for t in thread( mafs, [ "hg18", "panTro1" ] ) ]
+    
+    >>> len( threaded )
+    2
+    
+    >>> print threaded[0]
+    a score=0.0
+    s hg18.chr10 52686 44 + 135374737 GTGCTAACTTACTGCTCCACAGAAAACATCAATTCTGCTCATGC
+    s panTro1.chrUn_random 208115356 44 - 240967748 GTGCTAACTGACTGCTCCAGAGAAAACATCAATTCTGTTCATGT
+    <BLANKLINE>
+
+    >>> print threaded[1]
+    a score=0.0
+    s hg18.chr10 52730 69 + 135374737 GCAGGTACAATTCATCAAGAAAGGAATTACAACTTCAGAAATGTGTTCAAAATATATCCATACTTTGAC
+    s panTro1.chrUn_random 208115400 69 - 240967748 GCAGCTACTATTCATCAAGAAAGGGATTACAACTTCAGAAATGTGTTCAAAGTGTATCCATACTTTGAT
+    <BLANKLINE>
+    
+    """
+    for m in mafs:
+        new_maf = deepcopy( m )
+        new_components = get_components_for_species( new_maf, species )	
+        if new_components: 
+            remove_all_gap_columns( new_components )          
+            new_maf.components = new_components
+            new_maf.score = 0.0
+            new_maf.text_size = len(new_components[0].text)
+            yield new_maf
+        
+def get_components_for_species( alignment, species ):
+    """Return the component for each species in the list `species` or None"""
+    # If the number of components in the alignment is less that the requested number
+    # of species we can immediately fail
+    if len( alignment.components ) < len( species ): return None
+    # Otherwise, build an index of components by species, then lookup 
+    index = dict( [ ( c.src.split( '.' )[0], c ) for c in alignment.components ] )
+    try: return [ index[s] for s in species ]
+    except: return None
+
+def remove_all_gap_columns( components ):
+    """
+    Remove any columns containing only gaps from a set of alignment components,
+    text of components is modified IN PLACE.
+    
+    TODO: Optimize this with Pyrex.
+    """        
+    seqs = [ list( c.text ) for c in components ]
+    i = 0
+    text_size = len( seqs[0] )
+    while i < text_size:
+        all_gap = True
+        for seq in seqs:
+            if seq[i] != '-': all_gap = False
+        if all_gap:
+            for seq in seqs: del seq[i]
+            text_size -= 1
+        else:
+            i += 1
+    for i in range( len( components ) ):
+        components[i].text = ''.join( seqs[i] )
diff --git a/lib/bx/align/tools/tile.py b/lib/bx/align/tools/tile.py
new file mode 100644
index 0000000..acf18c5
--- /dev/null
+++ b/lib/bx/align/tools/tile.py
@@ -0,0 +1,81 @@
+"""
+Tools for tiling / projecting alignments onto an interval of a sequence.
+"""
+
+import bx.align as align
+from bx import misc
+import bx.seq.nib
+import os
+import string
+import sys
+
+
+def tile_interval( sources, index, ref_src, start, end, seq_db=None ):
+    """
+    Tile maf blocks onto an interval. The resulting block will span the interval
+    exactly and contain the column from the highest scoring alignment at each
+    position.
+
+    `sources`: list of sequence source names to include in final block
+    `index`: an instnace that can return maf blocks overlapping intervals
+    `ref_src`: source name of the interval (ie, hg17.chr7)
+    `start`: start of interval
+    `end`: end of interval
+    `seq_db`: a mapping for source names in the reference species to nib files
+    """
+    # First entry in sources should also be on the reference species
+    assert sources[0].split('.')[0] == ref_src.split('.')[0], \
+        "%s != %s" % ( sources[0].split('.')[0], ref_src.split('.')[0] )
+    base_len = end - start
+    blocks = index.get( ref_src, start, end )
+    # From low to high score
+    blocks.sort(key=lambda t: t.score)
+    mask = [ -1 ] * base_len
+    ref_src_size = None
+    for i, block in enumerate( blocks ):
+        ref = block.get_component_by_src_start( ref_src )
+        ref_src_size = ref.src_size
+        assert ref.strand == "+"
+        slice_start = max( start, ref.start )
+        slice_end = min( end, ref.end )
+        for j in range( slice_start, slice_end ):
+            mask[j-start] = i
+    tiled = []
+    for i in range( len( sources ) ):
+        tiled.append( [] )
+    for ss, ee, index in intervals_from_mask( mask ):
+        # Interval with no covering alignments
+        if index < 0:
+            # Get sequence if available, otherwise just use 'N'
+            if seq_db:
+                tiled[0].append( bx.seq.nib.NibFile( open( seq_db[ ref_src ] ) ).get( start+ss, ee-ss ) )
+            else:
+                tiled[0].append( "N" * (ee-ss) )
+            # Gaps in all other species
+            for row in tiled[1:]:
+                row.append( "-" * ( ee - ss ) )
+        else:
+            slice_start = start + ss
+            slice_end = start + ee
+            block = blocks[index]
+            ref = block.get_component_by_src_start( ref_src )
+            sliced = block.slice_by_component( ref, slice_start, slice_end )
+            sliced = sliced.limit_to_species( sources )
+            sliced.remove_all_gap_columns()
+            for i, src in enumerate( sources ):
+                comp = sliced.get_component_by_src_start( src )
+                if comp:
+                    tiled[i].append( comp.text )
+                else:
+                    tiled[i].append( "-" * sliced.text_size )
+    return [ "".join( t ) for t in tiled ]
+
+def intervals_from_mask( mask ):
+    start = 0
+    last = mask[0]
+    for i in range( 1, len( mask ) ):
+        if mask[i] != last:
+            yield start, i, last
+            start = i
+            last = mask[i]
+    yield start, len(mask), last
diff --git a/lib/bx/arrays/__init__.py b/lib/bx/arrays/__init__.py
new file mode 100644
index 0000000..84f13fc
--- /dev/null
+++ b/lib/bx/arrays/__init__.py
@@ -0,0 +1,3 @@
+"""
+Classes for working with arrays of data.
+"""
diff --git a/lib/bx/arrays/array_tree.c b/lib/bx/arrays/array_tree.c
new file mode 100644
index 0000000..434bc32
--- /dev/null
+++ b/lib/bx/arrays/array_tree.c
@@ -0,0 +1,16912 @@
+/* Generated by Cython 0.18 on Mon Jul 15 13:25:44 2013 */
+
+#define PY_SSIZE_T_CLEAN
+#include "Python.h"
+#ifndef Py_PYTHON_H
+    #error Python headers needed to compile C extensions, please install development version of Python.
+#elif PY_VERSION_HEX < 0x02040000
+    #error Cython requires Python 2.4+.
+#else
+#include <stddef.h> /* For offsetof */
+#ifndef offsetof
+#define offsetof(type, member) ( (size_t) & ((type*)0) -> member )
+#endif
+#if !defined(WIN32) && !defined(MS_WINDOWS)
+  #ifndef __stdcall
+    #define __stdcall
+  #endif
+  #ifndef __cdecl
+    #define __cdecl
+  #endif
+  #ifndef __fastcall
+    #define __fastcall
+  #endif
+#endif
+#ifndef DL_IMPORT
+  #define DL_IMPORT(t) t
+#endif
+#ifndef DL_EXPORT
+  #define DL_EXPORT(t) t
+#endif
+#ifndef PY_LONG_LONG
+  #define PY_LONG_LONG LONG_LONG
+#endif
+#ifndef Py_HUGE_VAL
+  #define Py_HUGE_VAL HUGE_VAL
+#endif
+#ifdef PYPY_VERSION
+#define CYTHON_COMPILING_IN_PYPY 1
+#define CYTHON_COMPILING_IN_CPYTHON 0
+#else
+#define CYTHON_COMPILING_IN_PYPY 0
+#define CYTHON_COMPILING_IN_CPYTHON 1
+#endif
+#if PY_VERSION_HEX < 0x02050000
+  typedef int Py_ssize_t;
+  #define PY_SSIZE_T_MAX INT_MAX
+  #define PY_SSIZE_T_MIN INT_MIN
+  #define PY_FORMAT_SIZE_T ""
+  #define CYTHON_FORMAT_SSIZE_T ""
+  #define PyInt_FromSsize_t(z) PyInt_FromLong(z)
+  #define PyInt_AsSsize_t(o)   __Pyx_PyInt_AsInt(o)
+  #define PyNumber_Index(o)    ((PyNumber_Check(o) && !PyFloat_Check(o)) ? PyNumber_Int(o) : \
+                                (PyErr_Format(PyExc_TypeError, \
+                                              "expected index value, got %.200s", Py_TYPE(o)->tp_name), \
+                                 (PyObject*)0))
+  #define __Pyx_PyIndex_Check(o) (PyNumber_Check(o) && !PyFloat_Check(o) && \
+                                  !PyComplex_Check(o))
+  #define PyIndex_Check __Pyx_PyIndex_Check
+  #define PyErr_WarnEx(category, message, stacklevel) PyErr_Warn(category, message)
+  #define __PYX_BUILD_PY_SSIZE_T "i"
+#else
+  #define __PYX_BUILD_PY_SSIZE_T "n"
+  #define CYTHON_FORMAT_SSIZE_T "z"
+  #define __Pyx_PyIndex_Check PyIndex_Check
+#endif
+#if PY_VERSION_HEX < 0x02060000
+  #define Py_REFCNT(ob) (((PyObject*)(ob))->ob_refcnt)
+  #define Py_TYPE(ob)   (((PyObject*)(ob))->ob_type)
+  #define Py_SIZE(ob)   (((PyVarObject*)(ob))->ob_size)
+  #define PyVarObject_HEAD_INIT(type, size) \
+          PyObject_HEAD_INIT(type) size,
+  #define PyType_Modified(t)
+  typedef struct {
+     void *buf;
+     PyObject *obj;
+     Py_ssize_t len;
+     Py_ssize_t itemsize;
+     int readonly;
+     int ndim;
+     char *format;
+     Py_ssize_t *shape;
+     Py_ssize_t *strides;
+     Py_ssize_t *suboffsets;
+     void *internal;
+  } Py_buffer;
+  #define PyBUF_SIMPLE 0
+  #define PyBUF_WRITABLE 0x0001
+  #define PyBUF_FORMAT 0x0004
+  #define PyBUF_ND 0x0008
+  #define PyBUF_STRIDES (0x0010 | PyBUF_ND)
+  #define PyBUF_C_CONTIGUOUS (0x0020 | PyBUF_STRIDES)
+  #define PyBUF_F_CONTIGUOUS (0x0040 | PyBUF_STRIDES)
+  #define PyBUF_ANY_CONTIGUOUS (0x0080 | PyBUF_STRIDES)
+  #define PyBUF_INDIRECT (0x0100 | PyBUF_STRIDES)
+  #define PyBUF_RECORDS (PyBUF_STRIDES | PyBUF_FORMAT | PyBUF_WRITABLE)
+  #define PyBUF_FULL (PyBUF_INDIRECT | PyBUF_FORMAT | PyBUF_WRITABLE)
+  typedef int (*getbufferproc)(PyObject *, Py_buffer *, int);
+  typedef void (*releasebufferproc)(PyObject *, Py_buffer *);
+#endif
+#if PY_MAJOR_VERSION < 3
+  #define __Pyx_BUILTIN_MODULE_NAME "__builtin__"
+  #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \
+          PyCode_New(a, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
+#else
+  #define __Pyx_BUILTIN_MODULE_NAME "builtins"
+  #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \
+          PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
+#endif
+#if PY_MAJOR_VERSION < 3 && PY_MINOR_VERSION < 6
+  #define PyUnicode_FromString(s) PyUnicode_Decode(s, strlen(s), "UTF-8", "strict")
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define Py_TPFLAGS_CHECKTYPES 0
+  #define Py_TPFLAGS_HAVE_INDEX 0
+#endif
+#if (PY_VERSION_HEX < 0x02060000) || (PY_MAJOR_VERSION >= 3)
+  #define Py_TPFLAGS_HAVE_NEWBUFFER 0
+#endif
+#if PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND)
+  #define CYTHON_PEP393_ENABLED 1
+  #define __Pyx_PyUnicode_READY(op)       (likely(PyUnicode_IS_READY(op)) ? \
+                                              0 : _PyUnicode_Ready((PyObject *)(op)))
+  #define __Pyx_PyUnicode_GET_LENGTH(u)   PyUnicode_GET_LENGTH(u)
+  #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_READ_CHAR(u, i)
+  #define __Pyx_PyUnicode_READ(k, d, i)   PyUnicode_READ(k, d, i)
+#else
+  #define CYTHON_PEP393_ENABLED 0
+  #define __Pyx_PyUnicode_READY(op)       (0)
+  #define __Pyx_PyUnicode_GET_LENGTH(u)   PyUnicode_GET_SIZE(u)
+  #define __Pyx_PyUnicode_READ_CHAR(u, i) ((Py_UCS4)(PyUnicode_AS_UNICODE(u)[i]))
+  #define __Pyx_PyUnicode_READ(k, d, i)   ((k=k), (Py_UCS4)(((Py_UNICODE*)d)[i]))
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define PyBaseString_Type            PyUnicode_Type
+  #define PyStringObject               PyUnicodeObject
+  #define PyString_Type                PyUnicode_Type
+  #define PyString_Check               PyUnicode_Check
+  #define PyString_CheckExact          PyUnicode_CheckExact
+#endif
+#if PY_VERSION_HEX < 0x02060000
+  #define PyBytesObject                PyStringObject
+  #define PyBytes_Type                 PyString_Type
+  #define PyBytes_Check                PyString_Check
+  #define PyBytes_CheckExact           PyString_CheckExact
+  #define PyBytes_FromString           PyString_FromString
+  #define PyBytes_FromStringAndSize    PyString_FromStringAndSize
+  #define PyBytes_FromFormat           PyString_FromFormat
+  #define PyBytes_DecodeEscape         PyString_DecodeEscape
+  #define PyBytes_AsString             PyString_AsString
+  #define PyBytes_AsStringAndSize      PyString_AsStringAndSize
+  #define PyBytes_Size                 PyString_Size
+  #define PyBytes_AS_STRING            PyString_AS_STRING
+  #define PyBytes_GET_SIZE             PyString_GET_SIZE
+  #define PyBytes_Repr                 PyString_Repr
+  #define PyBytes_Concat               PyString_Concat
+  #define PyBytes_ConcatAndDel         PyString_ConcatAndDel
+#endif
+#if PY_VERSION_HEX < 0x02060000
+  #define PySet_Check(obj)             PyObject_TypeCheck(obj, &PySet_Type)
+  #define PyFrozenSet_Check(obj)       PyObject_TypeCheck(obj, &PyFrozenSet_Type)
+#endif
+#ifndef PySet_CheckExact
+  #define PySet_CheckExact(obj)        (Py_TYPE(obj) == &PySet_Type)
+#endif
+#define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type)
+#if PY_MAJOR_VERSION >= 3
+  #define PyIntObject                  PyLongObject
+  #define PyInt_Type                   PyLong_Type
+  #define PyInt_Check(op)              PyLong_Check(op)
+  #define PyInt_CheckExact(op)         PyLong_CheckExact(op)
+  #define PyInt_FromString             PyLong_FromString
+  #define PyInt_FromUnicode            PyLong_FromUnicode
+  #define PyInt_FromLong               PyLong_FromLong
+  #define PyInt_FromSize_t             PyLong_FromSize_t
+  #define PyInt_FromSsize_t            PyLong_FromSsize_t
+  #define PyInt_AsLong                 PyLong_AsLong
+  #define PyInt_AS_LONG                PyLong_AS_LONG
+  #define PyInt_AsSsize_t              PyLong_AsSsize_t
+  #define PyInt_AsUnsignedLongMask     PyLong_AsUnsignedLongMask
+  #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define PyBoolObject                 PyLongObject
+#endif
+#if PY_VERSION_HEX < 0x03020000
+  typedef long Py_hash_t;
+  #define __Pyx_PyInt_FromHash_t PyInt_FromLong
+  #define __Pyx_PyInt_AsHash_t   PyInt_AsLong
+#else
+  #define __Pyx_PyInt_FromHash_t PyInt_FromSsize_t
+  #define __Pyx_PyInt_AsHash_t   PyInt_AsSsize_t
+#endif
+#if (PY_MAJOR_VERSION < 3) || (PY_VERSION_HEX >= 0x03010300)
+  #define __Pyx_PySequence_GetSlice(obj, a, b) PySequence_GetSlice(obj, a, b)
+  #define __Pyx_PySequence_SetSlice(obj, a, b, value) PySequence_SetSlice(obj, a, b, value)
+  #define __Pyx_PySequence_DelSlice(obj, a, b) PySequence_DelSlice(obj, a, b)
+#else
+  #define __Pyx_PySequence_GetSlice(obj, a, b) (unlikely(!(obj)) ? \
+        (PyErr_SetString(PyExc_SystemError, "null argument to internal routine"), (PyObject*)0) : \
+        (likely((obj)->ob_type->tp_as_mapping) ? (PySequence_GetSlice(obj, a, b)) : \
+            (PyErr_Format(PyExc_TypeError, "'%.200s' object is unsliceable", (obj)->ob_type->tp_name), (PyObject*)0)))
+  #define __Pyx_PySequence_SetSlice(obj, a, b, value) (unlikely(!(obj)) ? \
+        (PyErr_SetString(PyExc_SystemError, "null argument to internal routine"), -1) : \
+        (likely((obj)->ob_type->tp_as_mapping) ? (PySequence_SetSlice(obj, a, b, value)) : \
+            (PyErr_Format(PyExc_TypeError, "'%.200s' object doesn't support slice assignment", (obj)->ob_type->tp_name), -1)))
+  #define __Pyx_PySequence_DelSlice(obj, a, b) (unlikely(!(obj)) ? \
+        (PyErr_SetString(PyExc_SystemError, "null argument to internal routine"), -1) : \
+        (likely((obj)->ob_type->tp_as_mapping) ? (PySequence_DelSlice(obj, a, b)) : \
+            (PyErr_Format(PyExc_TypeError, "'%.200s' object doesn't support slice deletion", (obj)->ob_type->tp_name), -1)))
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define PyMethod_New(func, self, klass) ((self) ? PyMethod_New(func, self) : PyInstanceMethod_New(func))
+#endif
+#if PY_VERSION_HEX < 0x02050000
+  #define __Pyx_GetAttrString(o,n)   PyObject_GetAttrString((o),((char *)(n)))
+  #define __Pyx_SetAttrString(o,n,a) PyObject_SetAttrString((o),((char *)(n)),(a))
+  #define __Pyx_DelAttrString(o,n)   PyObject_DelAttrString((o),((char *)(n)))
+#else
+  #define __Pyx_GetAttrString(o,n)   PyObject_GetAttrString((o),(n))
+  #define __Pyx_SetAttrString(o,n,a) PyObject_SetAttrString((o),(n),(a))
+  #define __Pyx_DelAttrString(o,n)   PyObject_DelAttrString((o),(n))
+#endif
+#if PY_VERSION_HEX < 0x02050000
+  #define __Pyx_NAMESTR(n) ((char *)(n))
+  #define __Pyx_DOCSTR(n)  ((char *)(n))
+#else
+  #define __Pyx_NAMESTR(n) (n)
+  #define __Pyx_DOCSTR(n)  (n)
+#endif
+
+
+#if PY_MAJOR_VERSION >= 3
+  #define __Pyx_PyNumber_Divide(x,y)         PyNumber_TrueDivide(x,y)
+  #define __Pyx_PyNumber_InPlaceDivide(x,y)  PyNumber_InPlaceTrueDivide(x,y)
+#else
+  #define __Pyx_PyNumber_Divide(x,y)         PyNumber_TrueDivide(x,y)
+  #define __Pyx_PyNumber_InPlaceDivide(x,y)  PyNumber_InPlaceTrueDivide(x,y)
+#endif
+
+#ifndef __PYX_EXTERN_C
+  #ifdef __cplusplus
+    #define __PYX_EXTERN_C extern "C"
+  #else
+    #define __PYX_EXTERN_C extern
+  #endif
+#endif
+
+#if defined(WIN32) || defined(MS_WINDOWS)
+#define _USE_MATH_DEFINES
+#endif
+#include <math.h>
+#define __PYX_HAVE__bx__arrays__array_tree
+#define __PYX_HAVE_API__bx__arrays__array_tree
+#include "string.h"
+#include "stdio.h"
+#include "stdlib.h"
+#include "numpy/arrayobject.h"
+#include "numpy/ufuncobject.h"
+#ifdef _OPENMP
+#include <omp.h>
+#endif /* _OPENMP */
+
+#ifdef PYREX_WITHOUT_ASSERTIONS
+#define CYTHON_WITHOUT_ASSERTIONS
+#endif
+
+#ifndef CYTHON_INLINE
+  #if defined(__GNUC__)
+    #define CYTHON_INLINE __inline__
+  #elif defined(_MSC_VER)
+    #define CYTHON_INLINE __inline
+  #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+    #define CYTHON_INLINE inline
+  #else
+    #define CYTHON_INLINE
+  #endif
+#endif
+#ifndef CYTHON_UNUSED
+# if defined(__GNUC__)
+#   if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
+#     define CYTHON_UNUSED __attribute__ ((__unused__))
+#   else
+#     define CYTHON_UNUSED
+#   endif
+# elif defined(__ICC) || (defined(__INTEL_COMPILER) && !defined(_MSC_VER))
+#   define CYTHON_UNUSED __attribute__ ((__unused__))
+# else
+#   define CYTHON_UNUSED
+# endif
+#endif
+typedef struct {PyObject **p; char *s; const long n; const char* encoding; const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry; /*proto*/
+
+#define __Pyx_PyBytes_FromUString(s) PyBytes_FromString((char*)s)
+#define __Pyx_PyBytes_AsUString(s)   ((unsigned char*) PyBytes_AsString(s))
+#define __Pyx_Owned_Py_None(b) (Py_INCREF(Py_None), Py_None)
+#define __Pyx_PyBool_FromLong(b) ((b) ? (Py_INCREF(Py_True), Py_True) : (Py_INCREF(Py_False), Py_False))
+static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*);
+static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x);
+static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*);
+static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t);
+static CYTHON_INLINE size_t __Pyx_PyInt_AsSize_t(PyObject*);
+#if CYTHON_COMPILING_IN_CPYTHON
+#define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x))
+#else
+#define __pyx_PyFloat_AsDouble(x) PyFloat_AsDouble(x)
+#endif
+#define __pyx_PyFloat_AsFloat(x) ((float) __pyx_PyFloat_AsDouble(x))
+
+
+#ifdef __GNUC__
+  /* Test for GCC > 2.95 */
+  #if __GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))
+    #define likely(x)   __builtin_expect(!!(x), 1)
+    #define unlikely(x) __builtin_expect(!!(x), 0)
+  #else /* __GNUC__ > 2 ... */
+    #define likely(x)   (x)
+    #define unlikely(x) (x)
+  #endif /* __GNUC__ > 2 ... */
+#else /* __GNUC__ */
+  #define likely(x)   (x)
+  #define unlikely(x) (x)
+#endif /* __GNUC__ */
+    
+static PyObject *__pyx_m;
+static PyObject *__pyx_b;
+static PyObject *__pyx_empty_tuple;
+static PyObject *__pyx_empty_bytes;
+static int __pyx_lineno;
+static int __pyx_clineno = 0;
+static const char * __pyx_cfilenm= __FILE__;
+static const char *__pyx_filename;
+
+#if !defined(CYTHON_CCOMPLEX)
+  #if defined(__cplusplus)
+    #define CYTHON_CCOMPLEX 1
+  #elif defined(_Complex_I)
+    #define CYTHON_CCOMPLEX 1
+  #else
+    #define CYTHON_CCOMPLEX 0
+  #endif
+#endif
+#if CYTHON_CCOMPLEX
+  #ifdef __cplusplus
+    #include <complex>
+  #else
+    #include <complex.h>
+  #endif
+#endif
+#if CYTHON_CCOMPLEX && !defined(__cplusplus) && defined(__sun__) && defined(__GNUC__)
+  #undef _Complex_I
+  #define _Complex_I 1.0fj
+#endif
+
+
+static const char *__pyx_f[] = {
+  "array_tree.pyx",
+  "numpy.pxd",
+  "type.pxd",
+  "wiggle.pxd",
+};
+
+/* "numpy.pxd":723
+ * # in Cython to enable them only on the right systems.
+ * 
+ * ctypedef npy_int8       int8_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_int16      int16_t
+ * ctypedef npy_int32      int32_t
+ */
+typedef npy_int8 __pyx_t_5numpy_int8_t;
+
+/* "numpy.pxd":724
+ * 
+ * ctypedef npy_int8       int8_t
+ * ctypedef npy_int16      int16_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_int32      int32_t
+ * ctypedef npy_int64      int64_t
+ */
+typedef npy_int16 __pyx_t_5numpy_int16_t;
+
+/* "numpy.pxd":725
+ * ctypedef npy_int8       int8_t
+ * ctypedef npy_int16      int16_t
+ * ctypedef npy_int32      int32_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_int64      int64_t
+ * #ctypedef npy_int96      int96_t
+ */
+typedef npy_int32 __pyx_t_5numpy_int32_t;
+
+/* "numpy.pxd":726
+ * ctypedef npy_int16      int16_t
+ * ctypedef npy_int32      int32_t
+ * ctypedef npy_int64      int64_t             # <<<<<<<<<<<<<<
+ * #ctypedef npy_int96      int96_t
+ * #ctypedef npy_int128     int128_t
+ */
+typedef npy_int64 __pyx_t_5numpy_int64_t;
+
+/* "numpy.pxd":730
+ * #ctypedef npy_int128     int128_t
+ * 
+ * ctypedef npy_uint8      uint8_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_uint16     uint16_t
+ * ctypedef npy_uint32     uint32_t
+ */
+typedef npy_uint8 __pyx_t_5numpy_uint8_t;
+
+/* "numpy.pxd":731
+ * 
+ * ctypedef npy_uint8      uint8_t
+ * ctypedef npy_uint16     uint16_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_uint32     uint32_t
+ * ctypedef npy_uint64     uint64_t
+ */
+typedef npy_uint16 __pyx_t_5numpy_uint16_t;
+
+/* "numpy.pxd":732
+ * ctypedef npy_uint8      uint8_t
+ * ctypedef npy_uint16     uint16_t
+ * ctypedef npy_uint32     uint32_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_uint64     uint64_t
+ * #ctypedef npy_uint96     uint96_t
+ */
+typedef npy_uint32 __pyx_t_5numpy_uint32_t;
+
+/* "numpy.pxd":733
+ * ctypedef npy_uint16     uint16_t
+ * ctypedef npy_uint32     uint32_t
+ * ctypedef npy_uint64     uint64_t             # <<<<<<<<<<<<<<
+ * #ctypedef npy_uint96     uint96_t
+ * #ctypedef npy_uint128    uint128_t
+ */
+typedef npy_uint64 __pyx_t_5numpy_uint64_t;
+
+/* "numpy.pxd":737
+ * #ctypedef npy_uint128    uint128_t
+ * 
+ * ctypedef npy_float32    float32_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_float64    float64_t
+ * #ctypedef npy_float80    float80_t
+ */
+typedef npy_float32 __pyx_t_5numpy_float32_t;
+
+/* "numpy.pxd":738
+ * 
+ * ctypedef npy_float32    float32_t
+ * ctypedef npy_float64    float64_t             # <<<<<<<<<<<<<<
+ * #ctypedef npy_float80    float80_t
+ * #ctypedef npy_float128   float128_t
+ */
+typedef npy_float64 __pyx_t_5numpy_float64_t;
+
+/* "numpy.pxd":747
+ * # The int types are mapped a bit surprising --
+ * # numpy.int corresponds to 'l' and numpy.long to 'q'
+ * ctypedef npy_long       int_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_longlong   long_t
+ * ctypedef npy_longlong   longlong_t
+ */
+typedef npy_long __pyx_t_5numpy_int_t;
+
+/* "numpy.pxd":748
+ * # numpy.int corresponds to 'l' and numpy.long to 'q'
+ * ctypedef npy_long       int_t
+ * ctypedef npy_longlong   long_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_longlong   longlong_t
+ * 
+ */
+typedef npy_longlong __pyx_t_5numpy_long_t;
+
+/* "numpy.pxd":749
+ * ctypedef npy_long       int_t
+ * ctypedef npy_longlong   long_t
+ * ctypedef npy_longlong   longlong_t             # <<<<<<<<<<<<<<
+ * 
+ * ctypedef npy_ulong      uint_t
+ */
+typedef npy_longlong __pyx_t_5numpy_longlong_t;
+
+/* "numpy.pxd":751
+ * ctypedef npy_longlong   longlong_t
+ * 
+ * ctypedef npy_ulong      uint_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_ulonglong  ulong_t
+ * ctypedef npy_ulonglong  ulonglong_t
+ */
+typedef npy_ulong __pyx_t_5numpy_uint_t;
+
+/* "numpy.pxd":752
+ * 
+ * ctypedef npy_ulong      uint_t
+ * ctypedef npy_ulonglong  ulong_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_ulonglong  ulonglong_t
+ * 
+ */
+typedef npy_ulonglong __pyx_t_5numpy_ulong_t;
+
+/* "numpy.pxd":753
+ * ctypedef npy_ulong      uint_t
+ * ctypedef npy_ulonglong  ulong_t
+ * ctypedef npy_ulonglong  ulonglong_t             # <<<<<<<<<<<<<<
+ * 
+ * ctypedef npy_intp       intp_t
+ */
+typedef npy_ulonglong __pyx_t_5numpy_ulonglong_t;
+
+/* "numpy.pxd":755
+ * ctypedef npy_ulonglong  ulonglong_t
+ * 
+ * ctypedef npy_intp       intp_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_uintp      uintp_t
+ * 
+ */
+typedef npy_intp __pyx_t_5numpy_intp_t;
+
+/* "numpy.pxd":756
+ * 
+ * ctypedef npy_intp       intp_t
+ * ctypedef npy_uintp      uintp_t             # <<<<<<<<<<<<<<
+ * 
+ * ctypedef npy_double     float_t
+ */
+typedef npy_uintp __pyx_t_5numpy_uintp_t;
+
+/* "numpy.pxd":758
+ * ctypedef npy_uintp      uintp_t
+ * 
+ * ctypedef npy_double     float_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_double     double_t
+ * ctypedef npy_longdouble longdouble_t
+ */
+typedef npy_double __pyx_t_5numpy_float_t;
+
+/* "numpy.pxd":759
+ * 
+ * ctypedef npy_double     float_t
+ * ctypedef npy_double     double_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_longdouble longdouble_t
+ * 
+ */
+typedef npy_double __pyx_t_5numpy_double_t;
+
+/* "numpy.pxd":760
+ * ctypedef npy_double     float_t
+ * ctypedef npy_double     double_t
+ * ctypedef npy_longdouble longdouble_t             # <<<<<<<<<<<<<<
+ * 
+ * ctypedef npy_cfloat      cfloat_t
+ */
+typedef npy_longdouble __pyx_t_5numpy_longdouble_t;
+#if CYTHON_CCOMPLEX
+  #ifdef __cplusplus
+    typedef ::std::complex< float > __pyx_t_float_complex;
+  #else
+    typedef float _Complex __pyx_t_float_complex;
+  #endif
+#else
+    typedef struct { float real, imag; } __pyx_t_float_complex;
+#endif
+
+#if CYTHON_CCOMPLEX
+  #ifdef __cplusplus
+    typedef ::std::complex< double > __pyx_t_double_complex;
+  #else
+    typedef double _Complex __pyx_t_double_complex;
+  #endif
+#else
+    typedef struct { double real, imag; } __pyx_t_double_complex;
+#endif
+
+
+/*--- Type declarations ---*/
+struct __pyx_obj_2bx_6arrays_10array_tree_Summary;
+struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeLeaf;
+struct __pyx_obj_2bx_6arrays_10array_tree_FileArrayTree;
+struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTree;
+struct __pyx_obj_2bx_6arrays_10array_tree_FileArrayTreeDict;
+struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeNode;
+struct __pyx_obj_2bx_6arrays_6wiggle_WiggleReader;
+
+/* "numpy.pxd":762
+ * ctypedef npy_longdouble longdouble_t
+ * 
+ * ctypedef npy_cfloat      cfloat_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_cdouble     cdouble_t
+ * ctypedef npy_clongdouble clongdouble_t
+ */
+typedef npy_cfloat __pyx_t_5numpy_cfloat_t;
+
+/* "numpy.pxd":763
+ * 
+ * ctypedef npy_cfloat      cfloat_t
+ * ctypedef npy_cdouble     cdouble_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_clongdouble clongdouble_t
+ * 
+ */
+typedef npy_cdouble __pyx_t_5numpy_cdouble_t;
+
+/* "numpy.pxd":764
+ * ctypedef npy_cfloat      cfloat_t
+ * ctypedef npy_cdouble     cdouble_t
+ * ctypedef npy_clongdouble clongdouble_t             # <<<<<<<<<<<<<<
+ * 
+ * ctypedef npy_cdouble     complex_t
+ */
+typedef npy_clongdouble __pyx_t_5numpy_clongdouble_t;
+
+/* "numpy.pxd":766
+ * ctypedef npy_clongdouble clongdouble_t
+ * 
+ * ctypedef npy_cdouble     complex_t             # <<<<<<<<<<<<<<
+ * 
+ * cdef inline object PyArray_MultiIterNew1(a):
+ */
+typedef npy_cdouble __pyx_t_5numpy_complex_t;
+
+/* "bx/arrays/wiggle.pxd":1
+ * cdef enum linemode:             # <<<<<<<<<<<<<<
+ *     MODE_BED
+ *     MODE_FIXED
+ */
+enum __pyx_t_2bx_6arrays_6wiggle_linemode {
+  __pyx_e_2bx_6arrays_6wiggle_MODE_BED,
+  __pyx_e_2bx_6arrays_6wiggle_MODE_FIXED,
+  __pyx_e_2bx_6arrays_6wiggle_MODE_VARIABLE
+};
+
+/* "bx/arrays/array_tree.pyx":203
+ *             return min
+ * 
+ * cdef class Summary:             # <<<<<<<<<<<<<<
+ *     """
+ *     Summary for a non-leaf level of the tree, contains arrays of the min, max,
+ */
+struct __pyx_obj_2bx_6arrays_10array_tree_Summary {
+  PyObject_HEAD
+  PyObject *counts;
+  PyObject *frequencies;
+  PyObject *mins;
+  PyObject *maxs;
+  PyObject *sums;
+  PyObject *sumsquares;
+};
+
+
+/* "bx/arrays/array_tree.pyx":216
+ * 
+ * cdef class ArrayTreeNode
+ * cdef class ArrayTreeLeaf             # <<<<<<<<<<<<<<
+ * 
+ * cdef class ArrayTree:
+ */
+struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeLeaf {
+  PyObject_HEAD
+  struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTree *tree;
+  int min;
+  int max;
+  int frequency;
+  PyArrayObject *values;
+  long start_offset;
+};
+
+
+/* "bx/arrays/array_tree.pyx":120
+ *         FileCDBDict.to_file( cdb_dict, file, is_little_endian=is_little_endian )
+ * 
+ * cdef class FileArrayTree:             # <<<<<<<<<<<<<<
+ *     """
+ *     Wrapper for ArrayTree stored in file that reads as little as possible
+ */
+struct __pyx_obj_2bx_6arrays_10array_tree_FileArrayTree {
+  PyObject_HEAD
+  struct __pyx_vtabstruct_2bx_6arrays_10array_tree_FileArrayTree *__pyx_vtab;
+  int max;
+  int block_size;
+  PyObject *dtype;
+  int levels;
+  int offset;
+  int root_offset;
+  PyObject *io;
+};
+
+
+/* "bx/arrays/array_tree.pyx":218
+ * cdef class ArrayTreeLeaf
+ * 
+ * cdef class ArrayTree:             # <<<<<<<<<<<<<<
+ *     """
+ *     Stores a sparse array of data as a tree.
+ */
+struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTree {
+  PyObject_HEAD
+  int max;
+  int block_size;
+  PyObject *dtype;
+  int levels;
+  int no_leaves;
+  struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeNode *root;
+};
+
+
+/* "bx/arrays/array_tree.pyx":79
+ * 
+ * 
+ * cdef class FileArrayTreeDict:             # <<<<<<<<<<<<<<
+ *     """
+ *     Access to a file containing multiple array trees indexed by a string key.
+ */
+struct __pyx_obj_2bx_6arrays_10array_tree_FileArrayTreeDict {
+  PyObject_HEAD
+  PyObject *io;
+  PyObject *cdb_dict;
+};
+
+
+/* "bx/arrays/array_tree.pyx":215
+ *     cdef public object sumsquares
+ * 
+ * cdef class ArrayTreeNode             # <<<<<<<<<<<<<<
+ * cdef class ArrayTreeLeaf
+ * 
+ */
+struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeNode {
+  PyObject_HEAD
+  struct __pyx_vtabstruct_2bx_6arrays_10array_tree_ArrayTreeNode *__pyx_vtab;
+  struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTree *tree;
+  int min;
+  int max;
+  int block_size;
+  int level;
+  int child_size;
+  PyObject *children;
+  struct __pyx_obj_2bx_6arrays_10array_tree_Summary *summary;
+  long start_offset;
+};
+
+
+/* "bx/arrays/wiggle.pxd":6
+ *     MODE_VARIABLE
+ * 
+ * cdef class WiggleReader:             # <<<<<<<<<<<<<<
+ *     cdef object file
+ *     cdef object current_chrom
+ */
+struct __pyx_obj_2bx_6arrays_6wiggle_WiggleReader {
+  PyObject_HEAD
+  PyObject *file;
+  PyObject *current_chrom;
+  long current_pos;
+  long current_step;
+  long current_span;
+  enum __pyx_t_2bx_6arrays_6wiggle_linemode mode;
+};
+
+
+
+/* "bx/arrays/array_tree.pyx":120
+ *         FileCDBDict.to_file( cdb_dict, file, is_little_endian=is_little_endian )
+ * 
+ * cdef class FileArrayTree:             # <<<<<<<<<<<<<<
+ *     """
+ *     Wrapper for ArrayTree stored in file that reads as little as possible
+ */
+
+struct __pyx_vtabstruct_2bx_6arrays_10array_tree_FileArrayTree {
+  int (*r_seek_to_node)(struct __pyx_obj_2bx_6arrays_10array_tree_FileArrayTree *, int, int, PY_LONG_LONG, int, int);
+};
+static struct __pyx_vtabstruct_2bx_6arrays_10array_tree_FileArrayTree *__pyx_vtabptr_2bx_6arrays_10array_tree_FileArrayTree;
+
+
+/* "bx/arrays/array_tree.pyx":309
+ *         return tree
+ * 
+ * cdef class ArrayTreeNode:             # <<<<<<<<<<<<<<
+ *     """
+ *     Internal node of an ArrayTree. Contains summary data and pointers to
+ */
+
+struct __pyx_vtabstruct_2bx_6arrays_10array_tree_ArrayTreeNode {
+  PyObject *(*init_bin)(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeNode *, int);
+  PyObject *(*build_summary)(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeNode *, int __pyx_skip_dispatch);
+};
+static struct __pyx_vtabstruct_2bx_6arrays_10array_tree_ArrayTreeNode *__pyx_vtabptr_2bx_6arrays_10array_tree_ArrayTreeNode;
+static CYTHON_INLINE PyObject *__pyx_f_2bx_6arrays_10array_tree_13ArrayTreeNode_init_bin(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeNode *, int);
+#ifndef CYTHON_REFNANNY
+  #define CYTHON_REFNANNY 0
+#endif
+#if CYTHON_REFNANNY
+  typedef struct {
+    void (*INCREF)(void*, PyObject*, int);
+    void (*DECREF)(void*, PyObject*, int);
+    void (*GOTREF)(void*, PyObject*, int);
+    void (*GIVEREF)(void*, PyObject*, int);
+    void* (*SetupContext)(const char*, int, const char*);
+    void (*FinishContext)(void**);
+  } __Pyx_RefNannyAPIStruct;
+  static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL;
+  static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname); /*proto*/
+  #define __Pyx_RefNannyDeclarations void *__pyx_refnanny = NULL;
+#ifdef WITH_THREAD
+  #define __Pyx_RefNannySetupContext(name, acquire_gil) \
+          if (acquire_gil) { \
+              PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure(); \
+              __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__); \
+              PyGILState_Release(__pyx_gilstate_save); \
+          } else { \
+              __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__); \
+          }
+#else
+  #define __Pyx_RefNannySetupContext(name, acquire_gil) \
+          __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__)
+#endif
+  #define __Pyx_RefNannyFinishContext() \
+          __Pyx_RefNanny->FinishContext(&__pyx_refnanny)
+  #define __Pyx_INCREF(r)  __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_DECREF(r)  __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_GOTREF(r)  __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_XINCREF(r)  do { if((r) != NULL) {__Pyx_INCREF(r); }} while(0)
+  #define __Pyx_XDECREF(r)  do { if((r) != NULL) {__Pyx_DECREF(r); }} while(0)
+  #define __Pyx_XGOTREF(r)  do { if((r) != NULL) {__Pyx_GOTREF(r); }} while(0)
+  #define __Pyx_XGIVEREF(r) do { if((r) != NULL) {__Pyx_GIVEREF(r);}} while(0)
+#else
+  #define __Pyx_RefNannyDeclarations
+  #define __Pyx_RefNannySetupContext(name, acquire_gil)
+  #define __Pyx_RefNannyFinishContext()
+  #define __Pyx_INCREF(r) Py_INCREF(r)
+  #define __Pyx_DECREF(r) Py_DECREF(r)
+  #define __Pyx_GOTREF(r)
+  #define __Pyx_GIVEREF(r)
+  #define __Pyx_XINCREF(r) Py_XINCREF(r)
+  #define __Pyx_XDECREF(r) Py_XDECREF(r)
+  #define __Pyx_XGOTREF(r)
+  #define __Pyx_XGIVEREF(r)
+#endif /* CYTHON_REFNANNY */
+#define __Pyx_CLEAR(r)    do { PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);} while(0)
+#define __Pyx_XCLEAR(r)   do { if((r) != NULL) {PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);}} while(0)
+
+static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/
+
+static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
+    Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/
+
+static void __Pyx_RaiseDoubleKeywordsError(const char* func_name, PyObject* kw_name); /*proto*/
+
+static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
+    PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
+    const char* function_name); /*proto*/
+
+static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected);
+
+static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index);
+
+static CYTHON_INLINE int __Pyx_IterFinish(void); /*proto*/
+
+static int __Pyx_IternextUnpackEndCheck(PyObject *retval, Py_ssize_t expected); /*proto*/
+
+static CYTHON_INLINE int __Pyx_PyDict_Contains(PyObject* item, PyObject* dict, int eq) {
+    int result = PyDict_Contains(dict, item);
+    return unlikely(result < 0) ? result : (result == (eq == Py_EQ));
+}
+
+#if PY_MAJOR_VERSION >= 3
+static PyObject *__Pyx_PyDict_GetItem(PyObject *d, PyObject* key) {
+    PyObject *value;
+    value = PyDict_GetItemWithError(d, key);
+    if (unlikely(!value)) {
+        if (!PyErr_Occurred())
+            PyErr_SetObject(PyExc_KeyError, key);
+        return NULL;
+    }
+    Py_INCREF(value);
+    return value;
+}
+#else
+    #define __Pyx_PyDict_GetItem(d, key) PyObject_GetItem(d, key)
+#endif
+
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j) {
+    PyObject *r;
+    if (!j) return NULL;
+    r = PyObject_GetItem(o, j);
+    Py_DECREF(j);
+    return r;
+}
+#define __Pyx_GetItemInt_List(o, i, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \
+                                                    __Pyx_GetItemInt_List_Fast(o, i) : \
+                                                    __Pyx_GetItemInt_Generic(o, to_py_func(i)))
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    if (likely((0 <= i) & (i < PyList_GET_SIZE(o)))) {
+        PyObject *r = PyList_GET_ITEM(o, i);
+        Py_INCREF(r);
+        return r;
+    }
+    else if ((-PyList_GET_SIZE(o) <= i) & (i < 0)) {
+        PyObject *r = PyList_GET_ITEM(o, PyList_GET_SIZE(o) + i);
+        Py_INCREF(r);
+        return r;
+    }
+    return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
+#else
+    return PySequence_GetItem(o, i);
+#endif
+}
+#define __Pyx_GetItemInt_Tuple(o, i, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \
+                                                    __Pyx_GetItemInt_Tuple_Fast(o, i) : \
+                                                    __Pyx_GetItemInt_Generic(o, to_py_func(i)))
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    if (likely((0 <= i) & (i < PyTuple_GET_SIZE(o)))) {
+        PyObject *r = PyTuple_GET_ITEM(o, i);
+        Py_INCREF(r);
+        return r;
+    }
+    else if ((-PyTuple_GET_SIZE(o) <= i) & (i < 0)) {
+        PyObject *r = PyTuple_GET_ITEM(o, PyTuple_GET_SIZE(o) + i);
+        Py_INCREF(r);
+        return r;
+    }
+    return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
+#else
+    return PySequence_GetItem(o, i);
+#endif
+}
+#define __Pyx_GetItemInt(o, i, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \
+                                                    __Pyx_GetItemInt_Fast(o, i) : \
+                                                    __Pyx_GetItemInt_Generic(o, to_py_func(i)))
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    if (PyList_CheckExact(o)) {
+        Py_ssize_t n = (likely(i >= 0)) ? i : i + PyList_GET_SIZE(o);
+        if (likely((n >= 0) & (n < PyList_GET_SIZE(o)))) {
+            PyObject *r = PyList_GET_ITEM(o, n);
+            Py_INCREF(r);
+            return r;
+        }
+    }
+    else if (PyTuple_CheckExact(o)) {
+        Py_ssize_t n = (likely(i >= 0)) ? i : i + PyTuple_GET_SIZE(o);
+        if (likely((n >= 0) & (n < PyTuple_GET_SIZE(o)))) {
+            PyObject *r = PyTuple_GET_ITEM(o, n);
+            Py_INCREF(r);
+            return r;
+        }
+    } else {  /* inlined PySequence_GetItem() */
+        PySequenceMethods *m = Py_TYPE(o)->tp_as_sequence;
+        if (likely(m && m->sq_item)) {
+            if (unlikely(i < 0) && likely(m->sq_length)) {
+                Py_ssize_t l = m->sq_length(o);
+                if (unlikely(l < 0)) return NULL;
+                i += l;
+            }
+            return m->sq_item(o, i);
+        }
+    }
+#else
+    if (PySequence_Check(o)) {
+        return PySequence_GetItem(o, i);
+    }
+#endif
+    return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
+}
+
+static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void);
+
+static void __Pyx_UnpackTupleError(PyObject *, Py_ssize_t index); /*proto*/
+
+static CYTHON_INLINE int __Pyx_unpack_tuple2(PyObject* tuple, PyObject** value1, PyObject** value2,
+                                             int is_tuple, int has_known_size, int decref_tuple);
+
+static CYTHON_INLINE PyObject* __Pyx_dict_iterator(PyObject* dict, int is_dict, PyObject* method_name,
+                                                   Py_ssize_t* p_orig_length, int* p_is_dict);
+static CYTHON_INLINE int __Pyx_dict_iter_next(PyObject* dict_or_iter, Py_ssize_t orig_length, Py_ssize_t* ppos,
+                                              PyObject** pkey, PyObject** pvalue, PyObject** pitem, int is_dict);
+
+static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
+static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
+
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause); /*proto*/
+
+static CYTHON_INLINE int __Pyx_div_int(int, int); /* proto */
+
+#define UNARY_NEG_WOULD_OVERFLOW(x)            (((x) < 0) & ((unsigned long)(x) == 0-(unsigned long)(x)))
+
+static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type); /*proto*/
+
+static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
+    const char *name, int exact); /*proto*/
+
+#define __Pyx_SetItemInt(o, i, v, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \
+                                                    __Pyx_SetItemInt_Fast(o, i, v) : \
+                                                    __Pyx_SetItemInt_Generic(o, to_py_func(i), v))
+static CYTHON_INLINE int __Pyx_SetItemInt_Generic(PyObject *o, PyObject *j, PyObject *v) {
+    int r;
+    if (!j) return -1;
+    r = PyObject_SetItem(o, j, v);
+    Py_DECREF(j);
+    return r;
+}
+static CYTHON_INLINE int __Pyx_SetItemInt_Fast(PyObject *o, Py_ssize_t i, PyObject *v) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    if (PyList_CheckExact(o)) {
+        Py_ssize_t n = (likely(i >= 0)) ? i : i + PyList_GET_SIZE(o);
+        if (likely((n >= 0) & (n < PyList_GET_SIZE(o)))) {
+            PyObject* old = PyList_GET_ITEM(o, n);
+            Py_INCREF(v);
+            PyList_SET_ITEM(o, n, v);
+            Py_DECREF(old);
+            return 1;
+        }
+    } else {  /* inlined PySequence_SetItem() */
+        PySequenceMethods *m = Py_TYPE(o)->tp_as_sequence;
+        if (likely(m && m->sq_ass_item)) {
+            if (unlikely(i < 0) && likely(m->sq_length)) {
+                Py_ssize_t l = m->sq_length(o);
+                if (unlikely(l < 0)) return -1;
+                i += l;
+            }
+            return m->sq_ass_item(o, i, v);
+        }
+    }
+#else
+#if CYTHON_COMPILING_IN_PYPY
+    if (PySequence_Check(o) && !PyDict_Check(o)) {
+#else
+    if (PySequence_Check(o)) {
+#endif
+        return PySequence_SetItem(o, i, v);
+    }
+#endif
+    return __Pyx_SetItemInt_Generic(o, PyInt_FromSsize_t(i), v);
+}
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE int __Pyx_PyList_Append(PyObject* list, PyObject* x) {
+    PyListObject* L = (PyListObject*) list;
+    Py_ssize_t len = Py_SIZE(list);
+    if (likely(L->allocated > len)) {
+        Py_INCREF(x);
+        PyList_SET_ITEM(list, len, x);
+        Py_SIZE(list) = len+1;
+        return 0;
+    }
+    return PyList_Append(list, x);
+}
+#else
+#define __Pyx_PyList_Append(L,x) PyList_Append(L,x)
+#endif
+
+static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level); /*proto*/
+
+static CYTHON_INLINE void __Pyx_RaiseImportError(PyObject *name);
+
+static CYTHON_INLINE PY_LONG_LONG __Pyx_pow_PY_LONG_LONG(PY_LONG_LONG, PY_LONG_LONG); /* proto */
+
+static CYTHON_INLINE int __Pyx_pow_int(int, int); /* proto */
+
+#include "descrobject.h"
+static PyObject* __Pyx_Method_ClassMethod(PyObject *method); /*proto*/
+
+#if CYTHON_CCOMPLEX
+  #ifdef __cplusplus
+    #define __Pyx_CREAL(z) ((z).real())
+    #define __Pyx_CIMAG(z) ((z).imag())
+  #else
+    #define __Pyx_CREAL(z) (__real__(z))
+    #define __Pyx_CIMAG(z) (__imag__(z))
+  #endif
+#else
+    #define __Pyx_CREAL(z) ((z).real)
+    #define __Pyx_CIMAG(z) ((z).imag)
+#endif
+#if defined(_WIN32) && defined(__cplusplus) && CYTHON_CCOMPLEX
+    #define __Pyx_SET_CREAL(z,x) ((z).real(x))
+    #define __Pyx_SET_CIMAG(z,y) ((z).imag(y))
+#else
+    #define __Pyx_SET_CREAL(z,x) __Pyx_CREAL(z) = (x)
+    #define __Pyx_SET_CIMAG(z,y) __Pyx_CIMAG(z) = (y)
+#endif
+
+static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float, float);
+
+#if CYTHON_CCOMPLEX
+    #define __Pyx_c_eqf(a, b)   ((a)==(b))
+    #define __Pyx_c_sumf(a, b)  ((a)+(b))
+    #define __Pyx_c_difff(a, b) ((a)-(b))
+    #define __Pyx_c_prodf(a, b) ((a)*(b))
+    #define __Pyx_c_quotf(a, b) ((a)/(b))
+    #define __Pyx_c_negf(a)     (-(a))
+  #ifdef __cplusplus
+    #define __Pyx_c_is_zerof(z) ((z)==(float)0)
+    #define __Pyx_c_conjf(z)    (::std::conj(z))
+    #if 1
+        #define __Pyx_c_absf(z)     (::std::abs(z))
+        #define __Pyx_c_powf(a, b)  (::std::pow(a, b))
+    #endif
+  #else
+    #define __Pyx_c_is_zerof(z) ((z)==0)
+    #define __Pyx_c_conjf(z)    (conjf(z))
+    #if 1
+        #define __Pyx_c_absf(z)     (cabsf(z))
+        #define __Pyx_c_powf(a, b)  (cpowf(a, b))
+    #endif
+ #endif
+#else
+    static CYTHON_INLINE int __Pyx_c_eqf(__pyx_t_float_complex, __pyx_t_float_complex);
+    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_sumf(__pyx_t_float_complex, __pyx_t_float_complex);
+    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_difff(__pyx_t_float_complex, __pyx_t_float_complex);
+    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_prodf(__pyx_t_float_complex, __pyx_t_float_complex);
+    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_quotf(__pyx_t_float_complex, __pyx_t_float_complex);
+    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_negf(__pyx_t_float_complex);
+    static CYTHON_INLINE int __Pyx_c_is_zerof(__pyx_t_float_complex);
+    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_conjf(__pyx_t_float_complex);
+    #if 1
+        static CYTHON_INLINE float __Pyx_c_absf(__pyx_t_float_complex);
+        static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_powf(__pyx_t_float_complex, __pyx_t_float_complex);
+    #endif
+#endif
+
+static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double, double);
+
+#if CYTHON_CCOMPLEX
+    #define __Pyx_c_eq(a, b)   ((a)==(b))
+    #define __Pyx_c_sum(a, b)  ((a)+(b))
+    #define __Pyx_c_diff(a, b) ((a)-(b))
+    #define __Pyx_c_prod(a, b) ((a)*(b))
+    #define __Pyx_c_quot(a, b) ((a)/(b))
+    #define __Pyx_c_neg(a)     (-(a))
+  #ifdef __cplusplus
+    #define __Pyx_c_is_zero(z) ((z)==(double)0)
+    #define __Pyx_c_conj(z)    (::std::conj(z))
+    #if 1
+        #define __Pyx_c_abs(z)     (::std::abs(z))
+        #define __Pyx_c_pow(a, b)  (::std::pow(a, b))
+    #endif
+  #else
+    #define __Pyx_c_is_zero(z) ((z)==0)
+    #define __Pyx_c_conj(z)    (conj(z))
+    #if 1
+        #define __Pyx_c_abs(z)     (cabs(z))
+        #define __Pyx_c_pow(a, b)  (cpow(a, b))
+    #endif
+ #endif
+#else
+    static CYTHON_INLINE int __Pyx_c_eq(__pyx_t_double_complex, __pyx_t_double_complex);
+    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_sum(__pyx_t_double_complex, __pyx_t_double_complex);
+    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_diff(__pyx_t_double_complex, __pyx_t_double_complex);
+    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_prod(__pyx_t_double_complex, __pyx_t_double_complex);
+    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_quot(__pyx_t_double_complex, __pyx_t_double_complex);
+    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_neg(__pyx_t_double_complex);
+    static CYTHON_INLINE int __Pyx_c_is_zero(__pyx_t_double_complex);
+    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_conj(__pyx_t_double_complex);
+    #if 1
+        static CYTHON_INLINE double __Pyx_c_abs(__pyx_t_double_complex);
+        static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_pow(__pyx_t_double_complex, __pyx_t_double_complex);
+    #endif
+#endif
+
+static CYTHON_INLINE unsigned char __Pyx_PyInt_AsUnsignedChar(PyObject *);
+
+static CYTHON_INLINE unsigned short __Pyx_PyInt_AsUnsignedShort(PyObject *);
+
+static CYTHON_INLINE unsigned int __Pyx_PyInt_AsUnsignedInt(PyObject *);
+
+static CYTHON_INLINE char __Pyx_PyInt_AsChar(PyObject *);
+
+static CYTHON_INLINE short __Pyx_PyInt_AsShort(PyObject *);
+
+static CYTHON_INLINE int __Pyx_PyInt_AsInt(PyObject *);
+
+static CYTHON_INLINE signed char __Pyx_PyInt_AsSignedChar(PyObject *);
+
+static CYTHON_INLINE signed short __Pyx_PyInt_AsSignedShort(PyObject *);
+
+static CYTHON_INLINE signed int __Pyx_PyInt_AsSignedInt(PyObject *);
+
+static CYTHON_INLINE int __Pyx_PyInt_AsLongDouble(PyObject *);
+
+static CYTHON_INLINE unsigned long __Pyx_PyInt_AsUnsignedLong(PyObject *);
+
+static CYTHON_INLINE unsigned PY_LONG_LONG __Pyx_PyInt_AsUnsignedLongLong(PyObject *);
+
+static CYTHON_INLINE long __Pyx_PyInt_AsLong(PyObject *);
+
+static CYTHON_INLINE PY_LONG_LONG __Pyx_PyInt_AsLongLong(PyObject *);
+
+static CYTHON_INLINE signed long __Pyx_PyInt_AsSignedLong(PyObject *);
+
+static CYTHON_INLINE signed PY_LONG_LONG __Pyx_PyInt_AsSignedLongLong(PyObject *);
+
+static void __Pyx_WriteUnraisable(const char *name, int clineno,
+                                  int lineno, const char *filename); /*proto*/
+
+static CYTHON_INLINE int __Pyx_StrEq(const char *, const char *); /*proto*/
+
+static int __Pyx_check_binary_version(void);
+
+static int __Pyx_SetVtable(PyObject *dict, void *vtable); /*proto*/
+
+#if !defined(__Pyx_PyIdentifier_FromString)
+#if PY_MAJOR_VERSION < 3
+  #define __Pyx_PyIdentifier_FromString(s) PyString_FromString(s)
+#else
+  #define __Pyx_PyIdentifier_FromString(s) PyUnicode_FromString(s)
+#endif
+#endif
+
+static PyObject *__Pyx_ImportModule(const char *name); /*proto*/
+
+static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name, size_t size, int strict);  /*proto*/
+
+typedef struct {
+    int code_line;
+    PyCodeObject* code_object;
+} __Pyx_CodeObjectCacheEntry;
+struct __Pyx_CodeObjectCache {
+    int count;
+    int max_count;
+    __Pyx_CodeObjectCacheEntry* entries;
+};
+static struct __Pyx_CodeObjectCache __pyx_code_cache = {0,0,NULL};
+static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line);
+static PyCodeObject *__pyx_find_code_object(int code_line);
+static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object);
+
+static void __Pyx_AddTraceback(const char *funcname, int c_line,
+                               int py_line, const char *filename); /*proto*/
+
+static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
+
+
+/* Module declarations from 'cpython.buffer' */
+
+/* Module declarations from 'cpython.ref' */
+
+/* Module declarations from 'libc.string' */
+
+/* Module declarations from 'libc.stdio' */
+
+/* Module declarations from 'cpython.object' */
+
+/* Module declarations from '__builtin__' */
+
+/* Module declarations from 'cpython.type' */
+static PyTypeObject *__pyx_ptype_7cpython_4type_type = 0;
+
+/* Module declarations from 'libc.stdlib' */
+
+/* Module declarations from 'numpy' */
+
+/* Module declarations from 'numpy' */
+static PyTypeObject *__pyx_ptype_5numpy_dtype = 0;
+static PyTypeObject *__pyx_ptype_5numpy_flatiter = 0;
+static PyTypeObject *__pyx_ptype_5numpy_broadcast = 0;
+static PyTypeObject *__pyx_ptype_5numpy_ndarray = 0;
+static PyTypeObject *__pyx_ptype_5numpy_ufunc = 0;
+static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *, char *, char *, int *); /*proto*/
+
+/* Module declarations from 'bx.arrays.wiggle' */
+static PyTypeObject *__pyx_ptype_2bx_6arrays_6wiggle_WiggleReader = 0;
+
+/* Module declarations from 'bx.arrays' */
+
+/* Module declarations from 'bx' */
+
+/* Module declarations from 'bx.arrays.array_tree' */
+static PyTypeObject *__pyx_ptype_2bx_6arrays_10array_tree_FileArrayTreeDict = 0;
+static PyTypeObject *__pyx_ptype_2bx_6arrays_10array_tree_FileArrayTree = 0;
+static PyTypeObject *__pyx_ptype_2bx_6arrays_10array_tree_Summary = 0;
+static PyTypeObject *__pyx_ptype_2bx_6arrays_10array_tree_ArrayTreeNode = 0;
+static PyTypeObject *__pyx_ptype_2bx_6arrays_10array_tree_ArrayTreeLeaf = 0;
+static PyTypeObject *__pyx_ptype_2bx_6arrays_10array_tree_ArrayTree = 0;
+#define __Pyx_MODULE_NAME "bx.arrays.array_tree"
+int __pyx_module_is_main_bx__arrays__array_tree = 0;
+
+/* Implementation of 'bx.arrays.array_tree' */
+static PyObject *__pyx_builtin_ValueError;
+static PyObject *__pyx_builtin_range;
+static PyObject *__pyx_builtin_sum;
+static PyObject *__pyx_builtin_RuntimeError;
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_array_tree_dict_from_reader(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_reader, PyObject *__pyx_v_sizes, PyObject *__pyx_v_default_size, PyObject *__pyx_v_block_size, PyObject *__pyx_v_no_leaves); /* proto */
+static int __pyx_pf_2bx_6arrays_10array_tree_17FileArrayTreeDict___init__(struct __pyx_obj_2bx_6arrays_10array_tree_FileArrayTreeDict *__pyx_v_self, PyObject *__pyx_v_file); /* proto */
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_17FileArrayTreeDict_2__getitem__(struct __pyx_obj_2bx_6arrays_10array_tree_FileArrayTreeDict *__pyx_v_self, PyObject *__pyx_v_key); /* proto */
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_17FileArrayTreeDict_4dict_to_file(CYTHON_UNUSED PyObject *__pyx_v_Class, PyObject *__pyx_v_dict, PyObject *__pyx_v_file, PyObject *__pyx_v_is_little_endian, PyObject *__pyx_v_no_leaves); /* proto */
+static int __pyx_pf_2bx_6arrays_10array_tree_13FileArrayTree___init__(struct __pyx_obj_2bx_6arrays_10array_tree_FileArrayTree *__pyx_v_self, PyObject *__pyx_v_file, PyObject *__pyx_v_is_little_endian); /* proto */
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_13FileArrayTree_2__getitem__(struct __pyx_obj_2bx_6arrays_10array_tree_FileArrayTree *__pyx_v_self, PyObject *__pyx_v_index); /* proto */
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_13FileArrayTree_4get_summary(struct __pyx_obj_2bx_6arrays_10array_tree_FileArrayTree *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_level); /* proto */
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_13FileArrayTree_6get_leaf(struct __pyx_obj_2bx_6arrays_10array_tree_FileArrayTree *__pyx_v_self, PyObject *__pyx_v_index); /* proto */
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_13FileArrayTree_3max___get__(struct __pyx_obj_2bx_6arrays_10array_tree_FileArrayTree *__pyx_v_self); /* proto */
+static int __pyx_pf_2bx_6arrays_10array_tree_13FileArrayTree_3max_2__set__(struct __pyx_obj_2bx_6arrays_10array_tree_FileArrayTree *__pyx_v_self, PyObject *__pyx_v_value); /* proto */
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_13FileArrayTree_10block_size___get__(struct __pyx_obj_2bx_6arrays_10array_tree_FileArrayTree *__pyx_v_self); /* proto */
+static int __pyx_pf_2bx_6arrays_10array_tree_13FileArrayTree_10block_size_2__set__(struct __pyx_obj_2bx_6arrays_10array_tree_FileArrayTree *__pyx_v_self, PyObject *__pyx_v_value); /* proto */
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_13FileArrayTree_5dtype___get__(struct __pyx_obj_2bx_6arrays_10array_tree_FileArrayTree *__pyx_v_self); /* proto */
+static int __pyx_pf_2bx_6arrays_10array_tree_13FileArrayTree_5dtype_2__set__(struct __pyx_obj_2bx_6arrays_10array_tree_FileArrayTree *__pyx_v_self, PyObject *__pyx_v_value); /* proto */
+static int __pyx_pf_2bx_6arrays_10array_tree_13FileArrayTree_5dtype_4__del__(struct __pyx_obj_2bx_6arrays_10array_tree_FileArrayTree *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_13FileArrayTree_6levels___get__(struct __pyx_obj_2bx_6arrays_10array_tree_FileArrayTree *__pyx_v_self); /* proto */
+static int __pyx_pf_2bx_6arrays_10array_tree_13FileArrayTree_6levels_2__set__(struct __pyx_obj_2bx_6arrays_10array_tree_FileArrayTree *__pyx_v_self, PyObject *__pyx_v_value); /* proto */
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_13FileArrayTree_6offset___get__(struct __pyx_obj_2bx_6arrays_10array_tree_FileArrayTree *__pyx_v_self); /* proto */
+static int __pyx_pf_2bx_6arrays_10array_tree_13FileArrayTree_6offset_2__set__(struct __pyx_obj_2bx_6arrays_10array_tree_FileArrayTree *__pyx_v_self, PyObject *__pyx_v_value); /* proto */
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_13FileArrayTree_11root_offset___get__(struct __pyx_obj_2bx_6arrays_10array_tree_FileArrayTree *__pyx_v_self); /* proto */
+static int __pyx_pf_2bx_6arrays_10array_tree_13FileArrayTree_11root_offset_2__set__(struct __pyx_obj_2bx_6arrays_10array_tree_FileArrayTree *__pyx_v_self, PyObject *__pyx_v_value); /* proto */
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_7Summary_6counts___get__(struct __pyx_obj_2bx_6arrays_10array_tree_Summary *__pyx_v_self); /* proto */
+static int __pyx_pf_2bx_6arrays_10array_tree_7Summary_6counts_2__set__(struct __pyx_obj_2bx_6arrays_10array_tree_Summary *__pyx_v_self, PyObject *__pyx_v_value); /* proto */
+static int __pyx_pf_2bx_6arrays_10array_tree_7Summary_6counts_4__del__(struct __pyx_obj_2bx_6arrays_10array_tree_Summary *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_7Summary_11frequencies___get__(struct __pyx_obj_2bx_6arrays_10array_tree_Summary *__pyx_v_self); /* proto */
+static int __pyx_pf_2bx_6arrays_10array_tree_7Summary_11frequencies_2__set__(struct __pyx_obj_2bx_6arrays_10array_tree_Summary *__pyx_v_self, PyObject *__pyx_v_value); /* proto */
+static int __pyx_pf_2bx_6arrays_10array_tree_7Summary_11frequencies_4__del__(struct __pyx_obj_2bx_6arrays_10array_tree_Summary *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_7Summary_4mins___get__(struct __pyx_obj_2bx_6arrays_10array_tree_Summary *__pyx_v_self); /* proto */
+static int __pyx_pf_2bx_6arrays_10array_tree_7Summary_4mins_2__set__(struct __pyx_obj_2bx_6arrays_10array_tree_Summary *__pyx_v_self, PyObject *__pyx_v_value); /* proto */
+static int __pyx_pf_2bx_6arrays_10array_tree_7Summary_4mins_4__del__(struct __pyx_obj_2bx_6arrays_10array_tree_Summary *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_7Summary_4maxs___get__(struct __pyx_obj_2bx_6arrays_10array_tree_Summary *__pyx_v_self); /* proto */
+static int __pyx_pf_2bx_6arrays_10array_tree_7Summary_4maxs_2__set__(struct __pyx_obj_2bx_6arrays_10array_tree_Summary *__pyx_v_self, PyObject *__pyx_v_value); /* proto */
+static int __pyx_pf_2bx_6arrays_10array_tree_7Summary_4maxs_4__del__(struct __pyx_obj_2bx_6arrays_10array_tree_Summary *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_7Summary_4sums___get__(struct __pyx_obj_2bx_6arrays_10array_tree_Summary *__pyx_v_self); /* proto */
+static int __pyx_pf_2bx_6arrays_10array_tree_7Summary_4sums_2__set__(struct __pyx_obj_2bx_6arrays_10array_tree_Summary *__pyx_v_self, PyObject *__pyx_v_value); /* proto */
+static int __pyx_pf_2bx_6arrays_10array_tree_7Summary_4sums_4__del__(struct __pyx_obj_2bx_6arrays_10array_tree_Summary *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_7Summary_10sumsquares___get__(struct __pyx_obj_2bx_6arrays_10array_tree_Summary *__pyx_v_self); /* proto */
+static int __pyx_pf_2bx_6arrays_10array_tree_7Summary_10sumsquares_2__set__(struct __pyx_obj_2bx_6arrays_10array_tree_Summary *__pyx_v_self, PyObject *__pyx_v_value); /* proto */
+static int __pyx_pf_2bx_6arrays_10array_tree_7Summary_10sumsquares_4__del__(struct __pyx_obj_2bx_6arrays_10array_tree_Summary *__pyx_v_self); /* proto */
+static int __pyx_pf_2bx_6arrays_10array_tree_9ArrayTree___init__(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTree *__pyx_v_self, int __pyx_v_max, int __pyx_v_block_size, PyObject *__pyx_v_dtype, PyObject *__pyx_v_no_leaves); /* proto */
+static int __pyx_pf_2bx_6arrays_10array_tree_9ArrayTree_2__setitem__(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTree *__pyx_v_self, int __pyx_v_index, PyObject *__pyx_v_value); /* proto */
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_9ArrayTree_4set_range(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTree *__pyx_v_self, int __pyx_v_start, int __pyx_v_end, PyObject *__pyx_v_value); /* proto */
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_9ArrayTree_6__getitem__(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTree *__pyx_v_self, int __pyx_v_index); /* proto */
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_9ArrayTree_8to_file(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTree *__pyx_v_self, PyObject *__pyx_v_f, PyObject *__pyx_v_is_little_endian, PyObject *__pyx_v_no_leaves); /* proto */
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_9ArrayTree_10from_file(PyObject *__pyx_v_Class, PyObject *__pyx_v_f, PyObject *__pyx_v_is_little_endian); /* proto */
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_9ArrayTree_12from_sequence(PyObject *__pyx_v_Class, PyObject *__pyx_v_s, PyObject *__pyx_v_block_size); /* proto */
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_9ArrayTree_3max___get__(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTree *__pyx_v_self); /* proto */
+static int __pyx_pf_2bx_6arrays_10array_tree_9ArrayTree_3max_2__set__(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTree *__pyx_v_self, PyObject *__pyx_v_value); /* proto */
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_9ArrayTree_10block_size___get__(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTree *__pyx_v_self); /* proto */
+static int __pyx_pf_2bx_6arrays_10array_tree_9ArrayTree_10block_size_2__set__(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTree *__pyx_v_self, PyObject *__pyx_v_value); /* proto */
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_9ArrayTree_5dtype___get__(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTree *__pyx_v_self); /* proto */
+static int __pyx_pf_2bx_6arrays_10array_tree_9ArrayTree_5dtype_2__set__(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTree *__pyx_v_self, PyObject *__pyx_v_value); /* proto */
+static int __pyx_pf_2bx_6arrays_10array_tree_9ArrayTree_5dtype_4__del__(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTree *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_9ArrayTree_6levels___get__(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTree *__pyx_v_self); /* proto */
+static int __pyx_pf_2bx_6arrays_10array_tree_9ArrayTree_6levels_2__set__(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTree *__pyx_v_self, PyObject *__pyx_v_value); /* proto */
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_9ArrayTree_9no_leaves___get__(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTree *__pyx_v_self); /* proto */
+static int __pyx_pf_2bx_6arrays_10array_tree_9ArrayTree_9no_leaves_2__set__(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTree *__pyx_v_self, PyObject *__pyx_v_value); /* proto */
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_9ArrayTree_4root___get__(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTree *__pyx_v_self); /* proto */
+static int __pyx_pf_2bx_6arrays_10array_tree_9ArrayTree_4root_2__set__(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTree *__pyx_v_self, PyObject *__pyx_v_value); /* proto */
+static int __pyx_pf_2bx_6arrays_10array_tree_9ArrayTree_4root_4__del__(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTree *__pyx_v_self); /* proto */
+static int __pyx_pf_2bx_6arrays_10array_tree_13ArrayTreeNode___init__(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeNode *__pyx_v_self, struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTree *__pyx_v_tree, int __pyx_v_min, int __pyx_v_max, int __pyx_v_block_size, int __pyx_v_level); /* proto */
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_13ArrayTreeNode_2set(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeNode *__pyx_v_self, int __pyx_v_index, PyObject *__pyx_v_value); /* proto */
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_13ArrayTreeNode_4get(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeNode *__pyx_v_self, int __pyx_v_index); /* proto */
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_13ArrayTreeNode_6build_summary(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeNode *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_13ArrayTreeNode_8to_file_data_pass(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeNode *__pyx_v_self, PyObject *__pyx_v_io, PyObject *__pyx_v_level); /* proto */
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_13ArrayTreeNode_10to_file_offset_pass(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeNode *__pyx_v_self, PyObject *__pyx_v_io); /* proto */
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_13ArrayTreeNode_12from_file(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeNode *__pyx_v_self, PyObject *__pyx_v_io); /* proto */
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_13ArrayTreeNode_14get_from_file(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeNode *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v_io, PyObject *__pyx_v_index); /* proto */
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_13ArrayTreeNode_7summary___get__(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeNode *__pyx_v_self); /* proto */
+static int __pyx_pf_2bx_6arrays_10array_tree_13ArrayTreeNode_7summary_2__set__(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeNode *__pyx_v_self, PyObject *__pyx_v_value); /* proto */
+static int __pyx_pf_2bx_6arrays_10array_tree_13ArrayTreeNode_7summary_4__del__(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeNode *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_13ArrayTreeNode_12start_offset___get__(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeNode *__pyx_v_self); /* proto */
+static int __pyx_pf_2bx_6arrays_10array_tree_13ArrayTreeNode_12start_offset_2__set__(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeNode *__pyx_v_self, PyObject *__pyx_v_value); /* proto */
+static int __pyx_pf_2bx_6arrays_10array_tree_13ArrayTreeLeaf___init__(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeLeaf *__pyx_v_self, struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTree *__pyx_v_tree, int __pyx_v_min, int __pyx_v_max); /* proto */
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_13ArrayTreeLeaf_2set(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeLeaf *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value); /* proto */
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_13ArrayTreeLeaf_4get(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeLeaf *__pyx_v_self, PyObject *__pyx_v_index); /* proto */
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_13ArrayTreeLeaf_6to_file_data_pass(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeLeaf *__pyx_v_self, PyObject *__pyx_v_io, PyObject *__pyx_v_level); /* proto */
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_13ArrayTreeLeaf_8to_file_offset_pass(CYTHON_UNUSED struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeLeaf *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v_io); /* proto */
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_13ArrayTreeLeaf_10from_file(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeLeaf *__pyx_v_self, PyObject *__pyx_v_io); /* proto */
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_13ArrayTreeLeaf_9frequency___get__(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeLeaf *__pyx_v_self); /* proto */
+static int __pyx_pf_2bx_6arrays_10array_tree_13ArrayTreeLeaf_9frequency_2__set__(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeLeaf *__pyx_v_self, PyObject *__pyx_v_value); /* proto */
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_13ArrayTreeLeaf_6values___get__(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeLeaf *__pyx_v_self); /* proto */
+static int __pyx_pf_2bx_6arrays_10array_tree_13ArrayTreeLeaf_6values_2__set__(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeLeaf *__pyx_v_self, PyObject *__pyx_v_value); /* proto */
+static int __pyx_pf_2bx_6arrays_10array_tree_13ArrayTreeLeaf_6values_4__del__(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeLeaf *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_13ArrayTreeLeaf_12start_offset___get__(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeLeaf *__pyx_v_self); /* proto */
+static int __pyx_pf_2bx_6arrays_10array_tree_13ArrayTreeLeaf_12start_offset_2__set__(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeLeaf *__pyx_v_self, PyObject *__pyx_v_value); /* proto */
+static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /* proto */
+static void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info); /* proto */
+static char __pyx_k_8[] = "max < block_size not yet handled";
+static char __pyx_k_9[] = "level must be <= self.levels";
+static char __pyx_k_14[] = "\000\000\000";
+static char __pyx_k_19[] = "Writing without summaries is currently not supported";
+static char __pyx_k_21[] = "ndarray is not C contiguous";
+static char __pyx_k_23[] = "ndarray is not Fortran contiguous";
+static char __pyx_k_25[] = "Non-native byte order not supported";
+static char __pyx_k_27[] = "unknown dtype code in numpy.pxd (%d)";
+static char __pyx_k_28[] = "Format string allocated too short, see comment in numpy.pxd";
+static char __pyx_k_31[] = "Format string allocated too short.";
+static char __pyx_k_33[] = "array_tree_dict_from_reader";
+static char __pyx_k_34[] = "*";
+static char __pyx_k_35[] = "bx.misc.binary_file";
+static char __pyx_k_36[] = "bx.misc.cdb";
+static char __pyx_k_39[] = "/aut/proj/odenas/software/bx-python/lib/bx/arrays/array_tree.pyx";
+static char __pyx_k_40[] = "bx.arrays.array_tree";
+static char __pyx_k__B[] = "B";
+static char __pyx_k__H[] = "H";
+static char __pyx_k__I[] = "I";
+static char __pyx_k__L[] = "L";
+static char __pyx_k__O[] = "O";
+static char __pyx_k__Q[] = "Q";
+static char __pyx_k___[] = "_";
+static char __pyx_k__b[] = "b";
+static char __pyx_k__d[] = "d";
+static char __pyx_k__f[] = "f";
+static char __pyx_k__g[] = "g";
+static char __pyx_k__h[] = "h";
+static char __pyx_k__i[] = "i";
+static char __pyx_k__l[] = "l";
+static char __pyx_k__q[] = "q";
+static char __pyx_k__s[] = "s";
+static char __pyx_k__Zd[] = "Zd";
+static char __pyx_k__Zf[] = "Zf";
+static char __pyx_k__Zg[] = "Zg";
+static char __pyx_k__io[] = "io";
+static char __pyx_k__end[] = "end";
+static char __pyx_k__get[] = "get";
+static char __pyx_k__max[] = "max";
+static char __pyx_k__min[] = "min";
+static char __pyx_k__nan[] = "nan";
+static char __pyx_k__set[] = "set";
+static char __pyx_k__sum[] = "sum";
+static char __pyx_k__val[] = "val";
+static char __pyx_k__char[] = "char";
+static char __pyx_k__dict[] = "dict";
+static char __pyx_k__file[] = "file";
+static char __pyx_k__maxs[] = "maxs";
+static char __pyx_k__mins[] = "mins";
+static char __pyx_k__pack[] = "pack";
+static char __pyx_k__read[] = "read";
+static char __pyx_k__root[] = "root";
+static char __pyx_k__rval[] = "rval";
+static char __pyx_k__seek[] = "seek";
+static char __pyx_k__skip[] = "skip";
+static char __pyx_k__sums[] = "sums";
+static char __pyx_k__tell[] = "tell";
+static char __pyx_k__tree[] = "tree";
+static char __pyx_k__MAGIC[] = "MAGIC";
+static char __pyx_k__chrom[] = "chrom";
+static char __pyx_k__dtype[] = "dtype";
+static char __pyx_k__empty[] = "empty";
+static char __pyx_k__index[] = "index";
+static char __pyx_k__int32[] = "int32";
+static char __pyx_k__isnan[] = "isnan";
+static char __pyx_k__level[] = "level";
+static char __pyx_k__numpy[] = "numpy";
+static char __pyx_k__range[] = "range";
+static char __pyx_k__sizes[] = "sizes";
+static char __pyx_k__start[] = "start";
+static char __pyx_k__value[] = "value";
+static char __pyx_k__write[] = "write";
+static char __pyx_k__counts[] = "counts";
+static char __pyx_k__nanmax[] = "nanmax";
+static char __pyx_k__nanmin[] = "nanmin";
+static char __pyx_k__nansum[] = "nansum";
+static char __pyx_k__reader[] = "reader";
+static char __pyx_k__unpack[] = "unpack";
+static char __pyx_k__values[] = "values";
+static char __pyx_k__VERSION[] = "VERSION";
+static char __pyx_k____all__[] = "__all__";
+static char __pyx_k__float32[] = "float32";
+static char __pyx_k__summary[] = "summary";
+static char __pyx_k__to_file[] = "to_file";
+static char __pyx_k____main__[] = "__main__";
+static char __pyx_k____test__[] = "__test__";
+static char __pyx_k__itemsize[] = "itemsize";
+static char __pyx_k__iterkeys[] = "iterkeys";
+static char __pyx_k__ArrayTree[] = "ArrayTree";
+static char __pyx_k__frequency[] = "frequency";
+static char __pyx_k__from_file[] = "from_file";
+static char __pyx_k__iteritems[] = "iteritems";
+static char __pyx_k__no_leaves[] = "no_leaves";
+static char __pyx_k__set_range[] = "set_range";
+static char __pyx_k__ValueError[] = "ValueError";
+static char __pyx_k__block_size[] = "block_size";
+static char __pyx_k__last_chrom[] = "last_chrom";
+static char __pyx_k__sumsquares[] = "sumsquares";
+static char __pyx_k__FileCDBDict[] = "FileCDBDict";
+static char __pyx_k__frequencies[] = "frequencies";
+static char __pyx_k__read_uint32[] = "read_uint32";
+static char __pyx_k__read_uint64[] = "read_uint64";
+static char __pyx_k__RuntimeError[] = "RuntimeError";
+static char __pyx_k__default_size[] = "default_size";
+static char __pyx_k__dict_to_file[] = "dict_to_file";
+static char __pyx_k__start_offset[] = "start_offset";
+static char __pyx_k__write_uint32[] = "write_uint32";
+static char __pyx_k__write_uint64[] = "write_uint64";
+static char __pyx_k__build_summary[] = "build_summary";
+static char __pyx_k__from_sequence[] = "from_sequence";
+static char __pyx_k__read_raw_array[] = "read_raw_array";
+static char __pyx_k__last_array_tree[] = "last_array_tree";
+static char __pyx_k__write_raw_array[] = "write_raw_array";
+static char __pyx_k__BinaryFileReader[] = "BinaryFileReader";
+static char __pyx_k__BinaryFileWriter[] = "BinaryFileWriter";
+static char __pyx_k__is_little_endian[] = "is_little_endian";
+static char __pyx_k__FileArrayTreeDict[] = "FileArrayTreeDict";
+static char __pyx_k__to_file_data_pass[] = "to_file_data_pass";
+static char __pyx_k__NUM_SUMMARY_ARRAYS[] = "NUM_SUMMARY_ARRAYS";
+static char __pyx_k__to_file_offset_pass[] = "to_file_offset_pass";
+static PyObject *__pyx_kp_s_14;
+static PyObject *__pyx_kp_s_19;
+static PyObject *__pyx_kp_u_21;
+static PyObject *__pyx_kp_u_23;
+static PyObject *__pyx_kp_u_25;
+static PyObject *__pyx_kp_u_27;
+static PyObject *__pyx_kp_u_28;
+static PyObject *__pyx_kp_u_31;
+static PyObject *__pyx_n_s_33;
+static PyObject *__pyx_n_s_34;
+static PyObject *__pyx_n_s_35;
+static PyObject *__pyx_n_s_36;
+static PyObject *__pyx_kp_s_39;
+static PyObject *__pyx_n_s_40;
+static PyObject *__pyx_kp_s_8;
+static PyObject *__pyx_kp_s_9;
+static PyObject *__pyx_n_s__ArrayTree;
+static PyObject *__pyx_n_s__BinaryFileReader;
+static PyObject *__pyx_n_s__BinaryFileWriter;
+static PyObject *__pyx_n_s__FileArrayTreeDict;
+static PyObject *__pyx_n_s__FileCDBDict;
+static PyObject *__pyx_n_s__L;
+static PyObject *__pyx_n_s__MAGIC;
+static PyObject *__pyx_n_s__NUM_SUMMARY_ARRAYS;
+static PyObject *__pyx_n_s__RuntimeError;
+static PyObject *__pyx_n_s__VERSION;
+static PyObject *__pyx_n_s__ValueError;
+static PyObject *__pyx_n_s___;
+static PyObject *__pyx_n_s____all__;
+static PyObject *__pyx_n_s____main__;
+static PyObject *__pyx_n_s____test__;
+static PyObject *__pyx_n_s__block_size;
+static PyObject *__pyx_n_s__build_summary;
+static PyObject *__pyx_n_s__char;
+static PyObject *__pyx_n_s__chrom;
+static PyObject *__pyx_n_s__counts;
+static PyObject *__pyx_n_s__default_size;
+static PyObject *__pyx_n_s__dict;
+static PyObject *__pyx_n_s__dict_to_file;
+static PyObject *__pyx_n_s__dtype;
+static PyObject *__pyx_n_s__empty;
+static PyObject *__pyx_n_s__end;
+static PyObject *__pyx_n_s__f;
+static PyObject *__pyx_n_s__file;
+static PyObject *__pyx_n_s__float32;
+static PyObject *__pyx_n_s__frequencies;
+static PyObject *__pyx_n_s__frequency;
+static PyObject *__pyx_n_s__from_file;
+static PyObject *__pyx_n_s__from_sequence;
+static PyObject *__pyx_n_s__get;
+static PyObject *__pyx_n_s__index;
+static PyObject *__pyx_n_s__int32;
+static PyObject *__pyx_n_s__io;
+static PyObject *__pyx_n_s__is_little_endian;
+static PyObject *__pyx_n_s__isnan;
+static PyObject *__pyx_n_s__itemsize;
+static PyObject *__pyx_n_s__iteritems;
+static PyObject *__pyx_n_s__iterkeys;
+static PyObject *__pyx_n_s__last_array_tree;
+static PyObject *__pyx_n_s__last_chrom;
+static PyObject *__pyx_n_s__level;
+static PyObject *__pyx_n_s__max;
+static PyObject *__pyx_n_s__maxs;
+static PyObject *__pyx_n_s__min;
+static PyObject *__pyx_n_s__mins;
+static PyObject *__pyx_n_s__nan;
+static PyObject *__pyx_n_s__nanmax;
+static PyObject *__pyx_n_s__nanmin;
+static PyObject *__pyx_n_s__nansum;
+static PyObject *__pyx_n_s__no_leaves;
+static PyObject *__pyx_n_s__numpy;
+static PyObject *__pyx_n_s__pack;
+static PyObject *__pyx_n_s__range;
+static PyObject *__pyx_n_s__read;
+static PyObject *__pyx_n_s__read_raw_array;
+static PyObject *__pyx_n_s__read_uint32;
+static PyObject *__pyx_n_s__read_uint64;
+static PyObject *__pyx_n_s__reader;
+static PyObject *__pyx_n_s__root;
+static PyObject *__pyx_n_s__rval;
+static PyObject *__pyx_n_s__s;
+static PyObject *__pyx_n_s__seek;
+static PyObject *__pyx_n_s__set;
+static PyObject *__pyx_n_s__set_range;
+static PyObject *__pyx_n_s__sizes;
+static PyObject *__pyx_n_s__skip;
+static PyObject *__pyx_n_s__start;
+static PyObject *__pyx_n_s__start_offset;
+static PyObject *__pyx_n_s__sum;
+static PyObject *__pyx_n_s__summary;
+static PyObject *__pyx_n_s__sums;
+static PyObject *__pyx_n_s__sumsquares;
+static PyObject *__pyx_n_s__tell;
+static PyObject *__pyx_n_s__to_file;
+static PyObject *__pyx_n_s__to_file_data_pass;
+static PyObject *__pyx_n_s__to_file_offset_pass;
+static PyObject *__pyx_n_s__tree;
+static PyObject *__pyx_n_s__unpack;
+static PyObject *__pyx_n_s__val;
+static PyObject *__pyx_n_s__value;
+static PyObject *__pyx_n_s__values;
+static PyObject *__pyx_n_s__write;
+static PyObject *__pyx_n_s__write_raw_array;
+static PyObject *__pyx_n_s__write_uint32;
+static PyObject *__pyx_n_s__write_uint64;
+static PyObject *__pyx_int_0;
+static PyObject *__pyx_int_1;
+static PyObject *__pyx_int_2;
+static PyObject *__pyx_int_3;
+static PyObject *__pyx_int_6;
+static PyObject *__pyx_int_15;
+static PyObject *__pyx_int_1000;
+static PyObject *__pyx_int_823052252;
+static PyObject *__pyx_int_2147483647;
+static PyObject *__pyx_k_1;
+static PyObject *__pyx_k_2;
+static PyObject *__pyx_k_3;
+static PyObject *__pyx_k_5;
+static PyObject *__pyx_k_10;
+static PyObject *__pyx_k_11;
+static PyObject *__pyx_k_12;
+static PyObject *__pyx_k_13;
+static PyObject *__pyx_k_16;
+static PyObject *__pyx_k_tuple_4;
+static PyObject *__pyx_k_tuple_6;
+static PyObject *__pyx_k_tuple_7;
+static PyObject *__pyx_k_tuple_15;
+static PyObject *__pyx_k_tuple_17;
+static PyObject *__pyx_k_tuple_18;
+static PyObject *__pyx_k_tuple_20;
+static PyObject *__pyx_k_tuple_22;
+static PyObject *__pyx_k_tuple_24;
+static PyObject *__pyx_k_tuple_26;
+static PyObject *__pyx_k_tuple_29;
+static PyObject *__pyx_k_tuple_30;
+static PyObject *__pyx_k_tuple_32;
+static PyObject *__pyx_k_tuple_37;
+static PyObject *__pyx_k_codeobj_38;
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_1array_tree_dict_from_reader(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_mdef_2bx_6arrays_10array_tree_1array_tree_dict_from_reader = {__Pyx_NAMESTR("array_tree_dict_from_reader"), (PyCFunction)__pyx_pw_2bx_6arrays_10array_tree_1array_tree_dict_from_reader, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(0)};
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_1array_tree_dict_from_reader(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_reader = 0;
+  PyObject *__pyx_v_sizes = 0;
+  PyObject *__pyx_v_default_size = 0;
+  PyObject *__pyx_v_block_size = 0;
+  PyObject *__pyx_v_no_leaves = 0;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("array_tree_dict_from_reader (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__reader,&__pyx_n_s__sizes,&__pyx_n_s__default_size,&__pyx_n_s__block_size,&__pyx_n_s__no_leaves,0};
+    PyObject* values[5] = {0,0,0,0,0};
+    values[2] = ((PyObject *)__pyx_int_2147483647);
+    values[3] = ((PyObject *)__pyx_int_1000);
+    values[4] = __pyx_k_1;
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+        case  4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__reader)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__sizes)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("array_tree_dict_from_reader", 0, 2, 5, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 62; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+        case  2:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s__default_size);
+          if (value) { values[2] = value; kw_args--; }
+        }
+        case  3:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s__block_size);
+          if (value) { values[3] = value; kw_args--; }
+        }
+        case  4:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s__no_leaves);
+          if (value) { values[4] = value; kw_args--; }
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "array_tree_dict_from_reader") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 62; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else {
+      switch (PyTuple_GET_SIZE(__pyx_args)) {
+        case  5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+        case  4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+    }
+    __pyx_v_reader = values[0];
+    __pyx_v_sizes = values[1];
+    __pyx_v_default_size = values[2];
+    __pyx_v_block_size = values[3];
+    __pyx_v_no_leaves = values[4];
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("array_tree_dict_from_reader", 0, 2, 5, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 62; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.arrays.array_tree.array_tree_dict_from_reader", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_6arrays_10array_tree_array_tree_dict_from_reader(__pyx_self, __pyx_v_reader, __pyx_v_sizes, __pyx_v_default_size, __pyx_v_block_size, __pyx_v_no_leaves);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/arrays/array_tree.pyx":62
+ * NUM_SUMMARY_ARRAYS = 6
+ * 
+ * def array_tree_dict_from_reader( reader, sizes, default_size=2147483647, block_size=1000, no_leaves=False ):             # <<<<<<<<<<<<<<
+ *     # Create empty array trees
+ *     rval = {}
+ */
+
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_array_tree_dict_from_reader(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_reader, PyObject *__pyx_v_sizes, PyObject *__pyx_v_default_size, PyObject *__pyx_v_block_size, PyObject *__pyx_v_no_leaves) {
+  PyObject *__pyx_v_rval = NULL;
+  PyObject *__pyx_v_last_chrom = NULL;
+  PyObject *__pyx_v_last_array_tree = NULL;
+  PyObject *__pyx_v_chrom = NULL;
+  PyObject *__pyx_v_start = NULL;
+  PyObject *__pyx_v_end = NULL;
+  CYTHON_UNUSED PyObject *__pyx_v__ = NULL;
+  PyObject *__pyx_v_val = NULL;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  Py_ssize_t __pyx_t_2;
+  PyObject *(*__pyx_t_3)(PyObject *);
+  PyObject *__pyx_t_4 = NULL;
+  PyObject *__pyx_t_5 = NULL;
+  PyObject *__pyx_t_6 = NULL;
+  PyObject *__pyx_t_7 = NULL;
+  PyObject *__pyx_t_8 = NULL;
+  PyObject *__pyx_t_9 = NULL;
+  PyObject *__pyx_t_10 = NULL;
+  PyObject *(*__pyx_t_11)(PyObject *);
+  int __pyx_t_12;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("array_tree_dict_from_reader", 0);
+
+  /* "bx/arrays/array_tree.pyx":64
+ * def array_tree_dict_from_reader( reader, sizes, default_size=2147483647, block_size=1000, no_leaves=False ):
+ *     # Create empty array trees
+ *     rval = {}             # <<<<<<<<<<<<<<
+ *     ## for key, size in sizes.iteritems():
+ *     ##    rval[ key ] = ArrayTree( size, 1000 )
+ */
+  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 64; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(((PyObject *)__pyx_t_1));
+  __pyx_v_rval = ((PyObject*)__pyx_t_1);
+  __pyx_t_1 = 0;
+
+  /* "bx/arrays/array_tree.pyx":68
+ *     ##    rval[ key ] = ArrayTree( size, 1000 )
+ *     # Fill
+ *     last_chrom = None             # <<<<<<<<<<<<<<
+ *     last_array_tree = None
+ *     for chrom, start, end, _, val in reader:
+ */
+  __Pyx_INCREF(Py_None);
+  __pyx_v_last_chrom = Py_None;
+
+  /* "bx/arrays/array_tree.pyx":69
+ *     # Fill
+ *     last_chrom = None
+ *     last_array_tree = None             # <<<<<<<<<<<<<<
+ *     for chrom, start, end, _, val in reader:
+ *         if chrom != last_chrom:
+ */
+  __Pyx_INCREF(Py_None);
+  __pyx_v_last_array_tree = Py_None;
+
+  /* "bx/arrays/array_tree.pyx":70
+ *     last_chrom = None
+ *     last_array_tree = None
+ *     for chrom, start, end, _, val in reader:             # <<<<<<<<<<<<<<
+ *         if chrom != last_chrom:
+ *             if chrom not in rval:
+ */
+  if (PyList_CheckExact(__pyx_v_reader) || PyTuple_CheckExact(__pyx_v_reader)) {
+    __pyx_t_1 = __pyx_v_reader; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0;
+    __pyx_t_3 = NULL;
+  } else {
+    __pyx_t_2 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_reader); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 70; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __pyx_t_3 = Py_TYPE(__pyx_t_1)->tp_iternext;
+  }
+  for (;;) {
+    if (!__pyx_t_3 && PyList_CheckExact(__pyx_t_1)) {
+      if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_1)) break;
+      #if CYTHON_COMPILING_IN_CPYTHON
+      __pyx_t_4 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_4); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 70; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      #else
+      __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 70; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      #endif
+    } else if (!__pyx_t_3 && PyTuple_CheckExact(__pyx_t_1)) {
+      if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
+      #if CYTHON_COMPILING_IN_CPYTHON
+      __pyx_t_4 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_4); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 70; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      #else
+      __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 70; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      #endif
+    } else {
+      __pyx_t_4 = __pyx_t_3(__pyx_t_1);
+      if (unlikely(!__pyx_t_4)) {
+        if (PyErr_Occurred()) {
+          if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
+          else {__pyx_filename = __pyx_f[0]; __pyx_lineno = 70; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        }
+        break;
+      }
+      __Pyx_GOTREF(__pyx_t_4);
+    }
+    if ((likely(PyTuple_CheckExact(__pyx_t_4))) || (PyList_CheckExact(__pyx_t_4))) {
+      PyObject* sequence = __pyx_t_4;
+      #if CYTHON_COMPILING_IN_CPYTHON
+      Py_ssize_t size = Py_SIZE(sequence);
+      #else
+      Py_ssize_t size = PySequence_Size(sequence);
+      #endif
+      if (unlikely(size != 5)) {
+        if (size > 5) __Pyx_RaiseTooManyValuesError(5);
+        else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
+        {__pyx_filename = __pyx_f[0]; __pyx_lineno = 70; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      }
+      #if CYTHON_COMPILING_IN_CPYTHON
+      if (likely(PyTuple_CheckExact(sequence))) {
+        __pyx_t_5 = PyTuple_GET_ITEM(sequence, 0); 
+        __pyx_t_6 = PyTuple_GET_ITEM(sequence, 1); 
+        __pyx_t_7 = PyTuple_GET_ITEM(sequence, 2); 
+        __pyx_t_8 = PyTuple_GET_ITEM(sequence, 3); 
+        __pyx_t_9 = PyTuple_GET_ITEM(sequence, 4); 
+      } else {
+        __pyx_t_5 = PyList_GET_ITEM(sequence, 0); 
+        __pyx_t_6 = PyList_GET_ITEM(sequence, 1); 
+        __pyx_t_7 = PyList_GET_ITEM(sequence, 2); 
+        __pyx_t_8 = PyList_GET_ITEM(sequence, 3); 
+        __pyx_t_9 = PyList_GET_ITEM(sequence, 4); 
+      }
+      __Pyx_INCREF(__pyx_t_5);
+      __Pyx_INCREF(__pyx_t_6);
+      __Pyx_INCREF(__pyx_t_7);
+      __Pyx_INCREF(__pyx_t_8);
+      __Pyx_INCREF(__pyx_t_9);
+      #else
+      Py_ssize_t i;
+      PyObject** temps[5] = {&__pyx_t_5,&__pyx_t_6,&__pyx_t_7,&__pyx_t_8,&__pyx_t_9};
+      for (i=0; i < 5; i++) {
+        PyObject* item = PySequence_ITEM(sequence, i); if (unlikely(!item)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 70; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(item);
+        *(temps[i]) = item;
+      }
+      #endif
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    } else
+    {
+      Py_ssize_t index = -1;
+      PyObject** temps[5] = {&__pyx_t_5,&__pyx_t_6,&__pyx_t_7,&__pyx_t_8,&__pyx_t_9};
+      __pyx_t_10 = PyObject_GetIter(__pyx_t_4); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 70; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_10);
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      __pyx_t_11 = Py_TYPE(__pyx_t_10)->tp_iternext;
+      for (index=0; index < 5; index++) {
+        PyObject* item = __pyx_t_11(__pyx_t_10); if (unlikely(!item)) goto __pyx_L5_unpacking_failed;
+        __Pyx_GOTREF(item);
+        *(temps[index]) = item;
+      }
+      if (__Pyx_IternextUnpackEndCheck(__pyx_t_11(__pyx_t_10), 5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 70; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_11 = NULL;
+      __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+      goto __pyx_L6_unpacking_done;
+      __pyx_L5_unpacking_failed:;
+      __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+      __pyx_t_11 = NULL;
+      if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
+      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 70; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_L6_unpacking_done:;
+    }
+    __Pyx_XDECREF(__pyx_v_chrom);
+    __pyx_v_chrom = __pyx_t_5;
+    __pyx_t_5 = 0;
+    __Pyx_XDECREF(__pyx_v_start);
+    __pyx_v_start = __pyx_t_6;
+    __pyx_t_6 = 0;
+    __Pyx_XDECREF(__pyx_v_end);
+    __pyx_v_end = __pyx_t_7;
+    __pyx_t_7 = 0;
+    __Pyx_XDECREF(__pyx_v__);
+    __pyx_v__ = __pyx_t_8;
+    __pyx_t_8 = 0;
+    __Pyx_XDECREF(__pyx_v_val);
+    __pyx_v_val = __pyx_t_9;
+    __pyx_t_9 = 0;
+
+    /* "bx/arrays/array_tree.pyx":71
+ *     last_array_tree = None
+ *     for chrom, start, end, _, val in reader:
+ *         if chrom != last_chrom:             # <<<<<<<<<<<<<<
+ *             if chrom not in rval:
+ *                 rval[chrom] = ArrayTree( sizes.get( chrom, default_size ), block_size, no_leaves=no_leaves )
+ */
+    __pyx_t_4 = PyObject_RichCompare(__pyx_v_chrom, __pyx_v_last_chrom, Py_NE); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 71; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_12 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_12 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 71; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    if (__pyx_t_12) {
+
+      /* "bx/arrays/array_tree.pyx":72
+ *     for chrom, start, end, _, val in reader:
+ *         if chrom != last_chrom:
+ *             if chrom not in rval:             # <<<<<<<<<<<<<<
+ *                 rval[chrom] = ArrayTree( sizes.get( chrom, default_size ), block_size, no_leaves=no_leaves )
+ *             last_array_tree = rval[chrom]
+ */
+      __pyx_t_12 = (__Pyx_PyDict_Contains(__pyx_v_chrom, ((PyObject *)__pyx_v_rval), Py_NE)); if (unlikely(__pyx_t_12 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 72; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      if (__pyx_t_12) {
+
+        /* "bx/arrays/array_tree.pyx":73
+ *         if chrom != last_chrom:
+ *             if chrom not in rval:
+ *                 rval[chrom] = ArrayTree( sizes.get( chrom, default_size ), block_size, no_leaves=no_leaves )             # <<<<<<<<<<<<<<
+ *             last_array_tree = rval[chrom]
+ *         last_array_tree.set_range( start, end, val )
+ */
+        __pyx_t_4 = PyObject_GetAttr(__pyx_v_sizes, __pyx_n_s__get); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 73; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_4);
+        __pyx_t_9 = PyTuple_New(2); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 73; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_9);
+        __Pyx_INCREF(__pyx_v_chrom);
+        PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_v_chrom);
+        __Pyx_GIVEREF(__pyx_v_chrom);
+        __Pyx_INCREF(__pyx_v_default_size);
+        PyTuple_SET_ITEM(__pyx_t_9, 1, __pyx_v_default_size);
+        __Pyx_GIVEREF(__pyx_v_default_size);
+        __pyx_t_8 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_t_9), NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 73; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_8);
+        __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+        __Pyx_DECREF(((PyObject *)__pyx_t_9)); __pyx_t_9 = 0;
+        __pyx_t_9 = PyTuple_New(2); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 73; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_9);
+        PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_8);
+        __Pyx_GIVEREF(__pyx_t_8);
+        __Pyx_INCREF(__pyx_v_block_size);
+        PyTuple_SET_ITEM(__pyx_t_9, 1, __pyx_v_block_size);
+        __Pyx_GIVEREF(__pyx_v_block_size);
+        __pyx_t_8 = 0;
+        __pyx_t_8 = PyDict_New(); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 73; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(((PyObject *)__pyx_t_8));
+        if (PyDict_SetItem(__pyx_t_8, ((PyObject *)__pyx_n_s__no_leaves), __pyx_v_no_leaves) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 73; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_4 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_2bx_6arrays_10array_tree_ArrayTree)), ((PyObject *)__pyx_t_9), ((PyObject *)__pyx_t_8)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 73; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_4);
+        __Pyx_DECREF(((PyObject *)__pyx_t_9)); __pyx_t_9 = 0;
+        __Pyx_DECREF(((PyObject *)__pyx_t_8)); __pyx_t_8 = 0;
+        if (PyDict_SetItem(((PyObject *)__pyx_v_rval), __pyx_v_chrom, __pyx_t_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 73; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+        goto __pyx_L8;
+      }
+      __pyx_L8:;
+
+      /* "bx/arrays/array_tree.pyx":74
+ *             if chrom not in rval:
+ *                 rval[chrom] = ArrayTree( sizes.get( chrom, default_size ), block_size, no_leaves=no_leaves )
+ *             last_array_tree = rval[chrom]             # <<<<<<<<<<<<<<
+ *         last_array_tree.set_range( start, end, val )
+ *     return rval
+ */
+      __pyx_t_4 = __Pyx_PyDict_GetItem(((PyObject *)__pyx_v_rval), __pyx_v_chrom); if (!__pyx_t_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 74; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __Pyx_DECREF(__pyx_v_last_array_tree);
+      __pyx_v_last_array_tree = __pyx_t_4;
+      __pyx_t_4 = 0;
+      goto __pyx_L7;
+    }
+    __pyx_L7:;
+
+    /* "bx/arrays/array_tree.pyx":75
+ *                 rval[chrom] = ArrayTree( sizes.get( chrom, default_size ), block_size, no_leaves=no_leaves )
+ *             last_array_tree = rval[chrom]
+ *         last_array_tree.set_range( start, end, val )             # <<<<<<<<<<<<<<
+ *     return rval
+ * 
+ */
+    __pyx_t_4 = PyObject_GetAttr(__pyx_v_last_array_tree, __pyx_n_s__set_range); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 75; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    __pyx_t_8 = PyTuple_New(3); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 75; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_8);
+    __Pyx_INCREF(__pyx_v_start);
+    PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_v_start);
+    __Pyx_GIVEREF(__pyx_v_start);
+    __Pyx_INCREF(__pyx_v_end);
+    PyTuple_SET_ITEM(__pyx_t_8, 1, __pyx_v_end);
+    __Pyx_GIVEREF(__pyx_v_end);
+    __Pyx_INCREF(__pyx_v_val);
+    PyTuple_SET_ITEM(__pyx_t_8, 2, __pyx_v_val);
+    __Pyx_GIVEREF(__pyx_v_val);
+    __pyx_t_9 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_t_8), NULL); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 75; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_9);
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    __Pyx_DECREF(((PyObject *)__pyx_t_8)); __pyx_t_8 = 0;
+    __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+  }
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "bx/arrays/array_tree.pyx":76
+ *             last_array_tree = rval[chrom]
+ *         last_array_tree.set_range( start, end, val )
+ *     return rval             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __Pyx_INCREF(((PyObject *)__pyx_v_rval));
+  __pyx_r = ((PyObject *)__pyx_v_rval);
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_XDECREF(__pyx_t_5);
+  __Pyx_XDECREF(__pyx_t_6);
+  __Pyx_XDECREF(__pyx_t_7);
+  __Pyx_XDECREF(__pyx_t_8);
+  __Pyx_XDECREF(__pyx_t_9);
+  __Pyx_XDECREF(__pyx_t_10);
+  __Pyx_AddTraceback("bx.arrays.array_tree.array_tree_dict_from_reader", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_rval);
+  __Pyx_XDECREF(__pyx_v_last_chrom);
+  __Pyx_XDECREF(__pyx_v_last_array_tree);
+  __Pyx_XDECREF(__pyx_v_chrom);
+  __Pyx_XDECREF(__pyx_v_start);
+  __Pyx_XDECREF(__pyx_v_end);
+  __Pyx_XDECREF(__pyx_v__);
+  __Pyx_XDECREF(__pyx_v_val);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_2bx_6arrays_10array_tree_17FileArrayTreeDict_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static int __pyx_pw_2bx_6arrays_10array_tree_17FileArrayTreeDict_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_file = 0;
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__init__ (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__file,0};
+    PyObject* values[1] = {0};
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__file)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 85; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else if (PyTuple_GET_SIZE(__pyx_args) != 1) {
+      goto __pyx_L5_argtuple_error;
+    } else {
+      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+    }
+    __pyx_v_file = values[0];
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("__init__", 1, 1, 1, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 85; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.arrays.array_tree.FileArrayTreeDict.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return -1;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_6arrays_10array_tree_17FileArrayTreeDict___init__(((struct __pyx_obj_2bx_6arrays_10array_tree_FileArrayTreeDict *)__pyx_v_self), __pyx_v_file);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/arrays/array_tree.pyx":85
+ *     cdef object io
+ *     cdef object cdb_dict
+ *     def __init__( self, file ):             # <<<<<<<<<<<<<<
+ *         self.io = io = BinaryFileReader( file, MAGIC )
+ *         assert (0 <= io.read_uint32() <= 1) # Check for version 0 or 1
+ */
+
+static int __pyx_pf_2bx_6arrays_10array_tree_17FileArrayTreeDict___init__(struct __pyx_obj_2bx_6arrays_10array_tree_FileArrayTreeDict *__pyx_v_self, PyObject *__pyx_v_file) {
+  PyObject *__pyx_v_io = NULL;
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  int __pyx_t_4;
+  PyObject *__pyx_t_5 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__init__", 0);
+
+  /* "bx/arrays/array_tree.pyx":86
+ *     cdef object cdb_dict
+ *     def __init__( self, file ):
+ *         self.io = io = BinaryFileReader( file, MAGIC )             # <<<<<<<<<<<<<<
+ *         assert (0 <= io.read_uint32() <= 1) # Check for version 0 or 1
+ *         self.cdb_dict = FileCDBDict( file, is_little_endian=io.is_little_endian )
+ */
+  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__BinaryFileReader); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 86; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = __Pyx_GetName(__pyx_m, __pyx_n_s__MAGIC); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 86; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 86; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_INCREF(__pyx_v_file);
+  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_file);
+  __Pyx_GIVEREF(__pyx_v_file);
+  PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_2);
+  __Pyx_GIVEREF(__pyx_t_2);
+  __pyx_t_2 = 0;
+  __pyx_t_2 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 86; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
+  __Pyx_INCREF(__pyx_t_2);
+  __Pyx_GIVEREF(__pyx_t_2);
+  __Pyx_GOTREF(__pyx_v_self->io);
+  __Pyx_DECREF(__pyx_v_self->io);
+  __pyx_v_self->io = __pyx_t_2;
+  __Pyx_INCREF(__pyx_t_2);
+  __pyx_v_io = __pyx_t_2;
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+  /* "bx/arrays/array_tree.pyx":87
+ *     def __init__( self, file ):
+ *         self.io = io = BinaryFileReader( file, MAGIC )
+ *         assert (0 <= io.read_uint32() <= 1) # Check for version 0 or 1             # <<<<<<<<<<<<<<
+ *         self.cdb_dict = FileCDBDict( file, is_little_endian=io.is_little_endian )
+ *     def __getitem__( self, key ):
+ */
+  #ifndef CYTHON_WITHOUT_ASSERTIONS
+  __pyx_t_2 = PyObject_GetAttr(__pyx_v_io, __pyx_n_s__read_uint32); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 87; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 87; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_2 = PyObject_RichCompare(__pyx_int_0, __pyx_t_3, Py_LE); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 87; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (__Pyx_PyObject_IsTrue(__pyx_t_2)) {
+    __Pyx_DECREF(__pyx_t_2);
+    __pyx_t_2 = PyObject_RichCompare(__pyx_t_3, __pyx_int_1, Py_LE); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 87; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 87; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  if (unlikely(!__pyx_t_4)) {
+    PyErr_SetNone(PyExc_AssertionError);
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 87; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  #endif
+
+  /* "bx/arrays/array_tree.pyx":88
+ *         self.io = io = BinaryFileReader( file, MAGIC )
+ *         assert (0 <= io.read_uint32() <= 1) # Check for version 0 or 1
+ *         self.cdb_dict = FileCDBDict( file, is_little_endian=io.is_little_endian )             # <<<<<<<<<<<<<<
+ *     def __getitem__( self, key ):
+ *         offset = self.cdb_dict[key]
+ */
+  __pyx_t_2 = __Pyx_GetName(__pyx_m, __pyx_n_s__FileCDBDict); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 88; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 88; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_INCREF(__pyx_v_file);
+  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_file);
+  __Pyx_GIVEREF(__pyx_v_file);
+  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 88; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(((PyObject *)__pyx_t_1));
+  __pyx_t_5 = PyObject_GetAttr(__pyx_v_io, __pyx_n_s__is_little_endian); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 88; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  if (PyDict_SetItem(__pyx_t_1, ((PyObject *)__pyx_n_s__is_little_endian), __pyx_t_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 88; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+  __pyx_t_5 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_3), ((PyObject *)__pyx_t_1)); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 88; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+  __Pyx_GIVEREF(__pyx_t_5);
+  __Pyx_GOTREF(__pyx_v_self->cdb_dict);
+  __Pyx_DECREF(__pyx_v_self->cdb_dict);
+  __pyx_v_self->cdb_dict = __pyx_t_5;
+  __pyx_t_5 = 0;
+
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_5);
+  __Pyx_AddTraceback("bx.arrays.array_tree.FileArrayTreeDict.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = -1;
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_io);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_17FileArrayTreeDict_3__getitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_key); /*proto*/
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_17FileArrayTreeDict_3__getitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_key) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__getitem__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_6arrays_10array_tree_17FileArrayTreeDict_2__getitem__(((struct __pyx_obj_2bx_6arrays_10array_tree_FileArrayTreeDict *)__pyx_v_self), ((PyObject *)__pyx_v_key));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/arrays/array_tree.pyx":89
+ *         assert (0 <= io.read_uint32() <= 1) # Check for version 0 or 1
+ *         self.cdb_dict = FileCDBDict( file, is_little_endian=io.is_little_endian )
+ *     def __getitem__( self, key ):             # <<<<<<<<<<<<<<
+ *         offset = self.cdb_dict[key]
+ *         offset = self.io.unpack( "L", offset )[0]
+ */
+
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_17FileArrayTreeDict_2__getitem__(struct __pyx_obj_2bx_6arrays_10array_tree_FileArrayTreeDict *__pyx_v_self, PyObject *__pyx_v_key) {
+  PyObject *__pyx_v_offset = NULL;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__getitem__", 0);
+
+  /* "bx/arrays/array_tree.pyx":90
+ *         self.cdb_dict = FileCDBDict( file, is_little_endian=io.is_little_endian )
+ *     def __getitem__( self, key ):
+ *         offset = self.cdb_dict[key]             # <<<<<<<<<<<<<<
+ *         offset = self.io.unpack( "L", offset )[0]
+ *         self.io.seek( offset )
+ */
+  __pyx_t_1 = PyObject_GetItem(__pyx_v_self->cdb_dict, __pyx_v_key); if (!__pyx_t_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 90; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_v_offset = __pyx_t_1;
+  __pyx_t_1 = 0;
+
+  /* "bx/arrays/array_tree.pyx":91
+ *     def __getitem__( self, key ):
+ *         offset = self.cdb_dict[key]
+ *         offset = self.io.unpack( "L", offset )[0]             # <<<<<<<<<<<<<<
+ *         self.io.seek( offset )
+ *         return FileArrayTree( self.io.file, self.io.is_little_endian )
+ */
+  __pyx_t_1 = PyObject_GetAttr(__pyx_v_self->io, __pyx_n_s__unpack); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 91; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 91; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_INCREF(((PyObject *)__pyx_n_s__L));
+  PyTuple_SET_ITEM(__pyx_t_2, 0, ((PyObject *)__pyx_n_s__L));
+  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__L));
+  __Pyx_INCREF(__pyx_v_offset);
+  PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_v_offset);
+  __Pyx_GIVEREF(__pyx_v_offset);
+  __pyx_t_3 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 91; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
+  __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_3, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 91; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __Pyx_DECREF(__pyx_v_offset);
+  __pyx_v_offset = __pyx_t_2;
+  __pyx_t_2 = 0;
+
+  /* "bx/arrays/array_tree.pyx":92
+ *         offset = self.cdb_dict[key]
+ *         offset = self.io.unpack( "L", offset )[0]
+ *         self.io.seek( offset )             # <<<<<<<<<<<<<<
+ *         return FileArrayTree( self.io.file, self.io.is_little_endian )
+ * 
+ */
+  __pyx_t_2 = PyObject_GetAttr(__pyx_v_self->io, __pyx_n_s__seek); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 92; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 92; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_INCREF(__pyx_v_offset);
+  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_offset);
+  __Pyx_GIVEREF(__pyx_v_offset);
+  __pyx_t_1 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 92; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "bx/arrays/array_tree.pyx":93
+ *         offset = self.io.unpack( "L", offset )[0]
+ *         self.io.seek( offset )
+ *         return FileArrayTree( self.io.file, self.io.is_little_endian )             # <<<<<<<<<<<<<<
+ * 
+ *     @classmethod
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = PyObject_GetAttr(__pyx_v_self->io, __pyx_n_s__file); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 93; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_3 = PyObject_GetAttr(__pyx_v_self->io, __pyx_n_s__is_little_endian); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 93; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 93; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
+  __Pyx_GIVEREF(__pyx_t_1);
+  PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_3);
+  __Pyx_GIVEREF(__pyx_t_3);
+  __pyx_t_1 = 0;
+  __pyx_t_3 = 0;
+  __pyx_t_3 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_2bx_6arrays_10array_tree_FileArrayTree)), ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 93; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
+  __pyx_r = __pyx_t_3;
+  __pyx_t_3 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_AddTraceback("bx.arrays.array_tree.FileArrayTreeDict.__getitem__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_offset);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_17FileArrayTreeDict_5dict_to_file(PyObject *__pyx_v_Class, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_2bx_6arrays_10array_tree_17FileArrayTreeDict_4dict_to_file[] = "\n        Writes a dictionary of array trees to a file that can then be\n        read efficiently using this class.\n        ";
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_17FileArrayTreeDict_5dict_to_file(PyObject *__pyx_v_Class, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_dict = 0;
+  PyObject *__pyx_v_file = 0;
+  PyObject *__pyx_v_is_little_endian = 0;
+  PyObject *__pyx_v_no_leaves = 0;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("dict_to_file (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__dict,&__pyx_n_s__file,&__pyx_n_s__is_little_endian,&__pyx_n_s__no_leaves,0};
+    PyObject* values[4] = {0,0,0,0};
+    values[2] = __pyx_k_2;
+    values[3] = __pyx_k_3;
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__dict)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__file)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("dict_to_file", 0, 2, 4, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 96; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+        case  2:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s__is_little_endian);
+          if (value) { values[2] = value; kw_args--; }
+        }
+        case  3:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s__no_leaves);
+          if (value) { values[3] = value; kw_args--; }
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "dict_to_file") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 96; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else {
+      switch (PyTuple_GET_SIZE(__pyx_args)) {
+        case  4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+    }
+    __pyx_v_dict = values[0];
+    __pyx_v_file = values[1];
+    __pyx_v_is_little_endian = values[2];
+    __pyx_v_no_leaves = values[3];
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("dict_to_file", 0, 2, 4, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 96; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.arrays.array_tree.FileArrayTreeDict.dict_to_file", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_6arrays_10array_tree_17FileArrayTreeDict_4dict_to_file(((PyObject*)__pyx_v_Class), __pyx_v_dict, __pyx_v_file, __pyx_v_is_little_endian, __pyx_v_no_leaves);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/arrays/array_tree.pyx":96
+ * 
+ *     @classmethod
+ *     def dict_to_file( Class, dict, file, is_little_endian=True, no_leaves=False ):             # <<<<<<<<<<<<<<
+ *         """
+ *         Writes a dictionary of array trees to a file that can then be
+ */
+
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_17FileArrayTreeDict_4dict_to_file(CYTHON_UNUSED PyObject *__pyx_v_Class, PyObject *__pyx_v_dict, PyObject *__pyx_v_file, PyObject *__pyx_v_is_little_endian, PyObject *__pyx_v_no_leaves) {
+  PyObject *__pyx_v_io = NULL;
+  PyObject *__pyx_v_cdb_dict = NULL;
+  PyObject *__pyx_v_key = NULL;
+  PyObject *__pyx_v_cdb_offset = NULL;
+  PyObject *__pyx_v_value = NULL;
+  PyObject *__pyx_v_offset = NULL;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  Py_ssize_t __pyx_t_5;
+  Py_ssize_t __pyx_t_6;
+  int __pyx_t_7;
+  int __pyx_t_8;
+  PyObject *__pyx_t_9 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("dict_to_file", 0);
+
+  /* "bx/arrays/array_tree.pyx":101
+ *         read efficiently using this class.
+ *         """
+ *         io = BinaryFileWriter( file, is_little_endian=is_little_endian )             # <<<<<<<<<<<<<<
+ *         # Write magic number and version
+ *         io.write_uint32( MAGIC )
+ */
+  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__BinaryFileWriter); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 101; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 101; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_INCREF(__pyx_v_file);
+  PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_file);
+  __Pyx_GIVEREF(__pyx_v_file);
+  __pyx_t_3 = PyDict_New(); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 101; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(((PyObject *)__pyx_t_3));
+  if (PyDict_SetItem(__pyx_t_3, ((PyObject *)__pyx_n_s__is_little_endian), __pyx_v_is_little_endian) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 101; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_4 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_2), ((PyObject *)__pyx_t_3)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 101; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
+  __pyx_v_io = __pyx_t_4;
+  __pyx_t_4 = 0;
+
+  /* "bx/arrays/array_tree.pyx":103
+ *         io = BinaryFileWriter( file, is_little_endian=is_little_endian )
+ *         # Write magic number and version
+ *         io.write_uint32( MAGIC )             # <<<<<<<<<<<<<<
+ *         io.write_uint32( VERSION )
+ *         # Write cdb index with fake values just to fill space
+ */
+  __pyx_t_4 = PyObject_GetAttr(__pyx_v_io, __pyx_n_s__write_uint32); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 103; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __pyx_t_3 = __Pyx_GetName(__pyx_m, __pyx_n_s__MAGIC); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 103; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 103; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_3);
+  __Pyx_GIVEREF(__pyx_t_3);
+  __pyx_t_3 = 0;
+  __pyx_t_3 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 103; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+  /* "bx/arrays/array_tree.pyx":104
+ *         # Write magic number and version
+ *         io.write_uint32( MAGIC )
+ *         io.write_uint32( VERSION )             # <<<<<<<<<<<<<<
+ *         # Write cdb index with fake values just to fill space
+ *         cdb_dict = {}
+ */
+  __pyx_t_3 = PyObject_GetAttr(__pyx_v_io, __pyx_n_s__write_uint32); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 104; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_2 = __Pyx_GetName(__pyx_m, __pyx_n_s__VERSION); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 104; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 104; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_2);
+  __Pyx_GIVEREF(__pyx_t_2);
+  __pyx_t_2 = 0;
+  __pyx_t_2 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_t_4), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 104; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+  /* "bx/arrays/array_tree.pyx":106
+ *         io.write_uint32( VERSION )
+ *         # Write cdb index with fake values just to fill space
+ *         cdb_dict = {}             # <<<<<<<<<<<<<<
+ *         for key in dict.iterkeys():
+ *             cdb_dict[ key ] = io.pack( "L", 0 )
+ */
+  __pyx_t_2 = PyDict_New(); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 106; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(((PyObject *)__pyx_t_2));
+  __pyx_v_cdb_dict = ((PyObject*)__pyx_t_2);
+  __pyx_t_2 = 0;
+
+  /* "bx/arrays/array_tree.pyx":107
+ *         # Write cdb index with fake values just to fill space
+ *         cdb_dict = {}
+ *         for key in dict.iterkeys():             # <<<<<<<<<<<<<<
+ *             cdb_dict[ key ] = io.pack( "L", 0 )
+ *         cdb_offset = io.tell()
+ */
+  __pyx_t_5 = 0;
+  if (unlikely(__pyx_v_dict == Py_None)) {
+    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "iterkeys");
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 107; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  __pyx_t_4 = __Pyx_dict_iterator(__pyx_v_dict, 0, ((PyObject *)__pyx_n_s__iterkeys), (&__pyx_t_6), (&__pyx_t_7)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 107; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __Pyx_XDECREF(__pyx_t_2);
+  __pyx_t_2 = __pyx_t_4;
+  __pyx_t_4 = 0;
+  while (1) {
+    __pyx_t_8 = __Pyx_dict_iter_next(__pyx_t_2, __pyx_t_6, &__pyx_t_5, &__pyx_t_4, NULL, NULL, __pyx_t_7);
+    if (unlikely(__pyx_t_8 == 0)) break;
+    if (unlikely(__pyx_t_8 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 107; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    __Pyx_XDECREF(__pyx_v_key);
+    __pyx_v_key = __pyx_t_4;
+    __pyx_t_4 = 0;
+
+    /* "bx/arrays/array_tree.pyx":108
+ *         cdb_dict = {}
+ *         for key in dict.iterkeys():
+ *             cdb_dict[ key ] = io.pack( "L", 0 )             # <<<<<<<<<<<<<<
+ *         cdb_offset = io.tell()
+ *         FileCDBDict.to_file( cdb_dict, file, is_little_endian=is_little_endian )
+ */
+    __pyx_t_4 = PyObject_GetAttr(__pyx_v_io, __pyx_n_s__pack); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    __pyx_t_3 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_k_tuple_4), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    if (PyDict_SetItem(((PyObject *)__pyx_v_cdb_dict), __pyx_v_key, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  }
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+  /* "bx/arrays/array_tree.pyx":109
+ *         for key in dict.iterkeys():
+ *             cdb_dict[ key ] = io.pack( "L", 0 )
+ *         cdb_offset = io.tell()             # <<<<<<<<<<<<<<
+ *         FileCDBDict.to_file( cdb_dict, file, is_little_endian=is_little_endian )
+ *         # Write each tree and save offset
+ */
+  __pyx_t_2 = PyObject_GetAttr(__pyx_v_io, __pyx_n_s__tell); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 109; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 109; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_v_cdb_offset = __pyx_t_3;
+  __pyx_t_3 = 0;
+
+  /* "bx/arrays/array_tree.pyx":110
+ *             cdb_dict[ key ] = io.pack( "L", 0 )
+ *         cdb_offset = io.tell()
+ *         FileCDBDict.to_file( cdb_dict, file, is_little_endian=is_little_endian )             # <<<<<<<<<<<<<<
+ *         # Write each tree and save offset
+ *         for key, value in dict.iteritems():
+ */
+  __pyx_t_3 = __Pyx_GetName(__pyx_m, __pyx_n_s__FileCDBDict); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_2 = PyObject_GetAttr(__pyx_t_3, __pyx_n_s__to_file); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_INCREF(((PyObject *)__pyx_v_cdb_dict));
+  PyTuple_SET_ITEM(__pyx_t_3, 0, ((PyObject *)__pyx_v_cdb_dict));
+  __Pyx_GIVEREF(((PyObject *)__pyx_v_cdb_dict));
+  __Pyx_INCREF(__pyx_v_file);
+  PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_v_file);
+  __Pyx_GIVEREF(__pyx_v_file);
+  __pyx_t_4 = PyDict_New(); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(((PyObject *)__pyx_t_4));
+  if (PyDict_SetItem(__pyx_t_4, ((PyObject *)__pyx_n_s__is_little_endian), __pyx_v_is_little_endian) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_3), ((PyObject *)__pyx_t_4)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "bx/arrays/array_tree.pyx":112
+ *         FileCDBDict.to_file( cdb_dict, file, is_little_endian=is_little_endian )
+ *         # Write each tree and save offset
+ *         for key, value in dict.iteritems():             # <<<<<<<<<<<<<<
+ *             offset = io.tell()
+ *             cdb_dict[ key ] = io.pack( "L", offset )
+ */
+  __pyx_t_6 = 0;
+  if (unlikely(__pyx_v_dict == Py_None)) {
+    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "iteritems");
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 112; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  __pyx_t_4 = __Pyx_dict_iterator(__pyx_v_dict, 0, ((PyObject *)__pyx_n_s__iteritems), (&__pyx_t_5), (&__pyx_t_7)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 112; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __Pyx_XDECREF(__pyx_t_1);
+  __pyx_t_1 = __pyx_t_4;
+  __pyx_t_4 = 0;
+  while (1) {
+    __pyx_t_8 = __Pyx_dict_iter_next(__pyx_t_1, __pyx_t_5, &__pyx_t_6, &__pyx_t_4, &__pyx_t_3, NULL, __pyx_t_7);
+    if (unlikely(__pyx_t_8 == 0)) break;
+    if (unlikely(__pyx_t_8 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 112; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_XDECREF(__pyx_v_key);
+    __pyx_v_key = __pyx_t_4;
+    __pyx_t_4 = 0;
+    __Pyx_XDECREF(__pyx_v_value);
+    __pyx_v_value = __pyx_t_3;
+    __pyx_t_3 = 0;
+
+    /* "bx/arrays/array_tree.pyx":113
+ *         # Write each tree and save offset
+ *         for key, value in dict.iteritems():
+ *             offset = io.tell()             # <<<<<<<<<<<<<<
+ *             cdb_dict[ key ] = io.pack( "L", offset )
+ *             value.to_file( file, is_little_endian=is_little_endian, no_leaves=no_leaves )
+ */
+    __pyx_t_3 = PyObject_GetAttr(__pyx_v_io, __pyx_n_s__tell); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __pyx_t_4 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __Pyx_XDECREF(__pyx_v_offset);
+    __pyx_v_offset = __pyx_t_4;
+    __pyx_t_4 = 0;
+
+    /* "bx/arrays/array_tree.pyx":114
+ *         for key, value in dict.iteritems():
+ *             offset = io.tell()
+ *             cdb_dict[ key ] = io.pack( "L", offset )             # <<<<<<<<<<<<<<
+ *             value.to_file( file, is_little_endian=is_little_endian, no_leaves=no_leaves )
+ *         # Go back and write the index again
+ */
+    __pyx_t_4 = PyObject_GetAttr(__pyx_v_io, __pyx_n_s__pack); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 114; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 114; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_INCREF(((PyObject *)__pyx_n_s__L));
+    PyTuple_SET_ITEM(__pyx_t_3, 0, ((PyObject *)__pyx_n_s__L));
+    __Pyx_GIVEREF(((PyObject *)__pyx_n_s__L));
+    __Pyx_INCREF(__pyx_v_offset);
+    PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_v_offset);
+    __Pyx_GIVEREF(__pyx_v_offset);
+    __pyx_t_2 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 114; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
+    if (PyDict_SetItem(((PyObject *)__pyx_v_cdb_dict), __pyx_v_key, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 114; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+    /* "bx/arrays/array_tree.pyx":115
+ *             offset = io.tell()
+ *             cdb_dict[ key ] = io.pack( "L", offset )
+ *             value.to_file( file, is_little_endian=is_little_endian, no_leaves=no_leaves )             # <<<<<<<<<<<<<<
+ *         # Go back and write the index again
+ *         io.seek( cdb_offset )
+ */
+    __pyx_t_2 = PyObject_GetAttr(__pyx_v_value, __pyx_n_s__to_file); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_INCREF(__pyx_v_file);
+    PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_file);
+    __Pyx_GIVEREF(__pyx_v_file);
+    __pyx_t_4 = PyDict_New(); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(((PyObject *)__pyx_t_4));
+    if (PyDict_SetItem(__pyx_t_4, ((PyObject *)__pyx_n_s__is_little_endian), __pyx_v_is_little_endian) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (PyDict_SetItem(__pyx_t_4, ((PyObject *)__pyx_n_s__no_leaves), __pyx_v_no_leaves) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_9 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_3), ((PyObject *)__pyx_t_4)); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_9);
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
+    __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
+    __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+  }
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "bx/arrays/array_tree.pyx":117
+ *             value.to_file( file, is_little_endian=is_little_endian, no_leaves=no_leaves )
+ *         # Go back and write the index again
+ *         io.seek( cdb_offset )             # <<<<<<<<<<<<<<
+ *         FileCDBDict.to_file( cdb_dict, file, is_little_endian=is_little_endian )
+ * 
+ */
+  __pyx_t_1 = PyObject_GetAttr(__pyx_v_io, __pyx_n_s__seek); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 117; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_9 = PyTuple_New(1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 117; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_9);
+  __Pyx_INCREF(__pyx_v_cdb_offset);
+  PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_v_cdb_offset);
+  __Pyx_GIVEREF(__pyx_v_cdb_offset);
+  __pyx_t_4 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_9), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 117; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_9)); __pyx_t_9 = 0;
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+
+  /* "bx/arrays/array_tree.pyx":118
+ *         # Go back and write the index again
+ *         io.seek( cdb_offset )
+ *         FileCDBDict.to_file( cdb_dict, file, is_little_endian=is_little_endian )             # <<<<<<<<<<<<<<
+ * 
+ * cdef class FileArrayTree:
+ */
+  __pyx_t_4 = __Pyx_GetName(__pyx_m, __pyx_n_s__FileCDBDict); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 118; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __pyx_t_9 = PyObject_GetAttr(__pyx_t_4, __pyx_n_s__to_file); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 118; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_9);
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 118; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __Pyx_INCREF(((PyObject *)__pyx_v_cdb_dict));
+  PyTuple_SET_ITEM(__pyx_t_4, 0, ((PyObject *)__pyx_v_cdb_dict));
+  __Pyx_GIVEREF(((PyObject *)__pyx_v_cdb_dict));
+  __Pyx_INCREF(__pyx_v_file);
+  PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_v_file);
+  __Pyx_GIVEREF(__pyx_v_file);
+  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 118; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(((PyObject *)__pyx_t_1));
+  if (PyDict_SetItem(__pyx_t_1, ((PyObject *)__pyx_n_s__is_little_endian), __pyx_v_is_little_endian) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 118; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = PyObject_Call(__pyx_t_9, ((PyObject *)__pyx_t_4), ((PyObject *)__pyx_t_1)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 118; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_XDECREF(__pyx_t_9);
+  __Pyx_AddTraceback("bx.arrays.array_tree.FileArrayTreeDict.dict_to_file", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_io);
+  __Pyx_XDECREF(__pyx_v_cdb_dict);
+  __Pyx_XDECREF(__pyx_v_key);
+  __Pyx_XDECREF(__pyx_v_cdb_offset);
+  __Pyx_XDECREF(__pyx_v_value);
+  __Pyx_XDECREF(__pyx_v_offset);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_2bx_6arrays_10array_tree_13FileArrayTree_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static int __pyx_pw_2bx_6arrays_10array_tree_13FileArrayTree_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_file = 0;
+  PyObject *__pyx_v_is_little_endian = 0;
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__init__ (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__file,&__pyx_n_s__is_little_endian,0};
+    PyObject* values[2] = {0,0};
+    values[1] = __pyx_k_5;
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__file)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s__is_little_endian);
+          if (value) { values[1] = value; kw_args--; }
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 132; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else {
+      switch (PyTuple_GET_SIZE(__pyx_args)) {
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+    }
+    __pyx_v_file = values[0];
+    __pyx_v_is_little_endian = values[1];
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("__init__", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 132; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.arrays.array_tree.FileArrayTree.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return -1;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_6arrays_10array_tree_13FileArrayTree___init__(((struct __pyx_obj_2bx_6arrays_10array_tree_FileArrayTree *)__pyx_v_self), __pyx_v_file, __pyx_v_is_little_endian);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/arrays/array_tree.pyx":132
+ *     cdef object io
+ * 
+ *     def __init__( self, file, is_little_endian=True ):             # <<<<<<<<<<<<<<
+ *         self.io = BinaryFileReader( file, is_little_endian=is_little_endian )
+ *         self.offset = self.io.tell()
+ */
+
+static int __pyx_pf_2bx_6arrays_10array_tree_13FileArrayTree___init__(struct __pyx_obj_2bx_6arrays_10array_tree_FileArrayTree *__pyx_v_self, PyObject *__pyx_v_file, PyObject *__pyx_v_is_little_endian) {
+  PyObject *__pyx_v_dt = NULL;
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  int __pyx_t_5;
+  int __pyx_t_6;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__init__", 0);
+
+  /* "bx/arrays/array_tree.pyx":133
+ * 
+ *     def __init__( self, file, is_little_endian=True ):
+ *         self.io = BinaryFileReader( file, is_little_endian=is_little_endian )             # <<<<<<<<<<<<<<
+ *         self.offset = self.io.tell()
+ *         # Read basic info about the tree
+ */
+  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__BinaryFileReader); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 133; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 133; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_INCREF(__pyx_v_file);
+  PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_file);
+  __Pyx_GIVEREF(__pyx_v_file);
+  __pyx_t_3 = PyDict_New(); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 133; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(((PyObject *)__pyx_t_3));
+  if (PyDict_SetItem(__pyx_t_3, ((PyObject *)__pyx_n_s__is_little_endian), __pyx_v_is_little_endian) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 133; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_4 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_2), ((PyObject *)__pyx_t_3)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 133; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
+  __Pyx_GIVEREF(__pyx_t_4);
+  __Pyx_GOTREF(__pyx_v_self->io);
+  __Pyx_DECREF(__pyx_v_self->io);
+  __pyx_v_self->io = __pyx_t_4;
+  __pyx_t_4 = 0;
+
+  /* "bx/arrays/array_tree.pyx":134
+ *     def __init__( self, file, is_little_endian=True ):
+ *         self.io = BinaryFileReader( file, is_little_endian=is_little_endian )
+ *         self.offset = self.io.tell()             # <<<<<<<<<<<<<<
+ *         # Read basic info about the tree
+ *         self.max = self.io.read_uint32()
+ */
+  __pyx_t_4 = PyObject_GetAttr(__pyx_v_self->io, __pyx_n_s__tell); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 134; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __pyx_t_3 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 134; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  __pyx_t_5 = __Pyx_PyInt_AsInt(__pyx_t_3); if (unlikely((__pyx_t_5 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 134; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __pyx_v_self->offset = __pyx_t_5;
+
+  /* "bx/arrays/array_tree.pyx":136
+ *         self.offset = self.io.tell()
+ *         # Read basic info about the tree
+ *         self.max = self.io.read_uint32()             # <<<<<<<<<<<<<<
+ *         self.block_size = self.io.read_uint32()
+ *         # Read dtype and canonicalize
+ */
+  __pyx_t_3 = PyObject_GetAttr(__pyx_v_self->io, __pyx_n_s__read_uint32); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_4 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __pyx_t_5 = __Pyx_PyInt_AsInt(__pyx_t_4); if (unlikely((__pyx_t_5 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  __pyx_v_self->max = __pyx_t_5;
+
+  /* "bx/arrays/array_tree.pyx":137
+ *         # Read basic info about the tree
+ *         self.max = self.io.read_uint32()
+ *         self.block_size = self.io.read_uint32()             # <<<<<<<<<<<<<<
+ *         # Read dtype and canonicalize
+ *         dt = self.io.read( 1 )
+ */
+  __pyx_t_4 = PyObject_GetAttr(__pyx_v_self->io, __pyx_n_s__read_uint32); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 137; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __pyx_t_3 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 137; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  __pyx_t_5 = __Pyx_PyInt_AsInt(__pyx_t_3); if (unlikely((__pyx_t_5 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 137; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __pyx_v_self->block_size = __pyx_t_5;
+
+  /* "bx/arrays/array_tree.pyx":139
+ *         self.block_size = self.io.read_uint32()
+ *         # Read dtype and canonicalize
+ *         dt = self.io.read( 1 )             # <<<<<<<<<<<<<<
+ *         self.dtype = numpy.dtype( dt )
+ *         self.io.skip( 3 )
+ */
+  __pyx_t_3 = PyObject_GetAttr(__pyx_v_self->io, __pyx_n_s__read); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 139; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_4 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_k_tuple_6), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 139; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __pyx_v_dt = __pyx_t_4;
+  __pyx_t_4 = 0;
+
+  /* "bx/arrays/array_tree.pyx":140
+ *         # Read dtype and canonicalize
+ *         dt = self.io.read( 1 )
+ *         self.dtype = numpy.dtype( dt )             # <<<<<<<<<<<<<<
+ *         self.io.skip( 3 )
+ *         # How many levels are needed to cover the entire range?
+ */
+  __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 140; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __Pyx_INCREF(__pyx_v_dt);
+  PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_v_dt);
+  __Pyx_GIVEREF(__pyx_v_dt);
+  __pyx_t_3 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_5numpy_dtype)), ((PyObject *)__pyx_t_4), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 140; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
+  __Pyx_GIVEREF(__pyx_t_3);
+  __Pyx_GOTREF(__pyx_v_self->dtype);
+  __Pyx_DECREF(__pyx_v_self->dtype);
+  __pyx_v_self->dtype = __pyx_t_3;
+  __pyx_t_3 = 0;
+
+  /* "bx/arrays/array_tree.pyx":141
+ *         dt = self.io.read( 1 )
+ *         self.dtype = numpy.dtype( dt )
+ *         self.io.skip( 3 )             # <<<<<<<<<<<<<<
+ *         # How many levels are needed to cover the entire range?
+ *         self.levels = 0
+ */
+  __pyx_t_3 = PyObject_GetAttr(__pyx_v_self->io, __pyx_n_s__skip); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_4 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_k_tuple_7), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+
+  /* "bx/arrays/array_tree.pyx":143
+ *         self.io.skip( 3 )
+ *         # How many levels are needed to cover the entire range?
+ *         self.levels = 0             # <<<<<<<<<<<<<<
+ *         while ( <long long> self.block_size ) ** ( self.levels + 1 ) < self.max:
+ *             self.levels += 1
+ */
+  __pyx_v_self->levels = 0;
+
+  /* "bx/arrays/array_tree.pyx":144
+ *         # How many levels are needed to cover the entire range?
+ *         self.levels = 0
+ *         while ( <long long> self.block_size ) ** ( self.levels + 1 ) < self.max:             # <<<<<<<<<<<<<<
+ *             self.levels += 1
+ *         # Not yet dealing with the case where the root is a Leaf
+ */
+  while (1) {
+    __pyx_t_6 = (__Pyx_pow_PY_LONG_LONG(((PY_LONG_LONG)__pyx_v_self->block_size), ((PY_LONG_LONG)(__pyx_v_self->levels + 1))) < __pyx_v_self->max);
+    if (!__pyx_t_6) break;
+
+    /* "bx/arrays/array_tree.pyx":145
+ *         self.levels = 0
+ *         while ( <long long> self.block_size ) ** ( self.levels + 1 ) < self.max:
+ *             self.levels += 1             # <<<<<<<<<<<<<<
+ *         # Not yet dealing with the case where the root is a Leaf
+ *         assert self.levels > 0, "max < block_size not yet handled"
+ */
+    __pyx_v_self->levels = (__pyx_v_self->levels + 1);
+  }
+
+  /* "bx/arrays/array_tree.pyx":147
+ *             self.levels += 1
+ *         # Not yet dealing with the case where the root is a Leaf
+ *         assert self.levels > 0, "max < block_size not yet handled"             # <<<<<<<<<<<<<<
+ *         # Save offset of root
+ *         self.root_offset = self.io.tell()
+ */
+  #ifndef CYTHON_WITHOUT_ASSERTIONS
+  if (unlikely(!(__pyx_v_self->levels > 0))) {
+    PyErr_SetObject(PyExc_AssertionError, ((PyObject *)__pyx_kp_s_8));
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  #endif
+
+  /* "bx/arrays/array_tree.pyx":149
+ *         assert self.levels > 0, "max < block_size not yet handled"
+ *         # Save offset of root
+ *         self.root_offset = self.io.tell()             # <<<<<<<<<<<<<<
+ * 
+ *     def __getitem__( self, index ):
+ */
+  __pyx_t_4 = PyObject_GetAttr(__pyx_v_self->io, __pyx_n_s__tell); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 149; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __pyx_t_3 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 149; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  __pyx_t_5 = __Pyx_PyInt_AsInt(__pyx_t_3); if (unlikely((__pyx_t_5 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 149; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __pyx_v_self->root_offset = __pyx_t_5;
+
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_AddTraceback("bx.arrays.array_tree.FileArrayTree.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = -1;
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_dt);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_13FileArrayTree_3__getitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_index); /*proto*/
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_13FileArrayTree_3__getitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_index) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__getitem__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_6arrays_10array_tree_13FileArrayTree_2__getitem__(((struct __pyx_obj_2bx_6arrays_10array_tree_FileArrayTree *)__pyx_v_self), ((PyObject *)__pyx_v_index));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/arrays/array_tree.pyx":151
+ *         self.root_offset = self.io.tell()
+ * 
+ *     def __getitem__( self, index ):             # <<<<<<<<<<<<<<
+ *         min = self.r_seek_to_node( index, 0, self.root_offset, self.levels, 0 )
+ *         if min < 0:
+ */
+
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_13FileArrayTree_2__getitem__(struct __pyx_obj_2bx_6arrays_10array_tree_FileArrayTree *__pyx_v_self, PyObject *__pyx_v_index) {
+  PyObject *__pyx_v_min = NULL;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
+  int __pyx_t_3;
+  PyObject *__pyx_t_4 = NULL;
+  PyObject *__pyx_t_5 = NULL;
+  PyObject *__pyx_t_6 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__getitem__", 0);
+
+  /* "bx/arrays/array_tree.pyx":152
+ * 
+ *     def __getitem__( self, index ):
+ *         min = self.r_seek_to_node( index, 0, self.root_offset, self.levels, 0 )             # <<<<<<<<<<<<<<
+ *         if min < 0:
+ *             return nan
+ */
+  __pyx_t_1 = __Pyx_PyInt_AsInt(__pyx_v_index); if (unlikely((__pyx_t_1 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 152; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyInt_FromLong(((struct __pyx_vtabstruct_2bx_6arrays_10array_tree_FileArrayTree *)__pyx_v_self->__pyx_vtab)->r_seek_to_node(__pyx_v_self, __pyx_t_1, 0, __pyx_v_self->root_offset, __pyx_v_self->levels, 0)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 152; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_v_min = __pyx_t_2;
+  __pyx_t_2 = 0;
+
+  /* "bx/arrays/array_tree.pyx":153
+ *     def __getitem__( self, index ):
+ *         min = self.r_seek_to_node( index, 0, self.root_offset, self.levels, 0 )
+ *         if min < 0:             # <<<<<<<<<<<<<<
+ *             return nan
+ *         self.io.skip( self.dtype.itemsize * ( index - min ) )
+ */
+  __pyx_t_2 = PyObject_RichCompare(__pyx_v_min, __pyx_int_0, Py_LT); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 153; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 153; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  if (__pyx_t_3) {
+
+    /* "bx/arrays/array_tree.pyx":154
+ *         min = self.r_seek_to_node( index, 0, self.root_offset, self.levels, 0 )
+ *         if min < 0:
+ *             return nan             # <<<<<<<<<<<<<<
+ *         self.io.skip( self.dtype.itemsize * ( index - min ) )
+ *         return self.io.read_raw_array( self.dtype, 1 )[0]
+ */
+    __Pyx_XDECREF(__pyx_r);
+    __pyx_t_2 = __Pyx_GetName(__pyx_m, __pyx_n_s__nan); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 154; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_r = __pyx_t_2;
+    __pyx_t_2 = 0;
+    goto __pyx_L0;
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  /* "bx/arrays/array_tree.pyx":155
+ *         if min < 0:
+ *             return nan
+ *         self.io.skip( self.dtype.itemsize * ( index - min ) )             # <<<<<<<<<<<<<<
+ *         return self.io.read_raw_array( self.dtype, 1 )[0]
+ * 
+ */
+  __pyx_t_2 = PyObject_GetAttr(__pyx_v_self->io, __pyx_n_s__skip); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 155; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_4 = PyObject_GetAttr(__pyx_v_self->dtype, __pyx_n_s__itemsize); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 155; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __pyx_t_5 = PyNumber_Subtract(__pyx_v_index, __pyx_v_min); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 155; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __pyx_t_6 = PyNumber_Multiply(__pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 155; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_6);
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+  __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 155; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_6);
+  __Pyx_GIVEREF(__pyx_t_6);
+  __pyx_t_6 = 0;
+  __pyx_t_6 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_5), NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 155; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_6);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_5)); __pyx_t_5 = 0;
+  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+
+  /* "bx/arrays/array_tree.pyx":156
+ *             return nan
+ *         self.io.skip( self.dtype.itemsize * ( index - min ) )
+ *         return self.io.read_raw_array( self.dtype, 1 )[0]             # <<<<<<<<<<<<<<
+ * 
+ *     def get_summary( self, index, level ):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_6 = PyObject_GetAttr(__pyx_v_self->io, __pyx_n_s__read_raw_array); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_6);
+  __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __Pyx_INCREF(__pyx_v_self->dtype);
+  PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_v_self->dtype);
+  __Pyx_GIVEREF(__pyx_v_self->dtype);
+  __Pyx_INCREF(__pyx_int_1);
+  PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_int_1);
+  __Pyx_GIVEREF(__pyx_int_1);
+  __pyx_t_2 = PyObject_Call(__pyx_t_6, ((PyObject *)__pyx_t_5), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_5)); __pyx_t_5 = 0;
+  __pyx_t_5 = __Pyx_GetItemInt(__pyx_t_2, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_r = __pyx_t_5;
+  __pyx_t_5 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_XDECREF(__pyx_t_5);
+  __Pyx_XDECREF(__pyx_t_6);
+  __Pyx_AddTraceback("bx.arrays.array_tree.FileArrayTree.__getitem__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_min);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_13FileArrayTree_5get_summary(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_13FileArrayTree_5get_summary(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_index = 0;
+  PyObject *__pyx_v_level = 0;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("get_summary (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__index,&__pyx_n_s__level,0};
+    PyObject* values[2] = {0,0};
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__index)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__level)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("get_summary", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 158; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "get_summary") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 158; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
+      goto __pyx_L5_argtuple_error;
+    } else {
+      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+    }
+    __pyx_v_index = values[0];
+    __pyx_v_level = values[1];
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("get_summary", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 158; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.arrays.array_tree.FileArrayTree.get_summary", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_6arrays_10array_tree_13FileArrayTree_4get_summary(((struct __pyx_obj_2bx_6arrays_10array_tree_FileArrayTree *)__pyx_v_self), __pyx_v_index, __pyx_v_level);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/arrays/array_tree.pyx":158
+ *         return self.io.read_raw_array( self.dtype, 1 )[0]
+ * 
+ *     def get_summary( self, index, level ):             # <<<<<<<<<<<<<<
+ *         if level <= 0 or level > self.levels:
+ *             raise ValueError, "level must be <= self.levels"
+ */
+
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_13FileArrayTree_4get_summary(struct __pyx_obj_2bx_6arrays_10array_tree_FileArrayTree *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_level) {
+  struct __pyx_obj_2bx_6arrays_10array_tree_Summary *__pyx_v_s = NULL;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_t_2;
+  PyObject *__pyx_t_3 = NULL;
+  int __pyx_t_4;
+  int __pyx_t_5;
+  int __pyx_t_6;
+  int __pyx_t_7;
+  PyObject *__pyx_t_8 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("get_summary", 0);
+
+  /* "bx/arrays/array_tree.pyx":159
+ * 
+ *     def get_summary( self, index, level ):
+ *         if level <= 0 or level > self.levels:             # <<<<<<<<<<<<<<
+ *             raise ValueError, "level must be <= self.levels"
+ *         if self.r_seek_to_node( index, 0, self.root_offset, self.levels, level ) < 0:
+ */
+  __pyx_t_1 = PyObject_RichCompare(__pyx_v_level, __pyx_int_0, Py_LE); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 159; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 159; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  if (!__pyx_t_2) {
+    __pyx_t_1 = PyInt_FromLong(__pyx_v_self->levels); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 159; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __pyx_t_3 = PyObject_RichCompare(__pyx_v_level, __pyx_t_1, Py_GT); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 159; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 159; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __pyx_t_5 = __pyx_t_4;
+  } else {
+    __pyx_t_5 = __pyx_t_2;
+  }
+  if (__pyx_t_5) {
+
+    /* "bx/arrays/array_tree.pyx":160
+ *     def get_summary( self, index, level ):
+ *         if level <= 0 or level > self.levels:
+ *             raise ValueError, "level must be <= self.levels"             # <<<<<<<<<<<<<<
+ *         if self.r_seek_to_node( index, 0, self.root_offset, self.levels, level ) < 0:
+ *             return None
+ */
+    __Pyx_Raise(__pyx_builtin_ValueError, ((PyObject *)__pyx_kp_s_9), 0, 0);
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 160; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  /* "bx/arrays/array_tree.pyx":161
+ *         if level <= 0 or level > self.levels:
+ *             raise ValueError, "level must be <= self.levels"
+ *         if self.r_seek_to_node( index, 0, self.root_offset, self.levels, level ) < 0:             # <<<<<<<<<<<<<<
+ *             return None
+ *         # Read summary arrays
+ */
+  __pyx_t_6 = __Pyx_PyInt_AsInt(__pyx_v_index); if (unlikely((__pyx_t_6 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 161; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_7 = __Pyx_PyInt_AsInt(__pyx_v_level); if (unlikely((__pyx_t_7 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 161; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_5 = (((struct __pyx_vtabstruct_2bx_6arrays_10array_tree_FileArrayTree *)__pyx_v_self->__pyx_vtab)->r_seek_to_node(__pyx_v_self, __pyx_t_6, 0, __pyx_v_self->root_offset, __pyx_v_self->levels, __pyx_t_7) < 0);
+  if (__pyx_t_5) {
+
+    /* "bx/arrays/array_tree.pyx":162
+ *             raise ValueError, "level must be <= self.levels"
+ *         if self.r_seek_to_node( index, 0, self.root_offset, self.levels, level ) < 0:
+ *             return None             # <<<<<<<<<<<<<<
+ *         # Read summary arrays
+ *         s = Summary()
+ */
+    __Pyx_XDECREF(__pyx_r);
+    __Pyx_INCREF(Py_None);
+    __pyx_r = Py_None;
+    goto __pyx_L0;
+    goto __pyx_L4;
+  }
+  __pyx_L4:;
+
+  /* "bx/arrays/array_tree.pyx":164
+ *             return None
+ *         # Read summary arrays
+ *         s = Summary()             # <<<<<<<<<<<<<<
+ *         s.counts = self.io.read_raw_array( self.dtype, self.block_size )
+ *         s.frequencies = self.io.read_raw_array( self.dtype, self.block_size )
+ */
+  __pyx_t_3 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_2bx_6arrays_10array_tree_Summary)), ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 164; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_v_s = ((struct __pyx_obj_2bx_6arrays_10array_tree_Summary *)__pyx_t_3);
+  __pyx_t_3 = 0;
+
+  /* "bx/arrays/array_tree.pyx":165
+ *         # Read summary arrays
+ *         s = Summary()
+ *         s.counts = self.io.read_raw_array( self.dtype, self.block_size )             # <<<<<<<<<<<<<<
+ *         s.frequencies = self.io.read_raw_array( self.dtype, self.block_size )
+ *         s.sums = self.io.read_raw_array( self.dtype, self.block_size )
+ */
+  __pyx_t_3 = PyObject_GetAttr(__pyx_v_self->io, __pyx_n_s__read_raw_array); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 165; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_1 = PyInt_FromLong(__pyx_v_self->block_size); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 165; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_8 = PyTuple_New(2); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 165; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_8);
+  __Pyx_INCREF(__pyx_v_self->dtype);
+  PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_v_self->dtype);
+  __Pyx_GIVEREF(__pyx_v_self->dtype);
+  PyTuple_SET_ITEM(__pyx_t_8, 1, __pyx_t_1);
+  __Pyx_GIVEREF(__pyx_t_1);
+  __pyx_t_1 = 0;
+  __pyx_t_1 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_t_8), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 165; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_8)); __pyx_t_8 = 0;
+  __Pyx_GIVEREF(__pyx_t_1);
+  __Pyx_GOTREF(__pyx_v_s->counts);
+  __Pyx_DECREF(__pyx_v_s->counts);
+  __pyx_v_s->counts = __pyx_t_1;
+  __pyx_t_1 = 0;
+
+  /* "bx/arrays/array_tree.pyx":166
+ *         s = Summary()
+ *         s.counts = self.io.read_raw_array( self.dtype, self.block_size )
+ *         s.frequencies = self.io.read_raw_array( self.dtype, self.block_size )             # <<<<<<<<<<<<<<
+ *         s.sums = self.io.read_raw_array( self.dtype, self.block_size )
+ *         s.mins = self.io.read_raw_array( self.dtype, self.block_size)
+ */
+  __pyx_t_1 = PyObject_GetAttr(__pyx_v_self->io, __pyx_n_s__read_raw_array); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 166; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_8 = PyInt_FromLong(__pyx_v_self->block_size); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 166; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_8);
+  __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 166; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_INCREF(__pyx_v_self->dtype);
+  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_self->dtype);
+  __Pyx_GIVEREF(__pyx_v_self->dtype);
+  PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_8);
+  __Pyx_GIVEREF(__pyx_t_8);
+  __pyx_t_8 = 0;
+  __pyx_t_8 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 166; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_8);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
+  __Pyx_GIVEREF(__pyx_t_8);
+  __Pyx_GOTREF(__pyx_v_s->frequencies);
+  __Pyx_DECREF(__pyx_v_s->frequencies);
+  __pyx_v_s->frequencies = __pyx_t_8;
+  __pyx_t_8 = 0;
+
+  /* "bx/arrays/array_tree.pyx":167
+ *         s.counts = self.io.read_raw_array( self.dtype, self.block_size )
+ *         s.frequencies = self.io.read_raw_array( self.dtype, self.block_size )
+ *         s.sums = self.io.read_raw_array( self.dtype, self.block_size )             # <<<<<<<<<<<<<<
+ *         s.mins = self.io.read_raw_array( self.dtype, self.block_size)
+ *         s.maxs = self.io.read_raw_array( self.dtype, self.block_size )
+ */
+  __pyx_t_8 = PyObject_GetAttr(__pyx_v_self->io, __pyx_n_s__read_raw_array); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 167; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_8);
+  __pyx_t_3 = PyInt_FromLong(__pyx_v_self->block_size); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 167; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 167; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_INCREF(__pyx_v_self->dtype);
+  PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_self->dtype);
+  __Pyx_GIVEREF(__pyx_v_self->dtype);
+  PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_t_3);
+  __Pyx_GIVEREF(__pyx_t_3);
+  __pyx_t_3 = 0;
+  __pyx_t_3 = PyObject_Call(__pyx_t_8, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 167; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+  __Pyx_GIVEREF(__pyx_t_3);
+  __Pyx_GOTREF(__pyx_v_s->sums);
+  __Pyx_DECREF(__pyx_v_s->sums);
+  __pyx_v_s->sums = __pyx_t_3;
+  __pyx_t_3 = 0;
+
+  /* "bx/arrays/array_tree.pyx":168
+ *         s.frequencies = self.io.read_raw_array( self.dtype, self.block_size )
+ *         s.sums = self.io.read_raw_array( self.dtype, self.block_size )
+ *         s.mins = self.io.read_raw_array( self.dtype, self.block_size)             # <<<<<<<<<<<<<<
+ *         s.maxs = self.io.read_raw_array( self.dtype, self.block_size )
+ *         s.sumsquares = self.io.read_raw_array( self.dtype, self.block_size )
+ */
+  __pyx_t_3 = PyObject_GetAttr(__pyx_v_self->io, __pyx_n_s__read_raw_array); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 168; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_1 = PyInt_FromLong(__pyx_v_self->block_size); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 168; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_8 = PyTuple_New(2); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 168; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_8);
+  __Pyx_INCREF(__pyx_v_self->dtype);
+  PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_v_self->dtype);
+  __Pyx_GIVEREF(__pyx_v_self->dtype);
+  PyTuple_SET_ITEM(__pyx_t_8, 1, __pyx_t_1);
+  __Pyx_GIVEREF(__pyx_t_1);
+  __pyx_t_1 = 0;
+  __pyx_t_1 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_t_8), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 168; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_8)); __pyx_t_8 = 0;
+  __Pyx_GIVEREF(__pyx_t_1);
+  __Pyx_GOTREF(__pyx_v_s->mins);
+  __Pyx_DECREF(__pyx_v_s->mins);
+  __pyx_v_s->mins = __pyx_t_1;
+  __pyx_t_1 = 0;
+
+  /* "bx/arrays/array_tree.pyx":169
+ *         s.sums = self.io.read_raw_array( self.dtype, self.block_size )
+ *         s.mins = self.io.read_raw_array( self.dtype, self.block_size)
+ *         s.maxs = self.io.read_raw_array( self.dtype, self.block_size )             # <<<<<<<<<<<<<<
+ *         s.sumsquares = self.io.read_raw_array( self.dtype, self.block_size )
+ *         return s
+ */
+  __pyx_t_1 = PyObject_GetAttr(__pyx_v_self->io, __pyx_n_s__read_raw_array); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_8 = PyInt_FromLong(__pyx_v_self->block_size); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_8);
+  __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_INCREF(__pyx_v_self->dtype);
+  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_self->dtype);
+  __Pyx_GIVEREF(__pyx_v_self->dtype);
+  PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_8);
+  __Pyx_GIVEREF(__pyx_t_8);
+  __pyx_t_8 = 0;
+  __pyx_t_8 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_8);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
+  __Pyx_GIVEREF(__pyx_t_8);
+  __Pyx_GOTREF(__pyx_v_s->maxs);
+  __Pyx_DECREF(__pyx_v_s->maxs);
+  __pyx_v_s->maxs = __pyx_t_8;
+  __pyx_t_8 = 0;
+
+  /* "bx/arrays/array_tree.pyx":170
+ *         s.mins = self.io.read_raw_array( self.dtype, self.block_size)
+ *         s.maxs = self.io.read_raw_array( self.dtype, self.block_size )
+ *         s.sumsquares = self.io.read_raw_array( self.dtype, self.block_size )             # <<<<<<<<<<<<<<
+ *         return s
+ * 
+ */
+  __pyx_t_8 = PyObject_GetAttr(__pyx_v_self->io, __pyx_n_s__read_raw_array); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 170; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_8);
+  __pyx_t_3 = PyInt_FromLong(__pyx_v_self->block_size); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 170; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 170; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_INCREF(__pyx_v_self->dtype);
+  PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_self->dtype);
+  __Pyx_GIVEREF(__pyx_v_self->dtype);
+  PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_t_3);
+  __Pyx_GIVEREF(__pyx_t_3);
+  __pyx_t_3 = 0;
+  __pyx_t_3 = PyObject_Call(__pyx_t_8, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 170; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+  __Pyx_GIVEREF(__pyx_t_3);
+  __Pyx_GOTREF(__pyx_v_s->sumsquares);
+  __Pyx_DECREF(__pyx_v_s->sumsquares);
+  __pyx_v_s->sumsquares = __pyx_t_3;
+  __pyx_t_3 = 0;
+
+  /* "bx/arrays/array_tree.pyx":171
+ *         s.maxs = self.io.read_raw_array( self.dtype, self.block_size )
+ *         s.sumsquares = self.io.read_raw_array( self.dtype, self.block_size )
+ *         return s             # <<<<<<<<<<<<<<
+ * 
+ *     def get_leaf( self, index ):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __Pyx_INCREF(((PyObject *)__pyx_v_s));
+  __pyx_r = ((PyObject *)__pyx_v_s);
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_8);
+  __Pyx_AddTraceback("bx.arrays.array_tree.FileArrayTree.get_summary", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XDECREF((PyObject *)__pyx_v_s);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_13FileArrayTree_7get_leaf(PyObject *__pyx_v_self, PyObject *__pyx_v_index); /*proto*/
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_13FileArrayTree_7get_leaf(PyObject *__pyx_v_self, PyObject *__pyx_v_index) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("get_leaf (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_6arrays_10array_tree_13FileArrayTree_6get_leaf(((struct __pyx_obj_2bx_6arrays_10array_tree_FileArrayTree *)__pyx_v_self), ((PyObject *)__pyx_v_index));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/arrays/array_tree.pyx":173
+ *         return s
+ * 
+ *     def get_leaf( self, index ):             # <<<<<<<<<<<<<<
+ *         if self.r_seek_to_node( index, 0, self.root_offset, self.levels, 0 ) < 0:
+ *             return []
+ */
+
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_13FileArrayTree_6get_leaf(struct __pyx_obj_2bx_6arrays_10array_tree_FileArrayTree *__pyx_v_self, PyObject *__pyx_v_index) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  int __pyx_t_2;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  PyObject *__pyx_t_5 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("get_leaf", 0);
+
+  /* "bx/arrays/array_tree.pyx":174
+ * 
+ *     def get_leaf( self, index ):
+ *         if self.r_seek_to_node( index, 0, self.root_offset, self.levels, 0 ) < 0:             # <<<<<<<<<<<<<<
+ *             return []
+ *         return self.io.read_raw_array( self.dtype, self.block_size )
+ */
+  __pyx_t_1 = __Pyx_PyInt_AsInt(__pyx_v_index); if (unlikely((__pyx_t_1 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = (((struct __pyx_vtabstruct_2bx_6arrays_10array_tree_FileArrayTree *)__pyx_v_self->__pyx_vtab)->r_seek_to_node(__pyx_v_self, __pyx_t_1, 0, __pyx_v_self->root_offset, __pyx_v_self->levels, 0) < 0);
+  if (__pyx_t_2) {
+
+    /* "bx/arrays/array_tree.pyx":175
+ *     def get_leaf( self, index ):
+ *         if self.r_seek_to_node( index, 0, self.root_offset, self.levels, 0 ) < 0:
+ *             return []             # <<<<<<<<<<<<<<
+ *         return self.io.read_raw_array( self.dtype, self.block_size )
+ * 
+ */
+    __Pyx_XDECREF(__pyx_r);
+    __pyx_t_3 = PyList_New(0); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 175; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __pyx_r = ((PyObject *)__pyx_t_3);
+    __pyx_t_3 = 0;
+    goto __pyx_L0;
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  /* "bx/arrays/array_tree.pyx":176
+ *         if self.r_seek_to_node( index, 0, self.root_offset, self.levels, 0 ) < 0:
+ *             return []
+ *         return self.io.read_raw_array( self.dtype, self.block_size )             # <<<<<<<<<<<<<<
+ * 
+ *     cdef int r_seek_to_node( self, int index, int min, long long offset, int level, int desired_level ):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_3 = PyObject_GetAttr(__pyx_v_self->io, __pyx_n_s__read_raw_array); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_4 = PyInt_FromLong(__pyx_v_self->block_size); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __Pyx_INCREF(__pyx_v_self->dtype);
+  PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_v_self->dtype);
+  __Pyx_GIVEREF(__pyx_v_self->dtype);
+  PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_t_4);
+  __Pyx_GIVEREF(__pyx_t_4);
+  __pyx_t_4 = 0;
+  __pyx_t_4 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_t_5), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_5)); __pyx_t_5 = 0;
+  __pyx_r = __pyx_t_4;
+  __pyx_t_4 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_XDECREF(__pyx_t_5);
+  __Pyx_AddTraceback("bx.arrays.array_tree.FileArrayTree.get_leaf", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/arrays/array_tree.pyx":178
+ *         return self.io.read_raw_array( self.dtype, self.block_size )
+ * 
+ *     cdef int r_seek_to_node( self, int index, int min, long long offset, int level, int desired_level ):             # <<<<<<<<<<<<<<
+ *         """
+ *         Seek to the start of the node at `desired_level` that contains `index`.
+ */
+
+static int __pyx_f_2bx_6arrays_10array_tree_13FileArrayTree_r_seek_to_node(struct __pyx_obj_2bx_6arrays_10array_tree_FileArrayTree *__pyx_v_self, int __pyx_v_index, int __pyx_v_min, PY_LONG_LONG __pyx_v_offset, int __pyx_v_level, int __pyx_v_desired_level) {
+  int __pyx_v_child_size;
+  int __pyx_v_bin_index;
+  int __pyx_v_child_min;
+  PyObject *__pyx_v_child_offset = NULL;
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  int __pyx_t_4;
+  int __pyx_t_5;
+  PyObject *__pyx_t_6 = NULL;
+  PY_LONG_LONG __pyx_t_7;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("r_seek_to_node", 0);
+
+  /* "bx/arrays/array_tree.pyx":184
+ *         """
+ *         cdef int child_size, bin_index, child_min
+ *         self.io.seek( offset )             # <<<<<<<<<<<<<<
+ *         if level > desired_level:
+ *             child_size = self.block_size ** level
+ */
+  __pyx_t_1 = PyObject_GetAttr(__pyx_v_self->io, __pyx_n_s__seek); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 184; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = PyLong_FromLongLong(__pyx_v_offset); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 184; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 184; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_2);
+  __Pyx_GIVEREF(__pyx_t_2);
+  __pyx_t_2 = 0;
+  __pyx_t_2 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 184; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+  /* "bx/arrays/array_tree.pyx":185
+ *         cdef int child_size, bin_index, child_min
+ *         self.io.seek( offset )
+ *         if level > desired_level:             # <<<<<<<<<<<<<<
+ *             child_size = self.block_size ** level
+ *             bin_index = ( index - min ) // ( child_size )
+ */
+  __pyx_t_4 = (__pyx_v_level > __pyx_v_desired_level);
+  if (__pyx_t_4) {
+
+    /* "bx/arrays/array_tree.pyx":186
+ *         self.io.seek( offset )
+ *         if level > desired_level:
+ *             child_size = self.block_size ** level             # <<<<<<<<<<<<<<
+ *             bin_index = ( index - min ) // ( child_size )
+ *             child_min = min + ( bin_index * child_size )
+ */
+    __pyx_v_child_size = __Pyx_pow_int(__pyx_v_self->block_size, __pyx_v_level);
+
+    /* "bx/arrays/array_tree.pyx":187
+ *         if level > desired_level:
+ *             child_size = self.block_size ** level
+ *             bin_index = ( index - min ) // ( child_size )             # <<<<<<<<<<<<<<
+ *             child_min = min + ( bin_index * child_size )
+ *             # Skip summary arrays -- # arrays * itemsize * block_size
+ */
+    __pyx_t_5 = (__pyx_v_index - __pyx_v_min);
+    if (unlikely(__pyx_v_child_size == 0)) {
+      PyErr_Format(PyExc_ZeroDivisionError, "integer division or modulo by zero");
+      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+    else if (sizeof(int) == sizeof(long) && unlikely(__pyx_v_child_size == -1) && unlikely(UNARY_NEG_WOULD_OVERFLOW(__pyx_t_5))) {
+      PyErr_Format(PyExc_OverflowError, "value too large to perform division");
+      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+    __pyx_v_bin_index = __Pyx_div_int(__pyx_t_5, __pyx_v_child_size);
+
+    /* "bx/arrays/array_tree.pyx":188
+ *             child_size = self.block_size ** level
+ *             bin_index = ( index - min ) // ( child_size )
+ *             child_min = min + ( bin_index * child_size )             # <<<<<<<<<<<<<<
+ *             # Skip summary arrays -- # arrays * itemsize * block_size
+ *             self.io.skip( NUM_SUMMARY_ARRAYS * self.dtype.itemsize * self.block_size )
+ */
+    __pyx_v_child_min = (__pyx_v_min + (__pyx_v_bin_index * __pyx_v_child_size));
+
+    /* "bx/arrays/array_tree.pyx":190
+ *             child_min = min + ( bin_index * child_size )
+ *             # Skip summary arrays -- # arrays * itemsize * block_size
+ *             self.io.skip( NUM_SUMMARY_ARRAYS * self.dtype.itemsize * self.block_size )             # <<<<<<<<<<<<<<
+ *             # Skip to offset of correct child -- offsets are 8 bytes
+ *             self.io.skip( 8 * bin_index )
+ */
+    __pyx_t_2 = PyObject_GetAttr(__pyx_v_self->io, __pyx_n_s__skip); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 190; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_t_3 = __Pyx_GetName(__pyx_m, __pyx_n_s__NUM_SUMMARY_ARRAYS); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 190; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __pyx_t_1 = PyObject_GetAttr(__pyx_v_self->dtype, __pyx_n_s__itemsize); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 190; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __pyx_t_6 = PyNumber_Multiply(__pyx_t_3, __pyx_t_1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 190; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_6);
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    __pyx_t_1 = PyInt_FromLong(__pyx_v_self->block_size); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 190; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __pyx_t_3 = PyNumber_Multiply(__pyx_t_6, __pyx_t_1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 190; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 190; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_3);
+    __Pyx_GIVEREF(__pyx_t_3);
+    __pyx_t_3 = 0;
+    __pyx_t_3 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 190; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+    /* "bx/arrays/array_tree.pyx":192
+ *             self.io.skip( NUM_SUMMARY_ARRAYS * self.dtype.itemsize * self.block_size )
+ *             # Skip to offset of correct child -- offsets are 8 bytes
+ *             self.io.skip( 8 * bin_index )             # <<<<<<<<<<<<<<
+ *             # Read offset of child
+ *             child_offset = self.io.read_uint64()
+ */
+    __pyx_t_3 = PyObject_GetAttr(__pyx_v_self->io, __pyx_n_s__skip); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 192; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __pyx_t_1 = PyInt_FromLong((8 * __pyx_v_bin_index)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 192; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 192; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
+    __Pyx_GIVEREF(__pyx_t_1);
+    __pyx_t_1 = 0;
+    __pyx_t_1 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 192; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+    /* "bx/arrays/array_tree.pyx":194
+ *             self.io.skip( 8 * bin_index )
+ *             # Read offset of child
+ *             child_offset = self.io.read_uint64()             # <<<<<<<<<<<<<<
+ *             # print "co: %s\tbi: %s\tcm: %s\n" % (child_offset, bin_index, child_min)
+ *             if child_offset == 0:
+ */
+    __pyx_t_1 = PyObject_GetAttr(__pyx_v_self->io, __pyx_n_s__read_uint64); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 194; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __pyx_t_2 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 194; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    __pyx_v_child_offset = __pyx_t_2;
+    __pyx_t_2 = 0;
+
+    /* "bx/arrays/array_tree.pyx":196
+ *             child_offset = self.io.read_uint64()
+ *             # print "co: %s\tbi: %s\tcm: %s\n" % (child_offset, bin_index, child_min)
+ *             if child_offset == 0:             # <<<<<<<<<<<<<<
+ *                 return -1
+ *             return self.r_seek_to_node( index, child_min, child_offset, level - 1, desired_level )
+ */
+    __pyx_t_2 = PyObject_RichCompare(__pyx_v_child_offset, __pyx_int_0, Py_EQ); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 196; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 196; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    if (__pyx_t_4) {
+
+      /* "bx/arrays/array_tree.pyx":197
+ *             # print "co: %s\tbi: %s\tcm: %s\n" % (child_offset, bin_index, child_min)
+ *             if child_offset == 0:
+ *                 return -1             # <<<<<<<<<<<<<<
+ *             return self.r_seek_to_node( index, child_min, child_offset, level - 1, desired_level )
+ *         else:
+ */
+      __pyx_r = -1;
+      goto __pyx_L0;
+      goto __pyx_L4;
+    }
+    __pyx_L4:;
+
+    /* "bx/arrays/array_tree.pyx":198
+ *             if child_offset == 0:
+ *                 return -1
+ *             return self.r_seek_to_node( index, child_min, child_offset, level - 1, desired_level )             # <<<<<<<<<<<<<<
+ *         else:
+ *             # The file pointer is at the start of the desired node, do nothing
+ */
+    __pyx_t_7 = __Pyx_PyInt_AsLongLong(__pyx_v_child_offset); if (unlikely((__pyx_t_7 == (PY_LONG_LONG)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 198; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_r = ((struct __pyx_vtabstruct_2bx_6arrays_10array_tree_FileArrayTree *)__pyx_v_self->__pyx_vtab)->r_seek_to_node(__pyx_v_self, __pyx_v_index, __pyx_v_child_min, __pyx_t_7, (__pyx_v_level - 1), __pyx_v_desired_level);
+    goto __pyx_L0;
+    goto __pyx_L3;
+  }
+  /*else*/ {
+
+    /* "bx/arrays/array_tree.pyx":201
+ *         else:
+ *             # The file pointer is at the start of the desired node, do nothing
+ *             return min             # <<<<<<<<<<<<<<
+ * 
+ * cdef class Summary:
+ */
+    __pyx_r = __pyx_v_min;
+    goto __pyx_L0;
+  }
+  __pyx_L3:;
+
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_6);
+  __Pyx_WriteUnraisable("bx.arrays.array_tree.FileArrayTree.r_seek_to_node", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_child_offset);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_13FileArrayTree_3max_1__get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_13FileArrayTree_3max_1__get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_6arrays_10array_tree_13FileArrayTree_3max___get__(((struct __pyx_obj_2bx_6arrays_10array_tree_FileArrayTree *)__pyx_v_self));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/arrays/array_tree.pyx":124
+ *     Wrapper for ArrayTree stored in file that reads as little as possible
+ *     """
+ *     cdef public int max             # <<<<<<<<<<<<<<
+ *     cdef public int block_size
+ *     cdef public object dtype
+ */
+
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_13FileArrayTree_3max___get__(struct __pyx_obj_2bx_6arrays_10array_tree_FileArrayTree *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__get__", 0);
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = PyInt_FromLong(__pyx_v_self->max); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 124; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("bx.arrays.array_tree.FileArrayTree.max.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_2bx_6arrays_10array_tree_13FileArrayTree_3max_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value); /*proto*/
+static int __pyx_pw_2bx_6arrays_10array_tree_13FileArrayTree_3max_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__set__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_6arrays_10array_tree_13FileArrayTree_3max_2__set__(((struct __pyx_obj_2bx_6arrays_10array_tree_FileArrayTree *)__pyx_v_self), ((PyObject *)__pyx_v_value));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_2bx_6arrays_10array_tree_13FileArrayTree_3max_2__set__(struct __pyx_obj_2bx_6arrays_10array_tree_FileArrayTree *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__set__", 0);
+  __pyx_t_1 = __Pyx_PyInt_AsInt(__pyx_v_value); if (unlikely((__pyx_t_1 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 124; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_v_self->max = __pyx_t_1;
+
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_AddTraceback("bx.arrays.array_tree.FileArrayTree.max.__set__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = -1;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_13FileArrayTree_10block_size_1__get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_13FileArrayTree_10block_size_1__get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_6arrays_10array_tree_13FileArrayTree_10block_size___get__(((struct __pyx_obj_2bx_6arrays_10array_tree_FileArrayTree *)__pyx_v_self));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/arrays/array_tree.pyx":125
+ *     """
+ *     cdef public int max
+ *     cdef public int block_size             # <<<<<<<<<<<<<<
+ *     cdef public object dtype
+ *     cdef public int levels
+ */
+
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_13FileArrayTree_10block_size___get__(struct __pyx_obj_2bx_6arrays_10array_tree_FileArrayTree *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__get__", 0);
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = PyInt_FromLong(__pyx_v_self->block_size); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("bx.arrays.array_tree.FileArrayTree.block_size.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_2bx_6arrays_10array_tree_13FileArrayTree_10block_size_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value); /*proto*/
+static int __pyx_pw_2bx_6arrays_10array_tree_13FileArrayTree_10block_size_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__set__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_6arrays_10array_tree_13FileArrayTree_10block_size_2__set__(((struct __pyx_obj_2bx_6arrays_10array_tree_FileArrayTree *)__pyx_v_self), ((PyObject *)__pyx_v_value));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_2bx_6arrays_10array_tree_13FileArrayTree_10block_size_2__set__(struct __pyx_obj_2bx_6arrays_10array_tree_FileArrayTree *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__set__", 0);
+  __pyx_t_1 = __Pyx_PyInt_AsInt(__pyx_v_value); if (unlikely((__pyx_t_1 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_v_self->block_size = __pyx_t_1;
+
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_AddTraceback("bx.arrays.array_tree.FileArrayTree.block_size.__set__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = -1;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_13FileArrayTree_5dtype_1__get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_13FileArrayTree_5dtype_1__get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_6arrays_10array_tree_13FileArrayTree_5dtype___get__(((struct __pyx_obj_2bx_6arrays_10array_tree_FileArrayTree *)__pyx_v_self));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/arrays/array_tree.pyx":126
+ *     cdef public int max
+ *     cdef public int block_size
+ *     cdef public object dtype             # <<<<<<<<<<<<<<
+ *     cdef public int levels
+ *     cdef public int offset
+ */
+
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_13FileArrayTree_5dtype___get__(struct __pyx_obj_2bx_6arrays_10array_tree_FileArrayTree *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__get__", 0);
+  __Pyx_XDECREF(__pyx_r);
+  __Pyx_INCREF(__pyx_v_self->dtype);
+  __pyx_r = __pyx_v_self->dtype;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_2bx_6arrays_10array_tree_13FileArrayTree_5dtype_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value); /*proto*/
+static int __pyx_pw_2bx_6arrays_10array_tree_13FileArrayTree_5dtype_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__set__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_6arrays_10array_tree_13FileArrayTree_5dtype_2__set__(((struct __pyx_obj_2bx_6arrays_10array_tree_FileArrayTree *)__pyx_v_self), ((PyObject *)__pyx_v_value));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_2bx_6arrays_10array_tree_13FileArrayTree_5dtype_2__set__(struct __pyx_obj_2bx_6arrays_10array_tree_FileArrayTree *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__set__", 0);
+  __Pyx_INCREF(__pyx_v_value);
+  __Pyx_GIVEREF(__pyx_v_value);
+  __Pyx_GOTREF(__pyx_v_self->dtype);
+  __Pyx_DECREF(__pyx_v_self->dtype);
+  __pyx_v_self->dtype = __pyx_v_value;
+
+  __pyx_r = 0;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_2bx_6arrays_10array_tree_13FileArrayTree_5dtype_5__del__(PyObject *__pyx_v_self); /*proto*/
+static int __pyx_pw_2bx_6arrays_10array_tree_13FileArrayTree_5dtype_5__del__(PyObject *__pyx_v_self) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__del__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_6arrays_10array_tree_13FileArrayTree_5dtype_4__del__(((struct __pyx_obj_2bx_6arrays_10array_tree_FileArrayTree *)__pyx_v_self));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_2bx_6arrays_10array_tree_13FileArrayTree_5dtype_4__del__(struct __pyx_obj_2bx_6arrays_10array_tree_FileArrayTree *__pyx_v_self) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__del__", 0);
+  __Pyx_INCREF(Py_None);
+  __Pyx_GIVEREF(Py_None);
+  __Pyx_GOTREF(__pyx_v_self->dtype);
+  __Pyx_DECREF(__pyx_v_self->dtype);
+  __pyx_v_self->dtype = Py_None;
+
+  __pyx_r = 0;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_13FileArrayTree_6levels_1__get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_13FileArrayTree_6levels_1__get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_6arrays_10array_tree_13FileArrayTree_6levels___get__(((struct __pyx_obj_2bx_6arrays_10array_tree_FileArrayTree *)__pyx_v_self));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/arrays/array_tree.pyx":127
+ *     cdef public int block_size
+ *     cdef public object dtype
+ *     cdef public int levels             # <<<<<<<<<<<<<<
+ *     cdef public int offset
+ *     cdef public int root_offset
+ */
+
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_13FileArrayTree_6levels___get__(struct __pyx_obj_2bx_6arrays_10array_tree_FileArrayTree *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__get__", 0);
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = PyInt_FromLong(__pyx_v_self->levels); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("bx.arrays.array_tree.FileArrayTree.levels.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_2bx_6arrays_10array_tree_13FileArrayTree_6levels_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value); /*proto*/
+static int __pyx_pw_2bx_6arrays_10array_tree_13FileArrayTree_6levels_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__set__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_6arrays_10array_tree_13FileArrayTree_6levels_2__set__(((struct __pyx_obj_2bx_6arrays_10array_tree_FileArrayTree *)__pyx_v_self), ((PyObject *)__pyx_v_value));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_2bx_6arrays_10array_tree_13FileArrayTree_6levels_2__set__(struct __pyx_obj_2bx_6arrays_10array_tree_FileArrayTree *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__set__", 0);
+  __pyx_t_1 = __Pyx_PyInt_AsInt(__pyx_v_value); if (unlikely((__pyx_t_1 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_v_self->levels = __pyx_t_1;
+
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_AddTraceback("bx.arrays.array_tree.FileArrayTree.levels.__set__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = -1;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_13FileArrayTree_6offset_1__get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_13FileArrayTree_6offset_1__get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_6arrays_10array_tree_13FileArrayTree_6offset___get__(((struct __pyx_obj_2bx_6arrays_10array_tree_FileArrayTree *)__pyx_v_self));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/arrays/array_tree.pyx":128
+ *     cdef public object dtype
+ *     cdef public int levels
+ *     cdef public int offset             # <<<<<<<<<<<<<<
+ *     cdef public int root_offset
+ *     cdef object io
+ */
+
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_13FileArrayTree_6offset___get__(struct __pyx_obj_2bx_6arrays_10array_tree_FileArrayTree *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__get__", 0);
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = PyInt_FromLong(__pyx_v_self->offset); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 128; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("bx.arrays.array_tree.FileArrayTree.offset.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_2bx_6arrays_10array_tree_13FileArrayTree_6offset_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value); /*proto*/
+static int __pyx_pw_2bx_6arrays_10array_tree_13FileArrayTree_6offset_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__set__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_6arrays_10array_tree_13FileArrayTree_6offset_2__set__(((struct __pyx_obj_2bx_6arrays_10array_tree_FileArrayTree *)__pyx_v_self), ((PyObject *)__pyx_v_value));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_2bx_6arrays_10array_tree_13FileArrayTree_6offset_2__set__(struct __pyx_obj_2bx_6arrays_10array_tree_FileArrayTree *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__set__", 0);
+  __pyx_t_1 = __Pyx_PyInt_AsInt(__pyx_v_value); if (unlikely((__pyx_t_1 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 128; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_v_self->offset = __pyx_t_1;
+
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_AddTraceback("bx.arrays.array_tree.FileArrayTree.offset.__set__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = -1;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_13FileArrayTree_11root_offset_1__get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_13FileArrayTree_11root_offset_1__get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_6arrays_10array_tree_13FileArrayTree_11root_offset___get__(((struct __pyx_obj_2bx_6arrays_10array_tree_FileArrayTree *)__pyx_v_self));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/arrays/array_tree.pyx":129
+ *     cdef public int levels
+ *     cdef public int offset
+ *     cdef public int root_offset             # <<<<<<<<<<<<<<
+ *     cdef object io
+ * 
+ */
+
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_13FileArrayTree_11root_offset___get__(struct __pyx_obj_2bx_6arrays_10array_tree_FileArrayTree *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__get__", 0);
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = PyInt_FromLong(__pyx_v_self->root_offset); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 129; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("bx.arrays.array_tree.FileArrayTree.root_offset.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_2bx_6arrays_10array_tree_13FileArrayTree_11root_offset_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value); /*proto*/
+static int __pyx_pw_2bx_6arrays_10array_tree_13FileArrayTree_11root_offset_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__set__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_6arrays_10array_tree_13FileArrayTree_11root_offset_2__set__(((struct __pyx_obj_2bx_6arrays_10array_tree_FileArrayTree *)__pyx_v_self), ((PyObject *)__pyx_v_value));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_2bx_6arrays_10array_tree_13FileArrayTree_11root_offset_2__set__(struct __pyx_obj_2bx_6arrays_10array_tree_FileArrayTree *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__set__", 0);
+  __pyx_t_1 = __Pyx_PyInt_AsInt(__pyx_v_value); if (unlikely((__pyx_t_1 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 129; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_v_self->root_offset = __pyx_t_1;
+
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_AddTraceback("bx.arrays.array_tree.FileArrayTree.root_offset.__set__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = -1;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_7Summary_6counts_1__get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_7Summary_6counts_1__get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_6arrays_10array_tree_7Summary_6counts___get__(((struct __pyx_obj_2bx_6arrays_10array_tree_Summary *)__pyx_v_self));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/arrays/array_tree.pyx":208
+ *     valid count, sum, and sum-of-squares for each child.
+ *     """
+ *     cdef public object counts             # <<<<<<<<<<<<<<
+ *     cdef public object frequencies
+ *     cdef public object mins
+ */
+
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_7Summary_6counts___get__(struct __pyx_obj_2bx_6arrays_10array_tree_Summary *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__get__", 0);
+  __Pyx_XDECREF(__pyx_r);
+  __Pyx_INCREF(__pyx_v_self->counts);
+  __pyx_r = __pyx_v_self->counts;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_2bx_6arrays_10array_tree_7Summary_6counts_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value); /*proto*/
+static int __pyx_pw_2bx_6arrays_10array_tree_7Summary_6counts_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__set__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_6arrays_10array_tree_7Summary_6counts_2__set__(((struct __pyx_obj_2bx_6arrays_10array_tree_Summary *)__pyx_v_self), ((PyObject *)__pyx_v_value));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_2bx_6arrays_10array_tree_7Summary_6counts_2__set__(struct __pyx_obj_2bx_6arrays_10array_tree_Summary *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__set__", 0);
+  __Pyx_INCREF(__pyx_v_value);
+  __Pyx_GIVEREF(__pyx_v_value);
+  __Pyx_GOTREF(__pyx_v_self->counts);
+  __Pyx_DECREF(__pyx_v_self->counts);
+  __pyx_v_self->counts = __pyx_v_value;
+
+  __pyx_r = 0;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_2bx_6arrays_10array_tree_7Summary_6counts_5__del__(PyObject *__pyx_v_self); /*proto*/
+static int __pyx_pw_2bx_6arrays_10array_tree_7Summary_6counts_5__del__(PyObject *__pyx_v_self) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__del__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_6arrays_10array_tree_7Summary_6counts_4__del__(((struct __pyx_obj_2bx_6arrays_10array_tree_Summary *)__pyx_v_self));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_2bx_6arrays_10array_tree_7Summary_6counts_4__del__(struct __pyx_obj_2bx_6arrays_10array_tree_Summary *__pyx_v_self) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__del__", 0);
+  __Pyx_INCREF(Py_None);
+  __Pyx_GIVEREF(Py_None);
+  __Pyx_GOTREF(__pyx_v_self->counts);
+  __Pyx_DECREF(__pyx_v_self->counts);
+  __pyx_v_self->counts = Py_None;
+
+  __pyx_r = 0;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_7Summary_11frequencies_1__get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_7Summary_11frequencies_1__get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_6arrays_10array_tree_7Summary_11frequencies___get__(((struct __pyx_obj_2bx_6arrays_10array_tree_Summary *)__pyx_v_self));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/arrays/array_tree.pyx":209
+ *     """
+ *     cdef public object counts
+ *     cdef public object frequencies             # <<<<<<<<<<<<<<
+ *     cdef public object mins
+ *     cdef public object maxs
+ */
+
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_7Summary_11frequencies___get__(struct __pyx_obj_2bx_6arrays_10array_tree_Summary *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__get__", 0);
+  __Pyx_XDECREF(__pyx_r);
+  __Pyx_INCREF(__pyx_v_self->frequencies);
+  __pyx_r = __pyx_v_self->frequencies;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_2bx_6arrays_10array_tree_7Summary_11frequencies_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value); /*proto*/
+static int __pyx_pw_2bx_6arrays_10array_tree_7Summary_11frequencies_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__set__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_6arrays_10array_tree_7Summary_11frequencies_2__set__(((struct __pyx_obj_2bx_6arrays_10array_tree_Summary *)__pyx_v_self), ((PyObject *)__pyx_v_value));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_2bx_6arrays_10array_tree_7Summary_11frequencies_2__set__(struct __pyx_obj_2bx_6arrays_10array_tree_Summary *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__set__", 0);
+  __Pyx_INCREF(__pyx_v_value);
+  __Pyx_GIVEREF(__pyx_v_value);
+  __Pyx_GOTREF(__pyx_v_self->frequencies);
+  __Pyx_DECREF(__pyx_v_self->frequencies);
+  __pyx_v_self->frequencies = __pyx_v_value;
+
+  __pyx_r = 0;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_2bx_6arrays_10array_tree_7Summary_11frequencies_5__del__(PyObject *__pyx_v_self); /*proto*/
+static int __pyx_pw_2bx_6arrays_10array_tree_7Summary_11frequencies_5__del__(PyObject *__pyx_v_self) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__del__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_6arrays_10array_tree_7Summary_11frequencies_4__del__(((struct __pyx_obj_2bx_6arrays_10array_tree_Summary *)__pyx_v_self));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_2bx_6arrays_10array_tree_7Summary_11frequencies_4__del__(struct __pyx_obj_2bx_6arrays_10array_tree_Summary *__pyx_v_self) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__del__", 0);
+  __Pyx_INCREF(Py_None);
+  __Pyx_GIVEREF(Py_None);
+  __Pyx_GOTREF(__pyx_v_self->frequencies);
+  __Pyx_DECREF(__pyx_v_self->frequencies);
+  __pyx_v_self->frequencies = Py_None;
+
+  __pyx_r = 0;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_7Summary_4mins_1__get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_7Summary_4mins_1__get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_6arrays_10array_tree_7Summary_4mins___get__(((struct __pyx_obj_2bx_6arrays_10array_tree_Summary *)__pyx_v_self));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/arrays/array_tree.pyx":210
+ *     cdef public object counts
+ *     cdef public object frequencies
+ *     cdef public object mins             # <<<<<<<<<<<<<<
+ *     cdef public object maxs
+ *     cdef public object sums
+ */
+
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_7Summary_4mins___get__(struct __pyx_obj_2bx_6arrays_10array_tree_Summary *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__get__", 0);
+  __Pyx_XDECREF(__pyx_r);
+  __Pyx_INCREF(__pyx_v_self->mins);
+  __pyx_r = __pyx_v_self->mins;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_2bx_6arrays_10array_tree_7Summary_4mins_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value); /*proto*/
+static int __pyx_pw_2bx_6arrays_10array_tree_7Summary_4mins_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__set__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_6arrays_10array_tree_7Summary_4mins_2__set__(((struct __pyx_obj_2bx_6arrays_10array_tree_Summary *)__pyx_v_self), ((PyObject *)__pyx_v_value));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_2bx_6arrays_10array_tree_7Summary_4mins_2__set__(struct __pyx_obj_2bx_6arrays_10array_tree_Summary *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__set__", 0);
+  __Pyx_INCREF(__pyx_v_value);
+  __Pyx_GIVEREF(__pyx_v_value);
+  __Pyx_GOTREF(__pyx_v_self->mins);
+  __Pyx_DECREF(__pyx_v_self->mins);
+  __pyx_v_self->mins = __pyx_v_value;
+
+  __pyx_r = 0;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_2bx_6arrays_10array_tree_7Summary_4mins_5__del__(PyObject *__pyx_v_self); /*proto*/
+static int __pyx_pw_2bx_6arrays_10array_tree_7Summary_4mins_5__del__(PyObject *__pyx_v_self) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__del__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_6arrays_10array_tree_7Summary_4mins_4__del__(((struct __pyx_obj_2bx_6arrays_10array_tree_Summary *)__pyx_v_self));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_2bx_6arrays_10array_tree_7Summary_4mins_4__del__(struct __pyx_obj_2bx_6arrays_10array_tree_Summary *__pyx_v_self) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__del__", 0);
+  __Pyx_INCREF(Py_None);
+  __Pyx_GIVEREF(Py_None);
+  __Pyx_GOTREF(__pyx_v_self->mins);
+  __Pyx_DECREF(__pyx_v_self->mins);
+  __pyx_v_self->mins = Py_None;
+
+  __pyx_r = 0;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_7Summary_4maxs_1__get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_7Summary_4maxs_1__get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_6arrays_10array_tree_7Summary_4maxs___get__(((struct __pyx_obj_2bx_6arrays_10array_tree_Summary *)__pyx_v_self));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/arrays/array_tree.pyx":211
+ *     cdef public object frequencies
+ *     cdef public object mins
+ *     cdef public object maxs             # <<<<<<<<<<<<<<
+ *     cdef public object sums
+ *     cdef public object sumsquares
+ */
+
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_7Summary_4maxs___get__(struct __pyx_obj_2bx_6arrays_10array_tree_Summary *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__get__", 0);
+  __Pyx_XDECREF(__pyx_r);
+  __Pyx_INCREF(__pyx_v_self->maxs);
+  __pyx_r = __pyx_v_self->maxs;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_2bx_6arrays_10array_tree_7Summary_4maxs_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value); /*proto*/
+static int __pyx_pw_2bx_6arrays_10array_tree_7Summary_4maxs_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__set__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_6arrays_10array_tree_7Summary_4maxs_2__set__(((struct __pyx_obj_2bx_6arrays_10array_tree_Summary *)__pyx_v_self), ((PyObject *)__pyx_v_value));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_2bx_6arrays_10array_tree_7Summary_4maxs_2__set__(struct __pyx_obj_2bx_6arrays_10array_tree_Summary *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__set__", 0);
+  __Pyx_INCREF(__pyx_v_value);
+  __Pyx_GIVEREF(__pyx_v_value);
+  __Pyx_GOTREF(__pyx_v_self->maxs);
+  __Pyx_DECREF(__pyx_v_self->maxs);
+  __pyx_v_self->maxs = __pyx_v_value;
+
+  __pyx_r = 0;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_2bx_6arrays_10array_tree_7Summary_4maxs_5__del__(PyObject *__pyx_v_self); /*proto*/
+static int __pyx_pw_2bx_6arrays_10array_tree_7Summary_4maxs_5__del__(PyObject *__pyx_v_self) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__del__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_6arrays_10array_tree_7Summary_4maxs_4__del__(((struct __pyx_obj_2bx_6arrays_10array_tree_Summary *)__pyx_v_self));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_2bx_6arrays_10array_tree_7Summary_4maxs_4__del__(struct __pyx_obj_2bx_6arrays_10array_tree_Summary *__pyx_v_self) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__del__", 0);
+  __Pyx_INCREF(Py_None);
+  __Pyx_GIVEREF(Py_None);
+  __Pyx_GOTREF(__pyx_v_self->maxs);
+  __Pyx_DECREF(__pyx_v_self->maxs);
+  __pyx_v_self->maxs = Py_None;
+
+  __pyx_r = 0;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_7Summary_4sums_1__get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_7Summary_4sums_1__get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_6arrays_10array_tree_7Summary_4sums___get__(((struct __pyx_obj_2bx_6arrays_10array_tree_Summary *)__pyx_v_self));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/arrays/array_tree.pyx":212
+ *     cdef public object mins
+ *     cdef public object maxs
+ *     cdef public object sums             # <<<<<<<<<<<<<<
+ *     cdef public object sumsquares
+ * 
+ */
+
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_7Summary_4sums___get__(struct __pyx_obj_2bx_6arrays_10array_tree_Summary *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__get__", 0);
+  __Pyx_XDECREF(__pyx_r);
+  __Pyx_INCREF(__pyx_v_self->sums);
+  __pyx_r = __pyx_v_self->sums;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_2bx_6arrays_10array_tree_7Summary_4sums_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value); /*proto*/
+static int __pyx_pw_2bx_6arrays_10array_tree_7Summary_4sums_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__set__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_6arrays_10array_tree_7Summary_4sums_2__set__(((struct __pyx_obj_2bx_6arrays_10array_tree_Summary *)__pyx_v_self), ((PyObject *)__pyx_v_value));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_2bx_6arrays_10array_tree_7Summary_4sums_2__set__(struct __pyx_obj_2bx_6arrays_10array_tree_Summary *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__set__", 0);
+  __Pyx_INCREF(__pyx_v_value);
+  __Pyx_GIVEREF(__pyx_v_value);
+  __Pyx_GOTREF(__pyx_v_self->sums);
+  __Pyx_DECREF(__pyx_v_self->sums);
+  __pyx_v_self->sums = __pyx_v_value;
+
+  __pyx_r = 0;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_2bx_6arrays_10array_tree_7Summary_4sums_5__del__(PyObject *__pyx_v_self); /*proto*/
+static int __pyx_pw_2bx_6arrays_10array_tree_7Summary_4sums_5__del__(PyObject *__pyx_v_self) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__del__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_6arrays_10array_tree_7Summary_4sums_4__del__(((struct __pyx_obj_2bx_6arrays_10array_tree_Summary *)__pyx_v_self));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_2bx_6arrays_10array_tree_7Summary_4sums_4__del__(struct __pyx_obj_2bx_6arrays_10array_tree_Summary *__pyx_v_self) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__del__", 0);
+  __Pyx_INCREF(Py_None);
+  __Pyx_GIVEREF(Py_None);
+  __Pyx_GOTREF(__pyx_v_self->sums);
+  __Pyx_DECREF(__pyx_v_self->sums);
+  __pyx_v_self->sums = Py_None;
+
+  __pyx_r = 0;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_7Summary_10sumsquares_1__get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_7Summary_10sumsquares_1__get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_6arrays_10array_tree_7Summary_10sumsquares___get__(((struct __pyx_obj_2bx_6arrays_10array_tree_Summary *)__pyx_v_self));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/arrays/array_tree.pyx":213
+ *     cdef public object maxs
+ *     cdef public object sums
+ *     cdef public object sumsquares             # <<<<<<<<<<<<<<
+ * 
+ * cdef class ArrayTreeNode
+ */
+
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_7Summary_10sumsquares___get__(struct __pyx_obj_2bx_6arrays_10array_tree_Summary *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__get__", 0);
+  __Pyx_XDECREF(__pyx_r);
+  __Pyx_INCREF(__pyx_v_self->sumsquares);
+  __pyx_r = __pyx_v_self->sumsquares;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_2bx_6arrays_10array_tree_7Summary_10sumsquares_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value); /*proto*/
+static int __pyx_pw_2bx_6arrays_10array_tree_7Summary_10sumsquares_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__set__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_6arrays_10array_tree_7Summary_10sumsquares_2__set__(((struct __pyx_obj_2bx_6arrays_10array_tree_Summary *)__pyx_v_self), ((PyObject *)__pyx_v_value));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_2bx_6arrays_10array_tree_7Summary_10sumsquares_2__set__(struct __pyx_obj_2bx_6arrays_10array_tree_Summary *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__set__", 0);
+  __Pyx_INCREF(__pyx_v_value);
+  __Pyx_GIVEREF(__pyx_v_value);
+  __Pyx_GOTREF(__pyx_v_self->sumsquares);
+  __Pyx_DECREF(__pyx_v_self->sumsquares);
+  __pyx_v_self->sumsquares = __pyx_v_value;
+
+  __pyx_r = 0;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_2bx_6arrays_10array_tree_7Summary_10sumsquares_5__del__(PyObject *__pyx_v_self); /*proto*/
+static int __pyx_pw_2bx_6arrays_10array_tree_7Summary_10sumsquares_5__del__(PyObject *__pyx_v_self) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__del__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_6arrays_10array_tree_7Summary_10sumsquares_4__del__(((struct __pyx_obj_2bx_6arrays_10array_tree_Summary *)__pyx_v_self));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_2bx_6arrays_10array_tree_7Summary_10sumsquares_4__del__(struct __pyx_obj_2bx_6arrays_10array_tree_Summary *__pyx_v_self) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__del__", 0);
+  __Pyx_INCREF(Py_None);
+  __Pyx_GIVEREF(Py_None);
+  __Pyx_GOTREF(__pyx_v_self->sumsquares);
+  __Pyx_DECREF(__pyx_v_self->sumsquares);
+  __pyx_v_self->sumsquares = Py_None;
+
+  __pyx_r = 0;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_2bx_6arrays_10array_tree_9ArrayTree_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_2bx_6arrays_10array_tree_9ArrayTree___init__[] = "\n        Create a new array tree of size `max` \n        ";
+#if CYTHON_COMPILING_IN_CPYTHON
+struct wrapperbase __pyx_wrapperbase_2bx_6arrays_10array_tree_9ArrayTree___init__;
+#endif
+static int __pyx_pw_2bx_6arrays_10array_tree_9ArrayTree_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  int __pyx_v_max;
+  int __pyx_v_block_size;
+  PyObject *__pyx_v_dtype = 0;
+  PyObject *__pyx_v_no_leaves = 0;
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__init__ (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__max,&__pyx_n_s__block_size,&__pyx_n_s__dtype,&__pyx_n_s__no_leaves,0};
+    PyObject* values[4] = {0,0,0,0};
+    values[2] = __pyx_k_10;
+    values[3] = __pyx_k_11;
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__max)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__block_size)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("__init__", 0, 2, 4, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 241; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+        case  2:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s__dtype);
+          if (value) { values[2] = value; kw_args--; }
+        }
+        case  3:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s__no_leaves);
+          if (value) { values[3] = value; kw_args--; }
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 241; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else {
+      switch (PyTuple_GET_SIZE(__pyx_args)) {
+        case  4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+    }
+    __pyx_v_max = __Pyx_PyInt_AsInt(values[0]); if (unlikely((__pyx_v_max == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 241; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_block_size = __Pyx_PyInt_AsInt(values[1]); if (unlikely((__pyx_v_block_size == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 241; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_dtype = values[2];
+    __pyx_v_no_leaves = values[3];
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("__init__", 0, 2, 4, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 241; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.arrays.array_tree.ArrayTree.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return -1;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_6arrays_10array_tree_9ArrayTree___init__(((struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTree *)__pyx_v_self), __pyx_v_max, __pyx_v_block_size, __pyx_v_dtype, __pyx_v_no_leaves);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/arrays/array_tree.pyx":241
+ *     cdef public ArrayTreeNode root
+ * 
+ *     def __init__( self, int max, int block_size, dtype=float32, no_leaves=False ):             # <<<<<<<<<<<<<<
+ *         """
+ *         Create a new array tree of size `max`
+ */
+
+static int __pyx_pf_2bx_6arrays_10array_tree_9ArrayTree___init__(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTree *__pyx_v_self, int __pyx_v_max, int __pyx_v_block_size, PyObject *__pyx_v_dtype, PyObject *__pyx_v_no_leaves) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  int __pyx_t_4;
+  PyObject *__pyx_t_5 = NULL;
+  PyObject *__pyx_t_6 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__init__", 0);
+
+  /* "bx/arrays/array_tree.pyx":245
+ *         Create a new array tree of size `max`
+ *         """
+ *         self.max = max             # <<<<<<<<<<<<<<
+ *         self.block_size = block_size
+ *         self.no_leaves = no_leaves
+ */
+  __pyx_v_self->max = __pyx_v_max;
+
+  /* "bx/arrays/array_tree.pyx":246
+ *         """
+ *         self.max = max
+ *         self.block_size = block_size             # <<<<<<<<<<<<<<
+ *         self.no_leaves = no_leaves
+ *         # Force the dtype argument to its canonical dtype object
+ */
+  __pyx_v_self->block_size = __pyx_v_block_size;
+
+  /* "bx/arrays/array_tree.pyx":247
+ *         self.max = max
+ *         self.block_size = block_size
+ *         self.no_leaves = no_leaves             # <<<<<<<<<<<<<<
+ *         # Force the dtype argument to its canonical dtype object
+ *         self.dtype = numpy.dtype( dtype )
+ */
+  __pyx_t_1 = __Pyx_PyInt_AsInt(__pyx_v_no_leaves); if (unlikely((__pyx_t_1 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 247; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_v_self->no_leaves = __pyx_t_1;
+
+  /* "bx/arrays/array_tree.pyx":249
+ *         self.no_leaves = no_leaves
+ *         # Force the dtype argument to its canonical dtype object
+ *         self.dtype = numpy.dtype( dtype )             # <<<<<<<<<<<<<<
+ *         # How many levels are needed to cover the entire range?
+ *         self.levels = 0
+ */
+  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 249; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_INCREF(__pyx_v_dtype);
+  PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_dtype);
+  __Pyx_GIVEREF(__pyx_v_dtype);
+  __pyx_t_3 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_5numpy_dtype)), ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 249; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
+  __Pyx_GIVEREF(__pyx_t_3);
+  __Pyx_GOTREF(__pyx_v_self->dtype);
+  __Pyx_DECREF(__pyx_v_self->dtype);
+  __pyx_v_self->dtype = __pyx_t_3;
+  __pyx_t_3 = 0;
+
+  /* "bx/arrays/array_tree.pyx":251
+ *         self.dtype = numpy.dtype( dtype )
+ *         # How many levels are needed to cover the entire range?
+ *         self.levels = 0             # <<<<<<<<<<<<<<
+ *         while ( <long long> self.block_size ) ** ( self.levels + 1 ) < self.max:
+ *             self.levels += 1
+ */
+  __pyx_v_self->levels = 0;
+
+  /* "bx/arrays/array_tree.pyx":252
+ *         # How many levels are needed to cover the entire range?
+ *         self.levels = 0
+ *         while ( <long long> self.block_size ) ** ( self.levels + 1 ) < self.max:             # <<<<<<<<<<<<<<
+ *             self.levels += 1
+ *         # Not yet dealing with the case where the root is a Leaf
+ */
+  while (1) {
+    __pyx_t_4 = (__Pyx_pow_PY_LONG_LONG(((PY_LONG_LONG)__pyx_v_self->block_size), ((PY_LONG_LONG)(__pyx_v_self->levels + 1))) < __pyx_v_self->max);
+    if (!__pyx_t_4) break;
+
+    /* "bx/arrays/array_tree.pyx":253
+ *         self.levels = 0
+ *         while ( <long long> self.block_size ) ** ( self.levels + 1 ) < self.max:
+ *             self.levels += 1             # <<<<<<<<<<<<<<
+ *         # Not yet dealing with the case where the root is a Leaf
+ *         assert self.levels > 0, "max < block_size not yet handled"
+ */
+    __pyx_v_self->levels = (__pyx_v_self->levels + 1);
+  }
+
+  /* "bx/arrays/array_tree.pyx":255
+ *             self.levels += 1
+ *         # Not yet dealing with the case where the root is a Leaf
+ *         assert self.levels > 0, "max < block_size not yet handled"             # <<<<<<<<<<<<<<
+ *         # Create the root node`
+ *         self.root = ArrayTreeNode( self, 0, max, block_size, self.levels )
+ */
+  #ifndef CYTHON_WITHOUT_ASSERTIONS
+  if (unlikely(!(__pyx_v_self->levels > 0))) {
+    PyErr_SetObject(PyExc_AssertionError, ((PyObject *)__pyx_kp_s_8));
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 255; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  #endif
+
+  /* "bx/arrays/array_tree.pyx":257
+ *         assert self.levels > 0, "max < block_size not yet handled"
+ *         # Create the root node`
+ *         self.root = ArrayTreeNode( self, 0, max, block_size, self.levels )             # <<<<<<<<<<<<<<
+ * 
+ *     def __setitem__( self, int index, value ):
+ */
+  __pyx_t_3 = PyInt_FromLong(__pyx_v_max); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_2 = PyInt_FromLong(__pyx_v_block_size); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_5 = PyInt_FromLong(__pyx_v_self->levels); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __pyx_t_6 = PyTuple_New(5); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_6);
+  __Pyx_INCREF(((PyObject *)__pyx_v_self));
+  PyTuple_SET_ITEM(__pyx_t_6, 0, ((PyObject *)__pyx_v_self));
+  __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
+  __Pyx_INCREF(__pyx_int_0);
+  PyTuple_SET_ITEM(__pyx_t_6, 1, __pyx_int_0);
+  __Pyx_GIVEREF(__pyx_int_0);
+  PyTuple_SET_ITEM(__pyx_t_6, 2, __pyx_t_3);
+  __Pyx_GIVEREF(__pyx_t_3);
+  PyTuple_SET_ITEM(__pyx_t_6, 3, __pyx_t_2);
+  __Pyx_GIVEREF(__pyx_t_2);
+  PyTuple_SET_ITEM(__pyx_t_6, 4, __pyx_t_5);
+  __Pyx_GIVEREF(__pyx_t_5);
+  __pyx_t_3 = 0;
+  __pyx_t_2 = 0;
+  __pyx_t_5 = 0;
+  __pyx_t_5 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_2bx_6arrays_10array_tree_ArrayTreeNode)), ((PyObject *)__pyx_t_6), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __Pyx_DECREF(((PyObject *)__pyx_t_6)); __pyx_t_6 = 0;
+  __Pyx_GIVEREF(__pyx_t_5);
+  __Pyx_GOTREF(__pyx_v_self->root);
+  __Pyx_DECREF(((PyObject *)__pyx_v_self->root));
+  __pyx_v_self->root = ((struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeNode *)__pyx_t_5);
+  __pyx_t_5 = 0;
+
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_5);
+  __Pyx_XDECREF(__pyx_t_6);
+  __Pyx_AddTraceback("bx.arrays.array_tree.ArrayTree.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = -1;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_2bx_6arrays_10array_tree_9ArrayTree_3__setitem__(PyObject *__pyx_v_self, PyObject *__pyx_arg_index, PyObject *__pyx_v_value); /*proto*/
+static int __pyx_pw_2bx_6arrays_10array_tree_9ArrayTree_3__setitem__(PyObject *__pyx_v_self, PyObject *__pyx_arg_index, PyObject *__pyx_v_value) {
+  int __pyx_v_index;
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__setitem__ (wrapper)", 0);
+  assert(__pyx_arg_index); {
+    __pyx_v_index = __Pyx_PyInt_AsInt(__pyx_arg_index); if (unlikely((__pyx_v_index == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 259; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.arrays.array_tree.ArrayTree.__setitem__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return -1;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_6arrays_10array_tree_9ArrayTree_2__setitem__(((struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTree *)__pyx_v_self), ((int)__pyx_v_index), ((PyObject *)__pyx_v_value));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/arrays/array_tree.pyx":259
+ *         self.root = ArrayTreeNode( self, 0, max, block_size, self.levels )
+ * 
+ *     def __setitem__( self, int index, value ):             # <<<<<<<<<<<<<<
+ *         self.root.set( index, value )
+ * 
+ */
+
+static int __pyx_pf_2bx_6arrays_10array_tree_9ArrayTree_2__setitem__(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTree *__pyx_v_self, int __pyx_v_index, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__setitem__", 0);
+
+  /* "bx/arrays/array_tree.pyx":260
+ * 
+ *     def __setitem__( self, int index, value ):
+ *         self.root.set( index, value )             # <<<<<<<<<<<<<<
+ * 
+ *     def set_range( self, int start, int end, value ):
+ */
+  __pyx_t_1 = PyObject_GetAttr(((PyObject *)__pyx_v_self->root), __pyx_n_s__set); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 260; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = PyInt_FromLong(__pyx_v_index); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 260; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 260; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_2);
+  __Pyx_GIVEREF(__pyx_t_2);
+  __Pyx_INCREF(__pyx_v_value);
+  PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_v_value);
+  __Pyx_GIVEREF(__pyx_v_value);
+  __pyx_t_2 = 0;
+  __pyx_t_2 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 260; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_AddTraceback("bx.arrays.array_tree.ArrayTree.__setitem__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = -1;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_9ArrayTree_5set_range(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_9ArrayTree_5set_range(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  int __pyx_v_start;
+  int __pyx_v_end;
+  PyObject *__pyx_v_value = 0;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("set_range (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__start,&__pyx_n_s__end,&__pyx_n_s__value,0};
+    PyObject* values[3] = {0,0,0};
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__start)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__end)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("set_range", 1, 3, 3, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 262; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+        case  2:
+        if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__value)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("set_range", 1, 3, 3, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 262; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "set_range") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 262; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else if (PyTuple_GET_SIZE(__pyx_args) != 3) {
+      goto __pyx_L5_argtuple_error;
+    } else {
+      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+      values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+    }
+    __pyx_v_start = __Pyx_PyInt_AsInt(values[0]); if (unlikely((__pyx_v_start == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 262; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_end = __Pyx_PyInt_AsInt(values[1]); if (unlikely((__pyx_v_end == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 262; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_value = values[2];
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("set_range", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 262; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.arrays.array_tree.ArrayTree.set_range", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_6arrays_10array_tree_9ArrayTree_4set_range(((struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTree *)__pyx_v_self), __pyx_v_start, __pyx_v_end, __pyx_v_value);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/arrays/array_tree.pyx":262
+ *         self.root.set( index, value )
+ * 
+ *     def set_range( self, int start, int end, value ):             # <<<<<<<<<<<<<<
+ *         for i from start <= i < end:
+ *             self.root.set( i, value )
+ */
+
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_9ArrayTree_4set_range(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTree *__pyx_v_self, int __pyx_v_start, int __pyx_v_end, PyObject *__pyx_v_value) {
+  int __pyx_v_i;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("set_range", 0);
+
+  /* "bx/arrays/array_tree.pyx":263
+ * 
+ *     def set_range( self, int start, int end, value ):
+ *         for i from start <= i < end:             # <<<<<<<<<<<<<<
+ *             self.root.set( i, value )
+ * 
+ */
+  __pyx_t_1 = __pyx_v_end;
+  for (__pyx_v_i = __pyx_v_start; __pyx_v_i < __pyx_t_1; __pyx_v_i++) {
+
+    /* "bx/arrays/array_tree.pyx":264
+ *     def set_range( self, int start, int end, value ):
+ *         for i from start <= i < end:
+ *             self.root.set( i, value )             # <<<<<<<<<<<<<<
+ * 
+ *     def __getitem__( self, int index ):
+ */
+    __pyx_t_2 = PyObject_GetAttr(((PyObject *)__pyx_v_self->root), __pyx_n_s__set); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 264; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_t_3 = PyInt_FromLong(__pyx_v_i); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 264; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 264; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
+    __Pyx_GIVEREF(__pyx_t_3);
+    __Pyx_INCREF(__pyx_v_value);
+    PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_v_value);
+    __Pyx_GIVEREF(__pyx_v_value);
+    __pyx_t_3 = 0;
+    __pyx_t_3 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_4), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 264; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  }
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_AddTraceback("bx.arrays.array_tree.ArrayTree.set_range", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_9ArrayTree_7__getitem__(PyObject *__pyx_v_self, PyObject *__pyx_arg_index); /*proto*/
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_9ArrayTree_7__getitem__(PyObject *__pyx_v_self, PyObject *__pyx_arg_index) {
+  int __pyx_v_index;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__getitem__ (wrapper)", 0);
+  assert(__pyx_arg_index); {
+    __pyx_v_index = __Pyx_PyInt_AsInt(__pyx_arg_index); if (unlikely((__pyx_v_index == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 266; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.arrays.array_tree.ArrayTree.__getitem__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_6arrays_10array_tree_9ArrayTree_6__getitem__(((struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTree *)__pyx_v_self), ((int)__pyx_v_index));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/arrays/array_tree.pyx":266
+ *             self.root.set( i, value )
+ * 
+ *     def __getitem__( self, int index ):             # <<<<<<<<<<<<<<
+ *         return self.root.get( index )
+ * 
+ */
+
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_9ArrayTree_6__getitem__(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTree *__pyx_v_self, int __pyx_v_index) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__getitem__", 0);
+
+  /* "bx/arrays/array_tree.pyx":267
+ * 
+ *     def __getitem__( self, int index ):
+ *         return self.root.get( index )             # <<<<<<<<<<<<<<
+ * 
+ *     def to_file( self, f, is_little_endian=True, no_leaves=False ):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = PyObject_GetAttr(((PyObject *)__pyx_v_self->root), __pyx_n_s__get); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 267; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = PyInt_FromLong(__pyx_v_index); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 267; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 267; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_2);
+  __Pyx_GIVEREF(__pyx_t_2);
+  __pyx_t_2 = 0;
+  __pyx_t_2 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 267; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
+  __pyx_r = __pyx_t_2;
+  __pyx_t_2 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_AddTraceback("bx.arrays.array_tree.ArrayTree.__getitem__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_9ArrayTree_9to_file(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_9ArrayTree_9to_file(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_f = 0;
+  PyObject *__pyx_v_is_little_endian = 0;
+  PyObject *__pyx_v_no_leaves = 0;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("to_file (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__f,&__pyx_n_s__is_little_endian,&__pyx_n_s__no_leaves,0};
+    PyObject* values[3] = {0,0,0};
+    values[1] = __pyx_k_12;
+    values[2] = __pyx_k_13;
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__f)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s__is_little_endian);
+          if (value) { values[1] = value; kw_args--; }
+        }
+        case  2:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s__no_leaves);
+          if (value) { values[2] = value; kw_args--; }
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "to_file") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 269; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else {
+      switch (PyTuple_GET_SIZE(__pyx_args)) {
+        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+    }
+    __pyx_v_f = values[0];
+    __pyx_v_is_little_endian = values[1];
+    __pyx_v_no_leaves = values[2];
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("to_file", 0, 1, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 269; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.arrays.array_tree.ArrayTree.to_file", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_6arrays_10array_tree_9ArrayTree_8to_file(((struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTree *)__pyx_v_self), __pyx_v_f, __pyx_v_is_little_endian, __pyx_v_no_leaves);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/arrays/array_tree.pyx":269
+ *         return self.root.get( index )
+ * 
+ *     def to_file( self, f, is_little_endian=True, no_leaves=False ):             # <<<<<<<<<<<<<<
+ *         io = BinaryFileWriter( f, is_little_endian=is_little_endian )
+ *         ## io.write_uint32( VERSION )
+ */
+
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_9ArrayTree_8to_file(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTree *__pyx_v_self, PyObject *__pyx_v_f, PyObject *__pyx_v_is_little_endian, PyObject *__pyx_v_no_leaves) {
+  PyObject *__pyx_v_io = NULL;
+  long __pyx_v_bottom_level;
+  long __pyx_v_level;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  int __pyx_t_5;
+  long __pyx_t_6;
+  long __pyx_t_7;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("to_file", 0);
+
+  /* "bx/arrays/array_tree.pyx":270
+ * 
+ *     def to_file( self, f, is_little_endian=True, no_leaves=False ):
+ *         io = BinaryFileWriter( f, is_little_endian=is_little_endian )             # <<<<<<<<<<<<<<
+ *         ## io.write_uint32( VERSION )
+ *         io.write_uint32( self.max )
+ */
+  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__BinaryFileWriter); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 270; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 270; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_INCREF(__pyx_v_f);
+  PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_f);
+  __Pyx_GIVEREF(__pyx_v_f);
+  __pyx_t_3 = PyDict_New(); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 270; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(((PyObject *)__pyx_t_3));
+  if (PyDict_SetItem(__pyx_t_3, ((PyObject *)__pyx_n_s__is_little_endian), __pyx_v_is_little_endian) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 270; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_4 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_2), ((PyObject *)__pyx_t_3)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 270; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
+  __pyx_v_io = __pyx_t_4;
+  __pyx_t_4 = 0;
+
+  /* "bx/arrays/array_tree.pyx":272
+ *         io = BinaryFileWriter( f, is_little_endian=is_little_endian )
+ *         ## io.write_uint32( VERSION )
+ *         io.write_uint32( self.max )             # <<<<<<<<<<<<<<
+ *         io.write_uint32( self.block_size )
+ *         io.write( self.dtype.char )
+ */
+  __pyx_t_4 = PyObject_GetAttr(__pyx_v_io, __pyx_n_s__write_uint32); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 272; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __pyx_t_3 = PyInt_FromLong(__pyx_v_self->max); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 272; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 272; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_3);
+  __Pyx_GIVEREF(__pyx_t_3);
+  __pyx_t_3 = 0;
+  __pyx_t_3 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 272; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+  /* "bx/arrays/array_tree.pyx":273
+ *         ## io.write_uint32( VERSION )
+ *         io.write_uint32( self.max )
+ *         io.write_uint32( self.block_size )             # <<<<<<<<<<<<<<
+ *         io.write( self.dtype.char )
+ *         io.write( "\0\0\0" )
+ */
+  __pyx_t_3 = PyObject_GetAttr(__pyx_v_io, __pyx_n_s__write_uint32); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 273; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_2 = PyInt_FromLong(__pyx_v_self->block_size); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 273; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 273; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_2);
+  __Pyx_GIVEREF(__pyx_t_2);
+  __pyx_t_2 = 0;
+  __pyx_t_2 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_t_4), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 273; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+  /* "bx/arrays/array_tree.pyx":274
+ *         io.write_uint32( self.max )
+ *         io.write_uint32( self.block_size )
+ *         io.write( self.dtype.char )             # <<<<<<<<<<<<<<
+ *         io.write( "\0\0\0" )
+ *         # Data pass, level order
+ */
+  __pyx_t_2 = PyObject_GetAttr(__pyx_v_io, __pyx_n_s__write); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 274; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_4 = PyObject_GetAttr(__pyx_v_self->dtype, __pyx_n_s__char); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 274; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 274; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_4);
+  __Pyx_GIVEREF(__pyx_t_4);
+  __pyx_t_4 = 0;
+  __pyx_t_4 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 274; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+
+  /* "bx/arrays/array_tree.pyx":275
+ *         io.write_uint32( self.block_size )
+ *         io.write( self.dtype.char )
+ *         io.write( "\0\0\0" )             # <<<<<<<<<<<<<<
+ *         # Data pass, level order
+ *         if no_leaves:
+ */
+  __pyx_t_4 = PyObject_GetAttr(__pyx_v_io, __pyx_n_s__write); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 275; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __pyx_t_3 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_k_tuple_15), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 275; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+  /* "bx/arrays/array_tree.pyx":277
+ *         io.write( "\0\0\0" )
+ *         # Data pass, level order
+ *         if no_leaves:             # <<<<<<<<<<<<<<
+ *             bottom_level = 0
+ *         else:
+ */
+  __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_v_no_leaves); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 277; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (__pyx_t_5) {
+
+    /* "bx/arrays/array_tree.pyx":278
+ *         # Data pass, level order
+ *         if no_leaves:
+ *             bottom_level = 0             # <<<<<<<<<<<<<<
+ *         else:
+ *             bottom_level = -1
+ */
+    __pyx_v_bottom_level = 0;
+    goto __pyx_L3;
+  }
+  /*else*/ {
+
+    /* "bx/arrays/array_tree.pyx":280
+ *             bottom_level = 0
+ *         else:
+ *             bottom_level = -1             # <<<<<<<<<<<<<<
+ *         for level in range( self.levels, bottom_level, -1 ):
+ *             self.root.to_file_data_pass( io, level )
+ */
+    __pyx_v_bottom_level = -1;
+  }
+  __pyx_L3:;
+
+  /* "bx/arrays/array_tree.pyx":281
+ *         else:
+ *             bottom_level = -1
+ *         for level in range( self.levels, bottom_level, -1 ):             # <<<<<<<<<<<<<<
+ *             self.root.to_file_data_pass( io, level )
+ *         # Offset pass to fix up indexes
+ */
+  __pyx_t_6 = __pyx_v_bottom_level;
+  for (__pyx_t_7 = __pyx_v_self->levels; __pyx_t_7 > __pyx_t_6; __pyx_t_7-=1) {
+    __pyx_v_level = __pyx_t_7;
+
+    /* "bx/arrays/array_tree.pyx":282
+ *             bottom_level = -1
+ *         for level in range( self.levels, bottom_level, -1 ):
+ *             self.root.to_file_data_pass( io, level )             # <<<<<<<<<<<<<<
+ *         # Offset pass to fix up indexes
+ *         self.root.to_file_offset_pass( io )
+ */
+    __pyx_t_3 = PyObject_GetAttr(((PyObject *)__pyx_v_self->root), __pyx_n_s__to_file_data_pass); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 282; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __pyx_t_4 = PyInt_FromLong(__pyx_v_level); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 282; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 282; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __Pyx_INCREF(__pyx_v_io);
+    PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_io);
+    __Pyx_GIVEREF(__pyx_v_io);
+    PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_4);
+    __Pyx_GIVEREF(__pyx_t_4);
+    __pyx_t_4 = 0;
+    __pyx_t_4 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 282; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  }
+
+  /* "bx/arrays/array_tree.pyx":284
+ *             self.root.to_file_data_pass( io, level )
+ *         # Offset pass to fix up indexes
+ *         self.root.to_file_offset_pass( io )             # <<<<<<<<<<<<<<
+ * 
+ *     @classmethod
+ */
+  __pyx_t_4 = PyObject_GetAttr(((PyObject *)__pyx_v_self->root), __pyx_n_s__to_file_offset_pass); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 284; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 284; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_INCREF(__pyx_v_io);
+  PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_io);
+  __Pyx_GIVEREF(__pyx_v_io);
+  __pyx_t_3 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 284; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_AddTraceback("bx.arrays.array_tree.ArrayTree.to_file", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_io);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_9ArrayTree_11from_file(PyObject *__pyx_v_Class, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_9ArrayTree_11from_file(PyObject *__pyx_v_Class, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_f = 0;
+  PyObject *__pyx_v_is_little_endian = 0;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("from_file (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__f,&__pyx_n_s__is_little_endian,0};
+    PyObject* values[2] = {0,0};
+    values[1] = __pyx_k_16;
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__f)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s__is_little_endian);
+          if (value) { values[1] = value; kw_args--; }
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "from_file") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 287; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else {
+      switch (PyTuple_GET_SIZE(__pyx_args)) {
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+    }
+    __pyx_v_f = values[0];
+    __pyx_v_is_little_endian = values[1];
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("from_file", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 287; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.arrays.array_tree.ArrayTree.from_file", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_6arrays_10array_tree_9ArrayTree_10from_file(((PyObject*)__pyx_v_Class), __pyx_v_f, __pyx_v_is_little_endian);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/arrays/array_tree.pyx":287
+ * 
+ *     @classmethod
+ *     def from_file( Class, f, is_little_endian=True ):             # <<<<<<<<<<<<<<
+ *         io = BinaryFileReader( f, is_little_endian=is_little_endian )
+ *         ## assert io.read_uint32() == VERSION
+ */
+
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_9ArrayTree_10from_file(PyObject *__pyx_v_Class, PyObject *__pyx_v_f, PyObject *__pyx_v_is_little_endian) {
+  PyObject *__pyx_v_io = NULL;
+  PyObject *__pyx_v_max = NULL;
+  PyObject *__pyx_v_block_size = NULL;
+  PyObject *__pyx_v_dt = NULL;
+  PyObject *__pyx_v_tree = NULL;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("from_file", 0);
+
+  /* "bx/arrays/array_tree.pyx":288
+ *     @classmethod
+ *     def from_file( Class, f, is_little_endian=True ):
+ *         io = BinaryFileReader( f, is_little_endian=is_little_endian )             # <<<<<<<<<<<<<<
+ *         ## assert io.read_uint32() == VERSION
+ *         max = io.read_uint32()
+ */
+  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__BinaryFileReader); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 288; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 288; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_INCREF(__pyx_v_f);
+  PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_f);
+  __Pyx_GIVEREF(__pyx_v_f);
+  __pyx_t_3 = PyDict_New(); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 288; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(((PyObject *)__pyx_t_3));
+  if (PyDict_SetItem(__pyx_t_3, ((PyObject *)__pyx_n_s__is_little_endian), __pyx_v_is_little_endian) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 288; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_4 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_2), ((PyObject *)__pyx_t_3)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 288; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
+  __pyx_v_io = __pyx_t_4;
+  __pyx_t_4 = 0;
+
+  /* "bx/arrays/array_tree.pyx":290
+ *         io = BinaryFileReader( f, is_little_endian=is_little_endian )
+ *         ## assert io.read_uint32() == VERSION
+ *         max = io.read_uint32()             # <<<<<<<<<<<<<<
+ *         block_size = io.read_uint32()
+ *         dt = io.read( 1 )
+ */
+  __pyx_t_4 = PyObject_GetAttr(__pyx_v_io, __pyx_n_s__read_uint32); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 290; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __pyx_t_3 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 290; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  __pyx_v_max = __pyx_t_3;
+  __pyx_t_3 = 0;
+
+  /* "bx/arrays/array_tree.pyx":291
+ *         ## assert io.read_uint32() == VERSION
+ *         max = io.read_uint32()
+ *         block_size = io.read_uint32()             # <<<<<<<<<<<<<<
+ *         dt = io.read( 1 )
+ *         io.read( 3 )
+ */
+  __pyx_t_3 = PyObject_GetAttr(__pyx_v_io, __pyx_n_s__read_uint32); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 291; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_4 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 291; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __pyx_v_block_size = __pyx_t_4;
+  __pyx_t_4 = 0;
+
+  /* "bx/arrays/array_tree.pyx":292
+ *         max = io.read_uint32()
+ *         block_size = io.read_uint32()
+ *         dt = io.read( 1 )             # <<<<<<<<<<<<<<
+ *         io.read( 3 )
+ *         tree = Class( max, block_size, dt )
+ */
+  __pyx_t_4 = PyObject_GetAttr(__pyx_v_io, __pyx_n_s__read); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 292; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __pyx_t_3 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_k_tuple_17), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 292; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  __pyx_v_dt = __pyx_t_3;
+  __pyx_t_3 = 0;
+
+  /* "bx/arrays/array_tree.pyx":293
+ *         block_size = io.read_uint32()
+ *         dt = io.read( 1 )
+ *         io.read( 3 )             # <<<<<<<<<<<<<<
+ *         tree = Class( max, block_size, dt )
+ *         tree.root.from_file( io )
+ */
+  __pyx_t_3 = PyObject_GetAttr(__pyx_v_io, __pyx_n_s__read); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 293; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_4 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_k_tuple_18), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 293; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+
+  /* "bx/arrays/array_tree.pyx":294
+ *         dt = io.read( 1 )
+ *         io.read( 3 )
+ *         tree = Class( max, block_size, dt )             # <<<<<<<<<<<<<<
+ *         tree.root.from_file( io )
+ *         return tree
+ */
+  __pyx_t_4 = PyTuple_New(3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 294; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __Pyx_INCREF(__pyx_v_max);
+  PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_v_max);
+  __Pyx_GIVEREF(__pyx_v_max);
+  __Pyx_INCREF(__pyx_v_block_size);
+  PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_v_block_size);
+  __Pyx_GIVEREF(__pyx_v_block_size);
+  __Pyx_INCREF(__pyx_v_dt);
+  PyTuple_SET_ITEM(__pyx_t_4, 2, __pyx_v_dt);
+  __Pyx_GIVEREF(__pyx_v_dt);
+  __pyx_t_3 = PyObject_Call(((PyObject *)__pyx_v_Class), ((PyObject *)__pyx_t_4), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 294; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
+  __pyx_v_tree = __pyx_t_3;
+  __pyx_t_3 = 0;
+
+  /* "bx/arrays/array_tree.pyx":295
+ *         io.read( 3 )
+ *         tree = Class( max, block_size, dt )
+ *         tree.root.from_file( io )             # <<<<<<<<<<<<<<
+ *         return tree
+ * 
+ */
+  __pyx_t_3 = PyObject_GetAttr(__pyx_v_tree, __pyx_n_s__root); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 295; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_4 = PyObject_GetAttr(__pyx_t_3, __pyx_n_s__from_file); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 295; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 295; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_INCREF(__pyx_v_io);
+  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_io);
+  __Pyx_GIVEREF(__pyx_v_io);
+  __pyx_t_2 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 295; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+  /* "bx/arrays/array_tree.pyx":296
+ *         tree = Class( max, block_size, dt )
+ *         tree.root.from_file( io )
+ *         return tree             # <<<<<<<<<<<<<<
+ * 
+ *     @classmethod
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __Pyx_INCREF(__pyx_v_tree);
+  __pyx_r = __pyx_v_tree;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_AddTraceback("bx.arrays.array_tree.ArrayTree.from_file", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_io);
+  __Pyx_XDECREF(__pyx_v_max);
+  __Pyx_XDECREF(__pyx_v_block_size);
+  __Pyx_XDECREF(__pyx_v_dt);
+  __Pyx_XDECREF(__pyx_v_tree);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_9ArrayTree_13from_sequence(PyObject *__pyx_v_Class, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_2bx_6arrays_10array_tree_9ArrayTree_12from_sequence[] = "\n        Build an ArrayTree from a sequence like object (must have at least\n        length and getitem).\n        ";
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_9ArrayTree_13from_sequence(PyObject *__pyx_v_Class, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_s = 0;
+  PyObject *__pyx_v_block_size = 0;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("from_sequence (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__s,&__pyx_n_s__block_size,0};
+    PyObject* values[2] = {0,0};
+    values[1] = ((PyObject *)__pyx_int_1000);
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__s)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s__block_size);
+          if (value) { values[1] = value; kw_args--; }
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "from_sequence") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 299; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else {
+      switch (PyTuple_GET_SIZE(__pyx_args)) {
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+    }
+    __pyx_v_s = values[0];
+    __pyx_v_block_size = values[1];
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("from_sequence", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 299; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.arrays.array_tree.ArrayTree.from_sequence", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_6arrays_10array_tree_9ArrayTree_12from_sequence(((PyObject*)__pyx_v_Class), __pyx_v_s, __pyx_v_block_size);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/arrays/array_tree.pyx":299
+ * 
+ *     @classmethod
+ *     def from_sequence( Class, s, block_size=1000 ):             # <<<<<<<<<<<<<<
+ *         """
+ *         Build an ArrayTree from a sequence like object (must have at least
+ */
+
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_9ArrayTree_12from_sequence(PyObject *__pyx_v_Class, PyObject *__pyx_v_s, PyObject *__pyx_v_block_size) {
+  PyObject *__pyx_v_tree = NULL;
+  PyObject *__pyx_v_i = NULL;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  Py_ssize_t __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *(*__pyx_t_4)(PyObject *);
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("from_sequence", 0);
+
+  /* "bx/arrays/array_tree.pyx":304
+ *         length and getitem).
+ *         """
+ *         tree = Class( len( s ), block_size )             # <<<<<<<<<<<<<<
+ *         for i in range( len( s ) ):
+ *             tree[i] = s[i]
+ */
+  __pyx_t_1 = PyObject_Length(__pyx_v_s); if (unlikely(__pyx_t_1 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 304; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyInt_FromSsize_t(__pyx_t_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 304; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 304; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_2);
+  __Pyx_GIVEREF(__pyx_t_2);
+  __Pyx_INCREF(__pyx_v_block_size);
+  PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_v_block_size);
+  __Pyx_GIVEREF(__pyx_v_block_size);
+  __pyx_t_2 = 0;
+  __pyx_t_2 = PyObject_Call(((PyObject *)__pyx_v_Class), ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 304; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
+  __pyx_v_tree = __pyx_t_2;
+  __pyx_t_2 = 0;
+
+  /* "bx/arrays/array_tree.pyx":305
+ *         """
+ *         tree = Class( len( s ), block_size )
+ *         for i in range( len( s ) ):             # <<<<<<<<<<<<<<
+ *             tree[i] = s[i]
+ *         return tree
+ */
+  __pyx_t_1 = PyObject_Length(__pyx_v_s); if (unlikely(__pyx_t_1 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 305; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyInt_FromSsize_t(__pyx_t_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 305; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 305; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_2);
+  __Pyx_GIVEREF(__pyx_t_2);
+  __pyx_t_2 = 0;
+  __pyx_t_2 = PyObject_Call(__pyx_builtin_range, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 305; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
+  if (PyList_CheckExact(__pyx_t_2) || PyTuple_CheckExact(__pyx_t_2)) {
+    __pyx_t_3 = __pyx_t_2; __Pyx_INCREF(__pyx_t_3); __pyx_t_1 = 0;
+    __pyx_t_4 = NULL;
+  } else {
+    __pyx_t_1 = -1; __pyx_t_3 = PyObject_GetIter(__pyx_t_2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 305; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __pyx_t_4 = Py_TYPE(__pyx_t_3)->tp_iternext;
+  }
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  for (;;) {
+    if (!__pyx_t_4 && PyList_CheckExact(__pyx_t_3)) {
+      if (__pyx_t_1 >= PyList_GET_SIZE(__pyx_t_3)) break;
+      #if CYTHON_COMPILING_IN_CPYTHON
+      __pyx_t_2 = PyList_GET_ITEM(__pyx_t_3, __pyx_t_1); __Pyx_INCREF(__pyx_t_2); __pyx_t_1++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 305; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      #else
+      __pyx_t_2 = PySequence_ITEM(__pyx_t_3, __pyx_t_1); __pyx_t_1++; if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 305; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      #endif
+    } else if (!__pyx_t_4 && PyTuple_CheckExact(__pyx_t_3)) {
+      if (__pyx_t_1 >= PyTuple_GET_SIZE(__pyx_t_3)) break;
+      #if CYTHON_COMPILING_IN_CPYTHON
+      __pyx_t_2 = PyTuple_GET_ITEM(__pyx_t_3, __pyx_t_1); __Pyx_INCREF(__pyx_t_2); __pyx_t_1++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 305; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      #else
+      __pyx_t_2 = PySequence_ITEM(__pyx_t_3, __pyx_t_1); __pyx_t_1++; if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 305; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      #endif
+    } else {
+      __pyx_t_2 = __pyx_t_4(__pyx_t_3);
+      if (unlikely(!__pyx_t_2)) {
+        if (PyErr_Occurred()) {
+          if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
+          else {__pyx_filename = __pyx_f[0]; __pyx_lineno = 305; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        }
+        break;
+      }
+      __Pyx_GOTREF(__pyx_t_2);
+    }
+    __Pyx_XDECREF(__pyx_v_i);
+    __pyx_v_i = __pyx_t_2;
+    __pyx_t_2 = 0;
+
+    /* "bx/arrays/array_tree.pyx":306
+ *         tree = Class( len( s ), block_size )
+ *         for i in range( len( s ) ):
+ *             tree[i] = s[i]             # <<<<<<<<<<<<<<
+ *         return tree
+ * 
+ */
+    __pyx_t_2 = PyObject_GetItem(__pyx_v_s, __pyx_v_i); if (!__pyx_t_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 306; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    if (PyObject_SetItem(__pyx_v_tree, __pyx_v_i, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 306; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  }
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+  /* "bx/arrays/array_tree.pyx":307
+ *         for i in range( len( s ) ):
+ *             tree[i] = s[i]
+ *         return tree             # <<<<<<<<<<<<<<
+ * 
+ * cdef class ArrayTreeNode:
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __Pyx_INCREF(__pyx_v_tree);
+  __pyx_r = __pyx_v_tree;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_AddTraceback("bx.arrays.array_tree.ArrayTree.from_sequence", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_tree);
+  __Pyx_XDECREF(__pyx_v_i);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_9ArrayTree_3max_1__get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_9ArrayTree_3max_1__get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_6arrays_10array_tree_9ArrayTree_3max___get__(((struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTree *)__pyx_v_self));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/arrays/array_tree.pyx":234
+ *     """
+ * 
+ *     cdef public int max             # <<<<<<<<<<<<<<
+ *     cdef public int block_size
+ *     cdef public object dtype
+ */
+
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_9ArrayTree_3max___get__(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTree *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__get__", 0);
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = PyInt_FromLong(__pyx_v_self->max); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 234; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("bx.arrays.array_tree.ArrayTree.max.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_2bx_6arrays_10array_tree_9ArrayTree_3max_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value); /*proto*/
+static int __pyx_pw_2bx_6arrays_10array_tree_9ArrayTree_3max_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__set__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_6arrays_10array_tree_9ArrayTree_3max_2__set__(((struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTree *)__pyx_v_self), ((PyObject *)__pyx_v_value));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_2bx_6arrays_10array_tree_9ArrayTree_3max_2__set__(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTree *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__set__", 0);
+  __pyx_t_1 = __Pyx_PyInt_AsInt(__pyx_v_value); if (unlikely((__pyx_t_1 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 234; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_v_self->max = __pyx_t_1;
+
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_AddTraceback("bx.arrays.array_tree.ArrayTree.max.__set__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = -1;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_9ArrayTree_10block_size_1__get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_9ArrayTree_10block_size_1__get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_6arrays_10array_tree_9ArrayTree_10block_size___get__(((struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTree *)__pyx_v_self));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/arrays/array_tree.pyx":235
+ * 
+ *     cdef public int max
+ *     cdef public int block_size             # <<<<<<<<<<<<<<
+ *     cdef public object dtype
+ *     cdef public int levels
+ */
+
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_9ArrayTree_10block_size___get__(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTree *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__get__", 0);
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = PyInt_FromLong(__pyx_v_self->block_size); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 235; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("bx.arrays.array_tree.ArrayTree.block_size.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_2bx_6arrays_10array_tree_9ArrayTree_10block_size_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value); /*proto*/
+static int __pyx_pw_2bx_6arrays_10array_tree_9ArrayTree_10block_size_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__set__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_6arrays_10array_tree_9ArrayTree_10block_size_2__set__(((struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTree *)__pyx_v_self), ((PyObject *)__pyx_v_value));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_2bx_6arrays_10array_tree_9ArrayTree_10block_size_2__set__(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTree *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__set__", 0);
+  __pyx_t_1 = __Pyx_PyInt_AsInt(__pyx_v_value); if (unlikely((__pyx_t_1 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 235; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_v_self->block_size = __pyx_t_1;
+
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_AddTraceback("bx.arrays.array_tree.ArrayTree.block_size.__set__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = -1;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_9ArrayTree_5dtype_1__get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_9ArrayTree_5dtype_1__get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_6arrays_10array_tree_9ArrayTree_5dtype___get__(((struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTree *)__pyx_v_self));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/arrays/array_tree.pyx":236
+ *     cdef public int max
+ *     cdef public int block_size
+ *     cdef public object dtype             # <<<<<<<<<<<<<<
+ *     cdef public int levels
+ *     cdef public int no_leaves
+ */
+
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_9ArrayTree_5dtype___get__(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTree *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__get__", 0);
+  __Pyx_XDECREF(__pyx_r);
+  __Pyx_INCREF(__pyx_v_self->dtype);
+  __pyx_r = __pyx_v_self->dtype;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_2bx_6arrays_10array_tree_9ArrayTree_5dtype_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value); /*proto*/
+static int __pyx_pw_2bx_6arrays_10array_tree_9ArrayTree_5dtype_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__set__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_6arrays_10array_tree_9ArrayTree_5dtype_2__set__(((struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTree *)__pyx_v_self), ((PyObject *)__pyx_v_value));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_2bx_6arrays_10array_tree_9ArrayTree_5dtype_2__set__(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTree *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__set__", 0);
+  __Pyx_INCREF(__pyx_v_value);
+  __Pyx_GIVEREF(__pyx_v_value);
+  __Pyx_GOTREF(__pyx_v_self->dtype);
+  __Pyx_DECREF(__pyx_v_self->dtype);
+  __pyx_v_self->dtype = __pyx_v_value;
+
+  __pyx_r = 0;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_2bx_6arrays_10array_tree_9ArrayTree_5dtype_5__del__(PyObject *__pyx_v_self); /*proto*/
+static int __pyx_pw_2bx_6arrays_10array_tree_9ArrayTree_5dtype_5__del__(PyObject *__pyx_v_self) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__del__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_6arrays_10array_tree_9ArrayTree_5dtype_4__del__(((struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTree *)__pyx_v_self));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_2bx_6arrays_10array_tree_9ArrayTree_5dtype_4__del__(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTree *__pyx_v_self) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__del__", 0);
+  __Pyx_INCREF(Py_None);
+  __Pyx_GIVEREF(Py_None);
+  __Pyx_GOTREF(__pyx_v_self->dtype);
+  __Pyx_DECREF(__pyx_v_self->dtype);
+  __pyx_v_self->dtype = Py_None;
+
+  __pyx_r = 0;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_9ArrayTree_6levels_1__get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_9ArrayTree_6levels_1__get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_6arrays_10array_tree_9ArrayTree_6levels___get__(((struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTree *)__pyx_v_self));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/arrays/array_tree.pyx":237
+ *     cdef public int block_size
+ *     cdef public object dtype
+ *     cdef public int levels             # <<<<<<<<<<<<<<
+ *     cdef public int no_leaves
+ *     cdef public ArrayTreeNode root
+ */
+
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_9ArrayTree_6levels___get__(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTree *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__get__", 0);
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = PyInt_FromLong(__pyx_v_self->levels); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 237; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("bx.arrays.array_tree.ArrayTree.levels.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_2bx_6arrays_10array_tree_9ArrayTree_6levels_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value); /*proto*/
+static int __pyx_pw_2bx_6arrays_10array_tree_9ArrayTree_6levels_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__set__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_6arrays_10array_tree_9ArrayTree_6levels_2__set__(((struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTree *)__pyx_v_self), ((PyObject *)__pyx_v_value));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_2bx_6arrays_10array_tree_9ArrayTree_6levels_2__set__(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTree *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__set__", 0);
+  __pyx_t_1 = __Pyx_PyInt_AsInt(__pyx_v_value); if (unlikely((__pyx_t_1 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 237; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_v_self->levels = __pyx_t_1;
+
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_AddTraceback("bx.arrays.array_tree.ArrayTree.levels.__set__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = -1;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_9ArrayTree_9no_leaves_1__get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_9ArrayTree_9no_leaves_1__get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_6arrays_10array_tree_9ArrayTree_9no_leaves___get__(((struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTree *)__pyx_v_self));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/arrays/array_tree.pyx":238
+ *     cdef public object dtype
+ *     cdef public int levels
+ *     cdef public int no_leaves             # <<<<<<<<<<<<<<
+ *     cdef public ArrayTreeNode root
+ * 
+ */
+
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_9ArrayTree_9no_leaves___get__(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTree *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__get__", 0);
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = PyInt_FromLong(__pyx_v_self->no_leaves); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 238; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("bx.arrays.array_tree.ArrayTree.no_leaves.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_2bx_6arrays_10array_tree_9ArrayTree_9no_leaves_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value); /*proto*/
+static int __pyx_pw_2bx_6arrays_10array_tree_9ArrayTree_9no_leaves_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__set__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_6arrays_10array_tree_9ArrayTree_9no_leaves_2__set__(((struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTree *)__pyx_v_self), ((PyObject *)__pyx_v_value));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_2bx_6arrays_10array_tree_9ArrayTree_9no_leaves_2__set__(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTree *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__set__", 0);
+  __pyx_t_1 = __Pyx_PyInt_AsInt(__pyx_v_value); if (unlikely((__pyx_t_1 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 238; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_v_self->no_leaves = __pyx_t_1;
+
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_AddTraceback("bx.arrays.array_tree.ArrayTree.no_leaves.__set__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = -1;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_9ArrayTree_4root_1__get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_9ArrayTree_4root_1__get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_6arrays_10array_tree_9ArrayTree_4root___get__(((struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTree *)__pyx_v_self));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/arrays/array_tree.pyx":239
+ *     cdef public int levels
+ *     cdef public int no_leaves
+ *     cdef public ArrayTreeNode root             # <<<<<<<<<<<<<<
+ * 
+ *     def __init__( self, int max, int block_size, dtype=float32, no_leaves=False ):
+ */
+
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_9ArrayTree_4root___get__(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTree *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__get__", 0);
+  __Pyx_XDECREF(__pyx_r);
+  __Pyx_INCREF(((PyObject *)__pyx_v_self->root));
+  __pyx_r = ((PyObject *)__pyx_v_self->root);
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_2bx_6arrays_10array_tree_9ArrayTree_4root_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value); /*proto*/
+static int __pyx_pw_2bx_6arrays_10array_tree_9ArrayTree_4root_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__set__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_6arrays_10array_tree_9ArrayTree_4root_2__set__(((struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTree *)__pyx_v_self), ((PyObject *)__pyx_v_value));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_2bx_6arrays_10array_tree_9ArrayTree_4root_2__set__(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTree *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__set__", 0);
+  if (!(likely(((__pyx_v_value) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_value, __pyx_ptype_2bx_6arrays_10array_tree_ArrayTreeNode))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 239; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_INCREF(__pyx_v_value);
+  __Pyx_GIVEREF(__pyx_v_value);
+  __Pyx_GOTREF(__pyx_v_self->root);
+  __Pyx_DECREF(((PyObject *)__pyx_v_self->root));
+  __pyx_v_self->root = ((struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeNode *)__pyx_v_value);
+
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_AddTraceback("bx.arrays.array_tree.ArrayTree.root.__set__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = -1;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_2bx_6arrays_10array_tree_9ArrayTree_4root_5__del__(PyObject *__pyx_v_self); /*proto*/
+static int __pyx_pw_2bx_6arrays_10array_tree_9ArrayTree_4root_5__del__(PyObject *__pyx_v_self) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__del__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_6arrays_10array_tree_9ArrayTree_4root_4__del__(((struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTree *)__pyx_v_self));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_2bx_6arrays_10array_tree_9ArrayTree_4root_4__del__(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTree *__pyx_v_self) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__del__", 0);
+  __Pyx_INCREF(Py_None);
+  __Pyx_GIVEREF(Py_None);
+  __Pyx_GOTREF(__pyx_v_self->root);
+  __Pyx_DECREF(((PyObject *)__pyx_v_self->root));
+  __pyx_v_self->root = ((struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeNode *)Py_None);
+
+  __pyx_r = 0;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_2bx_6arrays_10array_tree_13ArrayTreeNode_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static int __pyx_pw_2bx_6arrays_10array_tree_13ArrayTreeNode_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTree *__pyx_v_tree = 0;
+  int __pyx_v_min;
+  int __pyx_v_max;
+  int __pyx_v_block_size;
+  int __pyx_v_level;
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__init__ (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__tree,&__pyx_n_s__min,&__pyx_n_s__max,&__pyx_n_s__block_size,&__pyx_n_s__level,0};
+    PyObject* values[5] = {0,0,0,0,0};
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+        case  4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__tree)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__min)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("__init__", 1, 5, 5, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+        case  2:
+        if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__max)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("__init__", 1, 5, 5, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+        case  3:
+        if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__block_size)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("__init__", 1, 5, 5, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+        case  4:
+        if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__level)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("__init__", 1, 5, 5, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else if (PyTuple_GET_SIZE(__pyx_args) != 5) {
+      goto __pyx_L5_argtuple_error;
+    } else {
+      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+      values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+      values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+      values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+    }
+    __pyx_v_tree = ((struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTree *)values[0]);
+    __pyx_v_min = __Pyx_PyInt_AsInt(values[1]); if (unlikely((__pyx_v_min == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_max = __Pyx_PyInt_AsInt(values[2]); if (unlikely((__pyx_v_max == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_block_size = __Pyx_PyInt_AsInt(values[3]); if (unlikely((__pyx_v_block_size == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_level = __Pyx_PyInt_AsInt(values[4]); if (unlikely((__pyx_v_level == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("__init__", 1, 5, 5, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.arrays.array_tree.ArrayTreeNode.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return -1;
+  __pyx_L4_argument_unpacking_done:;
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_tree), __pyx_ptype_2bx_6arrays_10array_tree_ArrayTree, 1, "tree", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_r = __pyx_pf_2bx_6arrays_10array_tree_13ArrayTreeNode___init__(((struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeNode *)__pyx_v_self), __pyx_v_tree, __pyx_v_min, __pyx_v_max, __pyx_v_block_size, __pyx_v_level);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __pyx_r = -1;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/arrays/array_tree.pyx":325
+ *     cdef public long start_offset
+ * 
+ *     def __init__( self, ArrayTree tree, int min, int max, int block_size, int level ):             # <<<<<<<<<<<<<<
+ *         self.tree = tree
+ *         self.min = min
+ */
+
+static int __pyx_pf_2bx_6arrays_10array_tree_13ArrayTreeNode___init__(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeNode *__pyx_v_self, struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTree *__pyx_v_tree, int __pyx_v_min, int __pyx_v_max, int __pyx_v_block_size, int __pyx_v_level) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__init__", 0);
+
+  /* "bx/arrays/array_tree.pyx":326
+ * 
+ *     def __init__( self, ArrayTree tree, int min, int max, int block_size, int level ):
+ *         self.tree = tree             # <<<<<<<<<<<<<<
+ *         self.min = min
+ *         self.max = max
+ */
+  __Pyx_INCREF(((PyObject *)__pyx_v_tree));
+  __Pyx_GIVEREF(((PyObject *)__pyx_v_tree));
+  __Pyx_GOTREF(__pyx_v_self->tree);
+  __Pyx_DECREF(((PyObject *)__pyx_v_self->tree));
+  __pyx_v_self->tree = __pyx_v_tree;
+
+  /* "bx/arrays/array_tree.pyx":327
+ *     def __init__( self, ArrayTree tree, int min, int max, int block_size, int level ):
+ *         self.tree = tree
+ *         self.min = min             # <<<<<<<<<<<<<<
+ *         self.max = max
+ *         self.block_size = block_size
+ */
+  __pyx_v_self->min = __pyx_v_min;
+
+  /* "bx/arrays/array_tree.pyx":328
+ *         self.tree = tree
+ *         self.min = min
+ *         self.max = max             # <<<<<<<<<<<<<<
+ *         self.block_size = block_size
+ *         self.level = level
+ */
+  __pyx_v_self->max = __pyx_v_max;
+
+  /* "bx/arrays/array_tree.pyx":329
+ *         self.min = min
+ *         self.max = max
+ *         self.block_size = block_size             # <<<<<<<<<<<<<<
+ *         self.level = level
+ *         # Each of my children represents block_size ** level values
+ */
+  __pyx_v_self->block_size = __pyx_v_block_size;
+
+  /* "bx/arrays/array_tree.pyx":330
+ *         self.max = max
+ *         self.block_size = block_size
+ *         self.level = level             # <<<<<<<<<<<<<<
+ *         # Each of my children represents block_size ** level values
+ *         self.child_size = self.block_size ** self.level
+ */
+  __pyx_v_self->level = __pyx_v_level;
+
+  /* "bx/arrays/array_tree.pyx":332
+ *         self.level = level
+ *         # Each of my children represents block_size ** level values
+ *         self.child_size = self.block_size ** self.level             # <<<<<<<<<<<<<<
+ *         self.children = [None] * self.block_size
+ *         self.summary = None
+ */
+  __pyx_v_self->child_size = __Pyx_pow_int(__pyx_v_self->block_size, __pyx_v_self->level);
+
+  /* "bx/arrays/array_tree.pyx":333
+ *         # Each of my children represents block_size ** level values
+ *         self.child_size = self.block_size ** self.level
+ *         self.children = [None] * self.block_size             # <<<<<<<<<<<<<<
+ *         self.summary = None
+ *         self.start_offset = 0
+ */
+  __pyx_t_1 = PyList_New(1 * ((__pyx_v_self->block_size<0) ? 0:__pyx_v_self->block_size)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 333; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  { Py_ssize_t __pyx_temp;
+    for (__pyx_temp=0; __pyx_temp < __pyx_v_self->block_size; __pyx_temp++) {
+      __Pyx_INCREF(Py_None);
+      PyList_SET_ITEM(__pyx_t_1, __pyx_temp, Py_None);
+      __Pyx_GIVEREF(Py_None);
+    }
+  }
+  __Pyx_GIVEREF(((PyObject *)__pyx_t_1));
+  __Pyx_GOTREF(__pyx_v_self->children);
+  __Pyx_DECREF(__pyx_v_self->children);
+  __pyx_v_self->children = ((PyObject *)__pyx_t_1);
+  __pyx_t_1 = 0;
+
+  /* "bx/arrays/array_tree.pyx":334
+ *         self.child_size = self.block_size ** self.level
+ *         self.children = [None] * self.block_size
+ *         self.summary = None             # <<<<<<<<<<<<<<
+ *         self.start_offset = 0
+ * 
+ */
+  __Pyx_INCREF(Py_None);
+  __Pyx_GIVEREF(Py_None);
+  __Pyx_GOTREF(__pyx_v_self->summary);
+  __Pyx_DECREF(((PyObject *)__pyx_v_self->summary));
+  __pyx_v_self->summary = ((struct __pyx_obj_2bx_6arrays_10array_tree_Summary *)Py_None);
+
+  /* "bx/arrays/array_tree.pyx":335
+ *         self.children = [None] * self.block_size
+ *         self.summary = None
+ *         self.start_offset = 0             # <<<<<<<<<<<<<<
+ * 
+ *     cdef inline init_bin( self, int index ):
+ */
+  __pyx_v_self->start_offset = 0;
+
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("bx.arrays.array_tree.ArrayTreeNode.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = -1;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/arrays/array_tree.pyx":337
+ *         self.start_offset = 0
+ * 
+ *     cdef inline init_bin( self, int index ):             # <<<<<<<<<<<<<<
+ *         cdef int min = self.min + ( index * self.child_size )
+ *         cdef int max = min + self.child_size
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_2bx_6arrays_10array_tree_13ArrayTreeNode_init_bin(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeNode *__pyx_v_self, int __pyx_v_index) {
+  int __pyx_v_min;
+  int __pyx_v_max;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  PyObject *__pyx_t_5 = NULL;
+  PyObject *__pyx_t_6 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("init_bin", 0);
+
+  /* "bx/arrays/array_tree.pyx":338
+ * 
+ *     cdef inline init_bin( self, int index ):
+ *         cdef int min = self.min + ( index * self.child_size )             # <<<<<<<<<<<<<<
+ *         cdef int max = min + self.child_size
+ *         if self.level == 1:
+ */
+  __pyx_v_min = (__pyx_v_self->min + (__pyx_v_index * __pyx_v_self->child_size));
+
+  /* "bx/arrays/array_tree.pyx":339
+ *     cdef inline init_bin( self, int index ):
+ *         cdef int min = self.min + ( index * self.child_size )
+ *         cdef int max = min + self.child_size             # <<<<<<<<<<<<<<
+ *         if self.level == 1:
+ *             self.children[ index ] = ArrayTreeLeaf( self.tree, min, max )
+ */
+  __pyx_v_max = (__pyx_v_min + __pyx_v_self->child_size);
+
+  /* "bx/arrays/array_tree.pyx":340
+ *         cdef int min = self.min + ( index * self.child_size )
+ *         cdef int max = min + self.child_size
+ *         if self.level == 1:             # <<<<<<<<<<<<<<
+ *             self.children[ index ] = ArrayTreeLeaf( self.tree, min, max )
+ *         else:
+ */
+  __pyx_t_1 = (__pyx_v_self->level == 1);
+  if (__pyx_t_1) {
+
+    /* "bx/arrays/array_tree.pyx":341
+ *         cdef int max = min + self.child_size
+ *         if self.level == 1:
+ *             self.children[ index ] = ArrayTreeLeaf( self.tree, min, max )             # <<<<<<<<<<<<<<
+ *         else:
+ *             self.children[ index ] = ArrayTreeNode( self.tree, min, max, self.block_size, self.level - 1 )
+ */
+    __pyx_t_2 = PyInt_FromLong(__pyx_v_min); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 341; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_t_3 = PyInt_FromLong(__pyx_v_max); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 341; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __pyx_t_4 = PyTuple_New(3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 341; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    __Pyx_INCREF(((PyObject *)__pyx_v_self->tree));
+    PyTuple_SET_ITEM(__pyx_t_4, 0, ((PyObject *)__pyx_v_self->tree));
+    __Pyx_GIVEREF(((PyObject *)__pyx_v_self->tree));
+    PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_2);
+    __Pyx_GIVEREF(__pyx_t_2);
+    PyTuple_SET_ITEM(__pyx_t_4, 2, __pyx_t_3);
+    __Pyx_GIVEREF(__pyx_t_3);
+    __pyx_t_2 = 0;
+    __pyx_t_3 = 0;
+    __pyx_t_3 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_2bx_6arrays_10array_tree_ArrayTreeLeaf)), ((PyObject *)__pyx_t_4), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 341; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
+    if (__Pyx_SetItemInt(__pyx_v_self->children, __pyx_v_index, __pyx_t_3, sizeof(int), PyInt_FromLong) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 341; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    goto __pyx_L3;
+  }
+  /*else*/ {
+
+    /* "bx/arrays/array_tree.pyx":343
+ *             self.children[ index ] = ArrayTreeLeaf( self.tree, min, max )
+ *         else:
+ *             self.children[ index ] = ArrayTreeNode( self.tree, min, max, self.block_size, self.level - 1 )             # <<<<<<<<<<<<<<
+ * 
+ *     def set( self, int index, value ):
+ */
+    __pyx_t_3 = PyInt_FromLong(__pyx_v_min); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 343; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __pyx_t_4 = PyInt_FromLong(__pyx_v_max); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 343; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    __pyx_t_2 = PyInt_FromLong(__pyx_v_self->block_size); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 343; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_t_5 = PyInt_FromLong((__pyx_v_self->level - 1)); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 343; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_5);
+    __pyx_t_6 = PyTuple_New(5); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 343; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_6);
+    __Pyx_INCREF(((PyObject *)__pyx_v_self->tree));
+    PyTuple_SET_ITEM(__pyx_t_6, 0, ((PyObject *)__pyx_v_self->tree));
+    __Pyx_GIVEREF(((PyObject *)__pyx_v_self->tree));
+    PyTuple_SET_ITEM(__pyx_t_6, 1, __pyx_t_3);
+    __Pyx_GIVEREF(__pyx_t_3);
+    PyTuple_SET_ITEM(__pyx_t_6, 2, __pyx_t_4);
+    __Pyx_GIVEREF(__pyx_t_4);
+    PyTuple_SET_ITEM(__pyx_t_6, 3, __pyx_t_2);
+    __Pyx_GIVEREF(__pyx_t_2);
+    PyTuple_SET_ITEM(__pyx_t_6, 4, __pyx_t_5);
+    __Pyx_GIVEREF(__pyx_t_5);
+    __pyx_t_3 = 0;
+    __pyx_t_4 = 0;
+    __pyx_t_2 = 0;
+    __pyx_t_5 = 0;
+    __pyx_t_5 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_2bx_6arrays_10array_tree_ArrayTreeNode)), ((PyObject *)__pyx_t_6), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 343; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_5);
+    __Pyx_DECREF(((PyObject *)__pyx_t_6)); __pyx_t_6 = 0;
+    if (__Pyx_SetItemInt(__pyx_v_self->children, __pyx_v_index, __pyx_t_5, sizeof(int), PyInt_FromLong) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 343; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+  }
+  __pyx_L3:;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_XDECREF(__pyx_t_5);
+  __Pyx_XDECREF(__pyx_t_6);
+  __Pyx_AddTraceback("bx.arrays.array_tree.ArrayTreeNode.init_bin", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_13ArrayTreeNode_3set(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_13ArrayTreeNode_3set(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  int __pyx_v_index;
+  PyObject *__pyx_v_value = 0;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("set (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__index,&__pyx_n_s__value,0};
+    PyObject* values[2] = {0,0};
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__index)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__value)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("set", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 345; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "set") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 345; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
+      goto __pyx_L5_argtuple_error;
+    } else {
+      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+    }
+    __pyx_v_index = __Pyx_PyInt_AsInt(values[0]); if (unlikely((__pyx_v_index == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 345; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_value = values[1];
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("set", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 345; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.arrays.array_tree.ArrayTreeNode.set", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_6arrays_10array_tree_13ArrayTreeNode_2set(((struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeNode *)__pyx_v_self), __pyx_v_index, __pyx_v_value);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/arrays/array_tree.pyx":345
+ *             self.children[ index ] = ArrayTreeNode( self.tree, min, max, self.block_size, self.level - 1 )
+ * 
+ *     def set( self, int index, value ):             # <<<<<<<<<<<<<<
+ *         cdef int bin_index = ( index - self.min ) // ( self.child_size )
+ *         if self.children[ bin_index ] is None:
+ */
+
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_13ArrayTreeNode_2set(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeNode *__pyx_v_self, int __pyx_v_index, PyObject *__pyx_v_value) {
+  int __pyx_v_bin_index;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
+  int __pyx_t_3;
+  PyObject *__pyx_t_4 = NULL;
+  PyObject *__pyx_t_5 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("set", 0);
+
+  /* "bx/arrays/array_tree.pyx":346
+ * 
+ *     def set( self, int index, value ):
+ *         cdef int bin_index = ( index - self.min ) // ( self.child_size )             # <<<<<<<<<<<<<<
+ *         if self.children[ bin_index ] is None:
+ *             self.init_bin( bin_index )
+ */
+  __pyx_t_1 = (__pyx_v_index - __pyx_v_self->min);
+  if (unlikely(__pyx_v_self->child_size == 0)) {
+    PyErr_Format(PyExc_ZeroDivisionError, "integer division or modulo by zero");
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 346; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  else if (sizeof(int) == sizeof(long) && unlikely(__pyx_v_self->child_size == -1) && unlikely(UNARY_NEG_WOULD_OVERFLOW(__pyx_t_1))) {
+    PyErr_Format(PyExc_OverflowError, "value too large to perform division");
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 346; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  __pyx_v_bin_index = __Pyx_div_int(__pyx_t_1, __pyx_v_self->child_size);
+
+  /* "bx/arrays/array_tree.pyx":347
+ *     def set( self, int index, value ):
+ *         cdef int bin_index = ( index - self.min ) // ( self.child_size )
+ *         if self.children[ bin_index ] is None:             # <<<<<<<<<<<<<<
+ *             self.init_bin( bin_index )
+ *         self.children[ bin_index ].set( index, value )
+ */
+  __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_self->children, __pyx_v_bin_index, sizeof(int), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 347; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = (__pyx_t_2 == Py_None);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  if (__pyx_t_3) {
+
+    /* "bx/arrays/array_tree.pyx":348
+ *         cdef int bin_index = ( index - self.min ) // ( self.child_size )
+ *         if self.children[ bin_index ] is None:
+ *             self.init_bin( bin_index )             # <<<<<<<<<<<<<<
+ *         self.children[ bin_index ].set( index, value )
+ * 
+ */
+    __pyx_t_2 = __pyx_f_2bx_6arrays_10array_tree_13ArrayTreeNode_init_bin(__pyx_v_self, __pyx_v_bin_index); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 348; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  /* "bx/arrays/array_tree.pyx":349
+ *         if self.children[ bin_index ] is None:
+ *             self.init_bin( bin_index )
+ *         self.children[ bin_index ].set( index, value )             # <<<<<<<<<<<<<<
+ * 
+ *     def get( self, int index ):
+ */
+  __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_self->children, __pyx_v_bin_index, sizeof(int), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 349; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_4 = PyObject_GetAttr(__pyx_t_2, __pyx_n_s__set); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 349; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_2 = PyInt_FromLong(__pyx_v_index); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 349; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 349; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_2);
+  __Pyx_GIVEREF(__pyx_t_2);
+  __Pyx_INCREF(__pyx_v_value);
+  PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_v_value);
+  __Pyx_GIVEREF(__pyx_v_value);
+  __pyx_t_2 = 0;
+  __pyx_t_2 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_t_5), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 349; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_5)); __pyx_t_5 = 0;
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_XDECREF(__pyx_t_5);
+  __Pyx_AddTraceback("bx.arrays.array_tree.ArrayTreeNode.set", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_13ArrayTreeNode_5get(PyObject *__pyx_v_self, PyObject *__pyx_arg_index); /*proto*/
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_13ArrayTreeNode_5get(PyObject *__pyx_v_self, PyObject *__pyx_arg_index) {
+  int __pyx_v_index;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("get (wrapper)", 0);
+  assert(__pyx_arg_index); {
+    __pyx_v_index = __Pyx_PyInt_AsInt(__pyx_arg_index); if (unlikely((__pyx_v_index == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 351; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.arrays.array_tree.ArrayTreeNode.get", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_6arrays_10array_tree_13ArrayTreeNode_4get(((struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeNode *)__pyx_v_self), ((int)__pyx_v_index));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/arrays/array_tree.pyx":351
+ *         self.children[ bin_index ].set( index, value )
+ * 
+ *     def get( self, int index ):             # <<<<<<<<<<<<<<
+ *         cdef int bin_index = ( index - self.min ) // ( self.child_size )
+ *         if self.children[ bin_index ] is None:
+ */
+
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_13ArrayTreeNode_4get(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeNode *__pyx_v_self, int __pyx_v_index) {
+  int __pyx_v_bin_index;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
+  int __pyx_t_3;
+  PyObject *__pyx_t_4 = NULL;
+  PyObject *__pyx_t_5 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("get", 0);
+
+  /* "bx/arrays/array_tree.pyx":352
+ * 
+ *     def get( self, int index ):
+ *         cdef int bin_index = ( index - self.min ) // ( self.child_size )             # <<<<<<<<<<<<<<
+ *         if self.children[ bin_index ] is None:
+ *             return nan
+ */
+  __pyx_t_1 = (__pyx_v_index - __pyx_v_self->min);
+  if (unlikely(__pyx_v_self->child_size == 0)) {
+    PyErr_Format(PyExc_ZeroDivisionError, "integer division or modulo by zero");
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  else if (sizeof(int) == sizeof(long) && unlikely(__pyx_v_self->child_size == -1) && unlikely(UNARY_NEG_WOULD_OVERFLOW(__pyx_t_1))) {
+    PyErr_Format(PyExc_OverflowError, "value too large to perform division");
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  __pyx_v_bin_index = __Pyx_div_int(__pyx_t_1, __pyx_v_self->child_size);
+
+  /* "bx/arrays/array_tree.pyx":353
+ *     def get( self, int index ):
+ *         cdef int bin_index = ( index - self.min ) // ( self.child_size )
+ *         if self.children[ bin_index ] is None:             # <<<<<<<<<<<<<<
+ *             return nan
+ *         else:
+ */
+  __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_self->children, __pyx_v_bin_index, sizeof(int), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 353; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = (__pyx_t_2 == Py_None);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  if (__pyx_t_3) {
+
+    /* "bx/arrays/array_tree.pyx":354
+ *         cdef int bin_index = ( index - self.min ) // ( self.child_size )
+ *         if self.children[ bin_index ] is None:
+ *             return nan             # <<<<<<<<<<<<<<
+ *         else:
+ *             return self.children[ bin_index ].get( index )
+ */
+    __Pyx_XDECREF(__pyx_r);
+    __pyx_t_2 = __Pyx_GetName(__pyx_m, __pyx_n_s__nan); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 354; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_r = __pyx_t_2;
+    __pyx_t_2 = 0;
+    goto __pyx_L0;
+    goto __pyx_L3;
+  }
+  /*else*/ {
+
+    /* "bx/arrays/array_tree.pyx":356
+ *             return nan
+ *         else:
+ *             return self.children[ bin_index ].get( index )             # <<<<<<<<<<<<<<
+ * 
+ *     cpdef build_summary( self ):
+ */
+    __Pyx_XDECREF(__pyx_r);
+    __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_self->children, __pyx_v_bin_index, sizeof(int), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 356; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_t_4 = PyObject_GetAttr(__pyx_t_2, __pyx_n_s__get); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 356; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    __pyx_t_2 = PyInt_FromLong(__pyx_v_index); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 356; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 356; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_5);
+    PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_2);
+    __Pyx_GIVEREF(__pyx_t_2);
+    __pyx_t_2 = 0;
+    __pyx_t_2 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_t_5), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 356; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    __Pyx_DECREF(((PyObject *)__pyx_t_5)); __pyx_t_5 = 0;
+    __pyx_r = __pyx_t_2;
+    __pyx_t_2 = 0;
+    goto __pyx_L0;
+  }
+  __pyx_L3:;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_XDECREF(__pyx_t_5);
+  __Pyx_AddTraceback("bx.arrays.array_tree.ArrayTreeNode.get", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/arrays/array_tree.pyx":358
+ *             return self.children[ bin_index ].get( index )
+ * 
+ *     cpdef build_summary( self ):             # <<<<<<<<<<<<<<
+ *         """
+ *         Build summary of children.
+ */
+
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_13ArrayTreeNode_7build_summary(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static PyObject *__pyx_f_2bx_6arrays_10array_tree_13ArrayTreeNode_build_summary(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeNode *__pyx_v_self, int __pyx_skip_dispatch) {
+  PyObject *__pyx_v_counts = NULL;
+  PyObject *__pyx_v_frequencies = NULL;
+  PyObject *__pyx_v_mins = NULL;
+  PyObject *__pyx_v_maxs = NULL;
+  PyObject *__pyx_v_sums = NULL;
+  PyObject *__pyx_v_sumsquares = NULL;
+  PyObject *__pyx_v_i = NULL;
+  PyObject *__pyx_v_v = NULL;
+  PyObject *__pyx_v_c = NULL;
+  struct __pyx_obj_2bx_6arrays_10array_tree_Summary *__pyx_v_s = NULL;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  Py_ssize_t __pyx_t_4;
+  PyObject *(*__pyx_t_5)(PyObject *);
+  int __pyx_t_6;
+  PyObject *__pyx_t_7 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("build_summary", 0);
+  /* Check if called by wrapper */
+  if (unlikely(__pyx_skip_dispatch)) ;
+  /* Check if overridden in Python */
+  else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
+    __pyx_t_1 = PyObject_GetAttr(((PyObject *)__pyx_v_self), __pyx_n_s__build_summary); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 358; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_2bx_6arrays_10array_tree_13ArrayTreeNode_7build_summary)) {
+      __Pyx_XDECREF(__pyx_r);
+      __pyx_t_2 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 358; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_2);
+      __pyx_r = __pyx_t_2;
+      __pyx_t_2 = 0;
+      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+      goto __pyx_L0;
+    }
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  }
+
+  /* "bx/arrays/array_tree.pyx":362
+ *         Build summary of children.
+ *         """
+ *         counts = empty( self.tree.block_size, self.tree.dtype )             # <<<<<<<<<<<<<<
+ *         frequencies = empty( self.tree.block_size, self.tree.dtype )
+ *         mins = empty( self.tree.block_size, self.tree.dtype )
+ */
+  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__empty); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 362; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = PyInt_FromLong(__pyx_v_self->tree->block_size); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 362; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 362; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_2);
+  __Pyx_GIVEREF(__pyx_t_2);
+  __Pyx_INCREF(__pyx_v_self->tree->dtype);
+  PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_v_self->tree->dtype);
+  __Pyx_GIVEREF(__pyx_v_self->tree->dtype);
+  __pyx_t_2 = 0;
+  __pyx_t_2 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 362; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
+  __pyx_v_counts = __pyx_t_2;
+  __pyx_t_2 = 0;
+
+  /* "bx/arrays/array_tree.pyx":363
+ *         """
+ *         counts = empty( self.tree.block_size, self.tree.dtype )
+ *         frequencies = empty( self.tree.block_size, self.tree.dtype )             # <<<<<<<<<<<<<<
+ *         mins = empty( self.tree.block_size, self.tree.dtype )
+ *         maxs = empty( self.tree.block_size, self.tree.dtype )
+ */
+  __pyx_t_2 = __Pyx_GetName(__pyx_m, __pyx_n_s__empty); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 363; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = PyInt_FromLong(__pyx_v_self->tree->block_size); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 363; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 363; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_3);
+  __Pyx_GIVEREF(__pyx_t_3);
+  __Pyx_INCREF(__pyx_v_self->tree->dtype);
+  PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_v_self->tree->dtype);
+  __Pyx_GIVEREF(__pyx_v_self->tree->dtype);
+  __pyx_t_3 = 0;
+  __pyx_t_3 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 363; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+  __pyx_v_frequencies = __pyx_t_3;
+  __pyx_t_3 = 0;
+
+  /* "bx/arrays/array_tree.pyx":364
+ *         counts = empty( self.tree.block_size, self.tree.dtype )
+ *         frequencies = empty( self.tree.block_size, self.tree.dtype )
+ *         mins = empty( self.tree.block_size, self.tree.dtype )             # <<<<<<<<<<<<<<
+ *         maxs = empty( self.tree.block_size, self.tree.dtype )
+ *         sums = empty( self.tree.block_size, self.tree.dtype )
+ */
+  __pyx_t_3 = __Pyx_GetName(__pyx_m, __pyx_n_s__empty); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 364; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_1 = PyInt_FromLong(__pyx_v_self->tree->block_size); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 364; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 364; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
+  __Pyx_GIVEREF(__pyx_t_1);
+  __Pyx_INCREF(__pyx_v_self->tree->dtype);
+  PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_v_self->tree->dtype);
+  __Pyx_GIVEREF(__pyx_v_self->tree->dtype);
+  __pyx_t_1 = 0;
+  __pyx_t_1 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 364; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
+  __pyx_v_mins = __pyx_t_1;
+  __pyx_t_1 = 0;
+
+  /* "bx/arrays/array_tree.pyx":365
+ *         frequencies = empty( self.tree.block_size, self.tree.dtype )
+ *         mins = empty( self.tree.block_size, self.tree.dtype )
+ *         maxs = empty( self.tree.block_size, self.tree.dtype )             # <<<<<<<<<<<<<<
+ *         sums = empty( self.tree.block_size, self.tree.dtype )
+ *         sumsquares = empty( self.tree.block_size, self.tree.dtype )
+ */
+  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__empty); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 365; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = PyInt_FromLong(__pyx_v_self->tree->block_size); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 365; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 365; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_2);
+  __Pyx_GIVEREF(__pyx_t_2);
+  __Pyx_INCREF(__pyx_v_self->tree->dtype);
+  PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_v_self->tree->dtype);
+  __Pyx_GIVEREF(__pyx_v_self->tree->dtype);
+  __pyx_t_2 = 0;
+  __pyx_t_2 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 365; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
+  __pyx_v_maxs = __pyx_t_2;
+  __pyx_t_2 = 0;
+
+  /* "bx/arrays/array_tree.pyx":366
+ *         mins = empty( self.tree.block_size, self.tree.dtype )
+ *         maxs = empty( self.tree.block_size, self.tree.dtype )
+ *         sums = empty( self.tree.block_size, self.tree.dtype )             # <<<<<<<<<<<<<<
+ *         sumsquares = empty( self.tree.block_size, self.tree.dtype )
+ *         for i in range( len( self.children ) ):
+ */
+  __pyx_t_2 = __Pyx_GetName(__pyx_m, __pyx_n_s__empty); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 366; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = PyInt_FromLong(__pyx_v_self->tree->block_size); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 366; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 366; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_3);
+  __Pyx_GIVEREF(__pyx_t_3);
+  __Pyx_INCREF(__pyx_v_self->tree->dtype);
+  PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_v_self->tree->dtype);
+  __Pyx_GIVEREF(__pyx_v_self->tree->dtype);
+  __pyx_t_3 = 0;
+  __pyx_t_3 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 366; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+  __pyx_v_sums = __pyx_t_3;
+  __pyx_t_3 = 0;
+
+  /* "bx/arrays/array_tree.pyx":367
+ *         maxs = empty( self.tree.block_size, self.tree.dtype )
+ *         sums = empty( self.tree.block_size, self.tree.dtype )
+ *         sumsquares = empty( self.tree.block_size, self.tree.dtype )             # <<<<<<<<<<<<<<
+ *         for i in range( len( self.children ) ):
+ *             if self.children[i]:
+ */
+  __pyx_t_3 = __Pyx_GetName(__pyx_m, __pyx_n_s__empty); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 367; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_1 = PyInt_FromLong(__pyx_v_self->tree->block_size); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 367; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 367; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
+  __Pyx_GIVEREF(__pyx_t_1);
+  __Pyx_INCREF(__pyx_v_self->tree->dtype);
+  PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_v_self->tree->dtype);
+  __Pyx_GIVEREF(__pyx_v_self->tree->dtype);
+  __pyx_t_1 = 0;
+  __pyx_t_1 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 367; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
+  __pyx_v_sumsquares = __pyx_t_1;
+  __pyx_t_1 = 0;
+
+  /* "bx/arrays/array_tree.pyx":368
+ *         sums = empty( self.tree.block_size, self.tree.dtype )
+ *         sumsquares = empty( self.tree.block_size, self.tree.dtype )
+ *         for i in range( len( self.children ) ):             # <<<<<<<<<<<<<<
+ *             if self.children[i]:
+ *                 if self.level == 1:
+ */
+  __pyx_t_1 = __pyx_v_self->children;
+  __Pyx_INCREF(__pyx_t_1);
+  __pyx_t_4 = PyObject_Length(__pyx_t_1); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 368; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_1 = PyInt_FromSsize_t(__pyx_t_4); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 368; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 368; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
+  __Pyx_GIVEREF(__pyx_t_1);
+  __pyx_t_1 = 0;
+  __pyx_t_1 = PyObject_Call(__pyx_builtin_range, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 368; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
+  if (PyList_CheckExact(__pyx_t_1) || PyTuple_CheckExact(__pyx_t_1)) {
+    __pyx_t_2 = __pyx_t_1; __Pyx_INCREF(__pyx_t_2); __pyx_t_4 = 0;
+    __pyx_t_5 = NULL;
+  } else {
+    __pyx_t_4 = -1; __pyx_t_2 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 368; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_t_5 = Py_TYPE(__pyx_t_2)->tp_iternext;
+  }
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  for (;;) {
+    if (!__pyx_t_5 && PyList_CheckExact(__pyx_t_2)) {
+      if (__pyx_t_4 >= PyList_GET_SIZE(__pyx_t_2)) break;
+      #if CYTHON_COMPILING_IN_CPYTHON
+      __pyx_t_1 = PyList_GET_ITEM(__pyx_t_2, __pyx_t_4); __Pyx_INCREF(__pyx_t_1); __pyx_t_4++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 368; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      #else
+      __pyx_t_1 = PySequence_ITEM(__pyx_t_2, __pyx_t_4); __pyx_t_4++; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 368; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      #endif
+    } else if (!__pyx_t_5 && PyTuple_CheckExact(__pyx_t_2)) {
+      if (__pyx_t_4 >= PyTuple_GET_SIZE(__pyx_t_2)) break;
+      #if CYTHON_COMPILING_IN_CPYTHON
+      __pyx_t_1 = PyTuple_GET_ITEM(__pyx_t_2, __pyx_t_4); __Pyx_INCREF(__pyx_t_1); __pyx_t_4++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 368; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      #else
+      __pyx_t_1 = PySequence_ITEM(__pyx_t_2, __pyx_t_4); __pyx_t_4++; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 368; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      #endif
+    } else {
+      __pyx_t_1 = __pyx_t_5(__pyx_t_2);
+      if (unlikely(!__pyx_t_1)) {
+        if (PyErr_Occurred()) {
+          if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
+          else {__pyx_filename = __pyx_f[0]; __pyx_lineno = 368; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        }
+        break;
+      }
+      __Pyx_GOTREF(__pyx_t_1);
+    }
+    __Pyx_XDECREF(__pyx_v_i);
+    __pyx_v_i = __pyx_t_1;
+    __pyx_t_1 = 0;
+
+    /* "bx/arrays/array_tree.pyx":369
+ *         sumsquares = empty( self.tree.block_size, self.tree.dtype )
+ *         for i in range( len( self.children ) ):
+ *             if self.children[i]:             # <<<<<<<<<<<<<<
+ *                 if self.level == 1:
+ *                     v = self.children[i].values
+ */
+    __pyx_t_1 = PyObject_GetItem(__pyx_v_self->children, __pyx_v_i); if (!__pyx_t_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 369; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 369; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    if (__pyx_t_6) {
+
+      /* "bx/arrays/array_tree.pyx":370
+ *         for i in range( len( self.children ) ):
+ *             if self.children[i]:
+ *                 if self.level == 1:             # <<<<<<<<<<<<<<
+ *                     v = self.children[i].values
+ *                     counts[i] = sum( ~isnan( v ) )
+ */
+      __pyx_t_6 = (__pyx_v_self->level == 1);
+      if (__pyx_t_6) {
+
+        /* "bx/arrays/array_tree.pyx":371
+ *             if self.children[i]:
+ *                 if self.level == 1:
+ *                     v = self.children[i].values             # <<<<<<<<<<<<<<
+ *                     counts[i] = sum( ~isnan( v ) )
+ *                     frequencies[i] = self.children[i].frequency
+ */
+        __pyx_t_1 = PyObject_GetItem(__pyx_v_self->children, __pyx_v_i); if (!__pyx_t_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 371; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_1);
+        __pyx_t_3 = PyObject_GetAttr(__pyx_t_1, __pyx_n_s__values); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 371; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_3);
+        __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+        __Pyx_XDECREF(__pyx_v_v);
+        __pyx_v_v = __pyx_t_3;
+        __pyx_t_3 = 0;
+
+        /* "bx/arrays/array_tree.pyx":372
+ *                 if self.level == 1:
+ *                     v = self.children[i].values
+ *                     counts[i] = sum( ~isnan( v ) )             # <<<<<<<<<<<<<<
+ *                     frequencies[i] = self.children[i].frequency
+ *                     mins[i] = nanmin( v )
+ */
+        __pyx_t_3 = __Pyx_GetName(__pyx_m, __pyx_n_s__isnan); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 372; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_3);
+        __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 372; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_1);
+        __Pyx_INCREF(__pyx_v_v);
+        PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_v);
+        __Pyx_GIVEREF(__pyx_v_v);
+        __pyx_t_7 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 372; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_7);
+        __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+        __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+        __pyx_t_1 = PyNumber_Invert(__pyx_t_7); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 372; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_1);
+        __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+        __pyx_t_7 = PyTuple_New(1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 372; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_7);
+        PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_1);
+        __Pyx_GIVEREF(__pyx_t_1);
+        __pyx_t_1 = 0;
+        __pyx_t_1 = PyObject_Call(__pyx_builtin_sum, ((PyObject *)__pyx_t_7), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 372; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_1);
+        __Pyx_DECREF(((PyObject *)__pyx_t_7)); __pyx_t_7 = 0;
+        if (PyObject_SetItem(__pyx_v_counts, __pyx_v_i, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 372; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+        /* "bx/arrays/array_tree.pyx":373
+ *                     v = self.children[i].values
+ *                     counts[i] = sum( ~isnan( v ) )
+ *                     frequencies[i] = self.children[i].frequency             # <<<<<<<<<<<<<<
+ *                     mins[i] = nanmin( v )
+ *                     maxs[i] = nanmax( v )
+ */
+        __pyx_t_1 = PyObject_GetItem(__pyx_v_self->children, __pyx_v_i); if (!__pyx_t_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 373; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_1);
+        __pyx_t_7 = PyObject_GetAttr(__pyx_t_1, __pyx_n_s__frequency); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 373; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_7);
+        __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+        if (PyObject_SetItem(__pyx_v_frequencies, __pyx_v_i, __pyx_t_7) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 373; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+
+        /* "bx/arrays/array_tree.pyx":374
+ *                     counts[i] = sum( ~isnan( v ) )
+ *                     frequencies[i] = self.children[i].frequency
+ *                     mins[i] = nanmin( v )             # <<<<<<<<<<<<<<
+ *                     maxs[i] = nanmax( v )
+ *                     sums[i] = nansum( v )
+ */
+        __pyx_t_7 = __Pyx_GetName(__pyx_m, __pyx_n_s__nanmin); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 374; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_7);
+        __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 374; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_1);
+        __Pyx_INCREF(__pyx_v_v);
+        PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_v);
+        __Pyx_GIVEREF(__pyx_v_v);
+        __pyx_t_3 = PyObject_Call(__pyx_t_7, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 374; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_3);
+        __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+        __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+        if (PyObject_SetItem(__pyx_v_mins, __pyx_v_i, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 374; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+        /* "bx/arrays/array_tree.pyx":375
+ *                     frequencies[i] = self.children[i].frequency
+ *                     mins[i] = nanmin( v )
+ *                     maxs[i] = nanmax( v )             # <<<<<<<<<<<<<<
+ *                     sums[i] = nansum( v )
+ *                     sumsquares[i] = nansum( v ** 2 )
+ */
+        __pyx_t_3 = __Pyx_GetName(__pyx_m, __pyx_n_s__nanmax); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 375; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_3);
+        __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 375; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_1);
+        __Pyx_INCREF(__pyx_v_v);
+        PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_v);
+        __Pyx_GIVEREF(__pyx_v_v);
+        __pyx_t_7 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 375; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_7);
+        __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+        __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+        if (PyObject_SetItem(__pyx_v_maxs, __pyx_v_i, __pyx_t_7) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 375; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+
+        /* "bx/arrays/array_tree.pyx":376
+ *                     mins[i] = nanmin( v )
+ *                     maxs[i] = nanmax( v )
+ *                     sums[i] = nansum( v )             # <<<<<<<<<<<<<<
+ *                     sumsquares[i] = nansum( v ** 2 )
+ *                 else:
+ */
+        __pyx_t_7 = __Pyx_GetName(__pyx_m, __pyx_n_s__nansum); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 376; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_7);
+        __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 376; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_1);
+        __Pyx_INCREF(__pyx_v_v);
+        PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_v);
+        __Pyx_GIVEREF(__pyx_v_v);
+        __pyx_t_3 = PyObject_Call(__pyx_t_7, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 376; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_3);
+        __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+        __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+        if (PyObject_SetItem(__pyx_v_sums, __pyx_v_i, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 376; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+        /* "bx/arrays/array_tree.pyx":377
+ *                     maxs[i] = nanmax( v )
+ *                     sums[i] = nansum( v )
+ *                     sumsquares[i] = nansum( v ** 2 )             # <<<<<<<<<<<<<<
+ *                 else:
+ *                     c = self.children[i]
+ */
+        __pyx_t_3 = __Pyx_GetName(__pyx_m, __pyx_n_s__nansum); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 377; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_3);
+        __pyx_t_1 = PyNumber_Power(__pyx_v_v, __pyx_int_2, Py_None); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 377; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_1);
+        __pyx_t_7 = PyTuple_New(1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 377; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_7);
+        PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_1);
+        __Pyx_GIVEREF(__pyx_t_1);
+        __pyx_t_1 = 0;
+        __pyx_t_1 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_t_7), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 377; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_1);
+        __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+        __Pyx_DECREF(((PyObject *)__pyx_t_7)); __pyx_t_7 = 0;
+        if (PyObject_SetItem(__pyx_v_sumsquares, __pyx_v_i, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 377; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+        goto __pyx_L6;
+      }
+      /*else*/ {
+
+        /* "bx/arrays/array_tree.pyx":379
+ *                     sumsquares[i] = nansum( v ** 2 )
+ *                 else:
+ *                     c = self.children[i]             # <<<<<<<<<<<<<<
+ *                     c.build_summary()
+ *                     counts[i] = sum( c.summary.counts )
+ */
+        __pyx_t_1 = PyObject_GetItem(__pyx_v_self->children, __pyx_v_i); if (!__pyx_t_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 379; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_1);
+        __Pyx_XDECREF(__pyx_v_c);
+        __pyx_v_c = __pyx_t_1;
+        __pyx_t_1 = 0;
+
+        /* "bx/arrays/array_tree.pyx":380
+ *                 else:
+ *                     c = self.children[i]
+ *                     c.build_summary()             # <<<<<<<<<<<<<<
+ *                     counts[i] = sum( c.summary.counts )
+ *                     frequencies[i] = sum( c.summary.frequencies )
+ */
+        __pyx_t_1 = PyObject_GetAttr(__pyx_v_c, __pyx_n_s__build_summary); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 380; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_1);
+        __pyx_t_7 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 380; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_7);
+        __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+        __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+
+        /* "bx/arrays/array_tree.pyx":381
+ *                     c = self.children[i]
+ *                     c.build_summary()
+ *                     counts[i] = sum( c.summary.counts )             # <<<<<<<<<<<<<<
+ *                     frequencies[i] = sum( c.summary.frequencies )
+ *                     mins[i] = nanmin( c.summary.mins )
+ */
+        __pyx_t_7 = PyObject_GetAttr(__pyx_v_c, __pyx_n_s__summary); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 381; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_7);
+        __pyx_t_1 = PyObject_GetAttr(__pyx_t_7, __pyx_n_s__counts); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 381; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_1);
+        __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+        __pyx_t_7 = PyTuple_New(1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 381; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_7);
+        PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_1);
+        __Pyx_GIVEREF(__pyx_t_1);
+        __pyx_t_1 = 0;
+        __pyx_t_1 = PyObject_Call(__pyx_builtin_sum, ((PyObject *)__pyx_t_7), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 381; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_1);
+        __Pyx_DECREF(((PyObject *)__pyx_t_7)); __pyx_t_7 = 0;
+        if (PyObject_SetItem(__pyx_v_counts, __pyx_v_i, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 381; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+        /* "bx/arrays/array_tree.pyx":382
+ *                     c.build_summary()
+ *                     counts[i] = sum( c.summary.counts )
+ *                     frequencies[i] = sum( c.summary.frequencies )             # <<<<<<<<<<<<<<
+ *                     mins[i] = nanmin( c.summary.mins )
+ *                     maxs[i] = nanmax( c.summary.maxs )
+ */
+        __pyx_t_1 = PyObject_GetAttr(__pyx_v_c, __pyx_n_s__summary); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 382; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_1);
+        __pyx_t_7 = PyObject_GetAttr(__pyx_t_1, __pyx_n_s__frequencies); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 382; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_7);
+        __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+        __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 382; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_1);
+        PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_7);
+        __Pyx_GIVEREF(__pyx_t_7);
+        __pyx_t_7 = 0;
+        __pyx_t_7 = PyObject_Call(__pyx_builtin_sum, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 382; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_7);
+        __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+        if (PyObject_SetItem(__pyx_v_frequencies, __pyx_v_i, __pyx_t_7) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 382; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+
+        /* "bx/arrays/array_tree.pyx":383
+ *                     counts[i] = sum( c.summary.counts )
+ *                     frequencies[i] = sum( c.summary.frequencies )
+ *                     mins[i] = nanmin( c.summary.mins )             # <<<<<<<<<<<<<<
+ *                     maxs[i] = nanmax( c.summary.maxs )
+ *                     sums[i] = nansum( c.summary.sums )
+ */
+        __pyx_t_7 = __Pyx_GetName(__pyx_m, __pyx_n_s__nanmin); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 383; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_7);
+        __pyx_t_1 = PyObject_GetAttr(__pyx_v_c, __pyx_n_s__summary); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 383; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_1);
+        __pyx_t_3 = PyObject_GetAttr(__pyx_t_1, __pyx_n_s__mins); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 383; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_3);
+        __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+        __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 383; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_1);
+        PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_3);
+        __Pyx_GIVEREF(__pyx_t_3);
+        __pyx_t_3 = 0;
+        __pyx_t_3 = PyObject_Call(__pyx_t_7, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 383; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_3);
+        __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+        __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+        if (PyObject_SetItem(__pyx_v_mins, __pyx_v_i, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 383; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+        /* "bx/arrays/array_tree.pyx":384
+ *                     frequencies[i] = sum( c.summary.frequencies )
+ *                     mins[i] = nanmin( c.summary.mins )
+ *                     maxs[i] = nanmax( c.summary.maxs )             # <<<<<<<<<<<<<<
+ *                     sums[i] = nansum( c.summary.sums )
+ *                     sumsquares[i] = nansum( c.summary.sumsquares )
+ */
+        __pyx_t_3 = __Pyx_GetName(__pyx_m, __pyx_n_s__nanmax); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 384; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_3);
+        __pyx_t_1 = PyObject_GetAttr(__pyx_v_c, __pyx_n_s__summary); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 384; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_1);
+        __pyx_t_7 = PyObject_GetAttr(__pyx_t_1, __pyx_n_s__maxs); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 384; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_7);
+        __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+        __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 384; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_1);
+        PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_7);
+        __Pyx_GIVEREF(__pyx_t_7);
+        __pyx_t_7 = 0;
+        __pyx_t_7 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 384; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_7);
+        __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+        __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+        if (PyObject_SetItem(__pyx_v_maxs, __pyx_v_i, __pyx_t_7) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 384; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+
+        /* "bx/arrays/array_tree.pyx":385
+ *                     mins[i] = nanmin( c.summary.mins )
+ *                     maxs[i] = nanmax( c.summary.maxs )
+ *                     sums[i] = nansum( c.summary.sums )             # <<<<<<<<<<<<<<
+ *                     sumsquares[i] = nansum( c.summary.sumsquares )
+ *             else:
+ */
+        __pyx_t_7 = __Pyx_GetName(__pyx_m, __pyx_n_s__nansum); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 385; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_7);
+        __pyx_t_1 = PyObject_GetAttr(__pyx_v_c, __pyx_n_s__summary); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 385; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_1);
+        __pyx_t_3 = PyObject_GetAttr(__pyx_t_1, __pyx_n_s__sums); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 385; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_3);
+        __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+        __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 385; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_1);
+        PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_3);
+        __Pyx_GIVEREF(__pyx_t_3);
+        __pyx_t_3 = 0;
+        __pyx_t_3 = PyObject_Call(__pyx_t_7, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 385; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_3);
+        __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+        __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+        if (PyObject_SetItem(__pyx_v_sums, __pyx_v_i, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 385; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+        /* "bx/arrays/array_tree.pyx":386
+ *                     maxs[i] = nanmax( c.summary.maxs )
+ *                     sums[i] = nansum( c.summary.sums )
+ *                     sumsquares[i] = nansum( c.summary.sumsquares )             # <<<<<<<<<<<<<<
+ *             else:
+ *                 counts[i] = 0
+ */
+        __pyx_t_3 = __Pyx_GetName(__pyx_m, __pyx_n_s__nansum); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 386; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_3);
+        __pyx_t_1 = PyObject_GetAttr(__pyx_v_c, __pyx_n_s__summary); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 386; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_1);
+        __pyx_t_7 = PyObject_GetAttr(__pyx_t_1, __pyx_n_s__sumsquares); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 386; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_7);
+        __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+        __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 386; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_1);
+        PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_7);
+        __Pyx_GIVEREF(__pyx_t_7);
+        __pyx_t_7 = 0;
+        __pyx_t_7 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 386; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_7);
+        __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+        __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+        if (PyObject_SetItem(__pyx_v_sumsquares, __pyx_v_i, __pyx_t_7) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 386; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+      }
+      __pyx_L6:;
+      goto __pyx_L5;
+    }
+    /*else*/ {
+
+      /* "bx/arrays/array_tree.pyx":388
+ *                     sumsquares[i] = nansum( c.summary.sumsquares )
+ *             else:
+ *                 counts[i] = 0             # <<<<<<<<<<<<<<
+ *                 frequencies[i] = 0
+ *                 mins[i] = nan
+ */
+      if (PyObject_SetItem(__pyx_v_counts, __pyx_v_i, __pyx_int_0) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 388; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+      /* "bx/arrays/array_tree.pyx":389
+ *             else:
+ *                 counts[i] = 0
+ *                 frequencies[i] = 0             # <<<<<<<<<<<<<<
+ *                 mins[i] = nan
+ *                 maxs[i] = nan
+ */
+      if (PyObject_SetItem(__pyx_v_frequencies, __pyx_v_i, __pyx_int_0) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 389; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+      /* "bx/arrays/array_tree.pyx":390
+ *                 counts[i] = 0
+ *                 frequencies[i] = 0
+ *                 mins[i] = nan             # <<<<<<<<<<<<<<
+ *                 maxs[i] = nan
+ *                 sums[i] = nan
+ */
+      __pyx_t_7 = __Pyx_GetName(__pyx_m, __pyx_n_s__nan); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 390; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_7);
+      if (PyObject_SetItem(__pyx_v_mins, __pyx_v_i, __pyx_t_7) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 390; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+
+      /* "bx/arrays/array_tree.pyx":391
+ *                 frequencies[i] = 0
+ *                 mins[i] = nan
+ *                 maxs[i] = nan             # <<<<<<<<<<<<<<
+ *                 sums[i] = nan
+ *                 sumsquares[i] = nan
+ */
+      __pyx_t_7 = __Pyx_GetName(__pyx_m, __pyx_n_s__nan); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 391; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_7);
+      if (PyObject_SetItem(__pyx_v_maxs, __pyx_v_i, __pyx_t_7) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 391; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+
+      /* "bx/arrays/array_tree.pyx":392
+ *                 mins[i] = nan
+ *                 maxs[i] = nan
+ *                 sums[i] = nan             # <<<<<<<<<<<<<<
+ *                 sumsquares[i] = nan
+ *         s = Summary()
+ */
+      __pyx_t_7 = __Pyx_GetName(__pyx_m, __pyx_n_s__nan); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 392; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_7);
+      if (PyObject_SetItem(__pyx_v_sums, __pyx_v_i, __pyx_t_7) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 392; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+
+      /* "bx/arrays/array_tree.pyx":393
+ *                 maxs[i] = nan
+ *                 sums[i] = nan
+ *                 sumsquares[i] = nan             # <<<<<<<<<<<<<<
+ *         s = Summary()
+ *         s.counts = counts
+ */
+      __pyx_t_7 = __Pyx_GetName(__pyx_m, __pyx_n_s__nan); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 393; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_7);
+      if (PyObject_SetItem(__pyx_v_sumsquares, __pyx_v_i, __pyx_t_7) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 393; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+    }
+    __pyx_L5:;
+  }
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+  /* "bx/arrays/array_tree.pyx":394
+ *                 sums[i] = nan
+ *                 sumsquares[i] = nan
+ *         s = Summary()             # <<<<<<<<<<<<<<
+ *         s.counts = counts
+ *         s.frequencies = frequencies
+ */
+  __pyx_t_2 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_2bx_6arrays_10array_tree_Summary)), ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 394; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_v_s = ((struct __pyx_obj_2bx_6arrays_10array_tree_Summary *)__pyx_t_2);
+  __pyx_t_2 = 0;
+
+  /* "bx/arrays/array_tree.pyx":395
+ *                 sumsquares[i] = nan
+ *         s = Summary()
+ *         s.counts = counts             # <<<<<<<<<<<<<<
+ *         s.frequencies = frequencies
+ *         s.mins = mins
+ */
+  __Pyx_INCREF(__pyx_v_counts);
+  __Pyx_GIVEREF(__pyx_v_counts);
+  __Pyx_GOTREF(__pyx_v_s->counts);
+  __Pyx_DECREF(__pyx_v_s->counts);
+  __pyx_v_s->counts = __pyx_v_counts;
+
+  /* "bx/arrays/array_tree.pyx":396
+ *         s = Summary()
+ *         s.counts = counts
+ *         s.frequencies = frequencies             # <<<<<<<<<<<<<<
+ *         s.mins = mins
+ *         s.maxs = maxs
+ */
+  __Pyx_INCREF(__pyx_v_frequencies);
+  __Pyx_GIVEREF(__pyx_v_frequencies);
+  __Pyx_GOTREF(__pyx_v_s->frequencies);
+  __Pyx_DECREF(__pyx_v_s->frequencies);
+  __pyx_v_s->frequencies = __pyx_v_frequencies;
+
+  /* "bx/arrays/array_tree.pyx":397
+ *         s.counts = counts
+ *         s.frequencies = frequencies
+ *         s.mins = mins             # <<<<<<<<<<<<<<
+ *         s.maxs = maxs
+ *         s.sums = sums
+ */
+  __Pyx_INCREF(__pyx_v_mins);
+  __Pyx_GIVEREF(__pyx_v_mins);
+  __Pyx_GOTREF(__pyx_v_s->mins);
+  __Pyx_DECREF(__pyx_v_s->mins);
+  __pyx_v_s->mins = __pyx_v_mins;
+
+  /* "bx/arrays/array_tree.pyx":398
+ *         s.frequencies = frequencies
+ *         s.mins = mins
+ *         s.maxs = maxs             # <<<<<<<<<<<<<<
+ *         s.sums = sums
+ *         s.sumsquares = sumsquares
+ */
+  __Pyx_INCREF(__pyx_v_maxs);
+  __Pyx_GIVEREF(__pyx_v_maxs);
+  __Pyx_GOTREF(__pyx_v_s->maxs);
+  __Pyx_DECREF(__pyx_v_s->maxs);
+  __pyx_v_s->maxs = __pyx_v_maxs;
+
+  /* "bx/arrays/array_tree.pyx":399
+ *         s.mins = mins
+ *         s.maxs = maxs
+ *         s.sums = sums             # <<<<<<<<<<<<<<
+ *         s.sumsquares = sumsquares
+ *         self.summary = s
+ */
+  __Pyx_INCREF(__pyx_v_sums);
+  __Pyx_GIVEREF(__pyx_v_sums);
+  __Pyx_GOTREF(__pyx_v_s->sums);
+  __Pyx_DECREF(__pyx_v_s->sums);
+  __pyx_v_s->sums = __pyx_v_sums;
+
+  /* "bx/arrays/array_tree.pyx":400
+ *         s.maxs = maxs
+ *         s.sums = sums
+ *         s.sumsquares = sumsquares             # <<<<<<<<<<<<<<
+ *         self.summary = s
+ * 
+ */
+  __Pyx_INCREF(__pyx_v_sumsquares);
+  __Pyx_GIVEREF(__pyx_v_sumsquares);
+  __Pyx_GOTREF(__pyx_v_s->sumsquares);
+  __Pyx_DECREF(__pyx_v_s->sumsquares);
+  __pyx_v_s->sumsquares = __pyx_v_sumsquares;
+
+  /* "bx/arrays/array_tree.pyx":401
+ *         s.sums = sums
+ *         s.sumsquares = sumsquares
+ *         self.summary = s             # <<<<<<<<<<<<<<
+ * 
+ *     def to_file_data_pass( self, io, level ):
+ */
+  __Pyx_INCREF(((PyObject *)__pyx_v_s));
+  __Pyx_GIVEREF(((PyObject *)__pyx_v_s));
+  __Pyx_GOTREF(__pyx_v_self->summary);
+  __Pyx_DECREF(((PyObject *)__pyx_v_self->summary));
+  __pyx_v_self->summary = __pyx_v_s;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_7);
+  __Pyx_AddTraceback("bx.arrays.array_tree.ArrayTreeNode.build_summary", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_counts);
+  __Pyx_XDECREF(__pyx_v_frequencies);
+  __Pyx_XDECREF(__pyx_v_mins);
+  __Pyx_XDECREF(__pyx_v_maxs);
+  __Pyx_XDECREF(__pyx_v_sums);
+  __Pyx_XDECREF(__pyx_v_sumsquares);
+  __Pyx_XDECREF(__pyx_v_i);
+  __Pyx_XDECREF(__pyx_v_v);
+  __Pyx_XDECREF(__pyx_v_c);
+  __Pyx_XDECREF((PyObject *)__pyx_v_s);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_13ArrayTreeNode_7build_summary(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_2bx_6arrays_10array_tree_13ArrayTreeNode_6build_summary[] = "\n        Build summary of children. \n        ";
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_13ArrayTreeNode_7build_summary(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("build_summary (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_6arrays_10array_tree_13ArrayTreeNode_6build_summary(((struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeNode *)__pyx_v_self));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/arrays/array_tree.pyx":358
+ *             return self.children[ bin_index ].get( index )
+ * 
+ *     cpdef build_summary( self ):             # <<<<<<<<<<<<<<
+ *         """
+ *         Build summary of children.
+ */
+
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_13ArrayTreeNode_6build_summary(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeNode *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("build_summary", 0);
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = ((struct __pyx_vtabstruct_2bx_6arrays_10array_tree_ArrayTreeNode *)__pyx_v_self->__pyx_vtab)->build_summary(__pyx_v_self, 1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 358; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("bx.arrays.array_tree.ArrayTreeNode.build_summary", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_13ArrayTreeNode_9to_file_data_pass(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_2bx_6arrays_10array_tree_13ArrayTreeNode_8to_file_data_pass[] = "\n        First pass of writing to file, writes data and saves position of block.\n        ";
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_13ArrayTreeNode_9to_file_data_pass(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_io = 0;
+  PyObject *__pyx_v_level = 0;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("to_file_data_pass (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__io,&__pyx_n_s__level,0};
+    PyObject* values[2] = {0,0};
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__io)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__level)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("to_file_data_pass", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 403; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "to_file_data_pass") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 403; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
+      goto __pyx_L5_argtuple_error;
+    } else {
+      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+    }
+    __pyx_v_io = values[0];
+    __pyx_v_level = values[1];
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("to_file_data_pass", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 403; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.arrays.array_tree.ArrayTreeNode.to_file_data_pass", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_6arrays_10array_tree_13ArrayTreeNode_8to_file_data_pass(((struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeNode *)__pyx_v_self), __pyx_v_io, __pyx_v_level);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/arrays/array_tree.pyx":403
+ *         self.summary = s
+ * 
+ *     def to_file_data_pass( self, io, level ):             # <<<<<<<<<<<<<<
+ *         """
+ *         First pass of writing to file, writes data and saves position of block.
+ */
+
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_13ArrayTreeNode_8to_file_data_pass(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeNode *__pyx_v_self, PyObject *__pyx_v_io, PyObject *__pyx_v_level) {
+  PyObject *__pyx_v_i = NULL;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  long __pyx_t_4;
+  PyObject *__pyx_t_5 = NULL;
+  Py_ssize_t __pyx_t_6;
+  PyObject *(*__pyx_t_7)(PyObject *);
+  PyObject *__pyx_t_8 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("to_file_data_pass", 0);
+
+  /* "bx/arrays/array_tree.pyx":407
+ *         First pass of writing to file, writes data and saves position of block.
+ *         """
+ *         assert self.summary, "Writing without summaries is currently not supported"             # <<<<<<<<<<<<<<
+ *         # If we are at the current level being written, write a block
+ *         if self.level == level:
+ */
+  #ifndef CYTHON_WITHOUT_ASSERTIONS
+  __pyx_t_1 = __Pyx_PyObject_IsTrue(((PyObject *)__pyx_v_self->summary)); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 407; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (unlikely(!__pyx_t_1)) {
+    PyErr_SetObject(PyExc_AssertionError, ((PyObject *)__pyx_kp_s_19));
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 407; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  #endif
+
+  /* "bx/arrays/array_tree.pyx":409
+ *         assert self.summary, "Writing without summaries is currently not supported"
+ *         # If we are at the current level being written, write a block
+ *         if self.level == level:             # <<<<<<<<<<<<<<
+ *             # Save file offset where this block starts
+ *             self.start_offset = io.tell()
+ */
+  __pyx_t_2 = PyInt_FromLong(__pyx_v_self->level); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 409; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = PyObject_RichCompare(__pyx_t_2, __pyx_v_level, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 409; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 409; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  if (__pyx_t_1) {
+
+    /* "bx/arrays/array_tree.pyx":411
+ *         if self.level == level:
+ *             # Save file offset where this block starts
+ *             self.start_offset = io.tell()             # <<<<<<<<<<<<<<
+ *             # Write out summary data
+ *             io.write_raw_array( self.summary.counts )
+ */
+    __pyx_t_3 = PyObject_GetAttr(__pyx_v_io, __pyx_n_s__tell); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 411; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __pyx_t_2 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 411; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __pyx_t_4 = __Pyx_PyInt_AsLong(__pyx_t_2); if (unlikely((__pyx_t_4 == (long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 411; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    __pyx_v_self->start_offset = __pyx_t_4;
+
+    /* "bx/arrays/array_tree.pyx":413
+ *             self.start_offset = io.tell()
+ *             # Write out summary data
+ *             io.write_raw_array( self.summary.counts )             # <<<<<<<<<<<<<<
+ *             io.write_raw_array( self.summary.frequencies )
+ *             io.write_raw_array( self.summary.sums )
+ */
+    __pyx_t_2 = PyObject_GetAttr(__pyx_v_io, __pyx_n_s__write_raw_array); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 413; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 413; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_INCREF(__pyx_v_self->summary->counts);
+    PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_self->summary->counts);
+    __Pyx_GIVEREF(__pyx_v_self->summary->counts);
+    __pyx_t_5 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 413; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_5);
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
+    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+
+    /* "bx/arrays/array_tree.pyx":414
+ *             # Write out summary data
+ *             io.write_raw_array( self.summary.counts )
+ *             io.write_raw_array( self.summary.frequencies )             # <<<<<<<<<<<<<<
+ *             io.write_raw_array( self.summary.sums )
+ *             io.write_raw_array( self.summary.mins )
+ */
+    __pyx_t_5 = PyObject_GetAttr(__pyx_v_io, __pyx_n_s__write_raw_array); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 414; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_5);
+    __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 414; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_INCREF(__pyx_v_self->summary->frequencies);
+    PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_self->summary->frequencies);
+    __Pyx_GIVEREF(__pyx_v_self->summary->frequencies);
+    __pyx_t_2 = PyObject_Call(__pyx_t_5, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 414; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+    __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+    /* "bx/arrays/array_tree.pyx":415
+ *             io.write_raw_array( self.summary.counts )
+ *             io.write_raw_array( self.summary.frequencies )
+ *             io.write_raw_array( self.summary.sums )             # <<<<<<<<<<<<<<
+ *             io.write_raw_array( self.summary.mins )
+ *             io.write_raw_array( self.summary.maxs )
+ */
+    __pyx_t_2 = PyObject_GetAttr(__pyx_v_io, __pyx_n_s__write_raw_array); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 415; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 415; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_INCREF(__pyx_v_self->summary->sums);
+    PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_self->summary->sums);
+    __Pyx_GIVEREF(__pyx_v_self->summary->sums);
+    __pyx_t_5 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 415; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_5);
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
+    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+
+    /* "bx/arrays/array_tree.pyx":416
+ *             io.write_raw_array( self.summary.frequencies )
+ *             io.write_raw_array( self.summary.sums )
+ *             io.write_raw_array( self.summary.mins )             # <<<<<<<<<<<<<<
+ *             io.write_raw_array( self.summary.maxs )
+ *             io.write_raw_array( self.summary.sumsquares )
+ */
+    __pyx_t_5 = PyObject_GetAttr(__pyx_v_io, __pyx_n_s__write_raw_array); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 416; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_5);
+    __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 416; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_INCREF(__pyx_v_self->summary->mins);
+    PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_self->summary->mins);
+    __Pyx_GIVEREF(__pyx_v_self->summary->mins);
+    __pyx_t_2 = PyObject_Call(__pyx_t_5, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 416; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+    __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+    /* "bx/arrays/array_tree.pyx":417
+ *             io.write_raw_array( self.summary.sums )
+ *             io.write_raw_array( self.summary.mins )
+ *             io.write_raw_array( self.summary.maxs )             # <<<<<<<<<<<<<<
+ *             io.write_raw_array( self.summary.sumsquares )
+ *             # Skip enough room for child offsets (block_size children * 64bits)
+ */
+    __pyx_t_2 = PyObject_GetAttr(__pyx_v_io, __pyx_n_s__write_raw_array); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 417; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 417; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_INCREF(__pyx_v_self->summary->maxs);
+    PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_self->summary->maxs);
+    __Pyx_GIVEREF(__pyx_v_self->summary->maxs);
+    __pyx_t_5 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 417; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_5);
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
+    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+
+    /* "bx/arrays/array_tree.pyx":418
+ *             io.write_raw_array( self.summary.mins )
+ *             io.write_raw_array( self.summary.maxs )
+ *             io.write_raw_array( self.summary.sumsquares )             # <<<<<<<<<<<<<<
+ *             # Skip enough room for child offsets (block_size children * 64bits)
+ *             io.skip( self.tree.block_size * 8 )
+ */
+    __pyx_t_5 = PyObject_GetAttr(__pyx_v_io, __pyx_n_s__write_raw_array); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 418; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_5);
+    __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 418; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_INCREF(__pyx_v_self->summary->sumsquares);
+    PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_self->summary->sumsquares);
+    __Pyx_GIVEREF(__pyx_v_self->summary->sumsquares);
+    __pyx_t_2 = PyObject_Call(__pyx_t_5, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 418; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+    __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+    /* "bx/arrays/array_tree.pyx":420
+ *             io.write_raw_array( self.summary.sumsquares )
+ *             # Skip enough room for child offsets (block_size children * 64bits)
+ *             io.skip( self.tree.block_size * 8 )             # <<<<<<<<<<<<<<
+ *         # Must be writing a lower level, so recurse
+ *         else:
+ */
+    __pyx_t_2 = PyObject_GetAttr(__pyx_v_io, __pyx_n_s__skip); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 420; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_t_3 = PyInt_FromLong((__pyx_v_self->tree->block_size * 8)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 420; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 420; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_5);
+    PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_3);
+    __Pyx_GIVEREF(__pyx_t_3);
+    __pyx_t_3 = 0;
+    __pyx_t_3 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_5), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 420; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    __Pyx_DECREF(((PyObject *)__pyx_t_5)); __pyx_t_5 = 0;
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    goto __pyx_L3;
+  }
+  /*else*/ {
+
+    /* "bx/arrays/array_tree.pyx":424
+ *         else:
+ *             # Write all non-empty children
+ *             for i in range( len( self.children ) ):             # <<<<<<<<<<<<<<
+ *                 if self.children[i] is not None:
+ *                     self.children[i].to_file_data_pass( io, level )
+ */
+    __pyx_t_3 = __pyx_v_self->children;
+    __Pyx_INCREF(__pyx_t_3);
+    __pyx_t_6 = PyObject_Length(__pyx_t_3); if (unlikely(__pyx_t_6 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 424; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __pyx_t_3 = PyInt_FromSsize_t(__pyx_t_6); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 424; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 424; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_5);
+    PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_3);
+    __Pyx_GIVEREF(__pyx_t_3);
+    __pyx_t_3 = 0;
+    __pyx_t_3 = PyObject_Call(__pyx_builtin_range, ((PyObject *)__pyx_t_5), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 424; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_DECREF(((PyObject *)__pyx_t_5)); __pyx_t_5 = 0;
+    if (PyList_CheckExact(__pyx_t_3) || PyTuple_CheckExact(__pyx_t_3)) {
+      __pyx_t_5 = __pyx_t_3; __Pyx_INCREF(__pyx_t_5); __pyx_t_6 = 0;
+      __pyx_t_7 = NULL;
+    } else {
+      __pyx_t_6 = -1; __pyx_t_5 = PyObject_GetIter(__pyx_t_3); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 424; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_5);
+      __pyx_t_7 = Py_TYPE(__pyx_t_5)->tp_iternext;
+    }
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    for (;;) {
+      if (!__pyx_t_7 && PyList_CheckExact(__pyx_t_5)) {
+        if (__pyx_t_6 >= PyList_GET_SIZE(__pyx_t_5)) break;
+        #if CYTHON_COMPILING_IN_CPYTHON
+        __pyx_t_3 = PyList_GET_ITEM(__pyx_t_5, __pyx_t_6); __Pyx_INCREF(__pyx_t_3); __pyx_t_6++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 424; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #else
+        __pyx_t_3 = PySequence_ITEM(__pyx_t_5, __pyx_t_6); __pyx_t_6++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 424; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #endif
+      } else if (!__pyx_t_7 && PyTuple_CheckExact(__pyx_t_5)) {
+        if (__pyx_t_6 >= PyTuple_GET_SIZE(__pyx_t_5)) break;
+        #if CYTHON_COMPILING_IN_CPYTHON
+        __pyx_t_3 = PyTuple_GET_ITEM(__pyx_t_5, __pyx_t_6); __Pyx_INCREF(__pyx_t_3); __pyx_t_6++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 424; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #else
+        __pyx_t_3 = PySequence_ITEM(__pyx_t_5, __pyx_t_6); __pyx_t_6++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 424; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #endif
+      } else {
+        __pyx_t_3 = __pyx_t_7(__pyx_t_5);
+        if (unlikely(!__pyx_t_3)) {
+          if (PyErr_Occurred()) {
+            if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
+            else {__pyx_filename = __pyx_f[0]; __pyx_lineno = 424; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          }
+          break;
+        }
+        __Pyx_GOTREF(__pyx_t_3);
+      }
+      __Pyx_XDECREF(__pyx_v_i);
+      __pyx_v_i = __pyx_t_3;
+      __pyx_t_3 = 0;
+
+      /* "bx/arrays/array_tree.pyx":425
+ *             # Write all non-empty children
+ *             for i in range( len( self.children ) ):
+ *                 if self.children[i] is not None:             # <<<<<<<<<<<<<<
+ *                     self.children[i].to_file_data_pass( io, level )
+ * 
+ */
+      __pyx_t_3 = PyObject_GetItem(__pyx_v_self->children, __pyx_v_i); if (!__pyx_t_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 425; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_1 = (__pyx_t_3 != Py_None);
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      if (__pyx_t_1) {
+
+        /* "bx/arrays/array_tree.pyx":426
+ *             for i in range( len( self.children ) ):
+ *                 if self.children[i] is not None:
+ *                     self.children[i].to_file_data_pass( io, level )             # <<<<<<<<<<<<<<
+ * 
+ *     def to_file_offset_pass( self, io ):
+ */
+        __pyx_t_3 = PyObject_GetItem(__pyx_v_self->children, __pyx_v_i); if (!__pyx_t_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 426; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_3);
+        __pyx_t_2 = PyObject_GetAttr(__pyx_t_3, __pyx_n_s__to_file_data_pass); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 426; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_2);
+        __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+        __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 426; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_3);
+        __Pyx_INCREF(__pyx_v_io);
+        PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_io);
+        __Pyx_GIVEREF(__pyx_v_io);
+        __Pyx_INCREF(__pyx_v_level);
+        PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_v_level);
+        __Pyx_GIVEREF(__pyx_v_level);
+        __pyx_t_8 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 426; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_8);
+        __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+        __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
+        __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+        goto __pyx_L6;
+      }
+      __pyx_L6:;
+    }
+    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+  }
+  __pyx_L3:;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_5);
+  __Pyx_XDECREF(__pyx_t_8);
+  __Pyx_AddTraceback("bx.arrays.array_tree.ArrayTreeNode.to_file_data_pass", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_i);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_13ArrayTreeNode_11to_file_offset_pass(PyObject *__pyx_v_self, PyObject *__pyx_v_io); /*proto*/
+static char __pyx_doc_2bx_6arrays_10array_tree_13ArrayTreeNode_10to_file_offset_pass[] = "\n        Second pass of writing to file, seek to appropriate position and write\n        offsets of children.\n        ";
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_13ArrayTreeNode_11to_file_offset_pass(PyObject *__pyx_v_self, PyObject *__pyx_v_io) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("to_file_offset_pass (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_6arrays_10array_tree_13ArrayTreeNode_10to_file_offset_pass(((struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeNode *)__pyx_v_self), ((PyObject *)__pyx_v_io));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/arrays/array_tree.pyx":428
+ *                     self.children[i].to_file_data_pass( io, level )
+ * 
+ *     def to_file_offset_pass( self, io ):             # <<<<<<<<<<<<<<
+ *         """
+ *         Second pass of writing to file, seek to appropriate position and write
+ */
+
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_13ArrayTreeNode_10to_file_offset_pass(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeNode *__pyx_v_self, PyObject *__pyx_v_io) {
+  PyObject *__pyx_v_skip_amount = NULL;
+  PyObject *__pyx_v_child = NULL;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  Py_ssize_t __pyx_t_4;
+  PyObject *(*__pyx_t_5)(PyObject *);
+  int __pyx_t_6;
+  PyObject *__pyx_t_7 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("to_file_offset_pass", 0);
+
+  /* "bx/arrays/array_tree.pyx":434
+ *         """
+ *         # Seek to location of child offfsets (skip over # summary arrays)
+ *         skip_amount = NUM_SUMMARY_ARRAYS * self.tree.dtype.itemsize * self.block_size             # <<<<<<<<<<<<<<
+ *         io.seek( self.start_offset + skip_amount )
+ *         # Write the file offset of each child into the index
+ */
+  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__NUM_SUMMARY_ARRAYS); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 434; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = PyObject_GetAttr(__pyx_v_self->tree->dtype, __pyx_n_s__itemsize); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 434; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = PyNumber_Multiply(__pyx_t_1, __pyx_t_2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 434; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_2 = PyInt_FromLong(__pyx_v_self->block_size); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 434; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_1 = PyNumber_Multiply(__pyx_t_3, __pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 434; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_v_skip_amount = __pyx_t_1;
+  __pyx_t_1 = 0;
+
+  /* "bx/arrays/array_tree.pyx":435
+ *         # Seek to location of child offfsets (skip over # summary arrays)
+ *         skip_amount = NUM_SUMMARY_ARRAYS * self.tree.dtype.itemsize * self.block_size
+ *         io.seek( self.start_offset + skip_amount )             # <<<<<<<<<<<<<<
+ *         # Write the file offset of each child into the index
+ *         for child in self.children:
+ */
+  __pyx_t_1 = PyObject_GetAttr(__pyx_v_io, __pyx_n_s__seek); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 435; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = PyInt_FromLong(__pyx_v_self->start_offset); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 435; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = PyNumber_Add(__pyx_t_2, __pyx_v_skip_amount); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 435; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 435; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_3);
+  __Pyx_GIVEREF(__pyx_t_3);
+  __pyx_t_3 = 0;
+  __pyx_t_3 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 435; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+  /* "bx/arrays/array_tree.pyx":437
+ *         io.seek( self.start_offset + skip_amount )
+ *         # Write the file offset of each child into the index
+ *         for child in self.children:             # <<<<<<<<<<<<<<
+ *             if child is None:
+ *                 io.write_uint64( 0 )
+ */
+  if (PyList_CheckExact(__pyx_v_self->children) || PyTuple_CheckExact(__pyx_v_self->children)) {
+    __pyx_t_3 = __pyx_v_self->children; __Pyx_INCREF(__pyx_t_3); __pyx_t_4 = 0;
+    __pyx_t_5 = NULL;
+  } else {
+    __pyx_t_4 = -1; __pyx_t_3 = PyObject_GetIter(__pyx_v_self->children); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 437; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __pyx_t_5 = Py_TYPE(__pyx_t_3)->tp_iternext;
+  }
+  for (;;) {
+    if (!__pyx_t_5 && PyList_CheckExact(__pyx_t_3)) {
+      if (__pyx_t_4 >= PyList_GET_SIZE(__pyx_t_3)) break;
+      #if CYTHON_COMPILING_IN_CPYTHON
+      __pyx_t_2 = PyList_GET_ITEM(__pyx_t_3, __pyx_t_4); __Pyx_INCREF(__pyx_t_2); __pyx_t_4++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 437; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      #else
+      __pyx_t_2 = PySequence_ITEM(__pyx_t_3, __pyx_t_4); __pyx_t_4++; if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 437; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      #endif
+    } else if (!__pyx_t_5 && PyTuple_CheckExact(__pyx_t_3)) {
+      if (__pyx_t_4 >= PyTuple_GET_SIZE(__pyx_t_3)) break;
+      #if CYTHON_COMPILING_IN_CPYTHON
+      __pyx_t_2 = PyTuple_GET_ITEM(__pyx_t_3, __pyx_t_4); __Pyx_INCREF(__pyx_t_2); __pyx_t_4++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 437; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      #else
+      __pyx_t_2 = PySequence_ITEM(__pyx_t_3, __pyx_t_4); __pyx_t_4++; if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 437; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      #endif
+    } else {
+      __pyx_t_2 = __pyx_t_5(__pyx_t_3);
+      if (unlikely(!__pyx_t_2)) {
+        if (PyErr_Occurred()) {
+          if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
+          else {__pyx_filename = __pyx_f[0]; __pyx_lineno = 437; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        }
+        break;
+      }
+      __Pyx_GOTREF(__pyx_t_2);
+    }
+    __Pyx_XDECREF(__pyx_v_child);
+    __pyx_v_child = __pyx_t_2;
+    __pyx_t_2 = 0;
+
+    /* "bx/arrays/array_tree.pyx":438
+ *         # Write the file offset of each child into the index
+ *         for child in self.children:
+ *             if child is None:             # <<<<<<<<<<<<<<
+ *                 io.write_uint64( 0 )
+ *             else:
+ */
+    __pyx_t_6 = (__pyx_v_child == Py_None);
+    if (__pyx_t_6) {
+
+      /* "bx/arrays/array_tree.pyx":439
+ *         for child in self.children:
+ *             if child is None:
+ *                 io.write_uint64( 0 )             # <<<<<<<<<<<<<<
+ *             else:
+ *                 io.write_uint64( child.start_offset )
+ */
+      __pyx_t_2 = PyObject_GetAttr(__pyx_v_io, __pyx_n_s__write_uint64); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 439; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_2);
+      __pyx_t_1 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_k_tuple_20), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 439; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_1);
+      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+      goto __pyx_L5;
+    }
+    /*else*/ {
+
+      /* "bx/arrays/array_tree.pyx":441
+ *                 io.write_uint64( 0 )
+ *             else:
+ *                 io.write_uint64( child.start_offset )             # <<<<<<<<<<<<<<
+ *         # Recursively write offsets in child nodes
+ *         for child in self.children:
+ */
+      __pyx_t_1 = PyObject_GetAttr(__pyx_v_io, __pyx_n_s__write_uint64); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 441; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_1);
+      __pyx_t_2 = PyObject_GetAttr(__pyx_v_child, __pyx_n_s__start_offset); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 441; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_2);
+      __pyx_t_7 = PyTuple_New(1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 441; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_7);
+      PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_2);
+      __Pyx_GIVEREF(__pyx_t_2);
+      __pyx_t_2 = 0;
+      __pyx_t_2 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_7), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 441; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_2);
+      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+      __Pyx_DECREF(((PyObject *)__pyx_t_7)); __pyx_t_7 = 0;
+      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    }
+    __pyx_L5:;
+  }
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+  /* "bx/arrays/array_tree.pyx":443
+ *                 io.write_uint64( child.start_offset )
+ *         # Recursively write offsets in child nodes
+ *         for child in self.children:             # <<<<<<<<<<<<<<
+ *             if child is not None:
+ *                 child.to_file_offset_pass( io )
+ */
+  if (PyList_CheckExact(__pyx_v_self->children) || PyTuple_CheckExact(__pyx_v_self->children)) {
+    __pyx_t_3 = __pyx_v_self->children; __Pyx_INCREF(__pyx_t_3); __pyx_t_4 = 0;
+    __pyx_t_5 = NULL;
+  } else {
+    __pyx_t_4 = -1; __pyx_t_3 = PyObject_GetIter(__pyx_v_self->children); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 443; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __pyx_t_5 = Py_TYPE(__pyx_t_3)->tp_iternext;
+  }
+  for (;;) {
+    if (!__pyx_t_5 && PyList_CheckExact(__pyx_t_3)) {
+      if (__pyx_t_4 >= PyList_GET_SIZE(__pyx_t_3)) break;
+      #if CYTHON_COMPILING_IN_CPYTHON
+      __pyx_t_2 = PyList_GET_ITEM(__pyx_t_3, __pyx_t_4); __Pyx_INCREF(__pyx_t_2); __pyx_t_4++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 443; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      #else
+      __pyx_t_2 = PySequence_ITEM(__pyx_t_3, __pyx_t_4); __pyx_t_4++; if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 443; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      #endif
+    } else if (!__pyx_t_5 && PyTuple_CheckExact(__pyx_t_3)) {
+      if (__pyx_t_4 >= PyTuple_GET_SIZE(__pyx_t_3)) break;
+      #if CYTHON_COMPILING_IN_CPYTHON
+      __pyx_t_2 = PyTuple_GET_ITEM(__pyx_t_3, __pyx_t_4); __Pyx_INCREF(__pyx_t_2); __pyx_t_4++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 443; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      #else
+      __pyx_t_2 = PySequence_ITEM(__pyx_t_3, __pyx_t_4); __pyx_t_4++; if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 443; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      #endif
+    } else {
+      __pyx_t_2 = __pyx_t_5(__pyx_t_3);
+      if (unlikely(!__pyx_t_2)) {
+        if (PyErr_Occurred()) {
+          if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
+          else {__pyx_filename = __pyx_f[0]; __pyx_lineno = 443; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        }
+        break;
+      }
+      __Pyx_GOTREF(__pyx_t_2);
+    }
+    __Pyx_XDECREF(__pyx_v_child);
+    __pyx_v_child = __pyx_t_2;
+    __pyx_t_2 = 0;
+
+    /* "bx/arrays/array_tree.pyx":444
+ *         # Recursively write offsets in child nodes
+ *         for child in self.children:
+ *             if child is not None:             # <<<<<<<<<<<<<<
+ *                 child.to_file_offset_pass( io )
+ * 
+ */
+    __pyx_t_6 = (__pyx_v_child != Py_None);
+    if (__pyx_t_6) {
+
+      /* "bx/arrays/array_tree.pyx":445
+ *         for child in self.children:
+ *             if child is not None:
+ *                 child.to_file_offset_pass( io )             # <<<<<<<<<<<<<<
+ * 
+ *     def from_file( self, io ):
+ */
+      __pyx_t_2 = PyObject_GetAttr(__pyx_v_child, __pyx_n_s__to_file_offset_pass); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 445; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_2);
+      __pyx_t_7 = PyTuple_New(1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 445; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_7);
+      __Pyx_INCREF(__pyx_v_io);
+      PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_v_io);
+      __Pyx_GIVEREF(__pyx_v_io);
+      __pyx_t_1 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_7), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 445; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_1);
+      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+      __Pyx_DECREF(((PyObject *)__pyx_t_7)); __pyx_t_7 = 0;
+      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+      goto __pyx_L8;
+    }
+    __pyx_L8:;
+  }
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_7);
+  __Pyx_AddTraceback("bx.arrays.array_tree.ArrayTreeNode.to_file_offset_pass", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_skip_amount);
+  __Pyx_XDECREF(__pyx_v_child);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_13ArrayTreeNode_13from_file(PyObject *__pyx_v_self, PyObject *__pyx_v_io); /*proto*/
+static char __pyx_doc_2bx_6arrays_10array_tree_13ArrayTreeNode_12from_file[] = "\n        Load entire summary and all children into memory.\n        ";
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_13ArrayTreeNode_13from_file(PyObject *__pyx_v_self, PyObject *__pyx_v_io) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("from_file (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_6arrays_10array_tree_13ArrayTreeNode_12from_file(((struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeNode *)__pyx_v_self), ((PyObject *)__pyx_v_io));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/arrays/array_tree.pyx":447
+ *                 child.to_file_offset_pass( io )
+ * 
+ *     def from_file( self, io ):             # <<<<<<<<<<<<<<
+ *         """
+ *         Load entire summary and all children into memory.
+ */
+
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_13ArrayTreeNode_12from_file(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeNode *__pyx_v_self, PyObject *__pyx_v_io) {
+  PyObject *__pyx_v_dtype = NULL;
+  int __pyx_v_block_size;
+  struct __pyx_obj_2bx_6arrays_10array_tree_Summary *__pyx_v_s = NULL;
+  PyObject *__pyx_v_child_offsets = NULL;
+  int __pyx_v_i;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_t_2;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  PyObject *__pyx_t_5 = NULL;
+  int __pyx_t_6;
+  int __pyx_t_7;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("from_file", 0);
+
+  /* "bx/arrays/array_tree.pyx":451
+ *         Load entire summary and all children into memory.
+ *         """
+ *         dtype = self.tree.dtype             # <<<<<<<<<<<<<<
+ *         block_size = self.tree.block_size
+ *         # Read summary arrays
+ */
+  __pyx_t_1 = __pyx_v_self->tree->dtype;
+  __Pyx_INCREF(__pyx_t_1);
+  __pyx_v_dtype = __pyx_t_1;
+  __pyx_t_1 = 0;
+
+  /* "bx/arrays/array_tree.pyx":452
+ *         """
+ *         dtype = self.tree.dtype
+ *         block_size = self.tree.block_size             # <<<<<<<<<<<<<<
+ *         # Read summary arrays
+ *         s = Summary()
+ */
+  __pyx_t_2 = __pyx_v_self->tree->block_size;
+  __pyx_v_block_size = __pyx_t_2;
+
+  /* "bx/arrays/array_tree.pyx":454
+ *         block_size = self.tree.block_size
+ *         # Read summary arrays
+ *         s = Summary()             # <<<<<<<<<<<<<<
+ *         s.counts = io.read_raw_array( dtype, block_size )
+ *         s.frequencies = io.read_raw_array( int32, block_size )
+ */
+  __pyx_t_1 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_2bx_6arrays_10array_tree_Summary)), ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 454; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_v_s = ((struct __pyx_obj_2bx_6arrays_10array_tree_Summary *)__pyx_t_1);
+  __pyx_t_1 = 0;
+
+  /* "bx/arrays/array_tree.pyx":455
+ *         # Read summary arrays
+ *         s = Summary()
+ *         s.counts = io.read_raw_array( dtype, block_size )             # <<<<<<<<<<<<<<
+ *         s.frequencies = io.read_raw_array( int32, block_size )
+ *         s.sums = io.read_raw_array( dtype, block_size )
+ */
+  __pyx_t_1 = PyObject_GetAttr(__pyx_v_io, __pyx_n_s__read_raw_array); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 455; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_3 = PyInt_FromLong(__pyx_v_block_size); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 455; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 455; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __Pyx_INCREF(__pyx_v_dtype);
+  PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_v_dtype);
+  __Pyx_GIVEREF(__pyx_v_dtype);
+  PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_3);
+  __Pyx_GIVEREF(__pyx_t_3);
+  __pyx_t_3 = 0;
+  __pyx_t_3 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_4), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 455; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
+  __Pyx_GIVEREF(__pyx_t_3);
+  __Pyx_GOTREF(__pyx_v_s->counts);
+  __Pyx_DECREF(__pyx_v_s->counts);
+  __pyx_v_s->counts = __pyx_t_3;
+  __pyx_t_3 = 0;
+
+  /* "bx/arrays/array_tree.pyx":456
+ *         s = Summary()
+ *         s.counts = io.read_raw_array( dtype, block_size )
+ *         s.frequencies = io.read_raw_array( int32, block_size )             # <<<<<<<<<<<<<<
+ *         s.sums = io.read_raw_array( dtype, block_size )
+ *         s.mins = io.read_raw_array( dtype, block_size)
+ */
+  __pyx_t_3 = PyObject_GetAttr(__pyx_v_io, __pyx_n_s__read_raw_array); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 456; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_4 = __Pyx_GetName(__pyx_m, __pyx_n_s__int32); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 456; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __pyx_t_1 = PyInt_FromLong(__pyx_v_block_size); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 456; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 456; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_4);
+  __Pyx_GIVEREF(__pyx_t_4);
+  PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_t_1);
+  __Pyx_GIVEREF(__pyx_t_1);
+  __pyx_t_4 = 0;
+  __pyx_t_1 = 0;
+  __pyx_t_1 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_t_5), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 456; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_5)); __pyx_t_5 = 0;
+  __Pyx_GIVEREF(__pyx_t_1);
+  __Pyx_GOTREF(__pyx_v_s->frequencies);
+  __Pyx_DECREF(__pyx_v_s->frequencies);
+  __pyx_v_s->frequencies = __pyx_t_1;
+  __pyx_t_1 = 0;
+
+  /* "bx/arrays/array_tree.pyx":457
+ *         s.counts = io.read_raw_array( dtype, block_size )
+ *         s.frequencies = io.read_raw_array( int32, block_size )
+ *         s.sums = io.read_raw_array( dtype, block_size )             # <<<<<<<<<<<<<<
+ *         s.mins = io.read_raw_array( dtype, block_size)
+ *         s.maxs = io.read_raw_array( dtype, block_size )
+ */
+  __pyx_t_1 = PyObject_GetAttr(__pyx_v_io, __pyx_n_s__read_raw_array); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 457; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_5 = PyInt_FromLong(__pyx_v_block_size); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 457; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 457; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_INCREF(__pyx_v_dtype);
+  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_dtype);
+  __Pyx_GIVEREF(__pyx_v_dtype);
+  PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_5);
+  __Pyx_GIVEREF(__pyx_t_5);
+  __pyx_t_5 = 0;
+  __pyx_t_5 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 457; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
+  __Pyx_GIVEREF(__pyx_t_5);
+  __Pyx_GOTREF(__pyx_v_s->sums);
+  __Pyx_DECREF(__pyx_v_s->sums);
+  __pyx_v_s->sums = __pyx_t_5;
+  __pyx_t_5 = 0;
+
+  /* "bx/arrays/array_tree.pyx":458
+ *         s.frequencies = io.read_raw_array( int32, block_size )
+ *         s.sums = io.read_raw_array( dtype, block_size )
+ *         s.mins = io.read_raw_array( dtype, block_size)             # <<<<<<<<<<<<<<
+ *         s.maxs = io.read_raw_array( dtype, block_size )
+ *         s.sumsquares = io.read_raw_array( dtype, block_size )
+ */
+  __pyx_t_5 = PyObject_GetAttr(__pyx_v_io, __pyx_n_s__read_raw_array); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 458; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __pyx_t_3 = PyInt_FromLong(__pyx_v_block_size); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 458; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 458; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_INCREF(__pyx_v_dtype);
+  PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_dtype);
+  __Pyx_GIVEREF(__pyx_v_dtype);
+  PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_t_3);
+  __Pyx_GIVEREF(__pyx_t_3);
+  __pyx_t_3 = 0;
+  __pyx_t_3 = PyObject_Call(__pyx_t_5, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 458; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+  __Pyx_GIVEREF(__pyx_t_3);
+  __Pyx_GOTREF(__pyx_v_s->mins);
+  __Pyx_DECREF(__pyx_v_s->mins);
+  __pyx_v_s->mins = __pyx_t_3;
+  __pyx_t_3 = 0;
+
+  /* "bx/arrays/array_tree.pyx":459
+ *         s.sums = io.read_raw_array( dtype, block_size )
+ *         s.mins = io.read_raw_array( dtype, block_size)
+ *         s.maxs = io.read_raw_array( dtype, block_size )             # <<<<<<<<<<<<<<
+ *         s.sumsquares = io.read_raw_array( dtype, block_size )
+ *         self.summary = s
+ */
+  __pyx_t_3 = PyObject_GetAttr(__pyx_v_io, __pyx_n_s__read_raw_array); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 459; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_1 = PyInt_FromLong(__pyx_v_block_size); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 459; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 459; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __Pyx_INCREF(__pyx_v_dtype);
+  PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_v_dtype);
+  __Pyx_GIVEREF(__pyx_v_dtype);
+  PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_t_1);
+  __Pyx_GIVEREF(__pyx_t_1);
+  __pyx_t_1 = 0;
+  __pyx_t_1 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_t_5), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 459; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_5)); __pyx_t_5 = 0;
+  __Pyx_GIVEREF(__pyx_t_1);
+  __Pyx_GOTREF(__pyx_v_s->maxs);
+  __Pyx_DECREF(__pyx_v_s->maxs);
+  __pyx_v_s->maxs = __pyx_t_1;
+  __pyx_t_1 = 0;
+
+  /* "bx/arrays/array_tree.pyx":460
+ *         s.mins = io.read_raw_array( dtype, block_size)
+ *         s.maxs = io.read_raw_array( dtype, block_size )
+ *         s.sumsquares = io.read_raw_array( dtype, block_size )             # <<<<<<<<<<<<<<
+ *         self.summary = s
+ *         # Read offset of all children
+ */
+  __pyx_t_1 = PyObject_GetAttr(__pyx_v_io, __pyx_n_s__read_raw_array); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_5 = PyInt_FromLong(__pyx_v_block_size); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_INCREF(__pyx_v_dtype);
+  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_dtype);
+  __Pyx_GIVEREF(__pyx_v_dtype);
+  PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_5);
+  __Pyx_GIVEREF(__pyx_t_5);
+  __pyx_t_5 = 0;
+  __pyx_t_5 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
+  __Pyx_GIVEREF(__pyx_t_5);
+  __Pyx_GOTREF(__pyx_v_s->sumsquares);
+  __Pyx_DECREF(__pyx_v_s->sumsquares);
+  __pyx_v_s->sumsquares = __pyx_t_5;
+  __pyx_t_5 = 0;
+
+  /* "bx/arrays/array_tree.pyx":461
+ *         s.maxs = io.read_raw_array( dtype, block_size )
+ *         s.sumsquares = io.read_raw_array( dtype, block_size )
+ *         self.summary = s             # <<<<<<<<<<<<<<
+ *         # Read offset of all children
+ *         child_offsets = [ io.read_uint64() for i in range( block_size ) ]
+ */
+  __Pyx_INCREF(((PyObject *)__pyx_v_s));
+  __Pyx_GIVEREF(((PyObject *)__pyx_v_s));
+  __Pyx_GOTREF(__pyx_v_self->summary);
+  __Pyx_DECREF(((PyObject *)__pyx_v_self->summary));
+  __pyx_v_self->summary = __pyx_v_s;
+
+  /* "bx/arrays/array_tree.pyx":463
+ *         self.summary = s
+ *         # Read offset of all children
+ *         child_offsets = [ io.read_uint64() for i in range( block_size ) ]             # <<<<<<<<<<<<<<
+ *         for i in range( block_size ):
+ *             if child_offsets[i] > 0:
+ */
+  __pyx_t_5 = PyList_New(0); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 463; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __pyx_t_2 = __pyx_v_block_size;
+  for (__pyx_t_6 = 0; __pyx_t_6 < __pyx_t_2; __pyx_t_6+=1) {
+    __pyx_v_i = __pyx_t_6;
+    __pyx_t_3 = PyObject_GetAttr(__pyx_v_io, __pyx_n_s__read_uint64); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 463; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __pyx_t_1 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 463; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    if (unlikely(__Pyx_PyList_Append(__pyx_t_5, (PyObject*)__pyx_t_1))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 463; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  }
+  __pyx_t_1 = ((PyObject *)__pyx_t_5);
+  __Pyx_INCREF(__pyx_t_1);
+  __Pyx_DECREF(((PyObject *)__pyx_t_5)); __pyx_t_5 = 0;
+  __pyx_v_child_offsets = ((PyObject*)__pyx_t_1);
+  __pyx_t_1 = 0;
+
+  /* "bx/arrays/array_tree.pyx":464
+ *         # Read offset of all children
+ *         child_offsets = [ io.read_uint64() for i in range( block_size ) ]
+ *         for i in range( block_size ):             # <<<<<<<<<<<<<<
+ *             if child_offsets[i] > 0:
+ *                 self.init_bin( i )
+ */
+  __pyx_t_2 = __pyx_v_block_size;
+  for (__pyx_t_6 = 0; __pyx_t_6 < __pyx_t_2; __pyx_t_6+=1) {
+    __pyx_v_i = __pyx_t_6;
+
+    /* "bx/arrays/array_tree.pyx":465
+ *         child_offsets = [ io.read_uint64() for i in range( block_size ) ]
+ *         for i in range( block_size ):
+ *             if child_offsets[i] > 0:             # <<<<<<<<<<<<<<
+ *                 self.init_bin( i )
+ *                 io.seek( child_offsets[i] )
+ */
+    __pyx_t_1 = __Pyx_GetItemInt_List(((PyObject *)__pyx_v_child_offsets), __pyx_v_i, sizeof(int), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 465; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __pyx_t_5 = PyObject_RichCompare(__pyx_t_1, __pyx_int_0, Py_GT); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 465; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 465; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+    if (__pyx_t_7) {
+
+      /* "bx/arrays/array_tree.pyx":466
+ *         for i in range( block_size ):
+ *             if child_offsets[i] > 0:
+ *                 self.init_bin( i )             # <<<<<<<<<<<<<<
+ *                 io.seek( child_offsets[i] )
+ *                 self.children[i].from_file( io )
+ */
+      __pyx_t_5 = __pyx_f_2bx_6arrays_10array_tree_13ArrayTreeNode_init_bin(__pyx_v_self, __pyx_v_i); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 466; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_5);
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+
+      /* "bx/arrays/array_tree.pyx":467
+ *             if child_offsets[i] > 0:
+ *                 self.init_bin( i )
+ *                 io.seek( child_offsets[i] )             # <<<<<<<<<<<<<<
+ *                 self.children[i].from_file( io )
+ * 
+ */
+      __pyx_t_5 = PyObject_GetAttr(__pyx_v_io, __pyx_n_s__seek); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 467; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_5);
+      __pyx_t_1 = __Pyx_GetItemInt_List(((PyObject *)__pyx_v_child_offsets), __pyx_v_i, sizeof(int), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 467; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_1);
+      __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 467; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1);
+      __Pyx_GIVEREF(__pyx_t_1);
+      __pyx_t_1 = 0;
+      __pyx_t_1 = PyObject_Call(__pyx_t_5, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 467; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_1);
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
+      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+      /* "bx/arrays/array_tree.pyx":468
+ *                 self.init_bin( i )
+ *                 io.seek( child_offsets[i] )
+ *                 self.children[i].from_file( io )             # <<<<<<<<<<<<<<
+ * 
+ *     def get_from_file( self, io, index ):
+ */
+      __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_self->children, __pyx_v_i, sizeof(int), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 468; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_1);
+      __pyx_t_3 = PyObject_GetAttr(__pyx_t_1, __pyx_n_s__from_file); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 468; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+      __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 468; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_1);
+      __Pyx_INCREF(__pyx_v_io);
+      PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_io);
+      __Pyx_GIVEREF(__pyx_v_io);
+      __pyx_t_5 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 468; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_5);
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      goto __pyx_L7;
+    }
+    __pyx_L7:;
+  }
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_XDECREF(__pyx_t_5);
+  __Pyx_AddTraceback("bx.arrays.array_tree.ArrayTreeNode.from_file", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_dtype);
+  __Pyx_XDECREF((PyObject *)__pyx_v_s);
+  __Pyx_XDECREF(__pyx_v_child_offsets);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_13ArrayTreeNode_15get_from_file(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_13ArrayTreeNode_15get_from_file(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  CYTHON_UNUSED PyObject *__pyx_v_io = 0;
+  PyObject *__pyx_v_index = 0;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("get_from_file (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__io,&__pyx_n_s__index,0};
+    PyObject* values[2] = {0,0};
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__io)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__index)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("get_from_file", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 470; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "get_from_file") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 470; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
+      goto __pyx_L5_argtuple_error;
+    } else {
+      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+    }
+    __pyx_v_io = values[0];
+    __pyx_v_index = values[1];
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("get_from_file", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 470; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.arrays.array_tree.ArrayTreeNode.get_from_file", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_6arrays_10array_tree_13ArrayTreeNode_14get_from_file(((struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeNode *)__pyx_v_self), __pyx_v_io, __pyx_v_index);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/arrays/array_tree.pyx":470
+ *                 self.children[i].from_file( io )
+ * 
+ *     def get_from_file( self, io, index ):             # <<<<<<<<<<<<<<
+ *         cdef int bin_index = ( index - self.min ) //( self.child_size )
+ *         if self.children[ bin_index ] is None:
+ */
+
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_13ArrayTreeNode_14get_from_file(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeNode *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v_io, PyObject *__pyx_v_index) {
+  int __pyx_v_bin_index;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  int __pyx_t_4;
+  int __pyx_t_5;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("get_from_file", 0);
+
+  /* "bx/arrays/array_tree.pyx":471
+ * 
+ *     def get_from_file( self, io, index ):
+ *         cdef int bin_index = ( index - self.min ) //( self.child_size )             # <<<<<<<<<<<<<<
+ *         if self.children[ bin_index ] is None:
+ *             return nan
+ */
+  __pyx_t_1 = PyInt_FromLong(__pyx_v_self->min); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 471; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = PyNumber_Subtract(__pyx_v_index, __pyx_t_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 471; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_1 = PyInt_FromLong(__pyx_v_self->child_size); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 471; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_3 = PyNumber_FloorDivide(__pyx_t_2, __pyx_t_1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 471; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_4 = __Pyx_PyInt_AsInt(__pyx_t_3); if (unlikely((__pyx_t_4 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 471; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __pyx_v_bin_index = __pyx_t_4;
+
+  /* "bx/arrays/array_tree.pyx":472
+ *     def get_from_file( self, io, index ):
+ *         cdef int bin_index = ( index - self.min ) //( self.child_size )
+ *         if self.children[ bin_index ] is None:             # <<<<<<<<<<<<<<
+ *             return nan
+ *         else:
+ */
+  __pyx_t_3 = __Pyx_GetItemInt(__pyx_v_self->children, __pyx_v_bin_index, sizeof(int), PyInt_FromLong); if (!__pyx_t_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 472; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_5 = (__pyx_t_3 == Py_None);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  if (__pyx_t_5) {
+
+    /* "bx/arrays/array_tree.pyx":473
+ *         cdef int bin_index = ( index - self.min ) //( self.child_size )
+ *         if self.children[ bin_index ] is None:
+ *             return nan             # <<<<<<<<<<<<<<
+ *         else:
+ *             return self.children[ bin_index ].get( index )
+ */
+    __Pyx_XDECREF(__pyx_r);
+    __pyx_t_3 = __Pyx_GetName(__pyx_m, __pyx_n_s__nan); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 473; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __pyx_r = __pyx_t_3;
+    __pyx_t_3 = 0;
+    goto __pyx_L0;
+    goto __pyx_L3;
+  }
+  /*else*/ {
+
+    /* "bx/arrays/array_tree.pyx":475
+ *             return nan
+ *         else:
+ *             return self.children[ bin_index ].get( index )             # <<<<<<<<<<<<<<
+ * 
+ * cdef class ArrayTreeLeaf:
+ */
+    __Pyx_XDECREF(__pyx_r);
+    __pyx_t_3 = __Pyx_GetItemInt(__pyx_v_self->children, __pyx_v_bin_index, sizeof(int), PyInt_FromLong); if (!__pyx_t_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 475; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __pyx_t_1 = PyObject_GetAttr(__pyx_t_3, __pyx_n_s__get); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 475; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 475; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_INCREF(__pyx_v_index);
+    PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_index);
+    __Pyx_GIVEREF(__pyx_v_index);
+    __pyx_t_2 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 475; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
+    __pyx_r = __pyx_t_2;
+    __pyx_t_2 = 0;
+    goto __pyx_L0;
+  }
+  __pyx_L3:;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_AddTraceback("bx.arrays.array_tree.ArrayTreeNode.get_from_file", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_13ArrayTreeNode_7summary_1__get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_13ArrayTreeNode_7summary_1__get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_6arrays_10array_tree_13ArrayTreeNode_7summary___get__(((struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeNode *)__pyx_v_self));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/arrays/array_tree.pyx":322
+ *     cdef int child_size
+ *     cdef object children
+ *     cdef public Summary summary             # <<<<<<<<<<<<<<
+ *     cdef public long start_offset
+ * 
+ */
+
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_13ArrayTreeNode_7summary___get__(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeNode *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__get__", 0);
+  __Pyx_XDECREF(__pyx_r);
+  __Pyx_INCREF(((PyObject *)__pyx_v_self->summary));
+  __pyx_r = ((PyObject *)__pyx_v_self->summary);
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_2bx_6arrays_10array_tree_13ArrayTreeNode_7summary_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value); /*proto*/
+static int __pyx_pw_2bx_6arrays_10array_tree_13ArrayTreeNode_7summary_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__set__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_6arrays_10array_tree_13ArrayTreeNode_7summary_2__set__(((struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeNode *)__pyx_v_self), ((PyObject *)__pyx_v_value));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_2bx_6arrays_10array_tree_13ArrayTreeNode_7summary_2__set__(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeNode *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__set__", 0);
+  if (!(likely(((__pyx_v_value) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_value, __pyx_ptype_2bx_6arrays_10array_tree_Summary))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 322; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_INCREF(__pyx_v_value);
+  __Pyx_GIVEREF(__pyx_v_value);
+  __Pyx_GOTREF(__pyx_v_self->summary);
+  __Pyx_DECREF(((PyObject *)__pyx_v_self->summary));
+  __pyx_v_self->summary = ((struct __pyx_obj_2bx_6arrays_10array_tree_Summary *)__pyx_v_value);
+
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_AddTraceback("bx.arrays.array_tree.ArrayTreeNode.summary.__set__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = -1;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_2bx_6arrays_10array_tree_13ArrayTreeNode_7summary_5__del__(PyObject *__pyx_v_self); /*proto*/
+static int __pyx_pw_2bx_6arrays_10array_tree_13ArrayTreeNode_7summary_5__del__(PyObject *__pyx_v_self) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__del__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_6arrays_10array_tree_13ArrayTreeNode_7summary_4__del__(((struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeNode *)__pyx_v_self));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_2bx_6arrays_10array_tree_13ArrayTreeNode_7summary_4__del__(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeNode *__pyx_v_self) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__del__", 0);
+  __Pyx_INCREF(Py_None);
+  __Pyx_GIVEREF(Py_None);
+  __Pyx_GOTREF(__pyx_v_self->summary);
+  __Pyx_DECREF(((PyObject *)__pyx_v_self->summary));
+  __pyx_v_self->summary = ((struct __pyx_obj_2bx_6arrays_10array_tree_Summary *)Py_None);
+
+  __pyx_r = 0;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_13ArrayTreeNode_12start_offset_1__get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_13ArrayTreeNode_12start_offset_1__get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_6arrays_10array_tree_13ArrayTreeNode_12start_offset___get__(((struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeNode *)__pyx_v_self));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/arrays/array_tree.pyx":323
+ *     cdef object children
+ *     cdef public Summary summary
+ *     cdef public long start_offset             # <<<<<<<<<<<<<<
+ * 
+ *     def __init__( self, ArrayTree tree, int min, int max, int block_size, int level ):
+ */
+
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_13ArrayTreeNode_12start_offset___get__(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeNode *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__get__", 0);
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = PyInt_FromLong(__pyx_v_self->start_offset); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("bx.arrays.array_tree.ArrayTreeNode.start_offset.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_2bx_6arrays_10array_tree_13ArrayTreeNode_12start_offset_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value); /*proto*/
+static int __pyx_pw_2bx_6arrays_10array_tree_13ArrayTreeNode_12start_offset_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__set__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_6arrays_10array_tree_13ArrayTreeNode_12start_offset_2__set__(((struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeNode *)__pyx_v_self), ((PyObject *)__pyx_v_value));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_2bx_6arrays_10array_tree_13ArrayTreeNode_12start_offset_2__set__(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeNode *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  long __pyx_t_1;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__set__", 0);
+  __pyx_t_1 = __Pyx_PyInt_AsLong(__pyx_v_value); if (unlikely((__pyx_t_1 == (long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_v_self->start_offset = __pyx_t_1;
+
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_AddTraceback("bx.arrays.array_tree.ArrayTreeNode.start_offset.__set__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = -1;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_2bx_6arrays_10array_tree_13ArrayTreeLeaf_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static int __pyx_pw_2bx_6arrays_10array_tree_13ArrayTreeLeaf_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTree *__pyx_v_tree = 0;
+  int __pyx_v_min;
+  int __pyx_v_max;
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__init__ (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__tree,&__pyx_n_s__min,&__pyx_n_s__max,0};
+    PyObject* values[3] = {0,0,0};
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__tree)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__min)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("__init__", 1, 3, 3, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 489; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+        case  2:
+        if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__max)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("__init__", 1, 3, 3, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 489; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 489; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else if (PyTuple_GET_SIZE(__pyx_args) != 3) {
+      goto __pyx_L5_argtuple_error;
+    } else {
+      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+      values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+    }
+    __pyx_v_tree = ((struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTree *)values[0]);
+    __pyx_v_min = __Pyx_PyInt_AsInt(values[1]); if (unlikely((__pyx_v_min == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 489; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_max = __Pyx_PyInt_AsInt(values[2]); if (unlikely((__pyx_v_max == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 489; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("__init__", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 489; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.arrays.array_tree.ArrayTreeLeaf.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return -1;
+  __pyx_L4_argument_unpacking_done:;
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_tree), __pyx_ptype_2bx_6arrays_10array_tree_ArrayTree, 1, "tree", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 489; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_r = __pyx_pf_2bx_6arrays_10array_tree_13ArrayTreeLeaf___init__(((struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeLeaf *)__pyx_v_self), __pyx_v_tree, __pyx_v_min, __pyx_v_max);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __pyx_r = -1;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/arrays/array_tree.pyx":489
+ *     cdef public long start_offset
+ * 
+ *     def __init__( self, ArrayTree tree, int min, int max ):             # <<<<<<<<<<<<<<
+ *         self.tree = tree
+ *         self.min = min
+ */
+
+static int __pyx_pf_2bx_6arrays_10array_tree_13ArrayTreeLeaf___init__(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeLeaf *__pyx_v_self, struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTree *__pyx_v_tree, int __pyx_v_min, int __pyx_v_max) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__init__", 0);
+
+  /* "bx/arrays/array_tree.pyx":490
+ * 
+ *     def __init__( self, ArrayTree tree, int min, int max ):
+ *         self.tree = tree             # <<<<<<<<<<<<<<
+ *         self.min = min
+ *         self.max = max
+ */
+  __Pyx_INCREF(((PyObject *)__pyx_v_tree));
+  __Pyx_GIVEREF(((PyObject *)__pyx_v_tree));
+  __Pyx_GOTREF(__pyx_v_self->tree);
+  __Pyx_DECREF(((PyObject *)__pyx_v_self->tree));
+  __pyx_v_self->tree = __pyx_v_tree;
+
+  /* "bx/arrays/array_tree.pyx":491
+ *     def __init__( self, ArrayTree tree, int min, int max ):
+ *         self.tree = tree
+ *         self.min = min             # <<<<<<<<<<<<<<
+ *         self.max = max
+ *         self.frequency = 0
+ */
+  __pyx_v_self->min = __pyx_v_min;
+
+  /* "bx/arrays/array_tree.pyx":492
+ *         self.tree = tree
+ *         self.min = min
+ *         self.max = max             # <<<<<<<<<<<<<<
+ *         self.frequency = 0
+ *         self.values = empty( max - min, self.tree.dtype )
+ */
+  __pyx_v_self->max = __pyx_v_max;
+
+  /* "bx/arrays/array_tree.pyx":493
+ *         self.min = min
+ *         self.max = max
+ *         self.frequency = 0             # <<<<<<<<<<<<<<
+ *         self.values = empty( max - min, self.tree.dtype )
+ *         self.values[:] = nan
+ */
+  __pyx_v_self->frequency = 0;
+
+  /* "bx/arrays/array_tree.pyx":494
+ *         self.max = max
+ *         self.frequency = 0
+ *         self.values = empty( max - min, self.tree.dtype )             # <<<<<<<<<<<<<<
+ *         self.values[:] = nan
+ *         self.start_offset = 0
+ */
+  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__empty); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 494; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = PyInt_FromLong((__pyx_v_max - __pyx_v_min)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 494; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 494; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_2);
+  __Pyx_GIVEREF(__pyx_t_2);
+  __Pyx_INCREF(__pyx_v_self->tree->dtype);
+  PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_v_self->tree->dtype);
+  __Pyx_GIVEREF(__pyx_v_self->tree->dtype);
+  __pyx_t_2 = 0;
+  __pyx_t_2 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 494; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
+  if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 494; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GIVEREF(__pyx_t_2);
+  __Pyx_GOTREF(__pyx_v_self->values);
+  __Pyx_DECREF(((PyObject *)__pyx_v_self->values));
+  __pyx_v_self->values = ((PyArrayObject *)__pyx_t_2);
+  __pyx_t_2 = 0;
+
+  /* "bx/arrays/array_tree.pyx":495
+ *         self.frequency = 0
+ *         self.values = empty( max - min, self.tree.dtype )
+ *         self.values[:] = nan             # <<<<<<<<<<<<<<
+ *         self.start_offset = 0
+ * 
+ */
+  __pyx_t_2 = __Pyx_GetName(__pyx_m, __pyx_n_s__nan); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 495; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  if (__Pyx_PySequence_SetSlice(((PyObject *)__pyx_v_self->values), 0, PY_SSIZE_T_MAX, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 495; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+  /* "bx/arrays/array_tree.pyx":496
+ *         self.values = empty( max - min, self.tree.dtype )
+ *         self.values[:] = nan
+ *         self.start_offset = 0             # <<<<<<<<<<<<<<
+ * 
+ *     def set( self, index, value ):
+ */
+  __pyx_v_self->start_offset = 0;
+
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_AddTraceback("bx.arrays.array_tree.ArrayTreeLeaf.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = -1;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_13ArrayTreeLeaf_3set(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_13ArrayTreeLeaf_3set(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_index = 0;
+  PyObject *__pyx_v_value = 0;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("set (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__index,&__pyx_n_s__value,0};
+    PyObject* values[2] = {0,0};
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__index)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__value)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("set", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 498; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "set") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 498; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
+      goto __pyx_L5_argtuple_error;
+    } else {
+      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+    }
+    __pyx_v_index = values[0];
+    __pyx_v_value = values[1];
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("set", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 498; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.arrays.array_tree.ArrayTreeLeaf.set", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_6arrays_10array_tree_13ArrayTreeLeaf_2set(((struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeLeaf *)__pyx_v_self), __pyx_v_index, __pyx_v_value);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/arrays/array_tree.pyx":498
+ *         self.start_offset = 0
+ * 
+ *     def set( self, index, value ):             # <<<<<<<<<<<<<<
+ *         self.frequency += 1
+ *         self.values[ index - self.min ] = value
+ */
+
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_13ArrayTreeLeaf_2set(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeLeaf *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("set", 0);
+
+  /* "bx/arrays/array_tree.pyx":499
+ * 
+ *     def set( self, index, value ):
+ *         self.frequency += 1             # <<<<<<<<<<<<<<
+ *         self.values[ index - self.min ] = value
+ * 
+ */
+  __pyx_v_self->frequency = (__pyx_v_self->frequency + 1);
+
+  /* "bx/arrays/array_tree.pyx":500
+ *     def set( self, index, value ):
+ *         self.frequency += 1
+ *         self.values[ index - self.min ] = value             # <<<<<<<<<<<<<<
+ * 
+ *     def get( self, index ):
+ */
+  __pyx_t_1 = PyInt_FromLong(__pyx_v_self->min); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 500; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = PyNumber_Subtract(__pyx_v_index, __pyx_t_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 500; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  if (PyObject_SetItem(((PyObject *)__pyx_v_self->values), __pyx_t_2, __pyx_v_value) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 500; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_AddTraceback("bx.arrays.array_tree.ArrayTreeLeaf.set", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_13ArrayTreeLeaf_5get(PyObject *__pyx_v_self, PyObject *__pyx_v_index); /*proto*/
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_13ArrayTreeLeaf_5get(PyObject *__pyx_v_self, PyObject *__pyx_v_index) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("get (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_6arrays_10array_tree_13ArrayTreeLeaf_4get(((struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeLeaf *)__pyx_v_self), ((PyObject *)__pyx_v_index));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/arrays/array_tree.pyx":502
+ *         self.values[ index - self.min ] = value
+ * 
+ *     def get( self, index ):             # <<<<<<<<<<<<<<
+ *         return self.values[ index - self.min ]
+ * 
+ */
+
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_13ArrayTreeLeaf_4get(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeLeaf *__pyx_v_self, PyObject *__pyx_v_index) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("get", 0);
+
+  /* "bx/arrays/array_tree.pyx":503
+ * 
+ *     def get( self, index ):
+ *         return self.values[ index - self.min ]             # <<<<<<<<<<<<<<
+ * 
+ *     def to_file_data_pass( self, io, level ):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = PyInt_FromLong(__pyx_v_self->min); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 503; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = PyNumber_Subtract(__pyx_v_index, __pyx_t_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 503; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_1 = PyObject_GetItem(((PyObject *)__pyx_v_self->values), __pyx_t_2); if (!__pyx_t_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 503; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_AddTraceback("bx.arrays.array_tree.ArrayTreeLeaf.get", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_13ArrayTreeLeaf_7to_file_data_pass(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_13ArrayTreeLeaf_7to_file_data_pass(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_io = 0;
+  PyObject *__pyx_v_level = 0;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("to_file_data_pass (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__io,&__pyx_n_s__level,0};
+    PyObject* values[2] = {0,0};
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__io)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__level)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("to_file_data_pass", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 505; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "to_file_data_pass") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 505; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
+      goto __pyx_L5_argtuple_error;
+    } else {
+      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+    }
+    __pyx_v_io = values[0];
+    __pyx_v_level = values[1];
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("to_file_data_pass", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 505; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.arrays.array_tree.ArrayTreeLeaf.to_file_data_pass", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_6arrays_10array_tree_13ArrayTreeLeaf_6to_file_data_pass(((struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeLeaf *)__pyx_v_self), __pyx_v_io, __pyx_v_level);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/arrays/array_tree.pyx":505
+ *         return self.values[ index - self.min ]
+ * 
+ *     def to_file_data_pass( self, io, level ):             # <<<<<<<<<<<<<<
+ *         assert level == 0
+ *         self.start_offset = io.tell()
+ */
+
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_13ArrayTreeLeaf_6to_file_data_pass(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeLeaf *__pyx_v_self, PyObject *__pyx_v_io, PyObject *__pyx_v_level) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_t_2;
+  PyObject *__pyx_t_3 = NULL;
+  long __pyx_t_4;
+  PyObject *__pyx_t_5 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("to_file_data_pass", 0);
+
+  /* "bx/arrays/array_tree.pyx":506
+ * 
+ *     def to_file_data_pass( self, io, level ):
+ *         assert level == 0             # <<<<<<<<<<<<<<
+ *         self.start_offset = io.tell()
+ *         io.write_raw_array( self.values )
+ */
+  #ifndef CYTHON_WITHOUT_ASSERTIONS
+  __pyx_t_1 = PyObject_RichCompare(__pyx_v_level, __pyx_int_0, Py_EQ); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 506; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 506; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  if (unlikely(!__pyx_t_2)) {
+    PyErr_SetNone(PyExc_AssertionError);
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 506; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  #endif
+
+  /* "bx/arrays/array_tree.pyx":507
+ *     def to_file_data_pass( self, io, level ):
+ *         assert level == 0
+ *         self.start_offset = io.tell()             # <<<<<<<<<<<<<<
+ *         io.write_raw_array( self.values )
+ * 
+ */
+  __pyx_t_1 = PyObject_GetAttr(__pyx_v_io, __pyx_n_s__tell); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 507; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_3 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 507; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_4 = __Pyx_PyInt_AsLong(__pyx_t_3); if (unlikely((__pyx_t_4 == (long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 507; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __pyx_v_self->start_offset = __pyx_t_4;
+
+  /* "bx/arrays/array_tree.pyx":508
+ *         assert level == 0
+ *         self.start_offset = io.tell()
+ *         io.write_raw_array( self.values )             # <<<<<<<<<<<<<<
+ * 
+ *     def to_file_offset_pass( self, io ):
+ */
+  __pyx_t_3 = PyObject_GetAttr(__pyx_v_io, __pyx_n_s__write_raw_array); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 508; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 508; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_INCREF(((PyObject *)__pyx_v_self->values));
+  PyTuple_SET_ITEM(__pyx_t_1, 0, ((PyObject *)__pyx_v_self->values));
+  __Pyx_GIVEREF(((PyObject *)__pyx_v_self->values));
+  __pyx_t_5 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 508; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_5);
+  __Pyx_AddTraceback("bx.arrays.array_tree.ArrayTreeLeaf.to_file_data_pass", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_13ArrayTreeLeaf_9to_file_offset_pass(PyObject *__pyx_v_self, PyObject *__pyx_v_io); /*proto*/
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_13ArrayTreeLeaf_9to_file_offset_pass(PyObject *__pyx_v_self, PyObject *__pyx_v_io) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("to_file_offset_pass (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_6arrays_10array_tree_13ArrayTreeLeaf_8to_file_offset_pass(((struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeLeaf *)__pyx_v_self), ((PyObject *)__pyx_v_io));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/arrays/array_tree.pyx":510
+ *         io.write_raw_array( self.values )
+ * 
+ *     def to_file_offset_pass( self, io ):             # <<<<<<<<<<<<<<
+ *         pass
+ * 
+ */
+
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_13ArrayTreeLeaf_8to_file_offset_pass(CYTHON_UNUSED struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeLeaf *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v_io) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("to_file_offset_pass", 0);
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_13ArrayTreeLeaf_11from_file(PyObject *__pyx_v_self, PyObject *__pyx_v_io); /*proto*/
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_13ArrayTreeLeaf_11from_file(PyObject *__pyx_v_self, PyObject *__pyx_v_io) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("from_file (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_6arrays_10array_tree_13ArrayTreeLeaf_10from_file(((struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeLeaf *)__pyx_v_self), ((PyObject *)__pyx_v_io));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/arrays/array_tree.pyx":513
+ *         pass
+ * 
+ *     def from_file( self, io ):             # <<<<<<<<<<<<<<
+ *         self.values = io.read_raw_array( self.tree.dtype, self.tree.block_size )
+ */
+
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_13ArrayTreeLeaf_10from_file(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeLeaf *__pyx_v_self, PyObject *__pyx_v_io) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("from_file", 0);
+
+  /* "bx/arrays/array_tree.pyx":514
+ * 
+ *     def from_file( self, io ):
+ *         self.values = io.read_raw_array( self.tree.dtype, self.tree.block_size )             # <<<<<<<<<<<<<<
+ */
+  __pyx_t_1 = PyObject_GetAttr(__pyx_v_io, __pyx_n_s__read_raw_array); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = PyInt_FromLong(__pyx_v_self->tree->block_size); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_INCREF(__pyx_v_self->tree->dtype);
+  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_self->tree->dtype);
+  __Pyx_GIVEREF(__pyx_v_self->tree->dtype);
+  PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_2);
+  __Pyx_GIVEREF(__pyx_t_2);
+  __pyx_t_2 = 0;
+  __pyx_t_2 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
+  if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GIVEREF(__pyx_t_2);
+  __Pyx_GOTREF(__pyx_v_self->values);
+  __Pyx_DECREF(((PyObject *)__pyx_v_self->values));
+  __pyx_v_self->values = ((PyArrayObject *)__pyx_t_2);
+  __pyx_t_2 = 0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_AddTraceback("bx.arrays.array_tree.ArrayTreeLeaf.from_file", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_13ArrayTreeLeaf_9frequency_1__get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_13ArrayTreeLeaf_9frequency_1__get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_6arrays_10array_tree_13ArrayTreeLeaf_9frequency___get__(((struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeLeaf *)__pyx_v_self));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/arrays/array_tree.pyx":485
+ *     cdef int min
+ *     cdef int max
+ *     cdef public int frequency             # <<<<<<<<<<<<<<
+ *     cdef public numpy.ndarray values
+ *     cdef public long start_offset
+ */
+
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_13ArrayTreeLeaf_9frequency___get__(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeLeaf *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__get__", 0);
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = PyInt_FromLong(__pyx_v_self->frequency); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 485; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("bx.arrays.array_tree.ArrayTreeLeaf.frequency.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_2bx_6arrays_10array_tree_13ArrayTreeLeaf_9frequency_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value); /*proto*/
+static int __pyx_pw_2bx_6arrays_10array_tree_13ArrayTreeLeaf_9frequency_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__set__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_6arrays_10array_tree_13ArrayTreeLeaf_9frequency_2__set__(((struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeLeaf *)__pyx_v_self), ((PyObject *)__pyx_v_value));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_2bx_6arrays_10array_tree_13ArrayTreeLeaf_9frequency_2__set__(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeLeaf *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__set__", 0);
+  __pyx_t_1 = __Pyx_PyInt_AsInt(__pyx_v_value); if (unlikely((__pyx_t_1 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 485; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_v_self->frequency = __pyx_t_1;
+
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_AddTraceback("bx.arrays.array_tree.ArrayTreeLeaf.frequency.__set__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = -1;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_13ArrayTreeLeaf_6values_1__get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_13ArrayTreeLeaf_6values_1__get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_6arrays_10array_tree_13ArrayTreeLeaf_6values___get__(((struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeLeaf *)__pyx_v_self));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/arrays/array_tree.pyx":486
+ *     cdef int max
+ *     cdef public int frequency
+ *     cdef public numpy.ndarray values             # <<<<<<<<<<<<<<
+ *     cdef public long start_offset
+ * 
+ */
+
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_13ArrayTreeLeaf_6values___get__(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeLeaf *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__get__", 0);
+  __Pyx_XDECREF(__pyx_r);
+  __Pyx_INCREF(((PyObject *)__pyx_v_self->values));
+  __pyx_r = ((PyObject *)__pyx_v_self->values);
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_2bx_6arrays_10array_tree_13ArrayTreeLeaf_6values_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value); /*proto*/
+static int __pyx_pw_2bx_6arrays_10array_tree_13ArrayTreeLeaf_6values_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__set__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_6arrays_10array_tree_13ArrayTreeLeaf_6values_2__set__(((struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeLeaf *)__pyx_v_self), ((PyObject *)__pyx_v_value));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_2bx_6arrays_10array_tree_13ArrayTreeLeaf_6values_2__set__(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeLeaf *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__set__", 0);
+  if (!(likely(((__pyx_v_value) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_value, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 486; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_INCREF(__pyx_v_value);
+  __Pyx_GIVEREF(__pyx_v_value);
+  __Pyx_GOTREF(__pyx_v_self->values);
+  __Pyx_DECREF(((PyObject *)__pyx_v_self->values));
+  __pyx_v_self->values = ((PyArrayObject *)__pyx_v_value);
+
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_AddTraceback("bx.arrays.array_tree.ArrayTreeLeaf.values.__set__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = -1;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_2bx_6arrays_10array_tree_13ArrayTreeLeaf_6values_5__del__(PyObject *__pyx_v_self); /*proto*/
+static int __pyx_pw_2bx_6arrays_10array_tree_13ArrayTreeLeaf_6values_5__del__(PyObject *__pyx_v_self) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__del__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_6arrays_10array_tree_13ArrayTreeLeaf_6values_4__del__(((struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeLeaf *)__pyx_v_self));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_2bx_6arrays_10array_tree_13ArrayTreeLeaf_6values_4__del__(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeLeaf *__pyx_v_self) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__del__", 0);
+  __Pyx_INCREF(Py_None);
+  __Pyx_GIVEREF(Py_None);
+  __Pyx_GOTREF(__pyx_v_self->values);
+  __Pyx_DECREF(((PyObject *)__pyx_v_self->values));
+  __pyx_v_self->values = ((PyArrayObject *)Py_None);
+
+  __pyx_r = 0;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_13ArrayTreeLeaf_12start_offset_1__get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_2bx_6arrays_10array_tree_13ArrayTreeLeaf_12start_offset_1__get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_6arrays_10array_tree_13ArrayTreeLeaf_12start_offset___get__(((struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeLeaf *)__pyx_v_self));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/arrays/array_tree.pyx":487
+ *     cdef public int frequency
+ *     cdef public numpy.ndarray values
+ *     cdef public long start_offset             # <<<<<<<<<<<<<<
+ * 
+ *     def __init__( self, ArrayTree tree, int min, int max ):
+ */
+
+static PyObject *__pyx_pf_2bx_6arrays_10array_tree_13ArrayTreeLeaf_12start_offset___get__(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeLeaf *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__get__", 0);
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = PyInt_FromLong(__pyx_v_self->start_offset); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 487; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("bx.arrays.array_tree.ArrayTreeLeaf.start_offset.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_2bx_6arrays_10array_tree_13ArrayTreeLeaf_12start_offset_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value); /*proto*/
+static int __pyx_pw_2bx_6arrays_10array_tree_13ArrayTreeLeaf_12start_offset_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__set__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_6arrays_10array_tree_13ArrayTreeLeaf_12start_offset_2__set__(((struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeLeaf *)__pyx_v_self), ((PyObject *)__pyx_v_value));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_2bx_6arrays_10array_tree_13ArrayTreeLeaf_12start_offset_2__set__(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeLeaf *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  long __pyx_t_1;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__set__", 0);
+  __pyx_t_1 = __Pyx_PyInt_AsLong(__pyx_v_value); if (unlikely((__pyx_t_1 == (long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 487; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_v_self->start_offset = __pyx_t_1;
+
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_AddTraceback("bx.arrays.array_tree.ArrayTreeLeaf.start_offset.__set__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = -1;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static CYTHON_UNUSED int __pyx_pw_5numpy_7ndarray_1__getbuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /*proto*/
+static CYTHON_UNUSED int __pyx_pw_5numpy_7ndarray_1__getbuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__getbuffer__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_5numpy_7ndarray___getbuffer__(((PyArrayObject *)__pyx_v_self), ((Py_buffer *)__pyx_v_info), ((int)__pyx_v_flags));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "numpy.pxd":194
+ *         # experimental exception made for __getbuffer__ and __releasebuffer__
+ *         # -- the details of this may change.
+ *         def __getbuffer__(ndarray self, Py_buffer* info, int flags):             # <<<<<<<<<<<<<<
+ *             # This implementation of getbuffer is geared towards Cython
+ *             # requirements, and does not yet fullfill the PEP.
+ */
+
+static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) {
+  int __pyx_v_copy_shape;
+  int __pyx_v_i;
+  int __pyx_v_ndim;
+  int __pyx_v_endian_detector;
+  int __pyx_v_little_endian;
+  int __pyx_v_t;
+  char *__pyx_v_f;
+  PyArray_Descr *__pyx_v_descr = 0;
+  int __pyx_v_offset;
+  int __pyx_v_hasfields;
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  int __pyx_t_2;
+  int __pyx_t_3;
+  PyObject *__pyx_t_4 = NULL;
+  int __pyx_t_5;
+  int __pyx_t_6;
+  int __pyx_t_7;
+  PyObject *__pyx_t_8 = NULL;
+  char *__pyx_t_9;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__getbuffer__", 0);
+  if (__pyx_v_info != NULL) {
+    __pyx_v_info->obj = Py_None; __Pyx_INCREF(Py_None);
+    __Pyx_GIVEREF(__pyx_v_info->obj);
+  }
+
+  /* "numpy.pxd":200
+ *             # of flags
+ * 
+ *             if info == NULL: return             # <<<<<<<<<<<<<<
+ * 
+ *             cdef int copy_shape, i, ndim
+ */
+  __pyx_t_1 = (__pyx_v_info == NULL);
+  if (__pyx_t_1) {
+    __pyx_r = 0;
+    goto __pyx_L0;
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  /* "numpy.pxd":203
+ * 
+ *             cdef int copy_shape, i, ndim
+ *             cdef int endian_detector = 1             # <<<<<<<<<<<<<<
+ *             cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)
+ * 
+ */
+  __pyx_v_endian_detector = 1;
+
+  /* "numpy.pxd":204
+ *             cdef int copy_shape, i, ndim
+ *             cdef int endian_detector = 1
+ *             cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)             # <<<<<<<<<<<<<<
+ * 
+ *             ndim = PyArray_NDIM(self)
+ */
+  __pyx_v_little_endian = ((((char *)(&__pyx_v_endian_detector))[0]) != 0);
+
+  /* "numpy.pxd":206
+ *             cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)
+ * 
+ *             ndim = PyArray_NDIM(self)             # <<<<<<<<<<<<<<
+ * 
+ *             if sizeof(npy_intp) != sizeof(Py_ssize_t):
+ */
+  __pyx_v_ndim = PyArray_NDIM(__pyx_v_self);
+
+  /* "numpy.pxd":208
+ *             ndim = PyArray_NDIM(self)
+ * 
+ *             if sizeof(npy_intp) != sizeof(Py_ssize_t):             # <<<<<<<<<<<<<<
+ *                 copy_shape = 1
+ *             else:
+ */
+  __pyx_t_1 = ((sizeof(npy_intp)) != (sizeof(Py_ssize_t)));
+  if (__pyx_t_1) {
+
+    /* "numpy.pxd":209
+ * 
+ *             if sizeof(npy_intp) != sizeof(Py_ssize_t):
+ *                 copy_shape = 1             # <<<<<<<<<<<<<<
+ *             else:
+ *                 copy_shape = 0
+ */
+    __pyx_v_copy_shape = 1;
+    goto __pyx_L4;
+  }
+  /*else*/ {
+
+    /* "numpy.pxd":211
+ *                 copy_shape = 1
+ *             else:
+ *                 copy_shape = 0             # <<<<<<<<<<<<<<
+ * 
+ *             if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)
+ */
+    __pyx_v_copy_shape = 0;
+  }
+  __pyx_L4:;
+
+  /* "numpy.pxd":213
+ *                 copy_shape = 0
+ * 
+ *             if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)             # <<<<<<<<<<<<<<
+ *                 and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)):
+ *                 raise ValueError(u"ndarray is not C contiguous")
+ */
+  __pyx_t_1 = ((__pyx_v_flags & PyBUF_C_CONTIGUOUS) == PyBUF_C_CONTIGUOUS);
+  if (__pyx_t_1) {
+
+    /* "numpy.pxd":214
+ * 
+ *             if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)
+ *                 and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)):             # <<<<<<<<<<<<<<
+ *                 raise ValueError(u"ndarray is not C contiguous")
+ * 
+ */
+    __pyx_t_2 = (!PyArray_CHKFLAGS(__pyx_v_self, NPY_C_CONTIGUOUS));
+    __pyx_t_3 = __pyx_t_2;
+  } else {
+    __pyx_t_3 = __pyx_t_1;
+  }
+  if (__pyx_t_3) {
+
+    /* "numpy.pxd":215
+ *             if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)
+ *                 and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)):
+ *                 raise ValueError(u"ndarray is not C contiguous")             # <<<<<<<<<<<<<<
+ * 
+ *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
+ */
+    __pyx_t_4 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_k_tuple_22), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 215; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    __Pyx_Raise(__pyx_t_4, 0, 0, 0);
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    {__pyx_filename = __pyx_f[1]; __pyx_lineno = 215; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    goto __pyx_L5;
+  }
+  __pyx_L5:;
+
+  /* "numpy.pxd":217
+ *                 raise ValueError(u"ndarray is not C contiguous")
+ * 
+ *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)             # <<<<<<<<<<<<<<
+ *                 and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)):
+ *                 raise ValueError(u"ndarray is not Fortran contiguous")
+ */
+  __pyx_t_3 = ((__pyx_v_flags & PyBUF_F_CONTIGUOUS) == PyBUF_F_CONTIGUOUS);
+  if (__pyx_t_3) {
+
+    /* "numpy.pxd":218
+ * 
+ *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
+ *                 and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)):             # <<<<<<<<<<<<<<
+ *                 raise ValueError(u"ndarray is not Fortran contiguous")
+ * 
+ */
+    __pyx_t_1 = (!PyArray_CHKFLAGS(__pyx_v_self, NPY_F_CONTIGUOUS));
+    __pyx_t_2 = __pyx_t_1;
+  } else {
+    __pyx_t_2 = __pyx_t_3;
+  }
+  if (__pyx_t_2) {
+
+    /* "numpy.pxd":219
+ *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
+ *                 and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)):
+ *                 raise ValueError(u"ndarray is not Fortran contiguous")             # <<<<<<<<<<<<<<
+ * 
+ *             info.buf = PyArray_DATA(self)
+ */
+    __pyx_t_4 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_k_tuple_24), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 219; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    __Pyx_Raise(__pyx_t_4, 0, 0, 0);
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    {__pyx_filename = __pyx_f[1]; __pyx_lineno = 219; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    goto __pyx_L6;
+  }
+  __pyx_L6:;
+
+  /* "numpy.pxd":221
+ *                 raise ValueError(u"ndarray is not Fortran contiguous")
+ * 
+ *             info.buf = PyArray_DATA(self)             # <<<<<<<<<<<<<<
+ *             info.ndim = ndim
+ *             if copy_shape:
+ */
+  __pyx_v_info->buf = PyArray_DATA(__pyx_v_self);
+
+  /* "numpy.pxd":222
+ * 
+ *             info.buf = PyArray_DATA(self)
+ *             info.ndim = ndim             # <<<<<<<<<<<<<<
+ *             if copy_shape:
+ *                 # Allocate new buffer for strides and shape info.
+ */
+  __pyx_v_info->ndim = __pyx_v_ndim;
+
+  /* "numpy.pxd":223
+ *             info.buf = PyArray_DATA(self)
+ *             info.ndim = ndim
+ *             if copy_shape:             # <<<<<<<<<<<<<<
+ *                 # Allocate new buffer for strides and shape info.
+ *                 # This is allocated as one block, strides first.
+ */
+  if (__pyx_v_copy_shape) {
+
+    /* "numpy.pxd":226
+ *                 # Allocate new buffer for strides and shape info.
+ *                 # This is allocated as one block, strides first.
+ *                 info.strides = <Py_ssize_t*>stdlib.malloc(sizeof(Py_ssize_t) * <size_t>ndim * 2)             # <<<<<<<<<<<<<<
+ *                 info.shape = info.strides + ndim
+ *                 for i in range(ndim):
+ */
+    __pyx_v_info->strides = ((Py_ssize_t *)malloc((((sizeof(Py_ssize_t)) * ((size_t)__pyx_v_ndim)) * 2)));
+
+    /* "numpy.pxd":227
+ *                 # This is allocated as one block, strides first.
+ *                 info.strides = <Py_ssize_t*>stdlib.malloc(sizeof(Py_ssize_t) * <size_t>ndim * 2)
+ *                 info.shape = info.strides + ndim             # <<<<<<<<<<<<<<
+ *                 for i in range(ndim):
+ *                     info.strides[i] = PyArray_STRIDES(self)[i]
+ */
+    __pyx_v_info->shape = (__pyx_v_info->strides + __pyx_v_ndim);
+
+    /* "numpy.pxd":228
+ *                 info.strides = <Py_ssize_t*>stdlib.malloc(sizeof(Py_ssize_t) * <size_t>ndim * 2)
+ *                 info.shape = info.strides + ndim
+ *                 for i in range(ndim):             # <<<<<<<<<<<<<<
+ *                     info.strides[i] = PyArray_STRIDES(self)[i]
+ *                     info.shape[i] = PyArray_DIMS(self)[i]
+ */
+    __pyx_t_5 = __pyx_v_ndim;
+    for (__pyx_t_6 = 0; __pyx_t_6 < __pyx_t_5; __pyx_t_6+=1) {
+      __pyx_v_i = __pyx_t_6;
+
+      /* "numpy.pxd":229
+ *                 info.shape = info.strides + ndim
+ *                 for i in range(ndim):
+ *                     info.strides[i] = PyArray_STRIDES(self)[i]             # <<<<<<<<<<<<<<
+ *                     info.shape[i] = PyArray_DIMS(self)[i]
+ *             else:
+ */
+      (__pyx_v_info->strides[__pyx_v_i]) = (PyArray_STRIDES(__pyx_v_self)[__pyx_v_i]);
+
+      /* "numpy.pxd":230
+ *                 for i in range(ndim):
+ *                     info.strides[i] = PyArray_STRIDES(self)[i]
+ *                     info.shape[i] = PyArray_DIMS(self)[i]             # <<<<<<<<<<<<<<
+ *             else:
+ *                 info.strides = <Py_ssize_t*>PyArray_STRIDES(self)
+ */
+      (__pyx_v_info->shape[__pyx_v_i]) = (PyArray_DIMS(__pyx_v_self)[__pyx_v_i]);
+    }
+    goto __pyx_L7;
+  }
+  /*else*/ {
+
+    /* "numpy.pxd":232
+ *                     info.shape[i] = PyArray_DIMS(self)[i]
+ *             else:
+ *                 info.strides = <Py_ssize_t*>PyArray_STRIDES(self)             # <<<<<<<<<<<<<<
+ *                 info.shape = <Py_ssize_t*>PyArray_DIMS(self)
+ *             info.suboffsets = NULL
+ */
+    __pyx_v_info->strides = ((Py_ssize_t *)PyArray_STRIDES(__pyx_v_self));
+
+    /* "numpy.pxd":233
+ *             else:
+ *                 info.strides = <Py_ssize_t*>PyArray_STRIDES(self)
+ *                 info.shape = <Py_ssize_t*>PyArray_DIMS(self)             # <<<<<<<<<<<<<<
+ *             info.suboffsets = NULL
+ *             info.itemsize = PyArray_ITEMSIZE(self)
+ */
+    __pyx_v_info->shape = ((Py_ssize_t *)PyArray_DIMS(__pyx_v_self));
+  }
+  __pyx_L7:;
+
+  /* "numpy.pxd":234
+ *                 info.strides = <Py_ssize_t*>PyArray_STRIDES(self)
+ *                 info.shape = <Py_ssize_t*>PyArray_DIMS(self)
+ *             info.suboffsets = NULL             # <<<<<<<<<<<<<<
+ *             info.itemsize = PyArray_ITEMSIZE(self)
+ *             info.readonly = not PyArray_ISWRITEABLE(self)
+ */
+  __pyx_v_info->suboffsets = NULL;
+
+  /* "numpy.pxd":235
+ *                 info.shape = <Py_ssize_t*>PyArray_DIMS(self)
+ *             info.suboffsets = NULL
+ *             info.itemsize = PyArray_ITEMSIZE(self)             # <<<<<<<<<<<<<<
+ *             info.readonly = not PyArray_ISWRITEABLE(self)
+ * 
+ */
+  __pyx_v_info->itemsize = PyArray_ITEMSIZE(__pyx_v_self);
+
+  /* "numpy.pxd":236
+ *             info.suboffsets = NULL
+ *             info.itemsize = PyArray_ITEMSIZE(self)
+ *             info.readonly = not PyArray_ISWRITEABLE(self)             # <<<<<<<<<<<<<<
+ * 
+ *             cdef int t
+ */
+  __pyx_v_info->readonly = (!PyArray_ISWRITEABLE(__pyx_v_self));
+
+  /* "numpy.pxd":239
+ * 
+ *             cdef int t
+ *             cdef char* f = NULL             # <<<<<<<<<<<<<<
+ *             cdef dtype descr = self.descr
+ *             cdef list stack
+ */
+  __pyx_v_f = NULL;
+
+  /* "numpy.pxd":240
+ *             cdef int t
+ *             cdef char* f = NULL
+ *             cdef dtype descr = self.descr             # <<<<<<<<<<<<<<
+ *             cdef list stack
+ *             cdef int offset
+ */
+  __pyx_t_4 = ((PyObject *)__pyx_v_self->descr);
+  __Pyx_INCREF(__pyx_t_4);
+  __pyx_v_descr = ((PyArray_Descr *)__pyx_t_4);
+  __pyx_t_4 = 0;
+
+  /* "numpy.pxd":244
+ *             cdef int offset
+ * 
+ *             cdef bint hasfields = PyDataType_HASFIELDS(descr)             # <<<<<<<<<<<<<<
+ * 
+ *             if not hasfields and not copy_shape:
+ */
+  __pyx_v_hasfields = PyDataType_HASFIELDS(__pyx_v_descr);
+
+  /* "numpy.pxd":246
+ *             cdef bint hasfields = PyDataType_HASFIELDS(descr)
+ * 
+ *             if not hasfields and not copy_shape:             # <<<<<<<<<<<<<<
+ *                 # do not call releasebuffer
+ *                 info.obj = None
+ */
+  __pyx_t_2 = (!__pyx_v_hasfields);
+  if (__pyx_t_2) {
+    __pyx_t_3 = (!__pyx_v_copy_shape);
+    __pyx_t_1 = __pyx_t_3;
+  } else {
+    __pyx_t_1 = __pyx_t_2;
+  }
+  if (__pyx_t_1) {
+
+    /* "numpy.pxd":248
+ *             if not hasfields and not copy_shape:
+ *                 # do not call releasebuffer
+ *                 info.obj = None             # <<<<<<<<<<<<<<
+ *             else:
+ *                 # need to call releasebuffer
+ */
+    __Pyx_INCREF(Py_None);
+    __Pyx_GIVEREF(Py_None);
+    __Pyx_GOTREF(__pyx_v_info->obj);
+    __Pyx_DECREF(__pyx_v_info->obj);
+    __pyx_v_info->obj = Py_None;
+    goto __pyx_L10;
+  }
+  /*else*/ {
+
+    /* "numpy.pxd":251
+ *             else:
+ *                 # need to call releasebuffer
+ *                 info.obj = self             # <<<<<<<<<<<<<<
+ * 
+ *             if not hasfields:
+ */
+    __Pyx_INCREF(((PyObject *)__pyx_v_self));
+    __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
+    __Pyx_GOTREF(__pyx_v_info->obj);
+    __Pyx_DECREF(__pyx_v_info->obj);
+    __pyx_v_info->obj = ((PyObject *)__pyx_v_self);
+  }
+  __pyx_L10:;
+
+  /* "numpy.pxd":253
+ *                 info.obj = self
+ * 
+ *             if not hasfields:             # <<<<<<<<<<<<<<
+ *                 t = descr.type_num
+ *                 if ((descr.byteorder == c'>' and little_endian) or
+ */
+  __pyx_t_1 = (!__pyx_v_hasfields);
+  if (__pyx_t_1) {
+
+    /* "numpy.pxd":254
+ * 
+ *             if not hasfields:
+ *                 t = descr.type_num             # <<<<<<<<<<<<<<
+ *                 if ((descr.byteorder == c'>' and little_endian) or
+ *                     (descr.byteorder == c'<' and not little_endian)):
+ */
+    __pyx_t_5 = __pyx_v_descr->type_num;
+    __pyx_v_t = __pyx_t_5;
+
+    /* "numpy.pxd":255
+ *             if not hasfields:
+ *                 t = descr.type_num
+ *                 if ((descr.byteorder == c'>' and little_endian) or             # <<<<<<<<<<<<<<
+ *                     (descr.byteorder == c'<' and not little_endian)):
+ *                     raise ValueError(u"Non-native byte order not supported")
+ */
+    __pyx_t_1 = (__pyx_v_descr->byteorder == '>');
+    if (__pyx_t_1) {
+      __pyx_t_2 = __pyx_v_little_endian;
+    } else {
+      __pyx_t_2 = __pyx_t_1;
+    }
+    if (!__pyx_t_2) {
+
+      /* "numpy.pxd":256
+ *                 t = descr.type_num
+ *                 if ((descr.byteorder == c'>' and little_endian) or
+ *                     (descr.byteorder == c'<' and not little_endian)):             # <<<<<<<<<<<<<<
+ *                     raise ValueError(u"Non-native byte order not supported")
+ *                 if   t == NPY_BYTE:        f = "b"
+ */
+      __pyx_t_1 = (__pyx_v_descr->byteorder == '<');
+      if (__pyx_t_1) {
+        __pyx_t_3 = (!__pyx_v_little_endian);
+        __pyx_t_7 = __pyx_t_3;
+      } else {
+        __pyx_t_7 = __pyx_t_1;
+      }
+      __pyx_t_1 = __pyx_t_7;
+    } else {
+      __pyx_t_1 = __pyx_t_2;
+    }
+    if (__pyx_t_1) {
+
+      /* "numpy.pxd":257
+ *                 if ((descr.byteorder == c'>' and little_endian) or
+ *                     (descr.byteorder == c'<' and not little_endian)):
+ *                     raise ValueError(u"Non-native byte order not supported")             # <<<<<<<<<<<<<<
+ *                 if   t == NPY_BYTE:        f = "b"
+ *                 elif t == NPY_UBYTE:       f = "B"
+ */
+      __pyx_t_4 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_k_tuple_26), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __Pyx_Raise(__pyx_t_4, 0, 0, 0);
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      {__pyx_filename = __pyx_f[1]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      goto __pyx_L12;
+    }
+    __pyx_L12:;
+
+    /* "numpy.pxd":258
+ *                     (descr.byteorder == c'<' and not little_endian)):
+ *                     raise ValueError(u"Non-native byte order not supported")
+ *                 if   t == NPY_BYTE:        f = "b"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_UBYTE:       f = "B"
+ *                 elif t == NPY_SHORT:       f = "h"
+ */
+    __pyx_t_1 = (__pyx_v_t == NPY_BYTE);
+    if (__pyx_t_1) {
+      __pyx_v_f = __pyx_k__b;
+      goto __pyx_L13;
+    }
+
+    /* "numpy.pxd":259
+ *                     raise ValueError(u"Non-native byte order not supported")
+ *                 if   t == NPY_BYTE:        f = "b"
+ *                 elif t == NPY_UBYTE:       f = "B"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_SHORT:       f = "h"
+ *                 elif t == NPY_USHORT:      f = "H"
+ */
+    __pyx_t_1 = (__pyx_v_t == NPY_UBYTE);
+    if (__pyx_t_1) {
+      __pyx_v_f = __pyx_k__B;
+      goto __pyx_L13;
+    }
+
+    /* "numpy.pxd":260
+ *                 if   t == NPY_BYTE:        f = "b"
+ *                 elif t == NPY_UBYTE:       f = "B"
+ *                 elif t == NPY_SHORT:       f = "h"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_USHORT:      f = "H"
+ *                 elif t == NPY_INT:         f = "i"
+ */
+    __pyx_t_1 = (__pyx_v_t == NPY_SHORT);
+    if (__pyx_t_1) {
+      __pyx_v_f = __pyx_k__h;
+      goto __pyx_L13;
+    }
+
+    /* "numpy.pxd":261
+ *                 elif t == NPY_UBYTE:       f = "B"
+ *                 elif t == NPY_SHORT:       f = "h"
+ *                 elif t == NPY_USHORT:      f = "H"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_INT:         f = "i"
+ *                 elif t == NPY_UINT:        f = "I"
+ */
+    __pyx_t_1 = (__pyx_v_t == NPY_USHORT);
+    if (__pyx_t_1) {
+      __pyx_v_f = __pyx_k__H;
+      goto __pyx_L13;
+    }
+
+    /* "numpy.pxd":262
+ *                 elif t == NPY_SHORT:       f = "h"
+ *                 elif t == NPY_USHORT:      f = "H"
+ *                 elif t == NPY_INT:         f = "i"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_UINT:        f = "I"
+ *                 elif t == NPY_LONG:        f = "l"
+ */
+    __pyx_t_1 = (__pyx_v_t == NPY_INT);
+    if (__pyx_t_1) {
+      __pyx_v_f = __pyx_k__i;
+      goto __pyx_L13;
+    }
+
+    /* "numpy.pxd":263
+ *                 elif t == NPY_USHORT:      f = "H"
+ *                 elif t == NPY_INT:         f = "i"
+ *                 elif t == NPY_UINT:        f = "I"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_LONG:        f = "l"
+ *                 elif t == NPY_ULONG:       f = "L"
+ */
+    __pyx_t_1 = (__pyx_v_t == NPY_UINT);
+    if (__pyx_t_1) {
+      __pyx_v_f = __pyx_k__I;
+      goto __pyx_L13;
+    }
+
+    /* "numpy.pxd":264
+ *                 elif t == NPY_INT:         f = "i"
+ *                 elif t == NPY_UINT:        f = "I"
+ *                 elif t == NPY_LONG:        f = "l"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_ULONG:       f = "L"
+ *                 elif t == NPY_LONGLONG:    f = "q"
+ */
+    __pyx_t_1 = (__pyx_v_t == NPY_LONG);
+    if (__pyx_t_1) {
+      __pyx_v_f = __pyx_k__l;
+      goto __pyx_L13;
+    }
+
+    /* "numpy.pxd":265
+ *                 elif t == NPY_UINT:        f = "I"
+ *                 elif t == NPY_LONG:        f = "l"
+ *                 elif t == NPY_ULONG:       f = "L"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_LONGLONG:    f = "q"
+ *                 elif t == NPY_ULONGLONG:   f = "Q"
+ */
+    __pyx_t_1 = (__pyx_v_t == NPY_ULONG);
+    if (__pyx_t_1) {
+      __pyx_v_f = __pyx_k__L;
+      goto __pyx_L13;
+    }
+
+    /* "numpy.pxd":266
+ *                 elif t == NPY_LONG:        f = "l"
+ *                 elif t == NPY_ULONG:       f = "L"
+ *                 elif t == NPY_LONGLONG:    f = "q"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_ULONGLONG:   f = "Q"
+ *                 elif t == NPY_FLOAT:       f = "f"
+ */
+    __pyx_t_1 = (__pyx_v_t == NPY_LONGLONG);
+    if (__pyx_t_1) {
+      __pyx_v_f = __pyx_k__q;
+      goto __pyx_L13;
+    }
+
+    /* "numpy.pxd":267
+ *                 elif t == NPY_ULONG:       f = "L"
+ *                 elif t == NPY_LONGLONG:    f = "q"
+ *                 elif t == NPY_ULONGLONG:   f = "Q"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_FLOAT:       f = "f"
+ *                 elif t == NPY_DOUBLE:      f = "d"
+ */
+    __pyx_t_1 = (__pyx_v_t == NPY_ULONGLONG);
+    if (__pyx_t_1) {
+      __pyx_v_f = __pyx_k__Q;
+      goto __pyx_L13;
+    }
+
+    /* "numpy.pxd":268
+ *                 elif t == NPY_LONGLONG:    f = "q"
+ *                 elif t == NPY_ULONGLONG:   f = "Q"
+ *                 elif t == NPY_FLOAT:       f = "f"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_DOUBLE:      f = "d"
+ *                 elif t == NPY_LONGDOUBLE:  f = "g"
+ */
+    __pyx_t_1 = (__pyx_v_t == NPY_FLOAT);
+    if (__pyx_t_1) {
+      __pyx_v_f = __pyx_k__f;
+      goto __pyx_L13;
+    }
+
+    /* "numpy.pxd":269
+ *                 elif t == NPY_ULONGLONG:   f = "Q"
+ *                 elif t == NPY_FLOAT:       f = "f"
+ *                 elif t == NPY_DOUBLE:      f = "d"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_LONGDOUBLE:  f = "g"
+ *                 elif t == NPY_CFLOAT:      f = "Zf"
+ */
+    __pyx_t_1 = (__pyx_v_t == NPY_DOUBLE);
+    if (__pyx_t_1) {
+      __pyx_v_f = __pyx_k__d;
+      goto __pyx_L13;
+    }
+
+    /* "numpy.pxd":270
+ *                 elif t == NPY_FLOAT:       f = "f"
+ *                 elif t == NPY_DOUBLE:      f = "d"
+ *                 elif t == NPY_LONGDOUBLE:  f = "g"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_CFLOAT:      f = "Zf"
+ *                 elif t == NPY_CDOUBLE:     f = "Zd"
+ */
+    __pyx_t_1 = (__pyx_v_t == NPY_LONGDOUBLE);
+    if (__pyx_t_1) {
+      __pyx_v_f = __pyx_k__g;
+      goto __pyx_L13;
+    }
+
+    /* "numpy.pxd":271
+ *                 elif t == NPY_DOUBLE:      f = "d"
+ *                 elif t == NPY_LONGDOUBLE:  f = "g"
+ *                 elif t == NPY_CFLOAT:      f = "Zf"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_CDOUBLE:     f = "Zd"
+ *                 elif t == NPY_CLONGDOUBLE: f = "Zg"
+ */
+    __pyx_t_1 = (__pyx_v_t == NPY_CFLOAT);
+    if (__pyx_t_1) {
+      __pyx_v_f = __pyx_k__Zf;
+      goto __pyx_L13;
+    }
+
+    /* "numpy.pxd":272
+ *                 elif t == NPY_LONGDOUBLE:  f = "g"
+ *                 elif t == NPY_CFLOAT:      f = "Zf"
+ *                 elif t == NPY_CDOUBLE:     f = "Zd"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_CLONGDOUBLE: f = "Zg"
+ *                 elif t == NPY_OBJECT:      f = "O"
+ */
+    __pyx_t_1 = (__pyx_v_t == NPY_CDOUBLE);
+    if (__pyx_t_1) {
+      __pyx_v_f = __pyx_k__Zd;
+      goto __pyx_L13;
+    }
+
+    /* "numpy.pxd":273
+ *                 elif t == NPY_CFLOAT:      f = "Zf"
+ *                 elif t == NPY_CDOUBLE:     f = "Zd"
+ *                 elif t == NPY_CLONGDOUBLE: f = "Zg"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_OBJECT:      f = "O"
+ *                 else:
+ */
+    __pyx_t_1 = (__pyx_v_t == NPY_CLONGDOUBLE);
+    if (__pyx_t_1) {
+      __pyx_v_f = __pyx_k__Zg;
+      goto __pyx_L13;
+    }
+
+    /* "numpy.pxd":274
+ *                 elif t == NPY_CDOUBLE:     f = "Zd"
+ *                 elif t == NPY_CLONGDOUBLE: f = "Zg"
+ *                 elif t == NPY_OBJECT:      f = "O"             # <<<<<<<<<<<<<<
+ *                 else:
+ *                     raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
+ */
+    __pyx_t_1 = (__pyx_v_t == NPY_OBJECT);
+    if (__pyx_t_1) {
+      __pyx_v_f = __pyx_k__O;
+      goto __pyx_L13;
+    }
+    /*else*/ {
+
+      /* "numpy.pxd":276
+ *                 elif t == NPY_OBJECT:      f = "O"
+ *                 else:
+ *                     raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)             # <<<<<<<<<<<<<<
+ *                 info.format = f
+ *                 return
+ */
+      __pyx_t_4 = PyInt_FromLong(__pyx_v_t); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __pyx_t_8 = PyNumber_Remainder(((PyObject *)__pyx_kp_u_27), __pyx_t_4); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(((PyObject *)__pyx_t_8));
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      PyTuple_SET_ITEM(__pyx_t_4, 0, ((PyObject *)__pyx_t_8));
+      __Pyx_GIVEREF(((PyObject *)__pyx_t_8));
+      __pyx_t_8 = 0;
+      __pyx_t_8 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_t_4), NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_8);
+      __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
+      __Pyx_Raise(__pyx_t_8, 0, 0, 0);
+      __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+      {__pyx_filename = __pyx_f[1]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+    __pyx_L13:;
+
+    /* "numpy.pxd":277
+ *                 else:
+ *                     raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
+ *                 info.format = f             # <<<<<<<<<<<<<<
+ *                 return
+ *             else:
+ */
+    __pyx_v_info->format = __pyx_v_f;
+
+    /* "numpy.pxd":278
+ *                     raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
+ *                 info.format = f
+ *                 return             # <<<<<<<<<<<<<<
+ *             else:
+ *                 info.format = <char*>stdlib.malloc(_buffer_format_string_len)
+ */
+    __pyx_r = 0;
+    goto __pyx_L0;
+    goto __pyx_L11;
+  }
+  /*else*/ {
+
+    /* "numpy.pxd":280
+ *                 return
+ *             else:
+ *                 info.format = <char*>stdlib.malloc(_buffer_format_string_len)             # <<<<<<<<<<<<<<
+ *                 info.format[0] = c'^' # Native data types, manual alignment
+ *                 offset = 0
+ */
+    __pyx_v_info->format = ((char *)malloc(255));
+
+    /* "numpy.pxd":281
+ *             else:
+ *                 info.format = <char*>stdlib.malloc(_buffer_format_string_len)
+ *                 info.format[0] = c'^' # Native data types, manual alignment             # <<<<<<<<<<<<<<
+ *                 offset = 0
+ *                 f = _util_dtypestring(descr, info.format + 1,
+ */
+    (__pyx_v_info->format[0]) = '^';
+
+    /* "numpy.pxd":282
+ *                 info.format = <char*>stdlib.malloc(_buffer_format_string_len)
+ *                 info.format[0] = c'^' # Native data types, manual alignment
+ *                 offset = 0             # <<<<<<<<<<<<<<
+ *                 f = _util_dtypestring(descr, info.format + 1,
+ *                                       info.format + _buffer_format_string_len,
+ */
+    __pyx_v_offset = 0;
+
+    /* "numpy.pxd":285
+ *                 f = _util_dtypestring(descr, info.format + 1,
+ *                                       info.format + _buffer_format_string_len,
+ *                                       &offset)             # <<<<<<<<<<<<<<
+ *                 f[0] = c'\0' # Terminate format string
+ * 
+ */
+    __pyx_t_9 = __pyx_f_5numpy__util_dtypestring(__pyx_v_descr, (__pyx_v_info->format + 1), (__pyx_v_info->format + 255), (&__pyx_v_offset)); if (unlikely(__pyx_t_9 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 283; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_v_f = __pyx_t_9;
+
+    /* "numpy.pxd":286
+ *                                       info.format + _buffer_format_string_len,
+ *                                       &offset)
+ *                 f[0] = c'\0' # Terminate format string             # <<<<<<<<<<<<<<
+ * 
+ *         def __releasebuffer__(ndarray self, Py_buffer* info):
+ */
+    (__pyx_v_f[0]) = '\x00';
+  }
+  __pyx_L11:;
+
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_XDECREF(__pyx_t_8);
+  __Pyx_AddTraceback("numpy.ndarray.__getbuffer__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = -1;
+  if (__pyx_v_info != NULL && __pyx_v_info->obj != NULL) {
+    __Pyx_GOTREF(__pyx_v_info->obj);
+    __Pyx_DECREF(__pyx_v_info->obj); __pyx_v_info->obj = NULL;
+  }
+  goto __pyx_L2;
+  __pyx_L0:;
+  if (__pyx_v_info != NULL && __pyx_v_info->obj == Py_None) {
+    __Pyx_GOTREF(Py_None);
+    __Pyx_DECREF(Py_None); __pyx_v_info->obj = NULL;
+  }
+  __pyx_L2:;
+  __Pyx_XDECREF((PyObject *)__pyx_v_descr);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static CYTHON_UNUSED void __pyx_pw_5numpy_7ndarray_3__releasebuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info); /*proto*/
+static CYTHON_UNUSED void __pyx_pw_5numpy_7ndarray_3__releasebuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info) {
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__releasebuffer__ (wrapper)", 0);
+  __pyx_pf_5numpy_7ndarray_2__releasebuffer__(((PyArrayObject *)__pyx_v_self), ((Py_buffer *)__pyx_v_info));
+  __Pyx_RefNannyFinishContext();
+}
+
+/* "numpy.pxd":288
+ *                 f[0] = c'\0' # Terminate format string
+ * 
+ *         def __releasebuffer__(ndarray self, Py_buffer* info):             # <<<<<<<<<<<<<<
+ *             if PyArray_HASFIELDS(self):
+ *                 stdlib.free(info.format)
+ */
+
+static void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info) {
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("__releasebuffer__", 0);
+
+  /* "numpy.pxd":289
+ * 
+ *         def __releasebuffer__(ndarray self, Py_buffer* info):
+ *             if PyArray_HASFIELDS(self):             # <<<<<<<<<<<<<<
+ *                 stdlib.free(info.format)
+ *             if sizeof(npy_intp) != sizeof(Py_ssize_t):
+ */
+  __pyx_t_1 = PyArray_HASFIELDS(__pyx_v_self);
+  if (__pyx_t_1) {
+
+    /* "numpy.pxd":290
+ *         def __releasebuffer__(ndarray self, Py_buffer* info):
+ *             if PyArray_HASFIELDS(self):
+ *                 stdlib.free(info.format)             # <<<<<<<<<<<<<<
+ *             if sizeof(npy_intp) != sizeof(Py_ssize_t):
+ *                 stdlib.free(info.strides)
+ */
+    free(__pyx_v_info->format);
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  /* "numpy.pxd":291
+ *             if PyArray_HASFIELDS(self):
+ *                 stdlib.free(info.format)
+ *             if sizeof(npy_intp) != sizeof(Py_ssize_t):             # <<<<<<<<<<<<<<
+ *                 stdlib.free(info.strides)
+ *                 # info.shape was stored after info.strides in the same block
+ */
+  __pyx_t_1 = ((sizeof(npy_intp)) != (sizeof(Py_ssize_t)));
+  if (__pyx_t_1) {
+
+    /* "numpy.pxd":292
+ *                 stdlib.free(info.format)
+ *             if sizeof(npy_intp) != sizeof(Py_ssize_t):
+ *                 stdlib.free(info.strides)             # <<<<<<<<<<<<<<
+ *                 # info.shape was stored after info.strides in the same block
+ * 
+ */
+    free(__pyx_v_info->strides);
+    goto __pyx_L4;
+  }
+  __pyx_L4:;
+
+  __Pyx_RefNannyFinishContext();
+}
+
+/* "numpy.pxd":768
+ * ctypedef npy_cdouble     complex_t
+ * 
+ * cdef inline object PyArray_MultiIterNew1(a):             # <<<<<<<<<<<<<<
+ *     return PyArray_MultiIterNew(1, <void*>a)
+ * 
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew1(PyObject *__pyx_v_a) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("PyArray_MultiIterNew1", 0);
+
+  /* "numpy.pxd":769
+ * 
+ * cdef inline object PyArray_MultiIterNew1(a):
+ *     return PyArray_MultiIterNew(1, <void*>a)             # <<<<<<<<<<<<<<
+ * 
+ * cdef inline object PyArray_MultiIterNew2(a, b):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = PyArray_MultiIterNew(1, ((void *)__pyx_v_a)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 769; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("numpy.PyArray_MultiIterNew1", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "numpy.pxd":771
+ *     return PyArray_MultiIterNew(1, <void*>a)
+ * 
+ * cdef inline object PyArray_MultiIterNew2(a, b):             # <<<<<<<<<<<<<<
+ *     return PyArray_MultiIterNew(2, <void*>a, <void*>b)
+ * 
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew2(PyObject *__pyx_v_a, PyObject *__pyx_v_b) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("PyArray_MultiIterNew2", 0);
+
+  /* "numpy.pxd":772
+ * 
+ * cdef inline object PyArray_MultiIterNew2(a, b):
+ *     return PyArray_MultiIterNew(2, <void*>a, <void*>b)             # <<<<<<<<<<<<<<
+ * 
+ * cdef inline object PyArray_MultiIterNew3(a, b, c):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = PyArray_MultiIterNew(2, ((void *)__pyx_v_a), ((void *)__pyx_v_b)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 772; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("numpy.PyArray_MultiIterNew2", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "numpy.pxd":774
+ *     return PyArray_MultiIterNew(2, <void*>a, <void*>b)
+ * 
+ * cdef inline object PyArray_MultiIterNew3(a, b, c):             # <<<<<<<<<<<<<<
+ *     return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)
+ * 
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew3(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("PyArray_MultiIterNew3", 0);
+
+  /* "numpy.pxd":775
+ * 
+ * cdef inline object PyArray_MultiIterNew3(a, b, c):
+ *     return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)             # <<<<<<<<<<<<<<
+ * 
+ * cdef inline object PyArray_MultiIterNew4(a, b, c, d):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = PyArray_MultiIterNew(3, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 775; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("numpy.PyArray_MultiIterNew3", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "numpy.pxd":777
+ *     return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)
+ * 
+ * cdef inline object PyArray_MultiIterNew4(a, b, c, d):             # <<<<<<<<<<<<<<
+ *     return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)
+ * 
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew4(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c, PyObject *__pyx_v_d) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("PyArray_MultiIterNew4", 0);
+
+  /* "numpy.pxd":778
+ * 
+ * cdef inline object PyArray_MultiIterNew4(a, b, c, d):
+ *     return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)             # <<<<<<<<<<<<<<
+ * 
+ * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = PyArray_MultiIterNew(4, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c), ((void *)__pyx_v_d)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 778; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("numpy.PyArray_MultiIterNew4", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "numpy.pxd":780
+ *     return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)
+ * 
+ * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e):             # <<<<<<<<<<<<<<
+ *     return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)
+ * 
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew5(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c, PyObject *__pyx_v_d, PyObject *__pyx_v_e) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("PyArray_MultiIterNew5", 0);
+
+  /* "numpy.pxd":781
+ * 
+ * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e):
+ *     return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)             # <<<<<<<<<<<<<<
+ * 
+ * cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL:
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = PyArray_MultiIterNew(5, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c), ((void *)__pyx_v_d), ((void *)__pyx_v_e)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 781; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("numpy.PyArray_MultiIterNew5", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "numpy.pxd":783
+ *     return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)
+ * 
+ * cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL:             # <<<<<<<<<<<<<<
+ *     # Recursive utility function used in __getbuffer__ to get format
+ *     # string. The new location in the format string is returned.
+ */
+
+static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx_v_descr, char *__pyx_v_f, char *__pyx_v_end, int *__pyx_v_offset) {
+  PyArray_Descr *__pyx_v_child = 0;
+  int __pyx_v_endian_detector;
+  int __pyx_v_little_endian;
+  PyObject *__pyx_v_fields = 0;
+  PyObject *__pyx_v_childname = NULL;
+  PyObject *__pyx_v_new_offset = NULL;
+  PyObject *__pyx_v_t = NULL;
+  char *__pyx_r;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  Py_ssize_t __pyx_t_2;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  PyObject *__pyx_t_5 = NULL;
+  PyObject *(*__pyx_t_6)(PyObject *);
+  int __pyx_t_7;
+  int __pyx_t_8;
+  int __pyx_t_9;
+  int __pyx_t_10;
+  long __pyx_t_11;
+  char *__pyx_t_12;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("_util_dtypestring", 0);
+
+  /* "numpy.pxd":790
+ *     cdef int delta_offset
+ *     cdef tuple i
+ *     cdef int endian_detector = 1             # <<<<<<<<<<<<<<
+ *     cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)
+ *     cdef tuple fields
+ */
+  __pyx_v_endian_detector = 1;
+
+  /* "numpy.pxd":791
+ *     cdef tuple i
+ *     cdef int endian_detector = 1
+ *     cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)             # <<<<<<<<<<<<<<
+ *     cdef tuple fields
+ * 
+ */
+  __pyx_v_little_endian = ((((char *)(&__pyx_v_endian_detector))[0]) != 0);
+
+  /* "numpy.pxd":794
+ *     cdef tuple fields
+ * 
+ *     for childname in descr.names:             # <<<<<<<<<<<<<<
+ *         fields = descr.fields[childname]
+ *         child, new_offset = fields
+ */
+  if (unlikely(((PyObject *)__pyx_v_descr->names) == Py_None)) {
+    PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable");
+    {__pyx_filename = __pyx_f[1]; __pyx_lineno = 794; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  __pyx_t_1 = ((PyObject *)__pyx_v_descr->names); __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0;
+  for (;;) {
+    if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
+    #if CYTHON_COMPILING_IN_CPYTHON
+    __pyx_t_3 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_3); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 794; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    #else
+    __pyx_t_3 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 794; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    #endif
+    __Pyx_XDECREF(__pyx_v_childname);
+    __pyx_v_childname = __pyx_t_3;
+    __pyx_t_3 = 0;
+
+    /* "numpy.pxd":795
+ * 
+ *     for childname in descr.names:
+ *         fields = descr.fields[childname]             # <<<<<<<<<<<<<<
+ *         child, new_offset = fields
+ * 
+ */
+    __pyx_t_3 = PyObject_GetItem(__pyx_v_descr->fields, __pyx_v_childname); if (!__pyx_t_3) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 795; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    if (!(likely(PyTuple_CheckExact(__pyx_t_3))||((__pyx_t_3) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected tuple, got %.200s", Py_TYPE(__pyx_t_3)->tp_name), 0))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 795; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_XDECREF(((PyObject *)__pyx_v_fields));
+    __pyx_v_fields = ((PyObject*)__pyx_t_3);
+    __pyx_t_3 = 0;
+
+    /* "numpy.pxd":796
+ *     for childname in descr.names:
+ *         fields = descr.fields[childname]
+ *         child, new_offset = fields             # <<<<<<<<<<<<<<
+ * 
+ *         if (end - f) - (new_offset - offset[0]) < 15:
+ */
+    if (likely(PyTuple_CheckExact(((PyObject *)__pyx_v_fields)))) {
+      PyObject* sequence = ((PyObject *)__pyx_v_fields);
+      #if CYTHON_COMPILING_IN_CPYTHON
+      Py_ssize_t size = Py_SIZE(sequence);
+      #else
+      Py_ssize_t size = PySequence_Size(sequence);
+      #endif
+      if (unlikely(size != 2)) {
+        if (size > 2) __Pyx_RaiseTooManyValuesError(2);
+        else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
+        {__pyx_filename = __pyx_f[1]; __pyx_lineno = 796; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      }
+      #if CYTHON_COMPILING_IN_CPYTHON
+      __pyx_t_3 = PyTuple_GET_ITEM(sequence, 0); 
+      __pyx_t_4 = PyTuple_GET_ITEM(sequence, 1); 
+      __Pyx_INCREF(__pyx_t_3);
+      __Pyx_INCREF(__pyx_t_4);
+      #else
+      __pyx_t_3 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 796; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_4 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 796; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      #endif
+    } else if (1) {
+      __Pyx_RaiseNoneNotIterableError(); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 796; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    } else
+    {
+      Py_ssize_t index = -1;
+      __pyx_t_5 = PyObject_GetIter(((PyObject *)__pyx_v_fields)); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 796; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_5);
+      __pyx_t_6 = Py_TYPE(__pyx_t_5)->tp_iternext;
+      index = 0; __pyx_t_3 = __pyx_t_6(__pyx_t_5); if (unlikely(!__pyx_t_3)) goto __pyx_L5_unpacking_failed;
+      __Pyx_GOTREF(__pyx_t_3);
+      index = 1; __pyx_t_4 = __pyx_t_6(__pyx_t_5); if (unlikely(!__pyx_t_4)) goto __pyx_L5_unpacking_failed;
+      __Pyx_GOTREF(__pyx_t_4);
+      if (__Pyx_IternextUnpackEndCheck(__pyx_t_6(__pyx_t_5), 2) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 796; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_6 = NULL;
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      goto __pyx_L6_unpacking_done;
+      __pyx_L5_unpacking_failed:;
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      __pyx_t_6 = NULL;
+      if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
+      {__pyx_filename = __pyx_f[1]; __pyx_lineno = 796; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_L6_unpacking_done:;
+    }
+    if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_ptype_5numpy_dtype))))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 796; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_XDECREF(((PyObject *)__pyx_v_child));
+    __pyx_v_child = ((PyArray_Descr *)__pyx_t_3);
+    __pyx_t_3 = 0;
+    __Pyx_XDECREF(__pyx_v_new_offset);
+    __pyx_v_new_offset = __pyx_t_4;
+    __pyx_t_4 = 0;
+
+    /* "numpy.pxd":798
+ *         child, new_offset = fields
+ * 
+ *         if (end - f) - (new_offset - offset[0]) < 15:             # <<<<<<<<<<<<<<
+ *             raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd")
+ * 
+ */
+    __pyx_t_4 = PyInt_FromLong((__pyx_v_end - __pyx_v_f)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 798; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    __pyx_t_3 = PyInt_FromLong((__pyx_v_offset[0])); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 798; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __pyx_t_5 = PyNumber_Subtract(__pyx_v_new_offset, __pyx_t_3); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 798; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_5);
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __pyx_t_3 = PyNumber_Subtract(__pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 798; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+    __pyx_t_5 = PyObject_RichCompare(__pyx_t_3, __pyx_int_15, Py_LT); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 798; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 798; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+    if (__pyx_t_7) {
+
+      /* "numpy.pxd":799
+ * 
+ *         if (end - f) - (new_offset - offset[0]) < 15:
+ *             raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd")             # <<<<<<<<<<<<<<
+ * 
+ *         if ((child.byteorder == c'>' and little_endian) or
+ */
+      __pyx_t_5 = PyObject_Call(__pyx_builtin_RuntimeError, ((PyObject *)__pyx_k_tuple_29), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_5);
+      __Pyx_Raise(__pyx_t_5, 0, 0, 0);
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      {__pyx_filename = __pyx_f[1]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      goto __pyx_L7;
+    }
+    __pyx_L7:;
+
+    /* "numpy.pxd":801
+ *             raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd")
+ * 
+ *         if ((child.byteorder == c'>' and little_endian) or             # <<<<<<<<<<<<<<
+ *             (child.byteorder == c'<' and not little_endian)):
+ *             raise ValueError(u"Non-native byte order not supported")
+ */
+    __pyx_t_7 = (__pyx_v_child->byteorder == '>');
+    if (__pyx_t_7) {
+      __pyx_t_8 = __pyx_v_little_endian;
+    } else {
+      __pyx_t_8 = __pyx_t_7;
+    }
+    if (!__pyx_t_8) {
+
+      /* "numpy.pxd":802
+ * 
+ *         if ((child.byteorder == c'>' and little_endian) or
+ *             (child.byteorder == c'<' and not little_endian)):             # <<<<<<<<<<<<<<
+ *             raise ValueError(u"Non-native byte order not supported")
+ *             # One could encode it in the format string and have Cython
+ */
+      __pyx_t_7 = (__pyx_v_child->byteorder == '<');
+      if (__pyx_t_7) {
+        __pyx_t_9 = (!__pyx_v_little_endian);
+        __pyx_t_10 = __pyx_t_9;
+      } else {
+        __pyx_t_10 = __pyx_t_7;
+      }
+      __pyx_t_7 = __pyx_t_10;
+    } else {
+      __pyx_t_7 = __pyx_t_8;
+    }
+    if (__pyx_t_7) {
+
+      /* "numpy.pxd":803
+ *         if ((child.byteorder == c'>' and little_endian) or
+ *             (child.byteorder == c'<' and not little_endian)):
+ *             raise ValueError(u"Non-native byte order not supported")             # <<<<<<<<<<<<<<
+ *             # One could encode it in the format string and have Cython
+ *             # complain instead, BUT: < and > in format strings also imply
+ */
+      __pyx_t_5 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_k_tuple_30), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 803; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_5);
+      __Pyx_Raise(__pyx_t_5, 0, 0, 0);
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      {__pyx_filename = __pyx_f[1]; __pyx_lineno = 803; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      goto __pyx_L8;
+    }
+    __pyx_L8:;
+
+    /* "numpy.pxd":813
+ * 
+ *         # Output padding bytes
+ *         while offset[0] < new_offset:             # <<<<<<<<<<<<<<
+ *             f[0] = 120 # "x"; pad byte
+ *             f += 1
+ */
+    while (1) {
+      __pyx_t_5 = PyInt_FromLong((__pyx_v_offset[0])); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 813; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_5);
+      __pyx_t_3 = PyObject_RichCompare(__pyx_t_5, __pyx_v_new_offset, Py_LT); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 813; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 813; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      if (!__pyx_t_7) break;
+
+      /* "numpy.pxd":814
+ *         # Output padding bytes
+ *         while offset[0] < new_offset:
+ *             f[0] = 120 # "x"; pad byte             # <<<<<<<<<<<<<<
+ *             f += 1
+ *             offset[0] += 1
+ */
+      (__pyx_v_f[0]) = 120;
+
+      /* "numpy.pxd":815
+ *         while offset[0] < new_offset:
+ *             f[0] = 120 # "x"; pad byte
+ *             f += 1             # <<<<<<<<<<<<<<
+ *             offset[0] += 1
+ * 
+ */
+      __pyx_v_f = (__pyx_v_f + 1);
+
+      /* "numpy.pxd":816
+ *             f[0] = 120 # "x"; pad byte
+ *             f += 1
+ *             offset[0] += 1             # <<<<<<<<<<<<<<
+ * 
+ *         offset[0] += child.itemsize
+ */
+      __pyx_t_11 = 0;
+      (__pyx_v_offset[__pyx_t_11]) = ((__pyx_v_offset[__pyx_t_11]) + 1);
+    }
+
+    /* "numpy.pxd":818
+ *             offset[0] += 1
+ * 
+ *         offset[0] += child.itemsize             # <<<<<<<<<<<<<<
+ * 
+ *         if not PyDataType_HASFIELDS(child):
+ */
+    __pyx_t_11 = 0;
+    (__pyx_v_offset[__pyx_t_11]) = ((__pyx_v_offset[__pyx_t_11]) + __pyx_v_child->elsize);
+
+    /* "numpy.pxd":820
+ *         offset[0] += child.itemsize
+ * 
+ *         if not PyDataType_HASFIELDS(child):             # <<<<<<<<<<<<<<
+ *             t = child.type_num
+ *             if end - f < 5:
+ */
+    __pyx_t_7 = (!PyDataType_HASFIELDS(__pyx_v_child));
+    if (__pyx_t_7) {
+
+      /* "numpy.pxd":821
+ * 
+ *         if not PyDataType_HASFIELDS(child):
+ *             t = child.type_num             # <<<<<<<<<<<<<<
+ *             if end - f < 5:
+ *                 raise RuntimeError(u"Format string allocated too short.")
+ */
+      __pyx_t_3 = PyInt_FromLong(__pyx_v_child->type_num); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 821; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __Pyx_XDECREF(__pyx_v_t);
+      __pyx_v_t = __pyx_t_3;
+      __pyx_t_3 = 0;
+
+      /* "numpy.pxd":822
+ *         if not PyDataType_HASFIELDS(child):
+ *             t = child.type_num
+ *             if end - f < 5:             # <<<<<<<<<<<<<<
+ *                 raise RuntimeError(u"Format string allocated too short.")
+ * 
+ */
+      __pyx_t_7 = ((__pyx_v_end - __pyx_v_f) < 5);
+      if (__pyx_t_7) {
+
+        /* "numpy.pxd":823
+ *             t = child.type_num
+ *             if end - f < 5:
+ *                 raise RuntimeError(u"Format string allocated too short.")             # <<<<<<<<<<<<<<
+ * 
+ *             # Until ticket #99 is fixed, use integers to avoid warnings
+ */
+        __pyx_t_3 = PyObject_Call(__pyx_builtin_RuntimeError, ((PyObject *)__pyx_k_tuple_32), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 823; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_3);
+        __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+        __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+        {__pyx_filename = __pyx_f[1]; __pyx_lineno = 823; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        goto __pyx_L12;
+      }
+      __pyx_L12:;
+
+      /* "numpy.pxd":826
+ * 
+ *             # Until ticket #99 is fixed, use integers to avoid warnings
+ *             if   t == NPY_BYTE:        f[0] =  98 #"b"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_UBYTE:       f[0] =  66 #"B"
+ *             elif t == NPY_SHORT:       f[0] = 104 #"h"
+ */
+      __pyx_t_3 = PyInt_FromLong(NPY_BYTE); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 826; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_5 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 826; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 826; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      if (__pyx_t_7) {
+        (__pyx_v_f[0]) = 98;
+        goto __pyx_L13;
+      }
+
+      /* "numpy.pxd":827
+ *             # Until ticket #99 is fixed, use integers to avoid warnings
+ *             if   t == NPY_BYTE:        f[0] =  98 #"b"
+ *             elif t == NPY_UBYTE:       f[0] =  66 #"B"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_SHORT:       f[0] = 104 #"h"
+ *             elif t == NPY_USHORT:      f[0] =  72 #"H"
+ */
+      __pyx_t_5 = PyInt_FromLong(NPY_UBYTE); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 827; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_5);
+      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_5, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 827; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 827; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      if (__pyx_t_7) {
+        (__pyx_v_f[0]) = 66;
+        goto __pyx_L13;
+      }
+
+      /* "numpy.pxd":828
+ *             if   t == NPY_BYTE:        f[0] =  98 #"b"
+ *             elif t == NPY_UBYTE:       f[0] =  66 #"B"
+ *             elif t == NPY_SHORT:       f[0] = 104 #"h"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_USHORT:      f[0] =  72 #"H"
+ *             elif t == NPY_INT:         f[0] = 105 #"i"
+ */
+      __pyx_t_3 = PyInt_FromLong(NPY_SHORT); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 828; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_5 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 828; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 828; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      if (__pyx_t_7) {
+        (__pyx_v_f[0]) = 104;
+        goto __pyx_L13;
+      }
+
+      /* "numpy.pxd":829
+ *             elif t == NPY_UBYTE:       f[0] =  66 #"B"
+ *             elif t == NPY_SHORT:       f[0] = 104 #"h"
+ *             elif t == NPY_USHORT:      f[0] =  72 #"H"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_INT:         f[0] = 105 #"i"
+ *             elif t == NPY_UINT:        f[0] =  73 #"I"
+ */
+      __pyx_t_5 = PyInt_FromLong(NPY_USHORT); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 829; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_5);
+      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_5, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 829; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 829; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      if (__pyx_t_7) {
+        (__pyx_v_f[0]) = 72;
+        goto __pyx_L13;
+      }
+
+      /* "numpy.pxd":830
+ *             elif t == NPY_SHORT:       f[0] = 104 #"h"
+ *             elif t == NPY_USHORT:      f[0] =  72 #"H"
+ *             elif t == NPY_INT:         f[0] = 105 #"i"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_UINT:        f[0] =  73 #"I"
+ *             elif t == NPY_LONG:        f[0] = 108 #"l"
+ */
+      __pyx_t_3 = PyInt_FromLong(NPY_INT); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 830; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_5 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 830; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 830; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      if (__pyx_t_7) {
+        (__pyx_v_f[0]) = 105;
+        goto __pyx_L13;
+      }
+
+      /* "numpy.pxd":831
+ *             elif t == NPY_USHORT:      f[0] =  72 #"H"
+ *             elif t == NPY_INT:         f[0] = 105 #"i"
+ *             elif t == NPY_UINT:        f[0] =  73 #"I"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_LONG:        f[0] = 108 #"l"
+ *             elif t == NPY_ULONG:       f[0] = 76  #"L"
+ */
+      __pyx_t_5 = PyInt_FromLong(NPY_UINT); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 831; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_5);
+      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_5, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 831; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 831; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      if (__pyx_t_7) {
+        (__pyx_v_f[0]) = 73;
+        goto __pyx_L13;
+      }
+
+      /* "numpy.pxd":832
+ *             elif t == NPY_INT:         f[0] = 105 #"i"
+ *             elif t == NPY_UINT:        f[0] =  73 #"I"
+ *             elif t == NPY_LONG:        f[0] = 108 #"l"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_ULONG:       f[0] = 76  #"L"
+ *             elif t == NPY_LONGLONG:    f[0] = 113 #"q"
+ */
+      __pyx_t_3 = PyInt_FromLong(NPY_LONG); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 832; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_5 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 832; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 832; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      if (__pyx_t_7) {
+        (__pyx_v_f[0]) = 108;
+        goto __pyx_L13;
+      }
+
+      /* "numpy.pxd":833
+ *             elif t == NPY_UINT:        f[0] =  73 #"I"
+ *             elif t == NPY_LONG:        f[0] = 108 #"l"
+ *             elif t == NPY_ULONG:       f[0] = 76  #"L"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_LONGLONG:    f[0] = 113 #"q"
+ *             elif t == NPY_ULONGLONG:   f[0] = 81  #"Q"
+ */
+      __pyx_t_5 = PyInt_FromLong(NPY_ULONG); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 833; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_5);
+      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_5, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 833; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 833; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      if (__pyx_t_7) {
+        (__pyx_v_f[0]) = 76;
+        goto __pyx_L13;
+      }
+
+      /* "numpy.pxd":834
+ *             elif t == NPY_LONG:        f[0] = 108 #"l"
+ *             elif t == NPY_ULONG:       f[0] = 76  #"L"
+ *             elif t == NPY_LONGLONG:    f[0] = 113 #"q"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_ULONGLONG:   f[0] = 81  #"Q"
+ *             elif t == NPY_FLOAT:       f[0] = 102 #"f"
+ */
+      __pyx_t_3 = PyInt_FromLong(NPY_LONGLONG); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 834; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_5 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 834; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 834; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      if (__pyx_t_7) {
+        (__pyx_v_f[0]) = 113;
+        goto __pyx_L13;
+      }
+
+      /* "numpy.pxd":835
+ *             elif t == NPY_ULONG:       f[0] = 76  #"L"
+ *             elif t == NPY_LONGLONG:    f[0] = 113 #"q"
+ *             elif t == NPY_ULONGLONG:   f[0] = 81  #"Q"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_FLOAT:       f[0] = 102 #"f"
+ *             elif t == NPY_DOUBLE:      f[0] = 100 #"d"
+ */
+      __pyx_t_5 = PyInt_FromLong(NPY_ULONGLONG); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 835; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_5);
+      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_5, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 835; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 835; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      if (__pyx_t_7) {
+        (__pyx_v_f[0]) = 81;
+        goto __pyx_L13;
+      }
+
+      /* "numpy.pxd":836
+ *             elif t == NPY_LONGLONG:    f[0] = 113 #"q"
+ *             elif t == NPY_ULONGLONG:   f[0] = 81  #"Q"
+ *             elif t == NPY_FLOAT:       f[0] = 102 #"f"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_DOUBLE:      f[0] = 100 #"d"
+ *             elif t == NPY_LONGDOUBLE:  f[0] = 103 #"g"
+ */
+      __pyx_t_3 = PyInt_FromLong(NPY_FLOAT); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 836; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_5 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 836; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 836; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      if (__pyx_t_7) {
+        (__pyx_v_f[0]) = 102;
+        goto __pyx_L13;
+      }
+
+      /* "numpy.pxd":837
+ *             elif t == NPY_ULONGLONG:   f[0] = 81  #"Q"
+ *             elif t == NPY_FLOAT:       f[0] = 102 #"f"
+ *             elif t == NPY_DOUBLE:      f[0] = 100 #"d"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_LONGDOUBLE:  f[0] = 103 #"g"
+ *             elif t == NPY_CFLOAT:      f[0] = 90; f[1] = 102; f += 1 # Zf
+ */
+      __pyx_t_5 = PyInt_FromLong(NPY_DOUBLE); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 837; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_5);
+      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_5, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 837; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 837; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      if (__pyx_t_7) {
+        (__pyx_v_f[0]) = 100;
+        goto __pyx_L13;
+      }
+
+      /* "numpy.pxd":838
+ *             elif t == NPY_FLOAT:       f[0] = 102 #"f"
+ *             elif t == NPY_DOUBLE:      f[0] = 100 #"d"
+ *             elif t == NPY_LONGDOUBLE:  f[0] = 103 #"g"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_CFLOAT:      f[0] = 90; f[1] = 102; f += 1 # Zf
+ *             elif t == NPY_CDOUBLE:     f[0] = 90; f[1] = 100; f += 1 # Zd
+ */
+      __pyx_t_3 = PyInt_FromLong(NPY_LONGDOUBLE); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 838; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_5 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 838; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 838; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      if (__pyx_t_7) {
+        (__pyx_v_f[0]) = 103;
+        goto __pyx_L13;
+      }
+
+      /* "numpy.pxd":839
+ *             elif t == NPY_DOUBLE:      f[0] = 100 #"d"
+ *             elif t == NPY_LONGDOUBLE:  f[0] = 103 #"g"
+ *             elif t == NPY_CFLOAT:      f[0] = 90; f[1] = 102; f += 1 # Zf             # <<<<<<<<<<<<<<
+ *             elif t == NPY_CDOUBLE:     f[0] = 90; f[1] = 100; f += 1 # Zd
+ *             elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg
+ */
+      __pyx_t_5 = PyInt_FromLong(NPY_CFLOAT); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 839; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_5);
+      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_5, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 839; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 839; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      if (__pyx_t_7) {
+        (__pyx_v_f[0]) = 90;
+        (__pyx_v_f[1]) = 102;
+        __pyx_v_f = (__pyx_v_f + 1);
+        goto __pyx_L13;
+      }
+
+      /* "numpy.pxd":840
+ *             elif t == NPY_LONGDOUBLE:  f[0] = 103 #"g"
+ *             elif t == NPY_CFLOAT:      f[0] = 90; f[1] = 102; f += 1 # Zf
+ *             elif t == NPY_CDOUBLE:     f[0] = 90; f[1] = 100; f += 1 # Zd             # <<<<<<<<<<<<<<
+ *             elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg
+ *             elif t == NPY_OBJECT:      f[0] = 79 #"O"
+ */
+      __pyx_t_3 = PyInt_FromLong(NPY_CDOUBLE); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 840; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_5 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 840; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 840; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      if (__pyx_t_7) {
+        (__pyx_v_f[0]) = 90;
+        (__pyx_v_f[1]) = 100;
+        __pyx_v_f = (__pyx_v_f + 1);
+        goto __pyx_L13;
+      }
+
+      /* "numpy.pxd":841
+ *             elif t == NPY_CFLOAT:      f[0] = 90; f[1] = 102; f += 1 # Zf
+ *             elif t == NPY_CDOUBLE:     f[0] = 90; f[1] = 100; f += 1 # Zd
+ *             elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg             # <<<<<<<<<<<<<<
+ *             elif t == NPY_OBJECT:      f[0] = 79 #"O"
+ *             else:
+ */
+      __pyx_t_5 = PyInt_FromLong(NPY_CLONGDOUBLE); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 841; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_5);
+      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_5, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 841; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 841; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      if (__pyx_t_7) {
+        (__pyx_v_f[0]) = 90;
+        (__pyx_v_f[1]) = 103;
+        __pyx_v_f = (__pyx_v_f + 1);
+        goto __pyx_L13;
+      }
+
+      /* "numpy.pxd":842
+ *             elif t == NPY_CDOUBLE:     f[0] = 90; f[1] = 100; f += 1 # Zd
+ *             elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg
+ *             elif t == NPY_OBJECT:      f[0] = 79 #"O"             # <<<<<<<<<<<<<<
+ *             else:
+ *                 raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
+ */
+      __pyx_t_3 = PyInt_FromLong(NPY_OBJECT); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 842; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_5 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 842; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 842; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      if (__pyx_t_7) {
+        (__pyx_v_f[0]) = 79;
+        goto __pyx_L13;
+      }
+      /*else*/ {
+
+        /* "numpy.pxd":844
+ *             elif t == NPY_OBJECT:      f[0] = 79 #"O"
+ *             else:
+ *                 raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)             # <<<<<<<<<<<<<<
+ *             f += 1
+ *         else:
+ */
+        __pyx_t_5 = PyNumber_Remainder(((PyObject *)__pyx_kp_u_27), __pyx_v_t); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 844; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(((PyObject *)__pyx_t_5));
+        __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 844; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_3);
+        PyTuple_SET_ITEM(__pyx_t_3, 0, ((PyObject *)__pyx_t_5));
+        __Pyx_GIVEREF(((PyObject *)__pyx_t_5));
+        __pyx_t_5 = 0;
+        __pyx_t_5 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 844; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_5);
+        __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
+        __Pyx_Raise(__pyx_t_5, 0, 0, 0);
+        __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+        {__pyx_filename = __pyx_f[1]; __pyx_lineno = 844; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      }
+      __pyx_L13:;
+
+      /* "numpy.pxd":845
+ *             else:
+ *                 raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
+ *             f += 1             # <<<<<<<<<<<<<<
+ *         else:
+ *             # Cython ignores struct boundary information ("T{...}"),
+ */
+      __pyx_v_f = (__pyx_v_f + 1);
+      goto __pyx_L11;
+    }
+    /*else*/ {
+
+      /* "numpy.pxd":849
+ *             # Cython ignores struct boundary information ("T{...}"),
+ *             # so don't output it
+ *             f = _util_dtypestring(child, f, end, offset)             # <<<<<<<<<<<<<<
+ *     return f
+ * 
+ */
+      __pyx_t_12 = __pyx_f_5numpy__util_dtypestring(__pyx_v_child, __pyx_v_f, __pyx_v_end, __pyx_v_offset); if (unlikely(__pyx_t_12 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 849; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_v_f = __pyx_t_12;
+    }
+    __pyx_L11:;
+  }
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "numpy.pxd":850
+ *             # so don't output it
+ *             f = _util_dtypestring(child, f, end, offset)
+ *     return f             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+  __pyx_r = __pyx_v_f;
+  goto __pyx_L0;
+
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_XDECREF(__pyx_t_5);
+  __Pyx_AddTraceback("numpy._util_dtypestring", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XDECREF((PyObject *)__pyx_v_child);
+  __Pyx_XDECREF(__pyx_v_fields);
+  __Pyx_XDECREF(__pyx_v_childname);
+  __Pyx_XDECREF(__pyx_v_new_offset);
+  __Pyx_XDECREF(__pyx_v_t);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "numpy.pxd":965
+ * 
+ * 
+ * cdef inline void set_array_base(ndarray arr, object base):             # <<<<<<<<<<<<<<
+ *      cdef PyObject* baseptr
+ *      if base is None:
+ */
+
+static CYTHON_INLINE void __pyx_f_5numpy_set_array_base(PyArrayObject *__pyx_v_arr, PyObject *__pyx_v_base) {
+  PyObject *__pyx_v_baseptr;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("set_array_base", 0);
+
+  /* "numpy.pxd":967
+ * cdef inline void set_array_base(ndarray arr, object base):
+ *      cdef PyObject* baseptr
+ *      if base is None:             # <<<<<<<<<<<<<<
+ *          baseptr = NULL
+ *      else:
+ */
+  __pyx_t_1 = (__pyx_v_base == Py_None);
+  if (__pyx_t_1) {
+
+    /* "numpy.pxd":968
+ *      cdef PyObject* baseptr
+ *      if base is None:
+ *          baseptr = NULL             # <<<<<<<<<<<<<<
+ *      else:
+ *          Py_INCREF(base) # important to do this before decref below!
+ */
+    __pyx_v_baseptr = NULL;
+    goto __pyx_L3;
+  }
+  /*else*/ {
+
+    /* "numpy.pxd":970
+ *          baseptr = NULL
+ *      else:
+ *          Py_INCREF(base) # important to do this before decref below!             # <<<<<<<<<<<<<<
+ *          baseptr = <PyObject*>base
+ *      Py_XDECREF(arr.base)
+ */
+    Py_INCREF(__pyx_v_base);
+
+    /* "numpy.pxd":971
+ *      else:
+ *          Py_INCREF(base) # important to do this before decref below!
+ *          baseptr = <PyObject*>base             # <<<<<<<<<<<<<<
+ *      Py_XDECREF(arr.base)
+ *      arr.base = baseptr
+ */
+    __pyx_v_baseptr = ((PyObject *)__pyx_v_base);
+  }
+  __pyx_L3:;
+
+  /* "numpy.pxd":972
+ *          Py_INCREF(base) # important to do this before decref below!
+ *          baseptr = <PyObject*>base
+ *      Py_XDECREF(arr.base)             # <<<<<<<<<<<<<<
+ *      arr.base = baseptr
+ * 
+ */
+  Py_XDECREF(__pyx_v_arr->base);
+
+  /* "numpy.pxd":973
+ *          baseptr = <PyObject*>base
+ *      Py_XDECREF(arr.base)
+ *      arr.base = baseptr             # <<<<<<<<<<<<<<
+ * 
+ * cdef inline object get_array_base(ndarray arr):
+ */
+  __pyx_v_arr->base = __pyx_v_baseptr;
+
+  __Pyx_RefNannyFinishContext();
+}
+
+/* "numpy.pxd":975
+ *      arr.base = baseptr
+ * 
+ * cdef inline object get_array_base(ndarray arr):             # <<<<<<<<<<<<<<
+ *     if arr.base is NULL:
+ *         return None
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_5numpy_get_array_base(PyArrayObject *__pyx_v_arr) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("get_array_base", 0);
+
+  /* "numpy.pxd":976
+ * 
+ * cdef inline object get_array_base(ndarray arr):
+ *     if arr.base is NULL:             # <<<<<<<<<<<<<<
+ *         return None
+ *     else:
+ */
+  __pyx_t_1 = (__pyx_v_arr->base == NULL);
+  if (__pyx_t_1) {
+
+    /* "numpy.pxd":977
+ * cdef inline object get_array_base(ndarray arr):
+ *     if arr.base is NULL:
+ *         return None             # <<<<<<<<<<<<<<
+ *     else:
+ *         return <object>arr.base
+ */
+    __Pyx_XDECREF(__pyx_r);
+    __Pyx_INCREF(Py_None);
+    __pyx_r = Py_None;
+    goto __pyx_L0;
+    goto __pyx_L3;
+  }
+  /*else*/ {
+
+    /* "numpy.pxd":979
+ *         return None
+ *     else:
+ *         return <object>arr.base             # <<<<<<<<<<<<<<
+ */
+    __Pyx_XDECREF(__pyx_r);
+    __Pyx_INCREF(((PyObject *)__pyx_v_arr->base));
+    __pyx_r = ((PyObject *)__pyx_v_arr->base);
+    goto __pyx_L0;
+  }
+  __pyx_L3:;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_tp_new_2bx_6arrays_10array_tree_FileArrayTreeDict(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) {
+  struct __pyx_obj_2bx_6arrays_10array_tree_FileArrayTreeDict *p;
+  PyObject *o = (*t->tp_alloc)(t, 0);
+  if (!o) return 0;
+  p = ((struct __pyx_obj_2bx_6arrays_10array_tree_FileArrayTreeDict *)o);
+  p->io = Py_None; Py_INCREF(Py_None);
+  p->cdb_dict = Py_None; Py_INCREF(Py_None);
+  return o;
+}
+
+static void __pyx_tp_dealloc_2bx_6arrays_10array_tree_FileArrayTreeDict(PyObject *o) {
+  struct __pyx_obj_2bx_6arrays_10array_tree_FileArrayTreeDict *p = (struct __pyx_obj_2bx_6arrays_10array_tree_FileArrayTreeDict *)o;
+  PyObject_GC_UnTrack(o);
+  Py_CLEAR(p->io);
+  Py_CLEAR(p->cdb_dict);
+  PyObject_GC_Track(o);
+  (*Py_TYPE(o)->tp_free)(o);
+}
+
+static int __pyx_tp_traverse_2bx_6arrays_10array_tree_FileArrayTreeDict(PyObject *o, visitproc v, void *a) {
+  int e;
+  struct __pyx_obj_2bx_6arrays_10array_tree_FileArrayTreeDict *p = (struct __pyx_obj_2bx_6arrays_10array_tree_FileArrayTreeDict *)o;
+  if (p->io) {
+    e = (*v)(p->io, a); if (e) return e;
+  }
+  if (p->cdb_dict) {
+    e = (*v)(p->cdb_dict, a); if (e) return e;
+  }
+  return 0;
+}
+
+static int __pyx_tp_clear_2bx_6arrays_10array_tree_FileArrayTreeDict(PyObject *o) {
+  struct __pyx_obj_2bx_6arrays_10array_tree_FileArrayTreeDict *p = (struct __pyx_obj_2bx_6arrays_10array_tree_FileArrayTreeDict *)o;
+  PyObject* tmp;
+  tmp = ((PyObject*)p->io);
+  p->io = Py_None; Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  tmp = ((PyObject*)p->cdb_dict);
+  p->cdb_dict = Py_None; Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  return 0;
+}
+static PyObject *__pyx_sq_item_2bx_6arrays_10array_tree_FileArrayTreeDict(PyObject *o, Py_ssize_t i) {
+  PyObject *r;
+  PyObject *x = PyInt_FromSsize_t(i); if(!x) return 0;
+  r = Py_TYPE(o)->tp_as_mapping->mp_subscript(o, x);
+  Py_DECREF(x);
+  return r;
+}
+
+static PyMethodDef __pyx_methods_2bx_6arrays_10array_tree_FileArrayTreeDict[] = {
+  {__Pyx_NAMESTR("dict_to_file"), (PyCFunction)__pyx_pw_2bx_6arrays_10array_tree_17FileArrayTreeDict_5dict_to_file, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(__pyx_doc_2bx_6arrays_10array_tree_17FileArrayTreeDict_4dict_to_file)},
+  {0, 0, 0, 0}
+};
+
+static PyNumberMethods __pyx_tp_as_number_FileArrayTreeDict = {
+  0, /*nb_add*/
+  0, /*nb_subtract*/
+  0, /*nb_multiply*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_divide*/
+  #endif
+  0, /*nb_remainder*/
+  0, /*nb_divmod*/
+  0, /*nb_power*/
+  0, /*nb_negative*/
+  0, /*nb_positive*/
+  0, /*nb_absolute*/
+  0, /*nb_nonzero*/
+  0, /*nb_invert*/
+  0, /*nb_lshift*/
+  0, /*nb_rshift*/
+  0, /*nb_and*/
+  0, /*nb_xor*/
+  0, /*nb_or*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_coerce*/
+  #endif
+  0, /*nb_int*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_long*/
+  #else
+  0, /*reserved*/
+  #endif
+  0, /*nb_float*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_oct*/
+  #endif
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_hex*/
+  #endif
+  0, /*nb_inplace_add*/
+  0, /*nb_inplace_subtract*/
+  0, /*nb_inplace_multiply*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_inplace_divide*/
+  #endif
+  0, /*nb_inplace_remainder*/
+  0, /*nb_inplace_power*/
+  0, /*nb_inplace_lshift*/
+  0, /*nb_inplace_rshift*/
+  0, /*nb_inplace_and*/
+  0, /*nb_inplace_xor*/
+  0, /*nb_inplace_or*/
+  0, /*nb_floor_divide*/
+  0, /*nb_true_divide*/
+  0, /*nb_inplace_floor_divide*/
+  0, /*nb_inplace_true_divide*/
+  #if PY_VERSION_HEX >= 0x02050000
+  0, /*nb_index*/
+  #endif
+};
+
+static PySequenceMethods __pyx_tp_as_sequence_FileArrayTreeDict = {
+  0, /*sq_length*/
+  0, /*sq_concat*/
+  0, /*sq_repeat*/
+  __pyx_sq_item_2bx_6arrays_10array_tree_FileArrayTreeDict, /*sq_item*/
+  0, /*sq_slice*/
+  0, /*sq_ass_item*/
+  0, /*sq_ass_slice*/
+  0, /*sq_contains*/
+  0, /*sq_inplace_concat*/
+  0, /*sq_inplace_repeat*/
+};
+
+static PyMappingMethods __pyx_tp_as_mapping_FileArrayTreeDict = {
+  0, /*mp_length*/
+  __pyx_pw_2bx_6arrays_10array_tree_17FileArrayTreeDict_3__getitem__, /*mp_subscript*/
+  0, /*mp_ass_subscript*/
+};
+
+static PyBufferProcs __pyx_tp_as_buffer_FileArrayTreeDict = {
+  #if PY_MAJOR_VERSION < 3
+  0, /*bf_getreadbuffer*/
+  #endif
+  #if PY_MAJOR_VERSION < 3
+  0, /*bf_getwritebuffer*/
+  #endif
+  #if PY_MAJOR_VERSION < 3
+  0, /*bf_getsegcount*/
+  #endif
+  #if PY_MAJOR_VERSION < 3
+  0, /*bf_getcharbuffer*/
+  #endif
+  #if PY_VERSION_HEX >= 0x02060000
+  0, /*bf_getbuffer*/
+  #endif
+  #if PY_VERSION_HEX >= 0x02060000
+  0, /*bf_releasebuffer*/
+  #endif
+};
+
+static PyTypeObject __pyx_type_2bx_6arrays_10array_tree_FileArrayTreeDict = {
+  PyVarObject_HEAD_INIT(0, 0)
+  __Pyx_NAMESTR("bx.arrays.array_tree.FileArrayTreeDict"), /*tp_name*/
+  sizeof(struct __pyx_obj_2bx_6arrays_10array_tree_FileArrayTreeDict), /*tp_basicsize*/
+  0, /*tp_itemsize*/
+  __pyx_tp_dealloc_2bx_6arrays_10array_tree_FileArrayTreeDict, /*tp_dealloc*/
+  0, /*tp_print*/
+  0, /*tp_getattr*/
+  0, /*tp_setattr*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*tp_compare*/
+  #else
+  0, /*reserved*/
+  #endif
+  0, /*tp_repr*/
+  &__pyx_tp_as_number_FileArrayTreeDict, /*tp_as_number*/
+  &__pyx_tp_as_sequence_FileArrayTreeDict, /*tp_as_sequence*/
+  &__pyx_tp_as_mapping_FileArrayTreeDict, /*tp_as_mapping*/
+  0, /*tp_hash*/
+  0, /*tp_call*/
+  0, /*tp_str*/
+  0, /*tp_getattro*/
+  0, /*tp_setattro*/
+  &__pyx_tp_as_buffer_FileArrayTreeDict, /*tp_as_buffer*/
+  Py_TPFLAGS_DEFAULT|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+  __Pyx_DOCSTR("\n    Access to a file containing multiple array trees indexed by a string key.\n    "), /*tp_doc*/
+  __pyx_tp_traverse_2bx_6arrays_10array_tree_FileArrayTreeDict, /*tp_traverse*/
+  __pyx_tp_clear_2bx_6arrays_10array_tree_FileArrayTreeDict, /*tp_clear*/
+  0, /*tp_richcompare*/
+  0, /*tp_weaklistoffset*/
+  0, /*tp_iter*/
+  0, /*tp_iternext*/
+  __pyx_methods_2bx_6arrays_10array_tree_FileArrayTreeDict, /*tp_methods*/
+  0, /*tp_members*/
+  0, /*tp_getset*/
+  0, /*tp_base*/
+  0, /*tp_dict*/
+  0, /*tp_descr_get*/
+  0, /*tp_descr_set*/
+  0, /*tp_dictoffset*/
+  __pyx_pw_2bx_6arrays_10array_tree_17FileArrayTreeDict_1__init__, /*tp_init*/
+  0, /*tp_alloc*/
+  __pyx_tp_new_2bx_6arrays_10array_tree_FileArrayTreeDict, /*tp_new*/
+  0, /*tp_free*/
+  0, /*tp_is_gc*/
+  0, /*tp_bases*/
+  0, /*tp_mro*/
+  0, /*tp_cache*/
+  0, /*tp_subclasses*/
+  0, /*tp_weaklist*/
+  0, /*tp_del*/
+  #if PY_VERSION_HEX >= 0x02060000
+  0, /*tp_version_tag*/
+  #endif
+};
+static struct __pyx_vtabstruct_2bx_6arrays_10array_tree_FileArrayTree __pyx_vtable_2bx_6arrays_10array_tree_FileArrayTree;
+
+static PyObject *__pyx_tp_new_2bx_6arrays_10array_tree_FileArrayTree(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) {
+  struct __pyx_obj_2bx_6arrays_10array_tree_FileArrayTree *p;
+  PyObject *o = (*t->tp_alloc)(t, 0);
+  if (!o) return 0;
+  p = ((struct __pyx_obj_2bx_6arrays_10array_tree_FileArrayTree *)o);
+  p->__pyx_vtab = __pyx_vtabptr_2bx_6arrays_10array_tree_FileArrayTree;
+  p->dtype = Py_None; Py_INCREF(Py_None);
+  p->io = Py_None; Py_INCREF(Py_None);
+  return o;
+}
+
+static void __pyx_tp_dealloc_2bx_6arrays_10array_tree_FileArrayTree(PyObject *o) {
+  struct __pyx_obj_2bx_6arrays_10array_tree_FileArrayTree *p = (struct __pyx_obj_2bx_6arrays_10array_tree_FileArrayTree *)o;
+  PyObject_GC_UnTrack(o);
+  Py_CLEAR(p->dtype);
+  Py_CLEAR(p->io);
+  PyObject_GC_Track(o);
+  (*Py_TYPE(o)->tp_free)(o);
+}
+
+static int __pyx_tp_traverse_2bx_6arrays_10array_tree_FileArrayTree(PyObject *o, visitproc v, void *a) {
+  int e;
+  struct __pyx_obj_2bx_6arrays_10array_tree_FileArrayTree *p = (struct __pyx_obj_2bx_6arrays_10array_tree_FileArrayTree *)o;
+  if (p->dtype) {
+    e = (*v)(p->dtype, a); if (e) return e;
+  }
+  if (p->io) {
+    e = (*v)(p->io, a); if (e) return e;
+  }
+  return 0;
+}
+
+static int __pyx_tp_clear_2bx_6arrays_10array_tree_FileArrayTree(PyObject *o) {
+  struct __pyx_obj_2bx_6arrays_10array_tree_FileArrayTree *p = (struct __pyx_obj_2bx_6arrays_10array_tree_FileArrayTree *)o;
+  PyObject* tmp;
+  tmp = ((PyObject*)p->dtype);
+  p->dtype = Py_None; Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  tmp = ((PyObject*)p->io);
+  p->io = Py_None; Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  return 0;
+}
+static PyObject *__pyx_sq_item_2bx_6arrays_10array_tree_FileArrayTree(PyObject *o, Py_ssize_t i) {
+  PyObject *r;
+  PyObject *x = PyInt_FromSsize_t(i); if(!x) return 0;
+  r = Py_TYPE(o)->tp_as_mapping->mp_subscript(o, x);
+  Py_DECREF(x);
+  return r;
+}
+
+static PyObject *__pyx_getprop_2bx_6arrays_10array_tree_13FileArrayTree_max(PyObject *o, CYTHON_UNUSED void *x) {
+  return __pyx_pw_2bx_6arrays_10array_tree_13FileArrayTree_3max_1__get__(o);
+}
+
+static int __pyx_setprop_2bx_6arrays_10array_tree_13FileArrayTree_max(PyObject *o, PyObject *v, CYTHON_UNUSED void *x) {
+  if (v) {
+    return __pyx_pw_2bx_6arrays_10array_tree_13FileArrayTree_3max_3__set__(o, v);
+  }
+  else {
+    PyErr_SetString(PyExc_NotImplementedError, "__del__");
+    return -1;
+  }
+}
+
+static PyObject *__pyx_getprop_2bx_6arrays_10array_tree_13FileArrayTree_block_size(PyObject *o, CYTHON_UNUSED void *x) {
+  return __pyx_pw_2bx_6arrays_10array_tree_13FileArrayTree_10block_size_1__get__(o);
+}
+
+static int __pyx_setprop_2bx_6arrays_10array_tree_13FileArrayTree_block_size(PyObject *o, PyObject *v, CYTHON_UNUSED void *x) {
+  if (v) {
+    return __pyx_pw_2bx_6arrays_10array_tree_13FileArrayTree_10block_size_3__set__(o, v);
+  }
+  else {
+    PyErr_SetString(PyExc_NotImplementedError, "__del__");
+    return -1;
+  }
+}
+
+static PyObject *__pyx_getprop_2bx_6arrays_10array_tree_13FileArrayTree_dtype(PyObject *o, CYTHON_UNUSED void *x) {
+  return __pyx_pw_2bx_6arrays_10array_tree_13FileArrayTree_5dtype_1__get__(o);
+}
+
+static int __pyx_setprop_2bx_6arrays_10array_tree_13FileArrayTree_dtype(PyObject *o, PyObject *v, CYTHON_UNUSED void *x) {
+  if (v) {
+    return __pyx_pw_2bx_6arrays_10array_tree_13FileArrayTree_5dtype_3__set__(o, v);
+  }
+  else {
+    return __pyx_pw_2bx_6arrays_10array_tree_13FileArrayTree_5dtype_5__del__(o);
+  }
+}
+
+static PyObject *__pyx_getprop_2bx_6arrays_10array_tree_13FileArrayTree_levels(PyObject *o, CYTHON_UNUSED void *x) {
+  return __pyx_pw_2bx_6arrays_10array_tree_13FileArrayTree_6levels_1__get__(o);
+}
+
+static int __pyx_setprop_2bx_6arrays_10array_tree_13FileArrayTree_levels(PyObject *o, PyObject *v, CYTHON_UNUSED void *x) {
+  if (v) {
+    return __pyx_pw_2bx_6arrays_10array_tree_13FileArrayTree_6levels_3__set__(o, v);
+  }
+  else {
+    PyErr_SetString(PyExc_NotImplementedError, "__del__");
+    return -1;
+  }
+}
+
+static PyObject *__pyx_getprop_2bx_6arrays_10array_tree_13FileArrayTree_offset(PyObject *o, CYTHON_UNUSED void *x) {
+  return __pyx_pw_2bx_6arrays_10array_tree_13FileArrayTree_6offset_1__get__(o);
+}
+
+static int __pyx_setprop_2bx_6arrays_10array_tree_13FileArrayTree_offset(PyObject *o, PyObject *v, CYTHON_UNUSED void *x) {
+  if (v) {
+    return __pyx_pw_2bx_6arrays_10array_tree_13FileArrayTree_6offset_3__set__(o, v);
+  }
+  else {
+    PyErr_SetString(PyExc_NotImplementedError, "__del__");
+    return -1;
+  }
+}
+
+static PyObject *__pyx_getprop_2bx_6arrays_10array_tree_13FileArrayTree_root_offset(PyObject *o, CYTHON_UNUSED void *x) {
+  return __pyx_pw_2bx_6arrays_10array_tree_13FileArrayTree_11root_offset_1__get__(o);
+}
+
+static int __pyx_setprop_2bx_6arrays_10array_tree_13FileArrayTree_root_offset(PyObject *o, PyObject *v, CYTHON_UNUSED void *x) {
+  if (v) {
+    return __pyx_pw_2bx_6arrays_10array_tree_13FileArrayTree_11root_offset_3__set__(o, v);
+  }
+  else {
+    PyErr_SetString(PyExc_NotImplementedError, "__del__");
+    return -1;
+  }
+}
+
+static PyMethodDef __pyx_methods_2bx_6arrays_10array_tree_FileArrayTree[] = {
+  {__Pyx_NAMESTR("get_summary"), (PyCFunction)__pyx_pw_2bx_6arrays_10array_tree_13FileArrayTree_5get_summary, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(0)},
+  {__Pyx_NAMESTR("get_leaf"), (PyCFunction)__pyx_pw_2bx_6arrays_10array_tree_13FileArrayTree_7get_leaf, METH_O, __Pyx_DOCSTR(0)},
+  {0, 0, 0, 0}
+};
+
+static struct PyGetSetDef __pyx_getsets_2bx_6arrays_10array_tree_FileArrayTree[] = {
+  {(char *)"max", __pyx_getprop_2bx_6arrays_10array_tree_13FileArrayTree_max, __pyx_setprop_2bx_6arrays_10array_tree_13FileArrayTree_max, 0, 0},
+  {(char *)"block_size", __pyx_getprop_2bx_6arrays_10array_tree_13FileArrayTree_block_size, __pyx_setprop_2bx_6arrays_10array_tree_13FileArrayTree_block_size, 0, 0},
+  {(char *)"dtype", __pyx_getprop_2bx_6arrays_10array_tree_13FileArrayTree_dtype, __pyx_setprop_2bx_6arrays_10array_tree_13FileArrayTree_dtype, 0, 0},
+  {(char *)"levels", __pyx_getprop_2bx_6arrays_10array_tree_13FileArrayTree_levels, __pyx_setprop_2bx_6arrays_10array_tree_13FileArrayTree_levels, 0, 0},
+  {(char *)"offset", __pyx_getprop_2bx_6arrays_10array_tree_13FileArrayTree_offset, __pyx_setprop_2bx_6arrays_10array_tree_13FileArrayTree_offset, 0, 0},
+  {(char *)"root_offset", __pyx_getprop_2bx_6arrays_10array_tree_13FileArrayTree_root_offset, __pyx_setprop_2bx_6arrays_10array_tree_13FileArrayTree_root_offset, 0, 0},
+  {0, 0, 0, 0, 0}
+};
+
+static PyNumberMethods __pyx_tp_as_number_FileArrayTree = {
+  0, /*nb_add*/
+  0, /*nb_subtract*/
+  0, /*nb_multiply*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_divide*/
+  #endif
+  0, /*nb_remainder*/
+  0, /*nb_divmod*/
+  0, /*nb_power*/
+  0, /*nb_negative*/
+  0, /*nb_positive*/
+  0, /*nb_absolute*/
+  0, /*nb_nonzero*/
+  0, /*nb_invert*/
+  0, /*nb_lshift*/
+  0, /*nb_rshift*/
+  0, /*nb_and*/
+  0, /*nb_xor*/
+  0, /*nb_or*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_coerce*/
+  #endif
+  0, /*nb_int*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_long*/
+  #else
+  0, /*reserved*/
+  #endif
+  0, /*nb_float*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_oct*/
+  #endif
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_hex*/
+  #endif
+  0, /*nb_inplace_add*/
+  0, /*nb_inplace_subtract*/
+  0, /*nb_inplace_multiply*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_inplace_divide*/
+  #endif
+  0, /*nb_inplace_remainder*/
+  0, /*nb_inplace_power*/
+  0, /*nb_inplace_lshift*/
+  0, /*nb_inplace_rshift*/
+  0, /*nb_inplace_and*/
+  0, /*nb_inplace_xor*/
+  0, /*nb_inplace_or*/
+  0, /*nb_floor_divide*/
+  0, /*nb_true_divide*/
+  0, /*nb_inplace_floor_divide*/
+  0, /*nb_inplace_true_divide*/
+  #if PY_VERSION_HEX >= 0x02050000
+  0, /*nb_index*/
+  #endif
+};
+
+static PySequenceMethods __pyx_tp_as_sequence_FileArrayTree = {
+  0, /*sq_length*/
+  0, /*sq_concat*/
+  0, /*sq_repeat*/
+  __pyx_sq_item_2bx_6arrays_10array_tree_FileArrayTree, /*sq_item*/
+  0, /*sq_slice*/
+  0, /*sq_ass_item*/
+  0, /*sq_ass_slice*/
+  0, /*sq_contains*/
+  0, /*sq_inplace_concat*/
+  0, /*sq_inplace_repeat*/
+};
+
+static PyMappingMethods __pyx_tp_as_mapping_FileArrayTree = {
+  0, /*mp_length*/
+  __pyx_pw_2bx_6arrays_10array_tree_13FileArrayTree_3__getitem__, /*mp_subscript*/
+  0, /*mp_ass_subscript*/
+};
+
+static PyBufferProcs __pyx_tp_as_buffer_FileArrayTree = {
+  #if PY_MAJOR_VERSION < 3
+  0, /*bf_getreadbuffer*/
+  #endif
+  #if PY_MAJOR_VERSION < 3
+  0, /*bf_getwritebuffer*/
+  #endif
+  #if PY_MAJOR_VERSION < 3
+  0, /*bf_getsegcount*/
+  #endif
+  #if PY_MAJOR_VERSION < 3
+  0, /*bf_getcharbuffer*/
+  #endif
+  #if PY_VERSION_HEX >= 0x02060000
+  0, /*bf_getbuffer*/
+  #endif
+  #if PY_VERSION_HEX >= 0x02060000
+  0, /*bf_releasebuffer*/
+  #endif
+};
+
+static PyTypeObject __pyx_type_2bx_6arrays_10array_tree_FileArrayTree = {
+  PyVarObject_HEAD_INIT(0, 0)
+  __Pyx_NAMESTR("bx.arrays.array_tree.FileArrayTree"), /*tp_name*/
+  sizeof(struct __pyx_obj_2bx_6arrays_10array_tree_FileArrayTree), /*tp_basicsize*/
+  0, /*tp_itemsize*/
+  __pyx_tp_dealloc_2bx_6arrays_10array_tree_FileArrayTree, /*tp_dealloc*/
+  0, /*tp_print*/
+  0, /*tp_getattr*/
+  0, /*tp_setattr*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*tp_compare*/
+  #else
+  0, /*reserved*/
+  #endif
+  0, /*tp_repr*/
+  &__pyx_tp_as_number_FileArrayTree, /*tp_as_number*/
+  &__pyx_tp_as_sequence_FileArrayTree, /*tp_as_sequence*/
+  &__pyx_tp_as_mapping_FileArrayTree, /*tp_as_mapping*/
+  0, /*tp_hash*/
+  0, /*tp_call*/
+  0, /*tp_str*/
+  0, /*tp_getattro*/
+  0, /*tp_setattro*/
+  &__pyx_tp_as_buffer_FileArrayTree, /*tp_as_buffer*/
+  Py_TPFLAGS_DEFAULT|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+  __Pyx_DOCSTR("\n    Wrapper for ArrayTree stored in file that reads as little as possible\n    "), /*tp_doc*/
+  __pyx_tp_traverse_2bx_6arrays_10array_tree_FileArrayTree, /*tp_traverse*/
+  __pyx_tp_clear_2bx_6arrays_10array_tree_FileArrayTree, /*tp_clear*/
+  0, /*tp_richcompare*/
+  0, /*tp_weaklistoffset*/
+  0, /*tp_iter*/
+  0, /*tp_iternext*/
+  __pyx_methods_2bx_6arrays_10array_tree_FileArrayTree, /*tp_methods*/
+  0, /*tp_members*/
+  __pyx_getsets_2bx_6arrays_10array_tree_FileArrayTree, /*tp_getset*/
+  0, /*tp_base*/
+  0, /*tp_dict*/
+  0, /*tp_descr_get*/
+  0, /*tp_descr_set*/
+  0, /*tp_dictoffset*/
+  __pyx_pw_2bx_6arrays_10array_tree_13FileArrayTree_1__init__, /*tp_init*/
+  0, /*tp_alloc*/
+  __pyx_tp_new_2bx_6arrays_10array_tree_FileArrayTree, /*tp_new*/
+  0, /*tp_free*/
+  0, /*tp_is_gc*/
+  0, /*tp_bases*/
+  0, /*tp_mro*/
+  0, /*tp_cache*/
+  0, /*tp_subclasses*/
+  0, /*tp_weaklist*/
+  0, /*tp_del*/
+  #if PY_VERSION_HEX >= 0x02060000
+  0, /*tp_version_tag*/
+  #endif
+};
+
+static PyObject *__pyx_tp_new_2bx_6arrays_10array_tree_Summary(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) {
+  struct __pyx_obj_2bx_6arrays_10array_tree_Summary *p;
+  PyObject *o = (*t->tp_alloc)(t, 0);
+  if (!o) return 0;
+  p = ((struct __pyx_obj_2bx_6arrays_10array_tree_Summary *)o);
+  p->counts = Py_None; Py_INCREF(Py_None);
+  p->frequencies = Py_None; Py_INCREF(Py_None);
+  p->mins = Py_None; Py_INCREF(Py_None);
+  p->maxs = Py_None; Py_INCREF(Py_None);
+  p->sums = Py_None; Py_INCREF(Py_None);
+  p->sumsquares = Py_None; Py_INCREF(Py_None);
+  return o;
+}
+
+static void __pyx_tp_dealloc_2bx_6arrays_10array_tree_Summary(PyObject *o) {
+  struct __pyx_obj_2bx_6arrays_10array_tree_Summary *p = (struct __pyx_obj_2bx_6arrays_10array_tree_Summary *)o;
+  PyObject_GC_UnTrack(o);
+  Py_CLEAR(p->counts);
+  Py_CLEAR(p->frequencies);
+  Py_CLEAR(p->mins);
+  Py_CLEAR(p->maxs);
+  Py_CLEAR(p->sums);
+  Py_CLEAR(p->sumsquares);
+  PyObject_GC_Track(o);
+  (*Py_TYPE(o)->tp_free)(o);
+}
+
+static int __pyx_tp_traverse_2bx_6arrays_10array_tree_Summary(PyObject *o, visitproc v, void *a) {
+  int e;
+  struct __pyx_obj_2bx_6arrays_10array_tree_Summary *p = (struct __pyx_obj_2bx_6arrays_10array_tree_Summary *)o;
+  if (p->counts) {
+    e = (*v)(p->counts, a); if (e) return e;
+  }
+  if (p->frequencies) {
+    e = (*v)(p->frequencies, a); if (e) return e;
+  }
+  if (p->mins) {
+    e = (*v)(p->mins, a); if (e) return e;
+  }
+  if (p->maxs) {
+    e = (*v)(p->maxs, a); if (e) return e;
+  }
+  if (p->sums) {
+    e = (*v)(p->sums, a); if (e) return e;
+  }
+  if (p->sumsquares) {
+    e = (*v)(p->sumsquares, a); if (e) return e;
+  }
+  return 0;
+}
+
+static int __pyx_tp_clear_2bx_6arrays_10array_tree_Summary(PyObject *o) {
+  struct __pyx_obj_2bx_6arrays_10array_tree_Summary *p = (struct __pyx_obj_2bx_6arrays_10array_tree_Summary *)o;
+  PyObject* tmp;
+  tmp = ((PyObject*)p->counts);
+  p->counts = Py_None; Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  tmp = ((PyObject*)p->frequencies);
+  p->frequencies = Py_None; Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  tmp = ((PyObject*)p->mins);
+  p->mins = Py_None; Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  tmp = ((PyObject*)p->maxs);
+  p->maxs = Py_None; Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  tmp = ((PyObject*)p->sums);
+  p->sums = Py_None; Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  tmp = ((PyObject*)p->sumsquares);
+  p->sumsquares = Py_None; Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  return 0;
+}
+
+static PyObject *__pyx_getprop_2bx_6arrays_10array_tree_7Summary_counts(PyObject *o, CYTHON_UNUSED void *x) {
+  return __pyx_pw_2bx_6arrays_10array_tree_7Summary_6counts_1__get__(o);
+}
+
+static int __pyx_setprop_2bx_6arrays_10array_tree_7Summary_counts(PyObject *o, PyObject *v, CYTHON_UNUSED void *x) {
+  if (v) {
+    return __pyx_pw_2bx_6arrays_10array_tree_7Summary_6counts_3__set__(o, v);
+  }
+  else {
+    return __pyx_pw_2bx_6arrays_10array_tree_7Summary_6counts_5__del__(o);
+  }
+}
+
+static PyObject *__pyx_getprop_2bx_6arrays_10array_tree_7Summary_frequencies(PyObject *o, CYTHON_UNUSED void *x) {
+  return __pyx_pw_2bx_6arrays_10array_tree_7Summary_11frequencies_1__get__(o);
+}
+
+static int __pyx_setprop_2bx_6arrays_10array_tree_7Summary_frequencies(PyObject *o, PyObject *v, CYTHON_UNUSED void *x) {
+  if (v) {
+    return __pyx_pw_2bx_6arrays_10array_tree_7Summary_11frequencies_3__set__(o, v);
+  }
+  else {
+    return __pyx_pw_2bx_6arrays_10array_tree_7Summary_11frequencies_5__del__(o);
+  }
+}
+
+static PyObject *__pyx_getprop_2bx_6arrays_10array_tree_7Summary_mins(PyObject *o, CYTHON_UNUSED void *x) {
+  return __pyx_pw_2bx_6arrays_10array_tree_7Summary_4mins_1__get__(o);
+}
+
+static int __pyx_setprop_2bx_6arrays_10array_tree_7Summary_mins(PyObject *o, PyObject *v, CYTHON_UNUSED void *x) {
+  if (v) {
+    return __pyx_pw_2bx_6arrays_10array_tree_7Summary_4mins_3__set__(o, v);
+  }
+  else {
+    return __pyx_pw_2bx_6arrays_10array_tree_7Summary_4mins_5__del__(o);
+  }
+}
+
+static PyObject *__pyx_getprop_2bx_6arrays_10array_tree_7Summary_maxs(PyObject *o, CYTHON_UNUSED void *x) {
+  return __pyx_pw_2bx_6arrays_10array_tree_7Summary_4maxs_1__get__(o);
+}
+
+static int __pyx_setprop_2bx_6arrays_10array_tree_7Summary_maxs(PyObject *o, PyObject *v, CYTHON_UNUSED void *x) {
+  if (v) {
+    return __pyx_pw_2bx_6arrays_10array_tree_7Summary_4maxs_3__set__(o, v);
+  }
+  else {
+    return __pyx_pw_2bx_6arrays_10array_tree_7Summary_4maxs_5__del__(o);
+  }
+}
+
+static PyObject *__pyx_getprop_2bx_6arrays_10array_tree_7Summary_sums(PyObject *o, CYTHON_UNUSED void *x) {
+  return __pyx_pw_2bx_6arrays_10array_tree_7Summary_4sums_1__get__(o);
+}
+
+static int __pyx_setprop_2bx_6arrays_10array_tree_7Summary_sums(PyObject *o, PyObject *v, CYTHON_UNUSED void *x) {
+  if (v) {
+    return __pyx_pw_2bx_6arrays_10array_tree_7Summary_4sums_3__set__(o, v);
+  }
+  else {
+    return __pyx_pw_2bx_6arrays_10array_tree_7Summary_4sums_5__del__(o);
+  }
+}
+
+static PyObject *__pyx_getprop_2bx_6arrays_10array_tree_7Summary_sumsquares(PyObject *o, CYTHON_UNUSED void *x) {
+  return __pyx_pw_2bx_6arrays_10array_tree_7Summary_10sumsquares_1__get__(o);
+}
+
+static int __pyx_setprop_2bx_6arrays_10array_tree_7Summary_sumsquares(PyObject *o, PyObject *v, CYTHON_UNUSED void *x) {
+  if (v) {
+    return __pyx_pw_2bx_6arrays_10array_tree_7Summary_10sumsquares_3__set__(o, v);
+  }
+  else {
+    return __pyx_pw_2bx_6arrays_10array_tree_7Summary_10sumsquares_5__del__(o);
+  }
+}
+
+static PyMethodDef __pyx_methods_2bx_6arrays_10array_tree_Summary[] = {
+  {0, 0, 0, 0}
+};
+
+static struct PyGetSetDef __pyx_getsets_2bx_6arrays_10array_tree_Summary[] = {
+  {(char *)"counts", __pyx_getprop_2bx_6arrays_10array_tree_7Summary_counts, __pyx_setprop_2bx_6arrays_10array_tree_7Summary_counts, 0, 0},
+  {(char *)"frequencies", __pyx_getprop_2bx_6arrays_10array_tree_7Summary_frequencies, __pyx_setprop_2bx_6arrays_10array_tree_7Summary_frequencies, 0, 0},
+  {(char *)"mins", __pyx_getprop_2bx_6arrays_10array_tree_7Summary_mins, __pyx_setprop_2bx_6arrays_10array_tree_7Summary_mins, 0, 0},
+  {(char *)"maxs", __pyx_getprop_2bx_6arrays_10array_tree_7Summary_maxs, __pyx_setprop_2bx_6arrays_10array_tree_7Summary_maxs, 0, 0},
+  {(char *)"sums", __pyx_getprop_2bx_6arrays_10array_tree_7Summary_sums, __pyx_setprop_2bx_6arrays_10array_tree_7Summary_sums, 0, 0},
+  {(char *)"sumsquares", __pyx_getprop_2bx_6arrays_10array_tree_7Summary_sumsquares, __pyx_setprop_2bx_6arrays_10array_tree_7Summary_sumsquares, 0, 0},
+  {0, 0, 0, 0, 0}
+};
+
+static PyNumberMethods __pyx_tp_as_number_Summary = {
+  0, /*nb_add*/
+  0, /*nb_subtract*/
+  0, /*nb_multiply*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_divide*/
+  #endif
+  0, /*nb_remainder*/
+  0, /*nb_divmod*/
+  0, /*nb_power*/
+  0, /*nb_negative*/
+  0, /*nb_positive*/
+  0, /*nb_absolute*/
+  0, /*nb_nonzero*/
+  0, /*nb_invert*/
+  0, /*nb_lshift*/
+  0, /*nb_rshift*/
+  0, /*nb_and*/
+  0, /*nb_xor*/
+  0, /*nb_or*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_coerce*/
+  #endif
+  0, /*nb_int*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_long*/
+  #else
+  0, /*reserved*/
+  #endif
+  0, /*nb_float*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_oct*/
+  #endif
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_hex*/
+  #endif
+  0, /*nb_inplace_add*/
+  0, /*nb_inplace_subtract*/
+  0, /*nb_inplace_multiply*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_inplace_divide*/
+  #endif
+  0, /*nb_inplace_remainder*/
+  0, /*nb_inplace_power*/
+  0, /*nb_inplace_lshift*/
+  0, /*nb_inplace_rshift*/
+  0, /*nb_inplace_and*/
+  0, /*nb_inplace_xor*/
+  0, /*nb_inplace_or*/
+  0, /*nb_floor_divide*/
+  0, /*nb_true_divide*/
+  0, /*nb_inplace_floor_divide*/
+  0, /*nb_inplace_true_divide*/
+  #if PY_VERSION_HEX >= 0x02050000
+  0, /*nb_index*/
+  #endif
+};
+
+static PySequenceMethods __pyx_tp_as_sequence_Summary = {
+  0, /*sq_length*/
+  0, /*sq_concat*/
+  0, /*sq_repeat*/
+  0, /*sq_item*/
+  0, /*sq_slice*/
+  0, /*sq_ass_item*/
+  0, /*sq_ass_slice*/
+  0, /*sq_contains*/
+  0, /*sq_inplace_concat*/
+  0, /*sq_inplace_repeat*/
+};
+
+static PyMappingMethods __pyx_tp_as_mapping_Summary = {
+  0, /*mp_length*/
+  0, /*mp_subscript*/
+  0, /*mp_ass_subscript*/
+};
+
+static PyBufferProcs __pyx_tp_as_buffer_Summary = {
+  #if PY_MAJOR_VERSION < 3
+  0, /*bf_getreadbuffer*/
+  #endif
+  #if PY_MAJOR_VERSION < 3
+  0, /*bf_getwritebuffer*/
+  #endif
+  #if PY_MAJOR_VERSION < 3
+  0, /*bf_getsegcount*/
+  #endif
+  #if PY_MAJOR_VERSION < 3
+  0, /*bf_getcharbuffer*/
+  #endif
+  #if PY_VERSION_HEX >= 0x02060000
+  0, /*bf_getbuffer*/
+  #endif
+  #if PY_VERSION_HEX >= 0x02060000
+  0, /*bf_releasebuffer*/
+  #endif
+};
+
+static PyTypeObject __pyx_type_2bx_6arrays_10array_tree_Summary = {
+  PyVarObject_HEAD_INIT(0, 0)
+  __Pyx_NAMESTR("bx.arrays.array_tree.Summary"), /*tp_name*/
+  sizeof(struct __pyx_obj_2bx_6arrays_10array_tree_Summary), /*tp_basicsize*/
+  0, /*tp_itemsize*/
+  __pyx_tp_dealloc_2bx_6arrays_10array_tree_Summary, /*tp_dealloc*/
+  0, /*tp_print*/
+  0, /*tp_getattr*/
+  0, /*tp_setattr*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*tp_compare*/
+  #else
+  0, /*reserved*/
+  #endif
+  0, /*tp_repr*/
+  &__pyx_tp_as_number_Summary, /*tp_as_number*/
+  &__pyx_tp_as_sequence_Summary, /*tp_as_sequence*/
+  &__pyx_tp_as_mapping_Summary, /*tp_as_mapping*/
+  0, /*tp_hash*/
+  0, /*tp_call*/
+  0, /*tp_str*/
+  0, /*tp_getattro*/
+  0, /*tp_setattro*/
+  &__pyx_tp_as_buffer_Summary, /*tp_as_buffer*/
+  Py_TPFLAGS_DEFAULT|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+  __Pyx_DOCSTR("\n    Summary for a non-leaf level of the tree, contains arrays of the min, max,\n    valid count, sum, and sum-of-squares for each child.\n    "), /*tp_doc*/
+  __pyx_tp_traverse_2bx_6arrays_10array_tree_Summary, /*tp_traverse*/
+  __pyx_tp_clear_2bx_6arrays_10array_tree_Summary, /*tp_clear*/
+  0, /*tp_richcompare*/
+  0, /*tp_weaklistoffset*/
+  0, /*tp_iter*/
+  0, /*tp_iternext*/
+  __pyx_methods_2bx_6arrays_10array_tree_Summary, /*tp_methods*/
+  0, /*tp_members*/
+  __pyx_getsets_2bx_6arrays_10array_tree_Summary, /*tp_getset*/
+  0, /*tp_base*/
+  0, /*tp_dict*/
+  0, /*tp_descr_get*/
+  0, /*tp_descr_set*/
+  0, /*tp_dictoffset*/
+  0, /*tp_init*/
+  0, /*tp_alloc*/
+  __pyx_tp_new_2bx_6arrays_10array_tree_Summary, /*tp_new*/
+  0, /*tp_free*/
+  0, /*tp_is_gc*/
+  0, /*tp_bases*/
+  0, /*tp_mro*/
+  0, /*tp_cache*/
+  0, /*tp_subclasses*/
+  0, /*tp_weaklist*/
+  0, /*tp_del*/
+  #if PY_VERSION_HEX >= 0x02060000
+  0, /*tp_version_tag*/
+  #endif
+};
+static struct __pyx_vtabstruct_2bx_6arrays_10array_tree_ArrayTreeNode __pyx_vtable_2bx_6arrays_10array_tree_ArrayTreeNode;
+
+static PyObject *__pyx_tp_new_2bx_6arrays_10array_tree_ArrayTreeNode(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) {
+  struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeNode *p;
+  PyObject *o = (*t->tp_alloc)(t, 0);
+  if (!o) return 0;
+  p = ((struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeNode *)o);
+  p->__pyx_vtab = __pyx_vtabptr_2bx_6arrays_10array_tree_ArrayTreeNode;
+  p->tree = ((struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTree *)Py_None); Py_INCREF(Py_None);
+  p->children = Py_None; Py_INCREF(Py_None);
+  p->summary = ((struct __pyx_obj_2bx_6arrays_10array_tree_Summary *)Py_None); Py_INCREF(Py_None);
+  return o;
+}
+
+static void __pyx_tp_dealloc_2bx_6arrays_10array_tree_ArrayTreeNode(PyObject *o) {
+  struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeNode *p = (struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeNode *)o;
+  PyObject_GC_UnTrack(o);
+  Py_CLEAR(p->tree);
+  Py_CLEAR(p->children);
+  Py_CLEAR(p->summary);
+  PyObject_GC_Track(o);
+  (*Py_TYPE(o)->tp_free)(o);
+}
+
+static int __pyx_tp_traverse_2bx_6arrays_10array_tree_ArrayTreeNode(PyObject *o, visitproc v, void *a) {
+  int e;
+  struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeNode *p = (struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeNode *)o;
+  if (p->tree) {
+    e = (*v)(((PyObject*)p->tree), a); if (e) return e;
+  }
+  if (p->children) {
+    e = (*v)(p->children, a); if (e) return e;
+  }
+  if (p->summary) {
+    e = (*v)(((PyObject*)p->summary), a); if (e) return e;
+  }
+  return 0;
+}
+
+static int __pyx_tp_clear_2bx_6arrays_10array_tree_ArrayTreeNode(PyObject *o) {
+  struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeNode *p = (struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeNode *)o;
+  PyObject* tmp;
+  tmp = ((PyObject*)p->tree);
+  p->tree = ((struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTree *)Py_None); Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  tmp = ((PyObject*)p->children);
+  p->children = Py_None; Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  tmp = ((PyObject*)p->summary);
+  p->summary = ((struct __pyx_obj_2bx_6arrays_10array_tree_Summary *)Py_None); Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  return 0;
+}
+
+static PyObject *__pyx_getprop_2bx_6arrays_10array_tree_13ArrayTreeNode_summary(PyObject *o, CYTHON_UNUSED void *x) {
+  return __pyx_pw_2bx_6arrays_10array_tree_13ArrayTreeNode_7summary_1__get__(o);
+}
+
+static int __pyx_setprop_2bx_6arrays_10array_tree_13ArrayTreeNode_summary(PyObject *o, PyObject *v, CYTHON_UNUSED void *x) {
+  if (v) {
+    return __pyx_pw_2bx_6arrays_10array_tree_13ArrayTreeNode_7summary_3__set__(o, v);
+  }
+  else {
+    return __pyx_pw_2bx_6arrays_10array_tree_13ArrayTreeNode_7summary_5__del__(o);
+  }
+}
+
+static PyObject *__pyx_getprop_2bx_6arrays_10array_tree_13ArrayTreeNode_start_offset(PyObject *o, CYTHON_UNUSED void *x) {
+  return __pyx_pw_2bx_6arrays_10array_tree_13ArrayTreeNode_12start_offset_1__get__(o);
+}
+
+static int __pyx_setprop_2bx_6arrays_10array_tree_13ArrayTreeNode_start_offset(PyObject *o, PyObject *v, CYTHON_UNUSED void *x) {
+  if (v) {
+    return __pyx_pw_2bx_6arrays_10array_tree_13ArrayTreeNode_12start_offset_3__set__(o, v);
+  }
+  else {
+    PyErr_SetString(PyExc_NotImplementedError, "__del__");
+    return -1;
+  }
+}
+
+static PyMethodDef __pyx_methods_2bx_6arrays_10array_tree_ArrayTreeNode[] = {
+  {__Pyx_NAMESTR("set"), (PyCFunction)__pyx_pw_2bx_6arrays_10array_tree_13ArrayTreeNode_3set, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(0)},
+  {__Pyx_NAMESTR("get"), (PyCFunction)__pyx_pw_2bx_6arrays_10array_tree_13ArrayTreeNode_5get, METH_O, __Pyx_DOCSTR(0)},
+  {__Pyx_NAMESTR("build_summary"), (PyCFunction)__pyx_pw_2bx_6arrays_10array_tree_13ArrayTreeNode_7build_summary, METH_NOARGS, __Pyx_DOCSTR(__pyx_doc_2bx_6arrays_10array_tree_13ArrayTreeNode_6build_summary)},
+  {__Pyx_NAMESTR("to_file_data_pass"), (PyCFunction)__pyx_pw_2bx_6arrays_10array_tree_13ArrayTreeNode_9to_file_data_pass, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(__pyx_doc_2bx_6arrays_10array_tree_13ArrayTreeNode_8to_file_data_pass)},
+  {__Pyx_NAMESTR("to_file_offset_pass"), (PyCFunction)__pyx_pw_2bx_6arrays_10array_tree_13ArrayTreeNode_11to_file_offset_pass, METH_O, __Pyx_DOCSTR(__pyx_doc_2bx_6arrays_10array_tree_13ArrayTreeNode_10to_file_offset_pass)},
+  {__Pyx_NAMESTR("from_file"), (PyCFunction)__pyx_pw_2bx_6arrays_10array_tree_13ArrayTreeNode_13from_file, METH_O, __Pyx_DOCSTR(__pyx_doc_2bx_6arrays_10array_tree_13ArrayTreeNode_12from_file)},
+  {__Pyx_NAMESTR("get_from_file"), (PyCFunction)__pyx_pw_2bx_6arrays_10array_tree_13ArrayTreeNode_15get_from_file, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(0)},
+  {0, 0, 0, 0}
+};
+
+static struct PyGetSetDef __pyx_getsets_2bx_6arrays_10array_tree_ArrayTreeNode[] = {
+  {(char *)"summary", __pyx_getprop_2bx_6arrays_10array_tree_13ArrayTreeNode_summary, __pyx_setprop_2bx_6arrays_10array_tree_13ArrayTreeNode_summary, 0, 0},
+  {(char *)"start_offset", __pyx_getprop_2bx_6arrays_10array_tree_13ArrayTreeNode_start_offset, __pyx_setprop_2bx_6arrays_10array_tree_13ArrayTreeNode_start_offset, 0, 0},
+  {0, 0, 0, 0, 0}
+};
+
+static PyNumberMethods __pyx_tp_as_number_ArrayTreeNode = {
+  0, /*nb_add*/
+  0, /*nb_subtract*/
+  0, /*nb_multiply*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_divide*/
+  #endif
+  0, /*nb_remainder*/
+  0, /*nb_divmod*/
+  0, /*nb_power*/
+  0, /*nb_negative*/
+  0, /*nb_positive*/
+  0, /*nb_absolute*/
+  0, /*nb_nonzero*/
+  0, /*nb_invert*/
+  0, /*nb_lshift*/
+  0, /*nb_rshift*/
+  0, /*nb_and*/
+  0, /*nb_xor*/
+  0, /*nb_or*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_coerce*/
+  #endif
+  0, /*nb_int*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_long*/
+  #else
+  0, /*reserved*/
+  #endif
+  0, /*nb_float*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_oct*/
+  #endif
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_hex*/
+  #endif
+  0, /*nb_inplace_add*/
+  0, /*nb_inplace_subtract*/
+  0, /*nb_inplace_multiply*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_inplace_divide*/
+  #endif
+  0, /*nb_inplace_remainder*/
+  0, /*nb_inplace_power*/
+  0, /*nb_inplace_lshift*/
+  0, /*nb_inplace_rshift*/
+  0, /*nb_inplace_and*/
+  0, /*nb_inplace_xor*/
+  0, /*nb_inplace_or*/
+  0, /*nb_floor_divide*/
+  0, /*nb_true_divide*/
+  0, /*nb_inplace_floor_divide*/
+  0, /*nb_inplace_true_divide*/
+  #if PY_VERSION_HEX >= 0x02050000
+  0, /*nb_index*/
+  #endif
+};
+
+static PySequenceMethods __pyx_tp_as_sequence_ArrayTreeNode = {
+  0, /*sq_length*/
+  0, /*sq_concat*/
+  0, /*sq_repeat*/
+  0, /*sq_item*/
+  0, /*sq_slice*/
+  0, /*sq_ass_item*/
+  0, /*sq_ass_slice*/
+  0, /*sq_contains*/
+  0, /*sq_inplace_concat*/
+  0, /*sq_inplace_repeat*/
+};
+
+static PyMappingMethods __pyx_tp_as_mapping_ArrayTreeNode = {
+  0, /*mp_length*/
+  0, /*mp_subscript*/
+  0, /*mp_ass_subscript*/
+};
+
+static PyBufferProcs __pyx_tp_as_buffer_ArrayTreeNode = {
+  #if PY_MAJOR_VERSION < 3
+  0, /*bf_getreadbuffer*/
+  #endif
+  #if PY_MAJOR_VERSION < 3
+  0, /*bf_getwritebuffer*/
+  #endif
+  #if PY_MAJOR_VERSION < 3
+  0, /*bf_getsegcount*/
+  #endif
+  #if PY_MAJOR_VERSION < 3
+  0, /*bf_getcharbuffer*/
+  #endif
+  #if PY_VERSION_HEX >= 0x02060000
+  0, /*bf_getbuffer*/
+  #endif
+  #if PY_VERSION_HEX >= 0x02060000
+  0, /*bf_releasebuffer*/
+  #endif
+};
+
+static PyTypeObject __pyx_type_2bx_6arrays_10array_tree_ArrayTreeNode = {
+  PyVarObject_HEAD_INIT(0, 0)
+  __Pyx_NAMESTR("bx.arrays.array_tree.ArrayTreeNode"), /*tp_name*/
+  sizeof(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeNode), /*tp_basicsize*/
+  0, /*tp_itemsize*/
+  __pyx_tp_dealloc_2bx_6arrays_10array_tree_ArrayTreeNode, /*tp_dealloc*/
+  0, /*tp_print*/
+  0, /*tp_getattr*/
+  0, /*tp_setattr*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*tp_compare*/
+  #else
+  0, /*reserved*/
+  #endif
+  0, /*tp_repr*/
+  &__pyx_tp_as_number_ArrayTreeNode, /*tp_as_number*/
+  &__pyx_tp_as_sequence_ArrayTreeNode, /*tp_as_sequence*/
+  &__pyx_tp_as_mapping_ArrayTreeNode, /*tp_as_mapping*/
+  0, /*tp_hash*/
+  0, /*tp_call*/
+  0, /*tp_str*/
+  0, /*tp_getattro*/
+  0, /*tp_setattro*/
+  &__pyx_tp_as_buffer_ArrayTreeNode, /*tp_as_buffer*/
+  Py_TPFLAGS_DEFAULT|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+  __Pyx_DOCSTR("\n    Internal node of an ArrayTree. Contains summary data and pointers to\n    subtrees.\n    "), /*tp_doc*/
+  __pyx_tp_traverse_2bx_6arrays_10array_tree_ArrayTreeNode, /*tp_traverse*/
+  __pyx_tp_clear_2bx_6arrays_10array_tree_ArrayTreeNode, /*tp_clear*/
+  0, /*tp_richcompare*/
+  0, /*tp_weaklistoffset*/
+  0, /*tp_iter*/
+  0, /*tp_iternext*/
+  __pyx_methods_2bx_6arrays_10array_tree_ArrayTreeNode, /*tp_methods*/
+  0, /*tp_members*/
+  __pyx_getsets_2bx_6arrays_10array_tree_ArrayTreeNode, /*tp_getset*/
+  0, /*tp_base*/
+  0, /*tp_dict*/
+  0, /*tp_descr_get*/
+  0, /*tp_descr_set*/
+  0, /*tp_dictoffset*/
+  __pyx_pw_2bx_6arrays_10array_tree_13ArrayTreeNode_1__init__, /*tp_init*/
+  0, /*tp_alloc*/
+  __pyx_tp_new_2bx_6arrays_10array_tree_ArrayTreeNode, /*tp_new*/
+  0, /*tp_free*/
+  0, /*tp_is_gc*/
+  0, /*tp_bases*/
+  0, /*tp_mro*/
+  0, /*tp_cache*/
+  0, /*tp_subclasses*/
+  0, /*tp_weaklist*/
+  0, /*tp_del*/
+  #if PY_VERSION_HEX >= 0x02060000
+  0, /*tp_version_tag*/
+  #endif
+};
+
+static PyObject *__pyx_tp_new_2bx_6arrays_10array_tree_ArrayTreeLeaf(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) {
+  struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeLeaf *p;
+  PyObject *o = (*t->tp_alloc)(t, 0);
+  if (!o) return 0;
+  p = ((struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeLeaf *)o);
+  p->tree = ((struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTree *)Py_None); Py_INCREF(Py_None);
+  p->values = ((PyArrayObject *)Py_None); Py_INCREF(Py_None);
+  return o;
+}
+
+static void __pyx_tp_dealloc_2bx_6arrays_10array_tree_ArrayTreeLeaf(PyObject *o) {
+  struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeLeaf *p = (struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeLeaf *)o;
+  PyObject_GC_UnTrack(o);
+  Py_CLEAR(p->tree);
+  Py_CLEAR(p->values);
+  PyObject_GC_Track(o);
+  (*Py_TYPE(o)->tp_free)(o);
+}
+
+static int __pyx_tp_traverse_2bx_6arrays_10array_tree_ArrayTreeLeaf(PyObject *o, visitproc v, void *a) {
+  int e;
+  struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeLeaf *p = (struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeLeaf *)o;
+  if (p->tree) {
+    e = (*v)(((PyObject*)p->tree), a); if (e) return e;
+  }
+  if (p->values) {
+    e = (*v)(((PyObject*)p->values), a); if (e) return e;
+  }
+  return 0;
+}
+
+static int __pyx_tp_clear_2bx_6arrays_10array_tree_ArrayTreeLeaf(PyObject *o) {
+  struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeLeaf *p = (struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeLeaf *)o;
+  PyObject* tmp;
+  tmp = ((PyObject*)p->tree);
+  p->tree = ((struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTree *)Py_None); Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  tmp = ((PyObject*)p->values);
+  p->values = ((PyArrayObject *)Py_None); Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  return 0;
+}
+
+static PyObject *__pyx_getprop_2bx_6arrays_10array_tree_13ArrayTreeLeaf_frequency(PyObject *o, CYTHON_UNUSED void *x) {
+  return __pyx_pw_2bx_6arrays_10array_tree_13ArrayTreeLeaf_9frequency_1__get__(o);
+}
+
+static int __pyx_setprop_2bx_6arrays_10array_tree_13ArrayTreeLeaf_frequency(PyObject *o, PyObject *v, CYTHON_UNUSED void *x) {
+  if (v) {
+    return __pyx_pw_2bx_6arrays_10array_tree_13ArrayTreeLeaf_9frequency_3__set__(o, v);
+  }
+  else {
+    PyErr_SetString(PyExc_NotImplementedError, "__del__");
+    return -1;
+  }
+}
+
+static PyObject *__pyx_getprop_2bx_6arrays_10array_tree_13ArrayTreeLeaf_values(PyObject *o, CYTHON_UNUSED void *x) {
+  return __pyx_pw_2bx_6arrays_10array_tree_13ArrayTreeLeaf_6values_1__get__(o);
+}
+
+static int __pyx_setprop_2bx_6arrays_10array_tree_13ArrayTreeLeaf_values(PyObject *o, PyObject *v, CYTHON_UNUSED void *x) {
+  if (v) {
+    return __pyx_pw_2bx_6arrays_10array_tree_13ArrayTreeLeaf_6values_3__set__(o, v);
+  }
+  else {
+    return __pyx_pw_2bx_6arrays_10array_tree_13ArrayTreeLeaf_6values_5__del__(o);
+  }
+}
+
+static PyObject *__pyx_getprop_2bx_6arrays_10array_tree_13ArrayTreeLeaf_start_offset(PyObject *o, CYTHON_UNUSED void *x) {
+  return __pyx_pw_2bx_6arrays_10array_tree_13ArrayTreeLeaf_12start_offset_1__get__(o);
+}
+
+static int __pyx_setprop_2bx_6arrays_10array_tree_13ArrayTreeLeaf_start_offset(PyObject *o, PyObject *v, CYTHON_UNUSED void *x) {
+  if (v) {
+    return __pyx_pw_2bx_6arrays_10array_tree_13ArrayTreeLeaf_12start_offset_3__set__(o, v);
+  }
+  else {
+    PyErr_SetString(PyExc_NotImplementedError, "__del__");
+    return -1;
+  }
+}
+
+static PyMethodDef __pyx_methods_2bx_6arrays_10array_tree_ArrayTreeLeaf[] = {
+  {__Pyx_NAMESTR("set"), (PyCFunction)__pyx_pw_2bx_6arrays_10array_tree_13ArrayTreeLeaf_3set, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(0)},
+  {__Pyx_NAMESTR("get"), (PyCFunction)__pyx_pw_2bx_6arrays_10array_tree_13ArrayTreeLeaf_5get, METH_O, __Pyx_DOCSTR(0)},
+  {__Pyx_NAMESTR("to_file_data_pass"), (PyCFunction)__pyx_pw_2bx_6arrays_10array_tree_13ArrayTreeLeaf_7to_file_data_pass, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(0)},
+  {__Pyx_NAMESTR("to_file_offset_pass"), (PyCFunction)__pyx_pw_2bx_6arrays_10array_tree_13ArrayTreeLeaf_9to_file_offset_pass, METH_O, __Pyx_DOCSTR(0)},
+  {__Pyx_NAMESTR("from_file"), (PyCFunction)__pyx_pw_2bx_6arrays_10array_tree_13ArrayTreeLeaf_11from_file, METH_O, __Pyx_DOCSTR(0)},
+  {0, 0, 0, 0}
+};
+
+static struct PyGetSetDef __pyx_getsets_2bx_6arrays_10array_tree_ArrayTreeLeaf[] = {
+  {(char *)"frequency", __pyx_getprop_2bx_6arrays_10array_tree_13ArrayTreeLeaf_frequency, __pyx_setprop_2bx_6arrays_10array_tree_13ArrayTreeLeaf_frequency, 0, 0},
+  {(char *)"values", __pyx_getprop_2bx_6arrays_10array_tree_13ArrayTreeLeaf_values, __pyx_setprop_2bx_6arrays_10array_tree_13ArrayTreeLeaf_values, 0, 0},
+  {(char *)"start_offset", __pyx_getprop_2bx_6arrays_10array_tree_13ArrayTreeLeaf_start_offset, __pyx_setprop_2bx_6arrays_10array_tree_13ArrayTreeLeaf_start_offset, 0, 0},
+  {0, 0, 0, 0, 0}
+};
+
+static PyNumberMethods __pyx_tp_as_number_ArrayTreeLeaf = {
+  0, /*nb_add*/
+  0, /*nb_subtract*/
+  0, /*nb_multiply*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_divide*/
+  #endif
+  0, /*nb_remainder*/
+  0, /*nb_divmod*/
+  0, /*nb_power*/
+  0, /*nb_negative*/
+  0, /*nb_positive*/
+  0, /*nb_absolute*/
+  0, /*nb_nonzero*/
+  0, /*nb_invert*/
+  0, /*nb_lshift*/
+  0, /*nb_rshift*/
+  0, /*nb_and*/
+  0, /*nb_xor*/
+  0, /*nb_or*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_coerce*/
+  #endif
+  0, /*nb_int*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_long*/
+  #else
+  0, /*reserved*/
+  #endif
+  0, /*nb_float*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_oct*/
+  #endif
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_hex*/
+  #endif
+  0, /*nb_inplace_add*/
+  0, /*nb_inplace_subtract*/
+  0, /*nb_inplace_multiply*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_inplace_divide*/
+  #endif
+  0, /*nb_inplace_remainder*/
+  0, /*nb_inplace_power*/
+  0, /*nb_inplace_lshift*/
+  0, /*nb_inplace_rshift*/
+  0, /*nb_inplace_and*/
+  0, /*nb_inplace_xor*/
+  0, /*nb_inplace_or*/
+  0, /*nb_floor_divide*/
+  0, /*nb_true_divide*/
+  0, /*nb_inplace_floor_divide*/
+  0, /*nb_inplace_true_divide*/
+  #if PY_VERSION_HEX >= 0x02050000
+  0, /*nb_index*/
+  #endif
+};
+
+static PySequenceMethods __pyx_tp_as_sequence_ArrayTreeLeaf = {
+  0, /*sq_length*/
+  0, /*sq_concat*/
+  0, /*sq_repeat*/
+  0, /*sq_item*/
+  0, /*sq_slice*/
+  0, /*sq_ass_item*/
+  0, /*sq_ass_slice*/
+  0, /*sq_contains*/
+  0, /*sq_inplace_concat*/
+  0, /*sq_inplace_repeat*/
+};
+
+static PyMappingMethods __pyx_tp_as_mapping_ArrayTreeLeaf = {
+  0, /*mp_length*/
+  0, /*mp_subscript*/
+  0, /*mp_ass_subscript*/
+};
+
+static PyBufferProcs __pyx_tp_as_buffer_ArrayTreeLeaf = {
+  #if PY_MAJOR_VERSION < 3
+  0, /*bf_getreadbuffer*/
+  #endif
+  #if PY_MAJOR_VERSION < 3
+  0, /*bf_getwritebuffer*/
+  #endif
+  #if PY_MAJOR_VERSION < 3
+  0, /*bf_getsegcount*/
+  #endif
+  #if PY_MAJOR_VERSION < 3
+  0, /*bf_getcharbuffer*/
+  #endif
+  #if PY_VERSION_HEX >= 0x02060000
+  0, /*bf_getbuffer*/
+  #endif
+  #if PY_VERSION_HEX >= 0x02060000
+  0, /*bf_releasebuffer*/
+  #endif
+};
+
+static PyTypeObject __pyx_type_2bx_6arrays_10array_tree_ArrayTreeLeaf = {
+  PyVarObject_HEAD_INIT(0, 0)
+  __Pyx_NAMESTR("bx.arrays.array_tree.ArrayTreeLeaf"), /*tp_name*/
+  sizeof(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeLeaf), /*tp_basicsize*/
+  0, /*tp_itemsize*/
+  __pyx_tp_dealloc_2bx_6arrays_10array_tree_ArrayTreeLeaf, /*tp_dealloc*/
+  0, /*tp_print*/
+  0, /*tp_getattr*/
+  0, /*tp_setattr*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*tp_compare*/
+  #else
+  0, /*reserved*/
+  #endif
+  0, /*tp_repr*/
+  &__pyx_tp_as_number_ArrayTreeLeaf, /*tp_as_number*/
+  &__pyx_tp_as_sequence_ArrayTreeLeaf, /*tp_as_sequence*/
+  &__pyx_tp_as_mapping_ArrayTreeLeaf, /*tp_as_mapping*/
+  0, /*tp_hash*/
+  0, /*tp_call*/
+  0, /*tp_str*/
+  0, /*tp_getattro*/
+  0, /*tp_setattro*/
+  &__pyx_tp_as_buffer_ArrayTreeLeaf, /*tp_as_buffer*/
+  Py_TPFLAGS_DEFAULT|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+  __Pyx_DOCSTR("\n    Leaf node of an ArrayTree, contains data values.\n    "), /*tp_doc*/
+  __pyx_tp_traverse_2bx_6arrays_10array_tree_ArrayTreeLeaf, /*tp_traverse*/
+  __pyx_tp_clear_2bx_6arrays_10array_tree_ArrayTreeLeaf, /*tp_clear*/
+  0, /*tp_richcompare*/
+  0, /*tp_weaklistoffset*/
+  0, /*tp_iter*/
+  0, /*tp_iternext*/
+  __pyx_methods_2bx_6arrays_10array_tree_ArrayTreeLeaf, /*tp_methods*/
+  0, /*tp_members*/
+  __pyx_getsets_2bx_6arrays_10array_tree_ArrayTreeLeaf, /*tp_getset*/
+  0, /*tp_base*/
+  0, /*tp_dict*/
+  0, /*tp_descr_get*/
+  0, /*tp_descr_set*/
+  0, /*tp_dictoffset*/
+  __pyx_pw_2bx_6arrays_10array_tree_13ArrayTreeLeaf_1__init__, /*tp_init*/
+  0, /*tp_alloc*/
+  __pyx_tp_new_2bx_6arrays_10array_tree_ArrayTreeLeaf, /*tp_new*/
+  0, /*tp_free*/
+  0, /*tp_is_gc*/
+  0, /*tp_bases*/
+  0, /*tp_mro*/
+  0, /*tp_cache*/
+  0, /*tp_subclasses*/
+  0, /*tp_weaklist*/
+  0, /*tp_del*/
+  #if PY_VERSION_HEX >= 0x02060000
+  0, /*tp_version_tag*/
+  #endif
+};
+
+static PyObject *__pyx_tp_new_2bx_6arrays_10array_tree_ArrayTree(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) {
+  struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTree *p;
+  PyObject *o = (*t->tp_alloc)(t, 0);
+  if (!o) return 0;
+  p = ((struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTree *)o);
+  p->dtype = Py_None; Py_INCREF(Py_None);
+  p->root = ((struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeNode *)Py_None); Py_INCREF(Py_None);
+  return o;
+}
+
+static void __pyx_tp_dealloc_2bx_6arrays_10array_tree_ArrayTree(PyObject *o) {
+  struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTree *p = (struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTree *)o;
+  PyObject_GC_UnTrack(o);
+  Py_CLEAR(p->dtype);
+  Py_CLEAR(p->root);
+  PyObject_GC_Track(o);
+  (*Py_TYPE(o)->tp_free)(o);
+}
+
+static int __pyx_tp_traverse_2bx_6arrays_10array_tree_ArrayTree(PyObject *o, visitproc v, void *a) {
+  int e;
+  struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTree *p = (struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTree *)o;
+  if (p->dtype) {
+    e = (*v)(p->dtype, a); if (e) return e;
+  }
+  if (p->root) {
+    e = (*v)(((PyObject*)p->root), a); if (e) return e;
+  }
+  return 0;
+}
+
+static int __pyx_tp_clear_2bx_6arrays_10array_tree_ArrayTree(PyObject *o) {
+  struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTree *p = (struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTree *)o;
+  PyObject* tmp;
+  tmp = ((PyObject*)p->dtype);
+  p->dtype = Py_None; Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  tmp = ((PyObject*)p->root);
+  p->root = ((struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeNode *)Py_None); Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  return 0;
+}
+static PyObject *__pyx_sq_item_2bx_6arrays_10array_tree_ArrayTree(PyObject *o, Py_ssize_t i) {
+  PyObject *r;
+  PyObject *x = PyInt_FromSsize_t(i); if(!x) return 0;
+  r = Py_TYPE(o)->tp_as_mapping->mp_subscript(o, x);
+  Py_DECREF(x);
+  return r;
+}
+
+static int __pyx_mp_ass_subscript_2bx_6arrays_10array_tree_ArrayTree(PyObject *o, PyObject *i, PyObject *v) {
+  if (v) {
+    return __pyx_pw_2bx_6arrays_10array_tree_9ArrayTree_3__setitem__(o, i, v);
+  }
+  else {
+    PyErr_Format(PyExc_NotImplementedError,
+      "Subscript deletion not supported by %s", Py_TYPE(o)->tp_name);
+    return -1;
+  }
+}
+
+static PyObject *__pyx_getprop_2bx_6arrays_10array_tree_9ArrayTree_max(PyObject *o, CYTHON_UNUSED void *x) {
+  return __pyx_pw_2bx_6arrays_10array_tree_9ArrayTree_3max_1__get__(o);
+}
+
+static int __pyx_setprop_2bx_6arrays_10array_tree_9ArrayTree_max(PyObject *o, PyObject *v, CYTHON_UNUSED void *x) {
+  if (v) {
+    return __pyx_pw_2bx_6arrays_10array_tree_9ArrayTree_3max_3__set__(o, v);
+  }
+  else {
+    PyErr_SetString(PyExc_NotImplementedError, "__del__");
+    return -1;
+  }
+}
+
+static PyObject *__pyx_getprop_2bx_6arrays_10array_tree_9ArrayTree_block_size(PyObject *o, CYTHON_UNUSED void *x) {
+  return __pyx_pw_2bx_6arrays_10array_tree_9ArrayTree_10block_size_1__get__(o);
+}
+
+static int __pyx_setprop_2bx_6arrays_10array_tree_9ArrayTree_block_size(PyObject *o, PyObject *v, CYTHON_UNUSED void *x) {
+  if (v) {
+    return __pyx_pw_2bx_6arrays_10array_tree_9ArrayTree_10block_size_3__set__(o, v);
+  }
+  else {
+    PyErr_SetString(PyExc_NotImplementedError, "__del__");
+    return -1;
+  }
+}
+
+static PyObject *__pyx_getprop_2bx_6arrays_10array_tree_9ArrayTree_dtype(PyObject *o, CYTHON_UNUSED void *x) {
+  return __pyx_pw_2bx_6arrays_10array_tree_9ArrayTree_5dtype_1__get__(o);
+}
+
+static int __pyx_setprop_2bx_6arrays_10array_tree_9ArrayTree_dtype(PyObject *o, PyObject *v, CYTHON_UNUSED void *x) {
+  if (v) {
+    return __pyx_pw_2bx_6arrays_10array_tree_9ArrayTree_5dtype_3__set__(o, v);
+  }
+  else {
+    return __pyx_pw_2bx_6arrays_10array_tree_9ArrayTree_5dtype_5__del__(o);
+  }
+}
+
+static PyObject *__pyx_getprop_2bx_6arrays_10array_tree_9ArrayTree_levels(PyObject *o, CYTHON_UNUSED void *x) {
+  return __pyx_pw_2bx_6arrays_10array_tree_9ArrayTree_6levels_1__get__(o);
+}
+
+static int __pyx_setprop_2bx_6arrays_10array_tree_9ArrayTree_levels(PyObject *o, PyObject *v, CYTHON_UNUSED void *x) {
+  if (v) {
+    return __pyx_pw_2bx_6arrays_10array_tree_9ArrayTree_6levels_3__set__(o, v);
+  }
+  else {
+    PyErr_SetString(PyExc_NotImplementedError, "__del__");
+    return -1;
+  }
+}
+
+static PyObject *__pyx_getprop_2bx_6arrays_10array_tree_9ArrayTree_no_leaves(PyObject *o, CYTHON_UNUSED void *x) {
+  return __pyx_pw_2bx_6arrays_10array_tree_9ArrayTree_9no_leaves_1__get__(o);
+}
+
+static int __pyx_setprop_2bx_6arrays_10array_tree_9ArrayTree_no_leaves(PyObject *o, PyObject *v, CYTHON_UNUSED void *x) {
+  if (v) {
+    return __pyx_pw_2bx_6arrays_10array_tree_9ArrayTree_9no_leaves_3__set__(o, v);
+  }
+  else {
+    PyErr_SetString(PyExc_NotImplementedError, "__del__");
+    return -1;
+  }
+}
+
+static PyObject *__pyx_getprop_2bx_6arrays_10array_tree_9ArrayTree_root(PyObject *o, CYTHON_UNUSED void *x) {
+  return __pyx_pw_2bx_6arrays_10array_tree_9ArrayTree_4root_1__get__(o);
+}
+
+static int __pyx_setprop_2bx_6arrays_10array_tree_9ArrayTree_root(PyObject *o, PyObject *v, CYTHON_UNUSED void *x) {
+  if (v) {
+    return __pyx_pw_2bx_6arrays_10array_tree_9ArrayTree_4root_3__set__(o, v);
+  }
+  else {
+    return __pyx_pw_2bx_6arrays_10array_tree_9ArrayTree_4root_5__del__(o);
+  }
+}
+
+static PyMethodDef __pyx_methods_2bx_6arrays_10array_tree_ArrayTree[] = {
+  {__Pyx_NAMESTR("set_range"), (PyCFunction)__pyx_pw_2bx_6arrays_10array_tree_9ArrayTree_5set_range, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(0)},
+  {__Pyx_NAMESTR("to_file"), (PyCFunction)__pyx_pw_2bx_6arrays_10array_tree_9ArrayTree_9to_file, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(0)},
+  {__Pyx_NAMESTR("from_file"), (PyCFunction)__pyx_pw_2bx_6arrays_10array_tree_9ArrayTree_11from_file, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(0)},
+  {__Pyx_NAMESTR("from_sequence"), (PyCFunction)__pyx_pw_2bx_6arrays_10array_tree_9ArrayTree_13from_sequence, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(__pyx_doc_2bx_6arrays_10array_tree_9ArrayTree_12from_sequence)},
+  {0, 0, 0, 0}
+};
+
+static struct PyGetSetDef __pyx_getsets_2bx_6arrays_10array_tree_ArrayTree[] = {
+  {(char *)"max", __pyx_getprop_2bx_6arrays_10array_tree_9ArrayTree_max, __pyx_setprop_2bx_6arrays_10array_tree_9ArrayTree_max, 0, 0},
+  {(char *)"block_size", __pyx_getprop_2bx_6arrays_10array_tree_9ArrayTree_block_size, __pyx_setprop_2bx_6arrays_10array_tree_9ArrayTree_block_size, 0, 0},
+  {(char *)"dtype", __pyx_getprop_2bx_6arrays_10array_tree_9ArrayTree_dtype, __pyx_setprop_2bx_6arrays_10array_tree_9ArrayTree_dtype, 0, 0},
+  {(char *)"levels", __pyx_getprop_2bx_6arrays_10array_tree_9ArrayTree_levels, __pyx_setprop_2bx_6arrays_10array_tree_9ArrayTree_levels, 0, 0},
+  {(char *)"no_leaves", __pyx_getprop_2bx_6arrays_10array_tree_9ArrayTree_no_leaves, __pyx_setprop_2bx_6arrays_10array_tree_9ArrayTree_no_leaves, 0, 0},
+  {(char *)"root", __pyx_getprop_2bx_6arrays_10array_tree_9ArrayTree_root, __pyx_setprop_2bx_6arrays_10array_tree_9ArrayTree_root, 0, 0},
+  {0, 0, 0, 0, 0}
+};
+
+static PyNumberMethods __pyx_tp_as_number_ArrayTree = {
+  0, /*nb_add*/
+  0, /*nb_subtract*/
+  0, /*nb_multiply*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_divide*/
+  #endif
+  0, /*nb_remainder*/
+  0, /*nb_divmod*/
+  0, /*nb_power*/
+  0, /*nb_negative*/
+  0, /*nb_positive*/
+  0, /*nb_absolute*/
+  0, /*nb_nonzero*/
+  0, /*nb_invert*/
+  0, /*nb_lshift*/
+  0, /*nb_rshift*/
+  0, /*nb_and*/
+  0, /*nb_xor*/
+  0, /*nb_or*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_coerce*/
+  #endif
+  0, /*nb_int*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_long*/
+  #else
+  0, /*reserved*/
+  #endif
+  0, /*nb_float*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_oct*/
+  #endif
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_hex*/
+  #endif
+  0, /*nb_inplace_add*/
+  0, /*nb_inplace_subtract*/
+  0, /*nb_inplace_multiply*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_inplace_divide*/
+  #endif
+  0, /*nb_inplace_remainder*/
+  0, /*nb_inplace_power*/
+  0, /*nb_inplace_lshift*/
+  0, /*nb_inplace_rshift*/
+  0, /*nb_inplace_and*/
+  0, /*nb_inplace_xor*/
+  0, /*nb_inplace_or*/
+  0, /*nb_floor_divide*/
+  0, /*nb_true_divide*/
+  0, /*nb_inplace_floor_divide*/
+  0, /*nb_inplace_true_divide*/
+  #if PY_VERSION_HEX >= 0x02050000
+  0, /*nb_index*/
+  #endif
+};
+
+static PySequenceMethods __pyx_tp_as_sequence_ArrayTree = {
+  0, /*sq_length*/
+  0, /*sq_concat*/
+  0, /*sq_repeat*/
+  __pyx_sq_item_2bx_6arrays_10array_tree_ArrayTree, /*sq_item*/
+  0, /*sq_slice*/
+  0, /*sq_ass_item*/
+  0, /*sq_ass_slice*/
+  0, /*sq_contains*/
+  0, /*sq_inplace_concat*/
+  0, /*sq_inplace_repeat*/
+};
+
+static PyMappingMethods __pyx_tp_as_mapping_ArrayTree = {
+  0, /*mp_length*/
+  __pyx_pw_2bx_6arrays_10array_tree_9ArrayTree_7__getitem__, /*mp_subscript*/
+  __pyx_mp_ass_subscript_2bx_6arrays_10array_tree_ArrayTree, /*mp_ass_subscript*/
+};
+
+static PyBufferProcs __pyx_tp_as_buffer_ArrayTree = {
+  #if PY_MAJOR_VERSION < 3
+  0, /*bf_getreadbuffer*/
+  #endif
+  #if PY_MAJOR_VERSION < 3
+  0, /*bf_getwritebuffer*/
+  #endif
+  #if PY_MAJOR_VERSION < 3
+  0, /*bf_getsegcount*/
+  #endif
+  #if PY_MAJOR_VERSION < 3
+  0, /*bf_getcharbuffer*/
+  #endif
+  #if PY_VERSION_HEX >= 0x02060000
+  0, /*bf_getbuffer*/
+  #endif
+  #if PY_VERSION_HEX >= 0x02060000
+  0, /*bf_releasebuffer*/
+  #endif
+};
+
+static PyTypeObject __pyx_type_2bx_6arrays_10array_tree_ArrayTree = {
+  PyVarObject_HEAD_INIT(0, 0)
+  __Pyx_NAMESTR("bx.arrays.array_tree.ArrayTree"), /*tp_name*/
+  sizeof(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTree), /*tp_basicsize*/
+  0, /*tp_itemsize*/
+  __pyx_tp_dealloc_2bx_6arrays_10array_tree_ArrayTree, /*tp_dealloc*/
+  0, /*tp_print*/
+  0, /*tp_getattr*/
+  0, /*tp_setattr*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*tp_compare*/
+  #else
+  0, /*reserved*/
+  #endif
+  0, /*tp_repr*/
+  &__pyx_tp_as_number_ArrayTree, /*tp_as_number*/
+  &__pyx_tp_as_sequence_ArrayTree, /*tp_as_sequence*/
+  &__pyx_tp_as_mapping_ArrayTree, /*tp_as_mapping*/
+  0, /*tp_hash*/
+  0, /*tp_call*/
+  0, /*tp_str*/
+  0, /*tp_getattro*/
+  0, /*tp_setattro*/
+  &__pyx_tp_as_buffer_ArrayTree, /*tp_as_buffer*/
+  Py_TPFLAGS_DEFAULT|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+  __Pyx_DOCSTR("\n    Stores a sparse array of data as a tree.\n    \n    An array of `self.max` values is stored in a tree in which each leaf\n    contains `self.block_size` values and each internal node contains\n    `self.block_size` children.\n    \n    Entirely empty subtrees are not stored. Thus, the storage is efficient for\n    data that is block sparse -- having contiguous chunks of `self.block_size` or\n    larger data. Currently it is not efficient if the data is strided (e.g. [...]
+  __pyx_tp_traverse_2bx_6arrays_10array_tree_ArrayTree, /*tp_traverse*/
+  __pyx_tp_clear_2bx_6arrays_10array_tree_ArrayTree, /*tp_clear*/
+  0, /*tp_richcompare*/
+  0, /*tp_weaklistoffset*/
+  0, /*tp_iter*/
+  0, /*tp_iternext*/
+  __pyx_methods_2bx_6arrays_10array_tree_ArrayTree, /*tp_methods*/
+  0, /*tp_members*/
+  __pyx_getsets_2bx_6arrays_10array_tree_ArrayTree, /*tp_getset*/
+  0, /*tp_base*/
+  0, /*tp_dict*/
+  0, /*tp_descr_get*/
+  0, /*tp_descr_set*/
+  0, /*tp_dictoffset*/
+  __pyx_pw_2bx_6arrays_10array_tree_9ArrayTree_1__init__, /*tp_init*/
+  0, /*tp_alloc*/
+  __pyx_tp_new_2bx_6arrays_10array_tree_ArrayTree, /*tp_new*/
+  0, /*tp_free*/
+  0, /*tp_is_gc*/
+  0, /*tp_bases*/
+  0, /*tp_mro*/
+  0, /*tp_cache*/
+  0, /*tp_subclasses*/
+  0, /*tp_weaklist*/
+  0, /*tp_del*/
+  #if PY_VERSION_HEX >= 0x02060000
+  0, /*tp_version_tag*/
+  #endif
+};
+
+static PyMethodDef __pyx_methods[] = {
+  {0, 0, 0, 0}
+};
+
+static char* __pyx_import_star_type_names[] = {
+  "ArrayTreeNode",
+  "FileArrayTree",
+  "FileArrayTreeDict",
+  "ArrayTreeLeaf",
+  "Summary",
+  "ArrayTree",
+  0
+};
+
+static int __pyx_import_star_set(PyObject *o, PyObject* py_name, char *name) {
+  char** type_name = __pyx_import_star_type_names;
+  while (*type_name) {
+    if (__Pyx_StrEq(name, *type_name)) {
+      PyErr_Format(PyExc_TypeError, "Cannot overwrite C type %s", name);
+      goto bad;
+    }
+    type_name++;
+  }
+  if (0);
+  else {
+    if (PyObject_SetAttr(__pyx_m, py_name, o) < 0) goto bad;
+  }
+  return 0;
+  bad:
+  return -1;
+}
+
+
+/* import_all_from is an unexposed function from ceval.c */
+
+static int
+__Pyx_import_all_from(PyObject *locals, PyObject *v)
+{
+    PyObject *all = __Pyx_GetAttrString(v, "__all__");
+    PyObject *dict, *name, *value;
+    int skip_leading_underscores = 0;
+    int pos, err;
+
+    if (all == NULL) {
+        if (!PyErr_ExceptionMatches(PyExc_AttributeError))
+            return -1; /* Unexpected error */
+        PyErr_Clear();
+        dict = __Pyx_GetAttrString(v, "__dict__");
+        if (dict == NULL) {
+            if (!PyErr_ExceptionMatches(PyExc_AttributeError))
+                return -1;
+            PyErr_SetString(PyExc_ImportError,
+            "from-import-* object has no __dict__ and no __all__");
+            return -1;
+        }
+#if PY_MAJOR_VERSION < 3
+        all = PyObject_CallMethod(dict, (char *)"keys", NULL);
+#else
+        all = PyMapping_Keys(dict);
+#endif
+        Py_DECREF(dict);
+        if (all == NULL)
+            return -1;
+        skip_leading_underscores = 1;
+    }
+
+    for (pos = 0, err = 0; ; pos++) {
+        name = PySequence_GetItem(all, pos);
+        if (name == NULL) {
+            if (!PyErr_ExceptionMatches(PyExc_IndexError))
+                err = -1;
+            else
+                PyErr_Clear();
+            break;
+        }
+        if (skip_leading_underscores &&
+#if PY_MAJOR_VERSION < 3
+            PyString_Check(name) &&
+            PyString_AS_STRING(name)[0] == '_')
+#else
+            PyUnicode_Check(name) &&
+            PyUnicode_AS_UNICODE(name)[0] == '_')
+#endif
+        {
+            Py_DECREF(name);
+            continue;
+        }
+        value = PyObject_GetAttr(v, name);
+        if (value == NULL)
+            err = -1;
+        else if (PyDict_CheckExact(locals))
+            err = PyDict_SetItem(locals, name, value);
+        else
+            err = PyObject_SetItem(locals, name, value);
+        Py_DECREF(name);
+        Py_XDECREF(value);
+        if (err != 0)
+            break;
+    }
+    Py_DECREF(all);
+    return err;
+}
+
+
+static int __pyx_import_star(PyObject* m) {
+
+    int i;
+    int ret = -1;
+    char* s;
+    PyObject *locals = 0;
+    PyObject *list = 0;
+#if PY_MAJOR_VERSION >= 3
+    PyObject *utf8_name = 0;
+#endif
+    PyObject *name;
+    PyObject *item;
+
+    locals = PyDict_New();              if (!locals) goto bad;
+    if (__Pyx_import_all_from(locals, m) < 0) goto bad;
+    list = PyDict_Items(locals);        if (!list) goto bad;
+
+    for(i=0; i<PyList_GET_SIZE(list); i++) {
+        name = PyTuple_GET_ITEM(PyList_GET_ITEM(list, i), 0);
+        item = PyTuple_GET_ITEM(PyList_GET_ITEM(list, i), 1);
+#if PY_MAJOR_VERSION >= 3
+        utf8_name = PyUnicode_AsUTF8String(name);
+        if (!utf8_name) goto bad;
+        s = PyBytes_AS_STRING(utf8_name);
+        if (__pyx_import_star_set(item, name, s) < 0) goto bad;
+        Py_DECREF(utf8_name); utf8_name = 0;
+#else
+        s = PyString_AsString(name);
+        if (!s) goto bad;
+        if (__pyx_import_star_set(item, name, s) < 0) goto bad;
+#endif
+    }
+    ret = 0;
+
+bad:
+    Py_XDECREF(locals);
+    Py_XDECREF(list);
+#if PY_MAJOR_VERSION >= 3
+    Py_XDECREF(utf8_name);
+#endif
+    return ret;
+}
+
+
+#if PY_MAJOR_VERSION >= 3
+static struct PyModuleDef __pyx_moduledef = {
+  #if PY_VERSION_HEX < 0x03020000
+    { PyObject_HEAD_INIT(NULL) NULL, 0, NULL },
+  #else
+    PyModuleDef_HEAD_INIT,
+  #endif
+    __Pyx_NAMESTR("array_tree"),
+    0, /* m_doc */
+    -1, /* m_size */
+    __pyx_methods /* m_methods */,
+    NULL, /* m_reload */
+    NULL, /* m_traverse */
+    NULL, /* m_clear */
+    NULL /* m_free */
+};
+#endif
+
+static __Pyx_StringTabEntry __pyx_string_tab[] = {
+  {&__pyx_kp_s_14, __pyx_k_14, sizeof(__pyx_k_14), 0, 0, 1, 0},
+  {&__pyx_kp_s_19, __pyx_k_19, sizeof(__pyx_k_19), 0, 0, 1, 0},
+  {&__pyx_kp_u_21, __pyx_k_21, sizeof(__pyx_k_21), 0, 1, 0, 0},
+  {&__pyx_kp_u_23, __pyx_k_23, sizeof(__pyx_k_23), 0, 1, 0, 0},
+  {&__pyx_kp_u_25, __pyx_k_25, sizeof(__pyx_k_25), 0, 1, 0, 0},
+  {&__pyx_kp_u_27, __pyx_k_27, sizeof(__pyx_k_27), 0, 1, 0, 0},
+  {&__pyx_kp_u_28, __pyx_k_28, sizeof(__pyx_k_28), 0, 1, 0, 0},
+  {&__pyx_kp_u_31, __pyx_k_31, sizeof(__pyx_k_31), 0, 1, 0, 0},
+  {&__pyx_n_s_33, __pyx_k_33, sizeof(__pyx_k_33), 0, 0, 1, 1},
+  {&__pyx_n_s_34, __pyx_k_34, sizeof(__pyx_k_34), 0, 0, 1, 1},
+  {&__pyx_n_s_35, __pyx_k_35, sizeof(__pyx_k_35), 0, 0, 1, 1},
+  {&__pyx_n_s_36, __pyx_k_36, sizeof(__pyx_k_36), 0, 0, 1, 1},
+  {&__pyx_kp_s_39, __pyx_k_39, sizeof(__pyx_k_39), 0, 0, 1, 0},
+  {&__pyx_n_s_40, __pyx_k_40, sizeof(__pyx_k_40), 0, 0, 1, 1},
+  {&__pyx_kp_s_8, __pyx_k_8, sizeof(__pyx_k_8), 0, 0, 1, 0},
+  {&__pyx_kp_s_9, __pyx_k_9, sizeof(__pyx_k_9), 0, 0, 1, 0},
+  {&__pyx_n_s__ArrayTree, __pyx_k__ArrayTree, sizeof(__pyx_k__ArrayTree), 0, 0, 1, 1},
+  {&__pyx_n_s__BinaryFileReader, __pyx_k__BinaryFileReader, sizeof(__pyx_k__BinaryFileReader), 0, 0, 1, 1},
+  {&__pyx_n_s__BinaryFileWriter, __pyx_k__BinaryFileWriter, sizeof(__pyx_k__BinaryFileWriter), 0, 0, 1, 1},
+  {&__pyx_n_s__FileArrayTreeDict, __pyx_k__FileArrayTreeDict, sizeof(__pyx_k__FileArrayTreeDict), 0, 0, 1, 1},
+  {&__pyx_n_s__FileCDBDict, __pyx_k__FileCDBDict, sizeof(__pyx_k__FileCDBDict), 0, 0, 1, 1},
+  {&__pyx_n_s__L, __pyx_k__L, sizeof(__pyx_k__L), 0, 0, 1, 1},
+  {&__pyx_n_s__MAGIC, __pyx_k__MAGIC, sizeof(__pyx_k__MAGIC), 0, 0, 1, 1},
+  {&__pyx_n_s__NUM_SUMMARY_ARRAYS, __pyx_k__NUM_SUMMARY_ARRAYS, sizeof(__pyx_k__NUM_SUMMARY_ARRAYS), 0, 0, 1, 1},
+  {&__pyx_n_s__RuntimeError, __pyx_k__RuntimeError, sizeof(__pyx_k__RuntimeError), 0, 0, 1, 1},
+  {&__pyx_n_s__VERSION, __pyx_k__VERSION, sizeof(__pyx_k__VERSION), 0, 0, 1, 1},
+  {&__pyx_n_s__ValueError, __pyx_k__ValueError, sizeof(__pyx_k__ValueError), 0, 0, 1, 1},
+  {&__pyx_n_s___, __pyx_k___, sizeof(__pyx_k___), 0, 0, 1, 1},
+  {&__pyx_n_s____all__, __pyx_k____all__, sizeof(__pyx_k____all__), 0, 0, 1, 1},
+  {&__pyx_n_s____main__, __pyx_k____main__, sizeof(__pyx_k____main__), 0, 0, 1, 1},
+  {&__pyx_n_s____test__, __pyx_k____test__, sizeof(__pyx_k____test__), 0, 0, 1, 1},
+  {&__pyx_n_s__block_size, __pyx_k__block_size, sizeof(__pyx_k__block_size), 0, 0, 1, 1},
+  {&__pyx_n_s__build_summary, __pyx_k__build_summary, sizeof(__pyx_k__build_summary), 0, 0, 1, 1},
+  {&__pyx_n_s__char, __pyx_k__char, sizeof(__pyx_k__char), 0, 0, 1, 1},
+  {&__pyx_n_s__chrom, __pyx_k__chrom, sizeof(__pyx_k__chrom), 0, 0, 1, 1},
+  {&__pyx_n_s__counts, __pyx_k__counts, sizeof(__pyx_k__counts), 0, 0, 1, 1},
+  {&__pyx_n_s__default_size, __pyx_k__default_size, sizeof(__pyx_k__default_size), 0, 0, 1, 1},
+  {&__pyx_n_s__dict, __pyx_k__dict, sizeof(__pyx_k__dict), 0, 0, 1, 1},
+  {&__pyx_n_s__dict_to_file, __pyx_k__dict_to_file, sizeof(__pyx_k__dict_to_file), 0, 0, 1, 1},
+  {&__pyx_n_s__dtype, __pyx_k__dtype, sizeof(__pyx_k__dtype), 0, 0, 1, 1},
+  {&__pyx_n_s__empty, __pyx_k__empty, sizeof(__pyx_k__empty), 0, 0, 1, 1},
+  {&__pyx_n_s__end, __pyx_k__end, sizeof(__pyx_k__end), 0, 0, 1, 1},
+  {&__pyx_n_s__f, __pyx_k__f, sizeof(__pyx_k__f), 0, 0, 1, 1},
+  {&__pyx_n_s__file, __pyx_k__file, sizeof(__pyx_k__file), 0, 0, 1, 1},
+  {&__pyx_n_s__float32, __pyx_k__float32, sizeof(__pyx_k__float32), 0, 0, 1, 1},
+  {&__pyx_n_s__frequencies, __pyx_k__frequencies, sizeof(__pyx_k__frequencies), 0, 0, 1, 1},
+  {&__pyx_n_s__frequency, __pyx_k__frequency, sizeof(__pyx_k__frequency), 0, 0, 1, 1},
+  {&__pyx_n_s__from_file, __pyx_k__from_file, sizeof(__pyx_k__from_file), 0, 0, 1, 1},
+  {&__pyx_n_s__from_sequence, __pyx_k__from_sequence, sizeof(__pyx_k__from_sequence), 0, 0, 1, 1},
+  {&__pyx_n_s__get, __pyx_k__get, sizeof(__pyx_k__get), 0, 0, 1, 1},
+  {&__pyx_n_s__index, __pyx_k__index, sizeof(__pyx_k__index), 0, 0, 1, 1},
+  {&__pyx_n_s__int32, __pyx_k__int32, sizeof(__pyx_k__int32), 0, 0, 1, 1},
+  {&__pyx_n_s__io, __pyx_k__io, sizeof(__pyx_k__io), 0, 0, 1, 1},
+  {&__pyx_n_s__is_little_endian, __pyx_k__is_little_endian, sizeof(__pyx_k__is_little_endian), 0, 0, 1, 1},
+  {&__pyx_n_s__isnan, __pyx_k__isnan, sizeof(__pyx_k__isnan), 0, 0, 1, 1},
+  {&__pyx_n_s__itemsize, __pyx_k__itemsize, sizeof(__pyx_k__itemsize), 0, 0, 1, 1},
+  {&__pyx_n_s__iteritems, __pyx_k__iteritems, sizeof(__pyx_k__iteritems), 0, 0, 1, 1},
+  {&__pyx_n_s__iterkeys, __pyx_k__iterkeys, sizeof(__pyx_k__iterkeys), 0, 0, 1, 1},
+  {&__pyx_n_s__last_array_tree, __pyx_k__last_array_tree, sizeof(__pyx_k__last_array_tree), 0, 0, 1, 1},
+  {&__pyx_n_s__last_chrom, __pyx_k__last_chrom, sizeof(__pyx_k__last_chrom), 0, 0, 1, 1},
+  {&__pyx_n_s__level, __pyx_k__level, sizeof(__pyx_k__level), 0, 0, 1, 1},
+  {&__pyx_n_s__max, __pyx_k__max, sizeof(__pyx_k__max), 0, 0, 1, 1},
+  {&__pyx_n_s__maxs, __pyx_k__maxs, sizeof(__pyx_k__maxs), 0, 0, 1, 1},
+  {&__pyx_n_s__min, __pyx_k__min, sizeof(__pyx_k__min), 0, 0, 1, 1},
+  {&__pyx_n_s__mins, __pyx_k__mins, sizeof(__pyx_k__mins), 0, 0, 1, 1},
+  {&__pyx_n_s__nan, __pyx_k__nan, sizeof(__pyx_k__nan), 0, 0, 1, 1},
+  {&__pyx_n_s__nanmax, __pyx_k__nanmax, sizeof(__pyx_k__nanmax), 0, 0, 1, 1},
+  {&__pyx_n_s__nanmin, __pyx_k__nanmin, sizeof(__pyx_k__nanmin), 0, 0, 1, 1},
+  {&__pyx_n_s__nansum, __pyx_k__nansum, sizeof(__pyx_k__nansum), 0, 0, 1, 1},
+  {&__pyx_n_s__no_leaves, __pyx_k__no_leaves, sizeof(__pyx_k__no_leaves), 0, 0, 1, 1},
+  {&__pyx_n_s__numpy, __pyx_k__numpy, sizeof(__pyx_k__numpy), 0, 0, 1, 1},
+  {&__pyx_n_s__pack, __pyx_k__pack, sizeof(__pyx_k__pack), 0, 0, 1, 1},
+  {&__pyx_n_s__range, __pyx_k__range, sizeof(__pyx_k__range), 0, 0, 1, 1},
+  {&__pyx_n_s__read, __pyx_k__read, sizeof(__pyx_k__read), 0, 0, 1, 1},
+  {&__pyx_n_s__read_raw_array, __pyx_k__read_raw_array, sizeof(__pyx_k__read_raw_array), 0, 0, 1, 1},
+  {&__pyx_n_s__read_uint32, __pyx_k__read_uint32, sizeof(__pyx_k__read_uint32), 0, 0, 1, 1},
+  {&__pyx_n_s__read_uint64, __pyx_k__read_uint64, sizeof(__pyx_k__read_uint64), 0, 0, 1, 1},
+  {&__pyx_n_s__reader, __pyx_k__reader, sizeof(__pyx_k__reader), 0, 0, 1, 1},
+  {&__pyx_n_s__root, __pyx_k__root, sizeof(__pyx_k__root), 0, 0, 1, 1},
+  {&__pyx_n_s__rval, __pyx_k__rval, sizeof(__pyx_k__rval), 0, 0, 1, 1},
+  {&__pyx_n_s__s, __pyx_k__s, sizeof(__pyx_k__s), 0, 0, 1, 1},
+  {&__pyx_n_s__seek, __pyx_k__seek, sizeof(__pyx_k__seek), 0, 0, 1, 1},
+  {&__pyx_n_s__set, __pyx_k__set, sizeof(__pyx_k__set), 0, 0, 1, 1},
+  {&__pyx_n_s__set_range, __pyx_k__set_range, sizeof(__pyx_k__set_range), 0, 0, 1, 1},
+  {&__pyx_n_s__sizes, __pyx_k__sizes, sizeof(__pyx_k__sizes), 0, 0, 1, 1},
+  {&__pyx_n_s__skip, __pyx_k__skip, sizeof(__pyx_k__skip), 0, 0, 1, 1},
+  {&__pyx_n_s__start, __pyx_k__start, sizeof(__pyx_k__start), 0, 0, 1, 1},
+  {&__pyx_n_s__start_offset, __pyx_k__start_offset, sizeof(__pyx_k__start_offset), 0, 0, 1, 1},
+  {&__pyx_n_s__sum, __pyx_k__sum, sizeof(__pyx_k__sum), 0, 0, 1, 1},
+  {&__pyx_n_s__summary, __pyx_k__summary, sizeof(__pyx_k__summary), 0, 0, 1, 1},
+  {&__pyx_n_s__sums, __pyx_k__sums, sizeof(__pyx_k__sums), 0, 0, 1, 1},
+  {&__pyx_n_s__sumsquares, __pyx_k__sumsquares, sizeof(__pyx_k__sumsquares), 0, 0, 1, 1},
+  {&__pyx_n_s__tell, __pyx_k__tell, sizeof(__pyx_k__tell), 0, 0, 1, 1},
+  {&__pyx_n_s__to_file, __pyx_k__to_file, sizeof(__pyx_k__to_file), 0, 0, 1, 1},
+  {&__pyx_n_s__to_file_data_pass, __pyx_k__to_file_data_pass, sizeof(__pyx_k__to_file_data_pass), 0, 0, 1, 1},
+  {&__pyx_n_s__to_file_offset_pass, __pyx_k__to_file_offset_pass, sizeof(__pyx_k__to_file_offset_pass), 0, 0, 1, 1},
+  {&__pyx_n_s__tree, __pyx_k__tree, sizeof(__pyx_k__tree), 0, 0, 1, 1},
+  {&__pyx_n_s__unpack, __pyx_k__unpack, sizeof(__pyx_k__unpack), 0, 0, 1, 1},
+  {&__pyx_n_s__val, __pyx_k__val, sizeof(__pyx_k__val), 0, 0, 1, 1},
+  {&__pyx_n_s__value, __pyx_k__value, sizeof(__pyx_k__value), 0, 0, 1, 1},
+  {&__pyx_n_s__values, __pyx_k__values, sizeof(__pyx_k__values), 0, 0, 1, 1},
+  {&__pyx_n_s__write, __pyx_k__write, sizeof(__pyx_k__write), 0, 0, 1, 1},
+  {&__pyx_n_s__write_raw_array, __pyx_k__write_raw_array, sizeof(__pyx_k__write_raw_array), 0, 0, 1, 1},
+  {&__pyx_n_s__write_uint32, __pyx_k__write_uint32, sizeof(__pyx_k__write_uint32), 0, 0, 1, 1},
+  {&__pyx_n_s__write_uint64, __pyx_k__write_uint64, sizeof(__pyx_k__write_uint64), 0, 0, 1, 1},
+  {0, 0, 0, 0, 0, 0, 0}
+};
+static int __Pyx_InitCachedBuiltins(void) {
+  __pyx_builtin_ValueError = __Pyx_GetName(__pyx_b, __pyx_n_s__ValueError); if (!__pyx_builtin_ValueError) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 160; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_builtin_range = __Pyx_GetName(__pyx_b, __pyx_n_s__range); if (!__pyx_builtin_range) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 281; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_builtin_sum = __Pyx_GetName(__pyx_b, __pyx_n_s__sum); if (!__pyx_builtin_sum) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 372; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_builtin_RuntimeError = __Pyx_GetName(__pyx_b, __pyx_n_s__RuntimeError); if (!__pyx_builtin_RuntimeError) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  return 0;
+  __pyx_L1_error:;
+  return -1;
+}
+
+static int __Pyx_InitCachedConstants(void) {
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0);
+
+  /* "bx/arrays/array_tree.pyx":108
+ *         cdb_dict = {}
+ *         for key in dict.iterkeys():
+ *             cdb_dict[ key ] = io.pack( "L", 0 )             # <<<<<<<<<<<<<<
+ *         cdb_offset = io.tell()
+ *         FileCDBDict.to_file( cdb_dict, file, is_little_endian=is_little_endian )
+ */
+  __pyx_k_tuple_4 = PyTuple_Pack(2, ((PyObject *)__pyx_n_s__L), __pyx_int_0); if (unlikely(!__pyx_k_tuple_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_k_tuple_4);
+  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_4));
+
+  /* "bx/arrays/array_tree.pyx":139
+ *         self.block_size = self.io.read_uint32()
+ *         # Read dtype and canonicalize
+ *         dt = self.io.read( 1 )             # <<<<<<<<<<<<<<
+ *         self.dtype = numpy.dtype( dt )
+ *         self.io.skip( 3 )
+ */
+  __pyx_k_tuple_6 = PyTuple_Pack(1, __pyx_int_1); if (unlikely(!__pyx_k_tuple_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 139; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_k_tuple_6);
+  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_6));
+
+  /* "bx/arrays/array_tree.pyx":141
+ *         dt = self.io.read( 1 )
+ *         self.dtype = numpy.dtype( dt )
+ *         self.io.skip( 3 )             # <<<<<<<<<<<<<<
+ *         # How many levels are needed to cover the entire range?
+ *         self.levels = 0
+ */
+  __pyx_k_tuple_7 = PyTuple_Pack(1, __pyx_int_3); if (unlikely(!__pyx_k_tuple_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_k_tuple_7);
+  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_7));
+
+  /* "bx/arrays/array_tree.pyx":275
+ *         io.write_uint32( self.block_size )
+ *         io.write( self.dtype.char )
+ *         io.write( "\0\0\0" )             # <<<<<<<<<<<<<<
+ *         # Data pass, level order
+ *         if no_leaves:
+ */
+  __pyx_k_tuple_15 = PyTuple_Pack(1, ((PyObject *)__pyx_kp_s_14)); if (unlikely(!__pyx_k_tuple_15)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 275; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_k_tuple_15);
+  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_15));
+
+  /* "bx/arrays/array_tree.pyx":292
+ *         max = io.read_uint32()
+ *         block_size = io.read_uint32()
+ *         dt = io.read( 1 )             # <<<<<<<<<<<<<<
+ *         io.read( 3 )
+ *         tree = Class( max, block_size, dt )
+ */
+  __pyx_k_tuple_17 = PyTuple_Pack(1, __pyx_int_1); if (unlikely(!__pyx_k_tuple_17)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 292; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_k_tuple_17);
+  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_17));
+
+  /* "bx/arrays/array_tree.pyx":293
+ *         block_size = io.read_uint32()
+ *         dt = io.read( 1 )
+ *         io.read( 3 )             # <<<<<<<<<<<<<<
+ *         tree = Class( max, block_size, dt )
+ *         tree.root.from_file( io )
+ */
+  __pyx_k_tuple_18 = PyTuple_Pack(1, __pyx_int_3); if (unlikely(!__pyx_k_tuple_18)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 293; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_k_tuple_18);
+  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_18));
+
+  /* "bx/arrays/array_tree.pyx":439
+ *         for child in self.children:
+ *             if child is None:
+ *                 io.write_uint64( 0 )             # <<<<<<<<<<<<<<
+ *             else:
+ *                 io.write_uint64( child.start_offset )
+ */
+  __pyx_k_tuple_20 = PyTuple_Pack(1, __pyx_int_0); if (unlikely(!__pyx_k_tuple_20)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 439; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_k_tuple_20);
+  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_20));
+
+  /* "numpy.pxd":215
+ *             if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)
+ *                 and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)):
+ *                 raise ValueError(u"ndarray is not C contiguous")             # <<<<<<<<<<<<<<
+ * 
+ *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
+ */
+  __pyx_k_tuple_22 = PyTuple_Pack(1, ((PyObject *)__pyx_kp_u_21)); if (unlikely(!__pyx_k_tuple_22)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 215; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_k_tuple_22);
+  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_22));
+
+  /* "numpy.pxd":219
+ *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
+ *                 and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)):
+ *                 raise ValueError(u"ndarray is not Fortran contiguous")             # <<<<<<<<<<<<<<
+ * 
+ *             info.buf = PyArray_DATA(self)
+ */
+  __pyx_k_tuple_24 = PyTuple_Pack(1, ((PyObject *)__pyx_kp_u_23)); if (unlikely(!__pyx_k_tuple_24)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 219; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_k_tuple_24);
+  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_24));
+
+  /* "numpy.pxd":257
+ *                 if ((descr.byteorder == c'>' and little_endian) or
+ *                     (descr.byteorder == c'<' and not little_endian)):
+ *                     raise ValueError(u"Non-native byte order not supported")             # <<<<<<<<<<<<<<
+ *                 if   t == NPY_BYTE:        f = "b"
+ *                 elif t == NPY_UBYTE:       f = "B"
+ */
+  __pyx_k_tuple_26 = PyTuple_Pack(1, ((PyObject *)__pyx_kp_u_25)); if (unlikely(!__pyx_k_tuple_26)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_k_tuple_26);
+  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_26));
+
+  /* "numpy.pxd":799
+ * 
+ *         if (end - f) - (new_offset - offset[0]) < 15:
+ *             raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd")             # <<<<<<<<<<<<<<
+ * 
+ *         if ((child.byteorder == c'>' and little_endian) or
+ */
+  __pyx_k_tuple_29 = PyTuple_Pack(1, ((PyObject *)__pyx_kp_u_28)); if (unlikely(!__pyx_k_tuple_29)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_k_tuple_29);
+  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_29));
+
+  /* "numpy.pxd":803
+ *         if ((child.byteorder == c'>' and little_endian) or
+ *             (child.byteorder == c'<' and not little_endian)):
+ *             raise ValueError(u"Non-native byte order not supported")             # <<<<<<<<<<<<<<
+ *             # One could encode it in the format string and have Cython
+ *             # complain instead, BUT: < and > in format strings also imply
+ */
+  __pyx_k_tuple_30 = PyTuple_Pack(1, ((PyObject *)__pyx_kp_u_25)); if (unlikely(!__pyx_k_tuple_30)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 803; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_k_tuple_30);
+  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_30));
+
+  /* "numpy.pxd":823
+ *             t = child.type_num
+ *             if end - f < 5:
+ *                 raise RuntimeError(u"Format string allocated too short.")             # <<<<<<<<<<<<<<
+ * 
+ *             # Until ticket #99 is fixed, use integers to avoid warnings
+ */
+  __pyx_k_tuple_32 = PyTuple_Pack(1, ((PyObject *)__pyx_kp_u_31)); if (unlikely(!__pyx_k_tuple_32)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 823; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_k_tuple_32);
+  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_32));
+
+  /* "bx/arrays/array_tree.pyx":62
+ * NUM_SUMMARY_ARRAYS = 6
+ * 
+ * def array_tree_dict_from_reader( reader, sizes, default_size=2147483647, block_size=1000, no_leaves=False ):             # <<<<<<<<<<<<<<
+ *     # Create empty array trees
+ *     rval = {}
+ */
+  __pyx_k_tuple_37 = PyTuple_Pack(13, ((PyObject *)__pyx_n_s__reader), ((PyObject *)__pyx_n_s__sizes), ((PyObject *)__pyx_n_s__default_size), ((PyObject *)__pyx_n_s__block_size), ((PyObject *)__pyx_n_s__no_leaves), ((PyObject *)__pyx_n_s__rval), ((PyObject *)__pyx_n_s__last_chrom), ((PyObject *)__pyx_n_s__last_array_tree), ((PyObject *)__pyx_n_s__chrom), ((PyObject *)__pyx_n_s__start), ((PyObject *)__pyx_n_s__end), ((PyObject *)__pyx_n_s___), ((PyObject *)__pyx_n_s__val)); if (unlikely(! [...]
+  __Pyx_GOTREF(__pyx_k_tuple_37);
+  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_37));
+  __pyx_k_codeobj_38 = (PyObject*)__Pyx_PyCode_New(5, 0, 13, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_k_tuple_37, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_39, __pyx_n_s_33, 62, __pyx_empty_bytes); if (unlikely(!__pyx_k_codeobj_38)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 62; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_RefNannyFinishContext();
+  return 0;
+  __pyx_L1_error:;
+  __Pyx_RefNannyFinishContext();
+  return -1;
+}
+
+static int __Pyx_InitGlobals(void) {
+  if (__Pyx_InitStrings(__pyx_string_tab) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  __pyx_int_0 = PyInt_FromLong(0); if (unlikely(!__pyx_int_0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  __pyx_int_1 = PyInt_FromLong(1); if (unlikely(!__pyx_int_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  __pyx_int_2 = PyInt_FromLong(2); if (unlikely(!__pyx_int_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  __pyx_int_3 = PyInt_FromLong(3); if (unlikely(!__pyx_int_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  __pyx_int_6 = PyInt_FromLong(6); if (unlikely(!__pyx_int_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  __pyx_int_15 = PyInt_FromLong(15); if (unlikely(!__pyx_int_15)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  __pyx_int_1000 = PyInt_FromLong(1000); if (unlikely(!__pyx_int_1000)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  __pyx_int_823052252 = PyInt_FromLong(823052252); if (unlikely(!__pyx_int_823052252)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  __pyx_int_2147483647 = PyInt_FromLong(2147483647); if (unlikely(!__pyx_int_2147483647)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  return 0;
+  __pyx_L1_error:;
+  return -1;
+}
+
+#if PY_MAJOR_VERSION < 3
+PyMODINIT_FUNC initarray_tree(void); /*proto*/
+PyMODINIT_FUNC initarray_tree(void)
+#else
+PyMODINIT_FUNC PyInit_array_tree(void); /*proto*/
+PyMODINIT_FUNC PyInit_array_tree(void)
+#endif
+{
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  __Pyx_RefNannyDeclarations
+  #if CYTHON_REFNANNY
+  __Pyx_RefNanny = __Pyx_RefNannyImportAPI("refnanny");
+  if (!__Pyx_RefNanny) {
+      PyErr_Clear();
+      __Pyx_RefNanny = __Pyx_RefNannyImportAPI("Cython.Runtime.refnanny");
+      if (!__Pyx_RefNanny)
+          Py_FatalError("failed to import 'refnanny' module");
+  }
+  #endif
+  __Pyx_RefNannySetupContext("PyMODINIT_FUNC PyInit_array_tree(void)", 0);
+  if ( __Pyx_check_binary_version() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_bytes)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #ifdef __Pyx_CyFunction_USED
+  if (__Pyx_CyFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #endif
+  #ifdef __Pyx_FusedFunction_USED
+  if (__pyx_FusedFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #endif
+  #ifdef __Pyx_Generator_USED
+  if (__pyx_Generator_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #endif
+  /*--- Library function declarations ---*/
+  /*--- Threads initialization code ---*/
+  #if defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS
+  #ifdef WITH_THREAD /* Python build with threading support? */
+  PyEval_InitThreads();
+  #endif
+  #endif
+  /*--- Module creation code ---*/
+  #if PY_MAJOR_VERSION < 3
+  __pyx_m = Py_InitModule4(__Pyx_NAMESTR("array_tree"), __pyx_methods, 0, 0, PYTHON_API_VERSION); Py_XINCREF(__pyx_m);
+  #else
+  __pyx_m = PyModule_Create(&__pyx_moduledef);
+  #endif
+  if (unlikely(!__pyx_m)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #if PY_MAJOR_VERSION >= 3
+  {
+    PyObject *modules = PyImport_GetModuleDict(); if (unlikely(!modules)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (!PyDict_GetItemString(modules, "bx.arrays.array_tree")) {
+      if (unlikely(PyDict_SetItemString(modules, "bx.arrays.array_tree", __pyx_m) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+  }
+  #endif
+  __pyx_b = PyImport_AddModule(__Pyx_NAMESTR(__Pyx_BUILTIN_MODULE_NAME)); if (unlikely(!__pyx_b)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #if CYTHON_COMPILING_IN_PYPY
+  Py_INCREF(__pyx_b);
+  #endif
+  if (__Pyx_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  /*--- Initialize various global constants etc. ---*/
+  if (unlikely(__Pyx_InitGlobals() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (__pyx_module_is_main_bx__arrays__array_tree) {
+    if (__Pyx_SetAttrString(__pyx_m, "__name__", __pyx_n_s____main__) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  }
+  /*--- Builtin init code ---*/
+  if (unlikely(__Pyx_InitCachedBuiltins() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  /*--- Constants init code ---*/
+  if (unlikely(__Pyx_InitCachedConstants() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  /*--- Global init code ---*/
+  /*--- Variable export code ---*/
+  /*--- Function export code ---*/
+  /*--- Type init code ---*/
+  if (PyType_Ready(&__pyx_type_2bx_6arrays_10array_tree_FileArrayTreeDict) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 79; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (__Pyx_SetAttrString(__pyx_m, "FileArrayTreeDict", (PyObject *)&__pyx_type_2bx_6arrays_10array_tree_FileArrayTreeDict) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 79; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_2bx_6arrays_10array_tree_FileArrayTreeDict = &__pyx_type_2bx_6arrays_10array_tree_FileArrayTreeDict;
+  __pyx_vtabptr_2bx_6arrays_10array_tree_FileArrayTree = &__pyx_vtable_2bx_6arrays_10array_tree_FileArrayTree;
+  __pyx_vtable_2bx_6arrays_10array_tree_FileArrayTree.r_seek_to_node = (int (*)(struct __pyx_obj_2bx_6arrays_10array_tree_FileArrayTree *, int, int, PY_LONG_LONG, int, int))__pyx_f_2bx_6arrays_10array_tree_13FileArrayTree_r_seek_to_node;
+  if (PyType_Ready(&__pyx_type_2bx_6arrays_10array_tree_FileArrayTree) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (__Pyx_SetVtable(__pyx_type_2bx_6arrays_10array_tree_FileArrayTree.tp_dict, __pyx_vtabptr_2bx_6arrays_10array_tree_FileArrayTree) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (__Pyx_SetAttrString(__pyx_m, "FileArrayTree", (PyObject *)&__pyx_type_2bx_6arrays_10array_tree_FileArrayTree) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_2bx_6arrays_10array_tree_FileArrayTree = &__pyx_type_2bx_6arrays_10array_tree_FileArrayTree;
+  if (PyType_Ready(&__pyx_type_2bx_6arrays_10array_tree_Summary) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 203; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (__Pyx_SetAttrString(__pyx_m, "Summary", (PyObject *)&__pyx_type_2bx_6arrays_10array_tree_Summary) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 203; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_2bx_6arrays_10array_tree_Summary = &__pyx_type_2bx_6arrays_10array_tree_Summary;
+  __pyx_vtabptr_2bx_6arrays_10array_tree_ArrayTreeNode = &__pyx_vtable_2bx_6arrays_10array_tree_ArrayTreeNode;
+  __pyx_vtable_2bx_6arrays_10array_tree_ArrayTreeNode.init_bin = (PyObject *(*)(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeNode *, int))__pyx_f_2bx_6arrays_10array_tree_13ArrayTreeNode_init_bin;
+  __pyx_vtable_2bx_6arrays_10array_tree_ArrayTreeNode.build_summary = (PyObject *(*)(struct __pyx_obj_2bx_6arrays_10array_tree_ArrayTreeNode *, int __pyx_skip_dispatch))__pyx_f_2bx_6arrays_10array_tree_13ArrayTreeNode_build_summary;
+  if (PyType_Ready(&__pyx_type_2bx_6arrays_10array_tree_ArrayTreeNode) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 309; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (__Pyx_SetVtable(__pyx_type_2bx_6arrays_10array_tree_ArrayTreeNode.tp_dict, __pyx_vtabptr_2bx_6arrays_10array_tree_ArrayTreeNode) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 309; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (__Pyx_SetAttrString(__pyx_m, "ArrayTreeNode", (PyObject *)&__pyx_type_2bx_6arrays_10array_tree_ArrayTreeNode) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 309; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_2bx_6arrays_10array_tree_ArrayTreeNode = &__pyx_type_2bx_6arrays_10array_tree_ArrayTreeNode;
+  if (PyType_Ready(&__pyx_type_2bx_6arrays_10array_tree_ArrayTreeLeaf) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 477; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (__Pyx_SetAttrString(__pyx_m, "ArrayTreeLeaf", (PyObject *)&__pyx_type_2bx_6arrays_10array_tree_ArrayTreeLeaf) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 477; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_2bx_6arrays_10array_tree_ArrayTreeLeaf = &__pyx_type_2bx_6arrays_10array_tree_ArrayTreeLeaf;
+  if (PyType_Ready(&__pyx_type_2bx_6arrays_10array_tree_ArrayTree) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 218; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #if CYTHON_COMPILING_IN_CPYTHON
+  {
+    PyObject *wrapper = __Pyx_GetAttrString((PyObject *)&__pyx_type_2bx_6arrays_10array_tree_ArrayTree, "__init__"); if (unlikely(!wrapper)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 218; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (Py_TYPE(wrapper) == &PyWrapperDescr_Type) {
+      __pyx_wrapperbase_2bx_6arrays_10array_tree_9ArrayTree___init__ = *((PyWrapperDescrObject *)wrapper)->d_base;
+      __pyx_wrapperbase_2bx_6arrays_10array_tree_9ArrayTree___init__.doc = __pyx_doc_2bx_6arrays_10array_tree_9ArrayTree___init__;
+      ((PyWrapperDescrObject *)wrapper)->d_base = &__pyx_wrapperbase_2bx_6arrays_10array_tree_9ArrayTree___init__;
+    }
+  }
+  #endif
+  if (__Pyx_SetAttrString(__pyx_m, "ArrayTree", (PyObject *)&__pyx_type_2bx_6arrays_10array_tree_ArrayTree) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 218; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_2bx_6arrays_10array_tree_ArrayTree = &__pyx_type_2bx_6arrays_10array_tree_ArrayTree;
+  /*--- Type import code ---*/
+  __pyx_ptype_7cpython_4type_type = __Pyx_ImportType(__Pyx_BUILTIN_MODULE_NAME, "type", 
+  #if CYTHON_COMPILING_IN_PYPY
+  sizeof(PyTypeObject),
+  #else
+  sizeof(PyHeapTypeObject),
+  #endif
+  0); if (unlikely(!__pyx_ptype_7cpython_4type_type)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 9; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_5numpy_dtype = __Pyx_ImportType("numpy", "dtype", sizeof(PyArray_Descr), 0); if (unlikely(!__pyx_ptype_5numpy_dtype)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 155; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_5numpy_flatiter = __Pyx_ImportType("numpy", "flatiter", sizeof(PyArrayIterObject), 0); if (unlikely(!__pyx_ptype_5numpy_flatiter)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 165; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_5numpy_broadcast = __Pyx_ImportType("numpy", "broadcast", sizeof(PyArrayMultiIterObject), 0); if (unlikely(!__pyx_ptype_5numpy_broadcast)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_5numpy_ndarray = __Pyx_ImportType("numpy", "ndarray", sizeof(PyArrayObject), 0); if (unlikely(!__pyx_ptype_5numpy_ndarray)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 178; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_5numpy_ufunc = __Pyx_ImportType("numpy", "ufunc", sizeof(PyUFuncObject), 0); if (unlikely(!__pyx_ptype_5numpy_ufunc)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 861; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_2bx_6arrays_6wiggle_WiggleReader = __Pyx_ImportType("bx.arrays.wiggle", "WiggleReader", sizeof(struct __pyx_obj_2bx_6arrays_6wiggle_WiggleReader), 1); if (unlikely(!__pyx_ptype_2bx_6arrays_6wiggle_WiggleReader)) {__pyx_filename = __pyx_f[3]; __pyx_lineno = 6; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  /*--- Variable import code ---*/
+  /*--- Function import code ---*/
+  /*--- Execution code ---*/
+
+  /* "bx/arrays/array_tree.pyx":3
+ * from __future__ import division
+ * 
+ * __all__ = [ 'ArrayTree', 'FileArrayTreeDict', 'array_tree_dict_from_reader' ]             # <<<<<<<<<<<<<<
+ * 
+ * import numpy
+ */
+  __pyx_t_1 = PyList_New(3); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_INCREF(((PyObject *)__pyx_n_s__ArrayTree));
+  PyList_SET_ITEM(__pyx_t_1, 0, ((PyObject *)__pyx_n_s__ArrayTree));
+  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__ArrayTree));
+  __Pyx_INCREF(((PyObject *)__pyx_n_s__FileArrayTreeDict));
+  PyList_SET_ITEM(__pyx_t_1, 1, ((PyObject *)__pyx_n_s__FileArrayTreeDict));
+  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__FileArrayTreeDict));
+  __Pyx_INCREF(((PyObject *)__pyx_n_s_33));
+  PyList_SET_ITEM(__pyx_t_1, 2, ((PyObject *)__pyx_n_s_33));
+  __Pyx_GIVEREF(((PyObject *)__pyx_n_s_33));
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s____all__, ((PyObject *)__pyx_t_1)) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+
+  /* "bx/arrays/array_tree.pyx":5
+ * __all__ = [ 'ArrayTree', 'FileArrayTreeDict', 'array_tree_dict_from_reader' ]
+ * 
+ * import numpy             # <<<<<<<<<<<<<<
+ * from numpy import *
+ * cimport numpy
+ */
+  __pyx_t_1 = __Pyx_Import(((PyObject *)__pyx_n_s__numpy), 0, -1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 5; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s__numpy, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 5; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "bx/arrays/array_tree.pyx":6
+ * 
+ * import numpy
+ * from numpy import *             # <<<<<<<<<<<<<<
+ * cimport numpy
+ * 
+ */
+  __pyx_t_1 = PyList_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 6; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_INCREF(((PyObject *)__pyx_n_s_34));
+  PyList_SET_ITEM(__pyx_t_1, 0, ((PyObject *)__pyx_n_s_34));
+  __Pyx_GIVEREF(((PyObject *)__pyx_n_s_34));
+  __pyx_t_2 = __Pyx_Import(((PyObject *)__pyx_n_s__numpy), ((PyObject *)__pyx_t_1), -1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 6; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+  if (__pyx_import_star(__pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 6; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+  /* "bx/arrays/array_tree.pyx":11
+ * cimport bx.arrays.wiggle
+ * 
+ * from bx.misc.binary_file import BinaryFileWriter, BinaryFileReader             # <<<<<<<<<<<<<<
+ * from bx.misc.cdb import FileCDBDict
+ * 
+ */
+  __pyx_t_2 = PyList_New(2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 11; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_INCREF(((PyObject *)__pyx_n_s__BinaryFileWriter));
+  PyList_SET_ITEM(__pyx_t_2, 0, ((PyObject *)__pyx_n_s__BinaryFileWriter));
+  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__BinaryFileWriter));
+  __Pyx_INCREF(((PyObject *)__pyx_n_s__BinaryFileReader));
+  PyList_SET_ITEM(__pyx_t_2, 1, ((PyObject *)__pyx_n_s__BinaryFileReader));
+  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__BinaryFileReader));
+  __pyx_t_1 = __Pyx_Import(((PyObject *)__pyx_n_s_35), ((PyObject *)__pyx_t_2), -1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 11; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
+  __pyx_t_2 = PyObject_GetAttr(__pyx_t_1, __pyx_n_s__BinaryFileWriter);
+  if (__pyx_t_2 == NULL) {
+    if (PyErr_ExceptionMatches(PyExc_AttributeError)) __Pyx_RaiseImportError(__pyx_n_s__BinaryFileWriter);
+    if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 11; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s__BinaryFileWriter, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 11; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_2 = PyObject_GetAttr(__pyx_t_1, __pyx_n_s__BinaryFileReader);
+  if (__pyx_t_2 == NULL) {
+    if (PyErr_ExceptionMatches(PyExc_AttributeError)) __Pyx_RaiseImportError(__pyx_n_s__BinaryFileReader);
+    if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 11; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s__BinaryFileReader, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 11; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "bx/arrays/array_tree.pyx":12
+ * 
+ * from bx.misc.binary_file import BinaryFileWriter, BinaryFileReader
+ * from bx.misc.cdb import FileCDBDict             # <<<<<<<<<<<<<<
+ * 
+ * """
+ */
+  __pyx_t_1 = PyList_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 12; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_INCREF(((PyObject *)__pyx_n_s__FileCDBDict));
+  PyList_SET_ITEM(__pyx_t_1, 0, ((PyObject *)__pyx_n_s__FileCDBDict));
+  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__FileCDBDict));
+  __pyx_t_2 = __Pyx_Import(((PyObject *)__pyx_n_s_36), ((PyObject *)__pyx_t_1), -1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 12; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+  __pyx_t_1 = PyObject_GetAttr(__pyx_t_2, __pyx_n_s__FileCDBDict);
+  if (__pyx_t_1 == NULL) {
+    if (PyErr_ExceptionMatches(PyExc_AttributeError)) __Pyx_RaiseImportError(__pyx_n_s__FileCDBDict);
+    if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 12; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s__FileCDBDict, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 12; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+  /* "bx/arrays/array_tree.pyx":58
+ * ##   - Compression for blocks?
+ * 
+ * MAGIC = 0x310ec7dc             # <<<<<<<<<<<<<<
+ * VERSION = 1
+ * NUM_SUMMARY_ARRAYS = 6
+ */
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s__MAGIC, __pyx_int_823052252) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 58; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "bx/arrays/array_tree.pyx":59
+ * 
+ * MAGIC = 0x310ec7dc
+ * VERSION = 1             # <<<<<<<<<<<<<<
+ * NUM_SUMMARY_ARRAYS = 6
+ * 
+ */
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s__VERSION, __pyx_int_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 59; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "bx/arrays/array_tree.pyx":60
+ * MAGIC = 0x310ec7dc
+ * VERSION = 1
+ * NUM_SUMMARY_ARRAYS = 6             # <<<<<<<<<<<<<<
+ * 
+ * def array_tree_dict_from_reader( reader, sizes, default_size=2147483647, block_size=1000, no_leaves=False ):
+ */
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s__NUM_SUMMARY_ARRAYS, __pyx_int_6) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 60; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "bx/arrays/array_tree.pyx":62
+ * NUM_SUMMARY_ARRAYS = 6
+ * 
+ * def array_tree_dict_from_reader( reader, sizes, default_size=2147483647, block_size=1000, no_leaves=False ):             # <<<<<<<<<<<<<<
+ *     # Create empty array trees
+ *     rval = {}
+ */
+  __pyx_t_2 = __Pyx_PyBool_FromLong(0); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 62; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_k_1 = __pyx_t_2;
+  __Pyx_GIVEREF(__pyx_t_2);
+  __pyx_t_2 = 0;
+  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_2bx_6arrays_10array_tree_1array_tree_dict_from_reader, NULL, __pyx_n_s_40); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 62; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_33, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 62; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+  /* "bx/arrays/array_tree.pyx":96
+ * 
+ *     @classmethod
+ *     def dict_to_file( Class, dict, file, is_little_endian=True, no_leaves=False ):             # <<<<<<<<<<<<<<
+ *         """
+ *         Writes a dictionary of array trees to a file that can then be
+ */
+  __pyx_t_2 = __Pyx_PyBool_FromLong(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 96; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_k_2 = __pyx_t_2;
+  __Pyx_GIVEREF(__pyx_t_2);
+  __pyx_t_2 = 0;
+  __pyx_t_2 = __Pyx_PyBool_FromLong(0); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 96; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_k_3 = __pyx_t_2;
+  __Pyx_GIVEREF(__pyx_t_2);
+  __pyx_t_2 = 0;
+
+  /* "bx/arrays/array_tree.pyx":95
+ *         return FileArrayTree( self.io.file, self.io.is_little_endian )
+ * 
+ *     @classmethod             # <<<<<<<<<<<<<<
+ *     def dict_to_file( Class, dict, file, is_little_endian=True, no_leaves=False ):
+ *         """
+ */
+  __pyx_t_2 = __Pyx_GetName((PyObject *)__pyx_ptype_2bx_6arrays_10array_tree_FileArrayTreeDict, __pyx_n_s__dict_to_file); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 96; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_1 = __Pyx_Method_ClassMethod(__pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 95; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  if (PyDict_SetItem((PyObject *)__pyx_ptype_2bx_6arrays_10array_tree_FileArrayTreeDict->tp_dict, __pyx_n_s__dict_to_file, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 96; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  PyType_Modified(__pyx_ptype_2bx_6arrays_10array_tree_FileArrayTreeDict);
+
+  /* "bx/arrays/array_tree.pyx":132
+ *     cdef object io
+ * 
+ *     def __init__( self, file, is_little_endian=True ):             # <<<<<<<<<<<<<<
+ *         self.io = BinaryFileReader( file, is_little_endian=is_little_endian )
+ *         self.offset = self.io.tell()
+ */
+  __pyx_t_1 = __Pyx_PyBool_FromLong(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_k_5 = __pyx_t_1;
+  __Pyx_GIVEREF(__pyx_t_1);
+  __pyx_t_1 = 0;
+
+  /* "bx/arrays/array_tree.pyx":241
+ *     cdef public ArrayTreeNode root
+ * 
+ *     def __init__( self, int max, int block_size, dtype=float32, no_leaves=False ):             # <<<<<<<<<<<<<<
+ *         """
+ *         Create a new array tree of size `max`
+ */
+  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__float32); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 241; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_k_10 = __pyx_t_1;
+  __Pyx_GIVEREF(__pyx_t_1);
+  __pyx_t_1 = 0;
+  __pyx_t_1 = __Pyx_PyBool_FromLong(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 241; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_k_11 = __pyx_t_1;
+  __Pyx_GIVEREF(__pyx_t_1);
+  __pyx_t_1 = 0;
+
+  /* "bx/arrays/array_tree.pyx":269
+ *         return self.root.get( index )
+ * 
+ *     def to_file( self, f, is_little_endian=True, no_leaves=False ):             # <<<<<<<<<<<<<<
+ *         io = BinaryFileWriter( f, is_little_endian=is_little_endian )
+ *         ## io.write_uint32( VERSION )
+ */
+  __pyx_t_1 = __Pyx_PyBool_FromLong(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 269; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_k_12 = __pyx_t_1;
+  __Pyx_GIVEREF(__pyx_t_1);
+  __pyx_t_1 = 0;
+  __pyx_t_1 = __Pyx_PyBool_FromLong(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 269; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_k_13 = __pyx_t_1;
+  __Pyx_GIVEREF(__pyx_t_1);
+  __pyx_t_1 = 0;
+
+  /* "bx/arrays/array_tree.pyx":287
+ * 
+ *     @classmethod
+ *     def from_file( Class, f, is_little_endian=True ):             # <<<<<<<<<<<<<<
+ *         io = BinaryFileReader( f, is_little_endian=is_little_endian )
+ *         ## assert io.read_uint32() == VERSION
+ */
+  __pyx_t_1 = __Pyx_PyBool_FromLong(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 287; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_k_16 = __pyx_t_1;
+  __Pyx_GIVEREF(__pyx_t_1);
+  __pyx_t_1 = 0;
+
+  /* "bx/arrays/array_tree.pyx":286
+ *         self.root.to_file_offset_pass( io )
+ * 
+ *     @classmethod             # <<<<<<<<<<<<<<
+ *     def from_file( Class, f, is_little_endian=True ):
+ *         io = BinaryFileReader( f, is_little_endian=is_little_endian )
+ */
+  __pyx_t_1 = __Pyx_GetName((PyObject *)__pyx_ptype_2bx_6arrays_10array_tree_ArrayTree, __pyx_n_s__from_file); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 287; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = __Pyx_Method_ClassMethod(__pyx_t_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 286; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  if (PyDict_SetItem((PyObject *)__pyx_ptype_2bx_6arrays_10array_tree_ArrayTree->tp_dict, __pyx_n_s__from_file, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 287; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  PyType_Modified(__pyx_ptype_2bx_6arrays_10array_tree_ArrayTree);
+
+  /* "bx/arrays/array_tree.pyx":299
+ * 
+ *     @classmethod
+ *     def from_sequence( Class, s, block_size=1000 ):             # <<<<<<<<<<<<<<
+ *         """
+ *         Build an ArrayTree from a sequence like object (must have at least
+ */
+  __pyx_t_2 = __Pyx_GetName((PyObject *)__pyx_ptype_2bx_6arrays_10array_tree_ArrayTree, __pyx_n_s__from_sequence); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 299; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_1 = __Pyx_Method_ClassMethod(__pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 298; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  if (PyDict_SetItem((PyObject *)__pyx_ptype_2bx_6arrays_10array_tree_ArrayTree->tp_dict, __pyx_n_s__from_sequence, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 299; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  PyType_Modified(__pyx_ptype_2bx_6arrays_10array_tree_ArrayTree);
+
+  /* "bx/arrays/array_tree.pyx":1
+ * from __future__ import division             # <<<<<<<<<<<<<<
+ * 
+ * __all__ = [ 'ArrayTree', 'FileArrayTreeDict', 'array_tree_dict_from_reader' ]
+ */
+  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(((PyObject *)__pyx_t_1));
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s____test__, ((PyObject *)__pyx_t_1)) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+
+  /* "numpy.pxd":975
+ *      arr.base = baseptr
+ * 
+ * cdef inline object get_array_base(ndarray arr):             # <<<<<<<<<<<<<<
+ *     if arr.base is NULL:
+ *         return None
+ */
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  if (__pyx_m) {
+    __Pyx_AddTraceback("init bx.arrays.array_tree", __pyx_clineno, __pyx_lineno, __pyx_filename);
+    Py_DECREF(__pyx_m); __pyx_m = 0;
+  } else if (!PyErr_Occurred()) {
+    PyErr_SetString(PyExc_ImportError, "init bx.arrays.array_tree");
+  }
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  #if PY_MAJOR_VERSION < 3
+  return;
+  #else
+  return __pyx_m;
+  #endif
+}
+
+/* Runtime support code */
+#if CYTHON_REFNANNY
+static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) {
+    PyObject *m = NULL, *p = NULL;
+    void *r = NULL;
+    m = PyImport_ImportModule((char *)modname);
+    if (!m) goto end;
+    p = PyObject_GetAttrString(m, (char *)"RefNannyAPI");
+    if (!p) goto end;
+    r = PyLong_AsVoidPtr(p);
+end:
+    Py_XDECREF(p);
+    Py_XDECREF(m);
+    return (__Pyx_RefNannyAPIStruct *)r;
+}
+#endif /* CYTHON_REFNANNY */
+
+static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name) {
+    PyObject *result;
+    result = PyObject_GetAttr(dict, name);
+    if (!result) {
+        if (dict != __pyx_b) {
+            PyErr_Clear();
+            result = PyObject_GetAttr(__pyx_b, name);
+        }
+        if (!result) {
+            PyErr_SetObject(PyExc_NameError, name);
+        }
+    }
+    return result;
+}
+
+static void __Pyx_RaiseArgtupleInvalid(
+    const char* func_name,
+    int exact,
+    Py_ssize_t num_min,
+    Py_ssize_t num_max,
+    Py_ssize_t num_found)
+{
+    Py_ssize_t num_expected;
+    const char *more_or_less;
+    if (num_found < num_min) {
+        num_expected = num_min;
+        more_or_less = "at least";
+    } else {
+        num_expected = num_max;
+        more_or_less = "at most";
+    }
+    if (exact) {
+        more_or_less = "exactly";
+    }
+    PyErr_Format(PyExc_TypeError,
+                 "%s() takes %s %" CYTHON_FORMAT_SSIZE_T "d positional argument%s (%" CYTHON_FORMAT_SSIZE_T "d given)",
+                 func_name, more_or_less, num_expected,
+                 (num_expected == 1) ? "" : "s", num_found);
+}
+
+static void __Pyx_RaiseDoubleKeywordsError(
+    const char* func_name,
+    PyObject* kw_name)
+{
+    PyErr_Format(PyExc_TypeError,
+        #if PY_MAJOR_VERSION >= 3
+        "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
+        #else
+        "%s() got multiple values for keyword argument '%s'", func_name,
+        PyString_AsString(kw_name));
+        #endif
+}
+
+static int __Pyx_ParseOptionalKeywords(
+    PyObject *kwds,
+    PyObject **argnames[],
+    PyObject *kwds2,
+    PyObject *values[],
+    Py_ssize_t num_pos_args,
+    const char* function_name)
+{
+    PyObject *key = 0, *value = 0;
+    Py_ssize_t pos = 0;
+    PyObject*** name;
+    PyObject*** first_kw_arg = argnames + num_pos_args;
+    while (PyDict_Next(kwds, &pos, &key, &value)) {
+        name = first_kw_arg;
+        while (*name && (**name != key)) name++;
+        if (*name) {
+            values[name-argnames] = value;
+            continue;
+        }
+        name = first_kw_arg;
+        #if PY_MAJOR_VERSION < 3
+        if (likely(PyString_CheckExact(key)) || likely(PyString_Check(key))) {
+            while (*name) {
+                if ((CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**name) == PyString_GET_SIZE(key))
+                        && _PyString_Eq(**name, key)) {
+                    values[name-argnames] = value;
+                    break;
+                }
+                name++;
+            }
+            if (*name) continue;
+            else {
+                PyObject*** argname = argnames;
+                while (argname != first_kw_arg) {
+                    if ((**argname == key) || (
+                            (CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**argname) == PyString_GET_SIZE(key))
+                             && _PyString_Eq(**argname, key))) {
+                        goto arg_passed_twice;
+                    }
+                    argname++;
+                }
+            }
+        } else
+        #endif
+        if (likely(PyUnicode_Check(key))) {
+            while (*name) {
+                int cmp = (**name == key) ? 0 :
+                #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3
+                    (PyUnicode_GET_SIZE(**name) != PyUnicode_GET_SIZE(key)) ? 1 :
+                #endif
+                    PyUnicode_Compare(**name, key);
+                if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad;
+                if (cmp == 0) {
+                    values[name-argnames] = value;
+                    break;
+                }
+                name++;
+            }
+            if (*name) continue;
+            else {
+                PyObject*** argname = argnames;
+                while (argname != first_kw_arg) {
+                    int cmp = (**argname == key) ? 0 :
+                    #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3
+                        (PyUnicode_GET_SIZE(**argname) != PyUnicode_GET_SIZE(key)) ? 1 :
+                    #endif
+                        PyUnicode_Compare(**argname, key);
+                    if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad;
+                    if (cmp == 0) goto arg_passed_twice;
+                    argname++;
+                }
+            }
+        } else
+            goto invalid_keyword_type;
+        if (kwds2) {
+            if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
+        } else {
+            goto invalid_keyword;
+        }
+    }
+    return 0;
+arg_passed_twice:
+    __Pyx_RaiseDoubleKeywordsError(function_name, key);
+    goto bad;
+invalid_keyword_type:
+    PyErr_Format(PyExc_TypeError,
+        "%s() keywords must be strings", function_name);
+    goto bad;
+invalid_keyword:
+    PyErr_Format(PyExc_TypeError,
+    #if PY_MAJOR_VERSION < 3
+        "%s() got an unexpected keyword argument '%s'",
+        function_name, PyString_AsString(key));
+    #else
+        "%s() got an unexpected keyword argument '%U'",
+        function_name, key);
+    #endif
+bad:
+    return -1;
+}
+
+static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected) {
+    PyErr_Format(PyExc_ValueError,
+                 "too many values to unpack (expected %" CYTHON_FORMAT_SSIZE_T "d)", expected);
+}
+
+static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index) {
+    PyErr_Format(PyExc_ValueError,
+                 "need more than %" CYTHON_FORMAT_SSIZE_T "d value%s to unpack",
+                 index, (index == 1) ? "" : "s");
+}
+
+static CYTHON_INLINE int __Pyx_IterFinish(void) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    PyThreadState *tstate = PyThreadState_GET();
+    PyObject* exc_type = tstate->curexc_type;
+    if (unlikely(exc_type)) {
+        if (likely(exc_type == PyExc_StopIteration) || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration)) {
+            PyObject *exc_value, *exc_tb;
+            exc_value = tstate->curexc_value;
+            exc_tb = tstate->curexc_traceback;
+            tstate->curexc_type = 0;
+            tstate->curexc_value = 0;
+            tstate->curexc_traceback = 0;
+            Py_DECREF(exc_type);
+            Py_XDECREF(exc_value);
+            Py_XDECREF(exc_tb);
+            return 0;
+        } else {
+            return -1;
+        }
+    }
+    return 0;
+#else
+    if (unlikely(PyErr_Occurred())) {
+        if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) {
+            PyErr_Clear();
+            return 0;
+        } else {
+            return -1;
+        }
+    }
+    return 0;
+#endif
+}
+
+static int __Pyx_IternextUnpackEndCheck(PyObject *retval, Py_ssize_t expected) {
+    if (unlikely(retval)) {
+        Py_DECREF(retval);
+        __Pyx_RaiseTooManyValuesError(expected);
+        return -1;
+    } else {
+        return __Pyx_IterFinish();
+    }
+    return 0;
+}
+
+static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void) {
+    PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable");
+}
+
+static void __Pyx_UnpackTupleError(PyObject *t, Py_ssize_t index) {
+    if (t == Py_None) {
+      __Pyx_RaiseNoneNotIterableError();
+    } else if (PyTuple_GET_SIZE(t) < index) {
+      __Pyx_RaiseNeedMoreValuesError(PyTuple_GET_SIZE(t));
+    } else {
+      __Pyx_RaiseTooManyValuesError(index);
+    }
+}
+
+static CYTHON_INLINE int __Pyx_unpack_tuple2(PyObject* tuple, PyObject** pvalue1, PyObject** pvalue2,
+                                             int is_tuple, int has_known_size, int decref_tuple) {
+    Py_ssize_t index;
+    PyObject *value1 = NULL, *value2 = NULL, *iter = NULL;
+    if (!is_tuple && unlikely(!PyTuple_Check(tuple))) {
+        iternextfunc iternext;
+        iter = PyObject_GetIter(tuple);
+        if (unlikely(!iter)) goto bad;
+        if (decref_tuple) { Py_DECREF(tuple); tuple = NULL; }
+        iternext = Py_TYPE(iter)->tp_iternext;
+        value1 = iternext(iter); if (unlikely(!value1)) { index = 0; goto unpacking_failed; }
+        value2 = iternext(iter); if (unlikely(!value2)) { index = 1; goto unpacking_failed; }
+        if (!has_known_size && unlikely(__Pyx_IternextUnpackEndCheck(iternext(iter), 2))) goto bad;
+        Py_DECREF(iter);
+    } else {
+        if (!has_known_size && unlikely(PyTuple_GET_SIZE(tuple) != 2)) {
+            __Pyx_UnpackTupleError(tuple, 2);
+            goto bad;
+        }
+#if CYTHON_COMPILING_IN_PYPY
+        value1 = PySequence_ITEM(tuple, 0);
+        if (unlikely(!value1)) goto bad;
+        value2 = PySequence_ITEM(tuple, 1);
+        if (unlikely(!value2)) goto bad;
+#else
+        value1 = PyTuple_GET_ITEM(tuple, 0);
+        value2 = PyTuple_GET_ITEM(tuple, 1);
+        Py_INCREF(value1);
+        Py_INCREF(value2);
+#endif
+        if (decref_tuple) { Py_DECREF(tuple); }
+    }
+    *pvalue1 = value1;
+    *pvalue2 = value2;
+    return 0;
+unpacking_failed:
+    if (!has_known_size && __Pyx_IterFinish() == 0)
+        __Pyx_RaiseNeedMoreValuesError(index);
+bad:
+    Py_XDECREF(iter);
+    Py_XDECREF(value1);
+    Py_XDECREF(value2);
+    if (decref_tuple) { Py_XDECREF(tuple); }
+    return -1;
+}
+
+static CYTHON_INLINE PyObject* __Pyx_dict_iterator(PyObject* iterable, int is_dict, PyObject* method_name,
+                                                   Py_ssize_t* p_orig_length, int* p_source_is_dict) {
+    is_dict = is_dict || likely(PyDict_CheckExact(iterable));
+    *p_source_is_dict = is_dict;
+#if !CYTHON_COMPILING_IN_PYPY
+    if (is_dict) {
+        *p_orig_length = PyDict_Size(iterable);
+        Py_INCREF(iterable);
+        return iterable;
+    }
+#endif
+    *p_orig_length = 0;
+    if (method_name) {
+        PyObject* iter;
+        iterable = PyObject_CallMethodObjArgs(iterable, method_name, NULL);
+        if (!iterable)
+            return NULL;
+#if !CYTHON_COMPILING_IN_PYPY
+        if (PyTuple_CheckExact(iterable) || PyList_CheckExact(iterable))
+            return iterable;
+#endif
+        iter = PyObject_GetIter(iterable);
+        Py_DECREF(iterable);
+        return iter;
+    }
+    return PyObject_GetIter(iterable);
+}
+static CYTHON_INLINE int __Pyx_dict_iter_next(PyObject* iter_obj, Py_ssize_t orig_length, Py_ssize_t* ppos,
+                                              PyObject** pkey, PyObject** pvalue, PyObject** pitem, int source_is_dict) {
+    PyObject* next_item;
+#if !CYTHON_COMPILING_IN_PYPY
+    if (source_is_dict) {
+        PyObject *key, *value;
+        if (unlikely(orig_length != PyDict_Size(iter_obj))) {
+            PyErr_SetString(PyExc_RuntimeError, "dictionary changed size during iteration");
+            return -1;
+        }
+        if (unlikely(!PyDict_Next(iter_obj, ppos, &key, &value))) {
+            return 0;
+        }
+        if (pitem) {
+            PyObject* tuple = PyTuple_New(2);
+            if (unlikely(!tuple)) {
+                return -1;
+            }
+            Py_INCREF(key);
+            Py_INCREF(value);
+            PyTuple_SET_ITEM(tuple, 0, key);
+            PyTuple_SET_ITEM(tuple, 1, value);
+            *pitem = tuple;
+        } else {
+            if (pkey) {
+                Py_INCREF(key);
+                *pkey = key;
+            }
+            if (pvalue) {
+                Py_INCREF(value);
+                *pvalue = value;
+            }
+        }
+        return 1;
+    } else if (PyTuple_CheckExact(iter_obj)) {
+        Py_ssize_t pos = *ppos;
+        if (unlikely(pos >= PyTuple_GET_SIZE(iter_obj))) return 0;
+        *ppos = pos + 1;
+        next_item = PyTuple_GET_ITEM(iter_obj, pos);
+        Py_INCREF(next_item);
+    } else if (PyList_CheckExact(iter_obj)) {
+        Py_ssize_t pos = *ppos;
+        if (unlikely(pos >= PyList_GET_SIZE(iter_obj))) return 0;
+        *ppos = pos + 1;
+        next_item = PyList_GET_ITEM(iter_obj, pos);
+        Py_INCREF(next_item);
+    } else
+#endif
+    {
+        next_item = PyIter_Next(iter_obj);
+        if (unlikely(!next_item)) {
+            return __Pyx_IterFinish();
+        }
+    }
+    if (pitem) {
+        *pitem = next_item;
+    } else if (pkey && pvalue) {
+        if (__Pyx_unpack_tuple2(next_item, pkey, pvalue, source_is_dict, source_is_dict, 1))
+            return -1;
+    } else if (pkey) {
+        *pkey = next_item;
+    } else {
+        *pvalue = next_item;
+    }
+    return 1;
+}
+
+static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    PyObject *tmp_type, *tmp_value, *tmp_tb;
+    PyThreadState *tstate = PyThreadState_GET();
+    tmp_type = tstate->curexc_type;
+    tmp_value = tstate->curexc_value;
+    tmp_tb = tstate->curexc_traceback;
+    tstate->curexc_type = type;
+    tstate->curexc_value = value;
+    tstate->curexc_traceback = tb;
+    Py_XDECREF(tmp_type);
+    Py_XDECREF(tmp_value);
+    Py_XDECREF(tmp_tb);
+#else
+    PyErr_Restore(type, value, tb);
+#endif
+}
+static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    PyThreadState *tstate = PyThreadState_GET();
+    *type = tstate->curexc_type;
+    *value = tstate->curexc_value;
+    *tb = tstate->curexc_traceback;
+    tstate->curexc_type = 0;
+    tstate->curexc_value = 0;
+    tstate->curexc_traceback = 0;
+#else
+    PyErr_Fetch(type, value, tb);
+#endif
+}
+
+#if PY_MAJOR_VERSION < 3
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb,
+                        CYTHON_UNUSED PyObject *cause) {
+    Py_XINCREF(type);
+    if (!value || value == Py_None)
+        value = NULL;
+    else
+        Py_INCREF(value);
+    if (!tb || tb == Py_None)
+        tb = NULL;
+    else {
+        Py_INCREF(tb);
+        if (!PyTraceBack_Check(tb)) {
+            PyErr_SetString(PyExc_TypeError,
+                "raise: arg 3 must be a traceback or None");
+            goto raise_error;
+        }
+    }
+    #if PY_VERSION_HEX < 0x02050000
+    if (PyClass_Check(type)) {
+    #else
+    if (PyType_Check(type)) {
+    #endif
+#if CYTHON_COMPILING_IN_PYPY
+        if (!value) {
+            Py_INCREF(Py_None);
+            value = Py_None;
+        }
+#endif
+        PyErr_NormalizeException(&type, &value, &tb);
+    } else {
+        if (value) {
+            PyErr_SetString(PyExc_TypeError,
+                "instance exception may not have a separate value");
+            goto raise_error;
+        }
+        value = type;
+        #if PY_VERSION_HEX < 0x02050000
+            if (PyInstance_Check(type)) {
+                type = (PyObject*) ((PyInstanceObject*)type)->in_class;
+                Py_INCREF(type);
+            }
+            else {
+                type = 0;
+                PyErr_SetString(PyExc_TypeError,
+                    "raise: exception must be an old-style class or instance");
+                goto raise_error;
+            }
+        #else
+            type = (PyObject*) Py_TYPE(type);
+            Py_INCREF(type);
+            if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
+                PyErr_SetString(PyExc_TypeError,
+                    "raise: exception class must be a subclass of BaseException");
+                goto raise_error;
+            }
+        #endif
+    }
+    __Pyx_ErrRestore(type, value, tb);
+    return;
+raise_error:
+    Py_XDECREF(value);
+    Py_XDECREF(type);
+    Py_XDECREF(tb);
+    return;
+}
+#else /* Python 3+ */
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause) {
+    PyObject* owned_instance = NULL;
+    if (tb == Py_None) {
+        tb = 0;
+    } else if (tb && !PyTraceBack_Check(tb)) {
+        PyErr_SetString(PyExc_TypeError,
+            "raise: arg 3 must be a traceback or None");
+        goto bad;
+    }
+    if (value == Py_None)
+        value = 0;
+    if (PyExceptionInstance_Check(type)) {
+        if (value) {
+            PyErr_SetString(PyExc_TypeError,
+                "instance exception may not have a separate value");
+            goto bad;
+        }
+        value = type;
+        type = (PyObject*) Py_TYPE(value);
+    } else if (PyExceptionClass_Check(type)) {
+        PyObject *args;
+        if (!value)
+            args = PyTuple_New(0);
+        else if (PyTuple_Check(value)) {
+            Py_INCREF(value);
+            args = value;
+        }
+        else
+            args = PyTuple_Pack(1, value);
+        if (!args)
+            goto bad;
+        owned_instance = PyEval_CallObject(type, args);
+        Py_DECREF(args);
+        if (!owned_instance)
+            goto bad;
+        value = owned_instance;
+        if (!PyExceptionInstance_Check(value)) {
+            PyErr_Format(PyExc_TypeError,
+                         "calling %R should have returned an instance of "
+                         "BaseException, not %R",
+                         type, Py_TYPE(value));
+            goto bad;
+        }
+    } else {
+        PyErr_SetString(PyExc_TypeError,
+            "raise: exception class must be a subclass of BaseException");
+        goto bad;
+    }
+    if (cause && cause != Py_None) {
+        PyObject *fixed_cause;
+        if (PyExceptionClass_Check(cause)) {
+            fixed_cause = PyObject_CallObject(cause, NULL);
+            if (fixed_cause == NULL)
+                goto bad;
+        }
+        else if (PyExceptionInstance_Check(cause)) {
+            fixed_cause = cause;
+            Py_INCREF(fixed_cause);
+        }
+        else {
+            PyErr_SetString(PyExc_TypeError,
+                            "exception causes must derive from "
+                            "BaseException");
+            goto bad;
+        }
+        PyException_SetCause(value, fixed_cause);
+    }
+    PyErr_SetObject(type, value);
+    if (tb) {
+        PyThreadState *tstate = PyThreadState_GET();
+        PyObject* tmp_tb = tstate->curexc_traceback;
+        if (tb != tmp_tb) {
+            Py_INCREF(tb);
+            tstate->curexc_traceback = tb;
+            Py_XDECREF(tmp_tb);
+        }
+    }
+bad:
+    Py_XDECREF(owned_instance);
+    return;
+}
+#endif
+
+static CYTHON_INLINE int __Pyx_div_int(int a, int b) {
+    int q = a / b;
+    int r = a - q*b;
+    q -= ((r != 0) & ((r ^ b) < 0));
+    return q;
+}
+
+static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type) {
+    if (unlikely(!type)) {
+        PyErr_Format(PyExc_SystemError, "Missing type object");
+        return 0;
+    }
+    if (likely(PyObject_TypeCheck(obj, type)))
+        return 1;
+    PyErr_Format(PyExc_TypeError, "Cannot convert %.200s to %.200s",
+                 Py_TYPE(obj)->tp_name, type->tp_name);
+    return 0;
+}
+
+static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
+    const char *name, int exact)
+{
+    if (!type) {
+        PyErr_Format(PyExc_SystemError, "Missing type object");
+        return 0;
+    }
+    if (none_allowed && obj == Py_None) return 1;
+    else if (exact) {
+        if (Py_TYPE(obj) == type) return 1;
+    }
+    else {
+        if (PyObject_TypeCheck(obj, type)) return 1;
+    }
+    PyErr_Format(PyExc_TypeError,
+        "Argument '%s' has incorrect type (expected %s, got %s)",
+        name, type->tp_name, Py_TYPE(obj)->tp_name);
+    return 0;
+}
+
+static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level) {
+    PyObject *empty_list = 0;
+    PyObject *module = 0;
+    PyObject *global_dict = 0;
+    PyObject *empty_dict = 0;
+    PyObject *list;
+    #if PY_VERSION_HEX < 0x03030000
+    PyObject *py_import = 0;
+    py_import = __Pyx_GetAttrString(__pyx_b, "__import__");
+    if (!py_import)
+        goto bad;
+    #endif
+    if (from_list)
+        list = from_list;
+    else {
+        empty_list = PyList_New(0);
+        if (!empty_list)
+            goto bad;
+        list = empty_list;
+    }
+    global_dict = PyModule_GetDict(__pyx_m);
+    if (!global_dict)
+        goto bad;
+    empty_dict = PyDict_New();
+    if (!empty_dict)
+        goto bad;
+    #if PY_VERSION_HEX >= 0x02050000
+    {
+        #if PY_MAJOR_VERSION >= 3
+        if (level == -1) {
+            if (strchr(__Pyx_MODULE_NAME, '.')) {
+                #if PY_VERSION_HEX < 0x03030000
+                PyObject *py_level = PyInt_FromLong(1);
+                if (!py_level)
+                    goto bad;
+                module = PyObject_CallFunctionObjArgs(py_import,
+                    name, global_dict, empty_dict, list, py_level, NULL);
+                Py_DECREF(py_level);
+                #else
+                module = PyImport_ImportModuleLevelObject(
+                    name, global_dict, empty_dict, list, 1);
+                #endif
+                if (!module) {
+                    if (!PyErr_ExceptionMatches(PyExc_ImportError))
+                        goto bad;
+                    PyErr_Clear();
+                }
+            }
+            level = 0; /* try absolute import on failure */
+        }
+        #endif
+        if (!module) {
+            #if PY_VERSION_HEX < 0x03030000
+            PyObject *py_level = PyInt_FromLong(level);
+            if (!py_level)
+                goto bad;
+            module = PyObject_CallFunctionObjArgs(py_import,
+                name, global_dict, empty_dict, list, py_level, NULL);
+            Py_DECREF(py_level);
+            #else
+            module = PyImport_ImportModuleLevelObject(
+                name, global_dict, empty_dict, list, level);
+            #endif
+        }
+    }
+    #else
+    if (level>0) {
+        PyErr_SetString(PyExc_RuntimeError, "Relative import is not supported for Python <=2.4.");
+        goto bad;
+    }
+    module = PyObject_CallFunctionObjArgs(py_import,
+        name, global_dict, empty_dict, list, NULL);
+    #endif
+bad:
+    #if PY_VERSION_HEX < 0x03030000
+    Py_XDECREF(py_import);
+    #endif
+    Py_XDECREF(empty_list);
+    Py_XDECREF(empty_dict);
+    return module;
+}
+
+static CYTHON_INLINE void __Pyx_RaiseImportError(PyObject *name) {
+#if PY_MAJOR_VERSION < 3
+    PyErr_Format(PyExc_ImportError, "cannot import name %.230s",
+                 PyString_AsString(name));
+#else
+    PyErr_Format(PyExc_ImportError, "cannot import name %S", name);
+#endif
+}
+
+static CYTHON_INLINE PY_LONG_LONG __Pyx_pow_PY_LONG_LONG(PY_LONG_LONG b, PY_LONG_LONG e) {
+    PY_LONG_LONG t = b;
+    switch (e) {
+        case 3:
+            t *= b;
+        case 2:
+            t *= b;
+        case 1:
+            return t;
+        case 0:
+            return 1;
+    }
+    #if 1
+    if (unlikely(e<0)) return 0;
+    #endif
+    t = 1;
+    while (likely(e)) {
+        t *= (b * (e&1)) | ((~e)&1);    /* 1 or b */
+        b *= b;
+        e >>= 1;
+    }
+    return t;
+}
+
+static CYTHON_INLINE int __Pyx_pow_int(int b, int e) {
+    int t = b;
+    switch (e) {
+        case 3:
+            t *= b;
+        case 2:
+            t *= b;
+        case 1:
+            return t;
+        case 0:
+            return 1;
+    }
+    #if 1
+    if (unlikely(e<0)) return 0;
+    #endif
+    t = 1;
+    while (likely(e)) {
+        t *= (b * (e&1)) | ((~e)&1);    /* 1 or b */
+        b *= b;
+        e >>= 1;
+    }
+    return t;
+}
+
+static PyObject* __Pyx_Method_ClassMethod(PyObject *method) {
+#if CYTHON_COMPILING_IN_PYPY
+    if (PyObject_TypeCheck(method, &PyWrapperDescr_Type)) { /* cdef classes */
+        return PyClassMethod_New(method);
+    }
+#else
+    static PyTypeObject *methoddescr_type = NULL;
+    if (methoddescr_type == NULL) {
+       PyObject *meth = __Pyx_GetAttrString((PyObject*)&PyList_Type, "append");
+       if (!meth) return NULL;
+       methoddescr_type = Py_TYPE(meth);
+       Py_DECREF(meth);
+    }
+    if (PyObject_TypeCheck(method, methoddescr_type)) { /* cdef classes */
+        PyMethodDescrObject *descr = (PyMethodDescrObject *)method;
+        #if PY_VERSION_HEX < 0x03020000
+        PyTypeObject *d_type = descr->d_type;
+        #else
+        PyTypeObject *d_type = descr->d_common.d_type;
+        #endif
+        return PyDescr_NewClassMethod(d_type, descr->d_method);
+    }
+#endif
+    else if (PyMethod_Check(method)) { /* python classes */
+        return PyClassMethod_New(PyMethod_GET_FUNCTION(method));
+    }
+    else if (PyCFunction_Check(method)) {
+        return PyClassMethod_New(method);
+    }
+#ifdef __Pyx_CyFunction_USED
+    else if (PyObject_TypeCheck(method, __pyx_CyFunctionType)) {
+        return PyClassMethod_New(method);
+    }
+#endif
+    PyErr_Format(PyExc_TypeError,
+                 "Class-level classmethod() can only be called on "
+                 "a method_descriptor or instance method.");
+    return NULL;
+}
+
+#if CYTHON_CCOMPLEX
+  #ifdef __cplusplus
+    static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float x, float y) {
+      return ::std::complex< float >(x, y);
+    }
+  #else
+    static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float x, float y) {
+      return x + y*(__pyx_t_float_complex)_Complex_I;
+    }
+  #endif
+#else
+    static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float x, float y) {
+      __pyx_t_float_complex z;
+      z.real = x;
+      z.imag = y;
+      return z;
+    }
+#endif
+
+#if CYTHON_CCOMPLEX
+#else
+    static CYTHON_INLINE int __Pyx_c_eqf(__pyx_t_float_complex a, __pyx_t_float_complex b) {
+       return (a.real == b.real) && (a.imag == b.imag);
+    }
+    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_sumf(__pyx_t_float_complex a, __pyx_t_float_complex b) {
+        __pyx_t_float_complex z;
+        z.real = a.real + b.real;
+        z.imag = a.imag + b.imag;
+        return z;
+    }
+    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_difff(__pyx_t_float_complex a, __pyx_t_float_complex b) {
+        __pyx_t_float_complex z;
+        z.real = a.real - b.real;
+        z.imag = a.imag - b.imag;
+        return z;
+    }
+    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_prodf(__pyx_t_float_complex a, __pyx_t_float_complex b) {
+        __pyx_t_float_complex z;
+        z.real = a.real * b.real - a.imag * b.imag;
+        z.imag = a.real * b.imag + a.imag * b.real;
+        return z;
+    }
+    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_quotf(__pyx_t_float_complex a, __pyx_t_float_complex b) {
+        __pyx_t_float_complex z;
+        float denom = b.real * b.real + b.imag * b.imag;
+        z.real = (a.real * b.real + a.imag * b.imag) / denom;
+        z.imag = (a.imag * b.real - a.real * b.imag) / denom;
+        return z;
+    }
+    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_negf(__pyx_t_float_complex a) {
+        __pyx_t_float_complex z;
+        z.real = -a.real;
+        z.imag = -a.imag;
+        return z;
+    }
+    static CYTHON_INLINE int __Pyx_c_is_zerof(__pyx_t_float_complex a) {
+       return (a.real == 0) && (a.imag == 0);
+    }
+    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_conjf(__pyx_t_float_complex a) {
+        __pyx_t_float_complex z;
+        z.real =  a.real;
+        z.imag = -a.imag;
+        return z;
+    }
+    #if 1
+        static CYTHON_INLINE float __Pyx_c_absf(__pyx_t_float_complex z) {
+          #if !defined(HAVE_HYPOT) || defined(_MSC_VER)
+            return sqrtf(z.real*z.real + z.imag*z.imag);
+          #else
+            return hypotf(z.real, z.imag);
+          #endif
+        }
+        static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_powf(__pyx_t_float_complex a, __pyx_t_float_complex b) {
+            __pyx_t_float_complex z;
+            float r, lnr, theta, z_r, z_theta;
+            if (b.imag == 0 && b.real == (int)b.real) {
+                if (b.real < 0) {
+                    float denom = a.real * a.real + a.imag * a.imag;
+                    a.real = a.real / denom;
+                    a.imag = -a.imag / denom;
+                    b.real = -b.real;
+                }
+                switch ((int)b.real) {
+                    case 0:
+                        z.real = 1;
+                        z.imag = 0;
+                        return z;
+                    case 1:
+                        return a;
+                    case 2:
+                        z = __Pyx_c_prodf(a, a);
+                        return __Pyx_c_prodf(a, a);
+                    case 3:
+                        z = __Pyx_c_prodf(a, a);
+                        return __Pyx_c_prodf(z, a);
+                    case 4:
+                        z = __Pyx_c_prodf(a, a);
+                        return __Pyx_c_prodf(z, z);
+                }
+            }
+            if (a.imag == 0) {
+                if (a.real == 0) {
+                    return a;
+                }
+                r = a.real;
+                theta = 0;
+            } else {
+                r = __Pyx_c_absf(a);
+                theta = atan2f(a.imag, a.real);
+            }
+            lnr = logf(r);
+            z_r = expf(lnr * b.real - theta * b.imag);
+            z_theta = theta * b.real + lnr * b.imag;
+            z.real = z_r * cosf(z_theta);
+            z.imag = z_r * sinf(z_theta);
+            return z;
+        }
+    #endif
+#endif
+
+#if CYTHON_CCOMPLEX
+  #ifdef __cplusplus
+    static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) {
+      return ::std::complex< double >(x, y);
+    }
+  #else
+    static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) {
+      return x + y*(__pyx_t_double_complex)_Complex_I;
+    }
+  #endif
+#else
+    static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) {
+      __pyx_t_double_complex z;
+      z.real = x;
+      z.imag = y;
+      return z;
+    }
+#endif
+
+#if CYTHON_CCOMPLEX
+#else
+    static CYTHON_INLINE int __Pyx_c_eq(__pyx_t_double_complex a, __pyx_t_double_complex b) {
+       return (a.real == b.real) && (a.imag == b.imag);
+    }
+    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_sum(__pyx_t_double_complex a, __pyx_t_double_complex b) {
+        __pyx_t_double_complex z;
+        z.real = a.real + b.real;
+        z.imag = a.imag + b.imag;
+        return z;
+    }
+    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_diff(__pyx_t_double_complex a, __pyx_t_double_complex b) {
+        __pyx_t_double_complex z;
+        z.real = a.real - b.real;
+        z.imag = a.imag - b.imag;
+        return z;
+    }
+    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_prod(__pyx_t_double_complex a, __pyx_t_double_complex b) {
+        __pyx_t_double_complex z;
+        z.real = a.real * b.real - a.imag * b.imag;
+        z.imag = a.real * b.imag + a.imag * b.real;
+        return z;
+    }
+    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_quot(__pyx_t_double_complex a, __pyx_t_double_complex b) {
+        __pyx_t_double_complex z;
+        double denom = b.real * b.real + b.imag * b.imag;
+        z.real = (a.real * b.real + a.imag * b.imag) / denom;
+        z.imag = (a.imag * b.real - a.real * b.imag) / denom;
+        return z;
+    }
+    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_neg(__pyx_t_double_complex a) {
+        __pyx_t_double_complex z;
+        z.real = -a.real;
+        z.imag = -a.imag;
+        return z;
+    }
+    static CYTHON_INLINE int __Pyx_c_is_zero(__pyx_t_double_complex a) {
+       return (a.real == 0) && (a.imag == 0);
+    }
+    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_conj(__pyx_t_double_complex a) {
+        __pyx_t_double_complex z;
+        z.real =  a.real;
+        z.imag = -a.imag;
+        return z;
+    }
+    #if 1
+        static CYTHON_INLINE double __Pyx_c_abs(__pyx_t_double_complex z) {
+          #if !defined(HAVE_HYPOT) || defined(_MSC_VER)
+            return sqrt(z.real*z.real + z.imag*z.imag);
+          #else
+            return hypot(z.real, z.imag);
+          #endif
+        }
+        static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_pow(__pyx_t_double_complex a, __pyx_t_double_complex b) {
+            __pyx_t_double_complex z;
+            double r, lnr, theta, z_r, z_theta;
+            if (b.imag == 0 && b.real == (int)b.real) {
+                if (b.real < 0) {
+                    double denom = a.real * a.real + a.imag * a.imag;
+                    a.real = a.real / denom;
+                    a.imag = -a.imag / denom;
+                    b.real = -b.real;
+                }
+                switch ((int)b.real) {
+                    case 0:
+                        z.real = 1;
+                        z.imag = 0;
+                        return z;
+                    case 1:
+                        return a;
+                    case 2:
+                        z = __Pyx_c_prod(a, a);
+                        return __Pyx_c_prod(a, a);
+                    case 3:
+                        z = __Pyx_c_prod(a, a);
+                        return __Pyx_c_prod(z, a);
+                    case 4:
+                        z = __Pyx_c_prod(a, a);
+                        return __Pyx_c_prod(z, z);
+                }
+            }
+            if (a.imag == 0) {
+                if (a.real == 0) {
+                    return a;
+                }
+                r = a.real;
+                theta = 0;
+            } else {
+                r = __Pyx_c_abs(a);
+                theta = atan2(a.imag, a.real);
+            }
+            lnr = log(r);
+            z_r = exp(lnr * b.real - theta * b.imag);
+            z_theta = theta * b.real + lnr * b.imag;
+            z.real = z_r * cos(z_theta);
+            z.imag = z_r * sin(z_theta);
+            return z;
+        }
+    #endif
+#endif
+
+static CYTHON_INLINE unsigned char __Pyx_PyInt_AsUnsignedChar(PyObject* x) {
+    const unsigned char neg_one = (unsigned char)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(unsigned char) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(unsigned char)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to unsigned char" :
+                    "value too large to convert to unsigned char");
+            }
+            return (unsigned char)-1;
+        }
+        return (unsigned char)val;
+    }
+    return (unsigned char)__Pyx_PyInt_AsUnsignedLong(x);
+}
+
+static CYTHON_INLINE unsigned short __Pyx_PyInt_AsUnsignedShort(PyObject* x) {
+    const unsigned short neg_one = (unsigned short)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(unsigned short) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(unsigned short)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to unsigned short" :
+                    "value too large to convert to unsigned short");
+            }
+            return (unsigned short)-1;
+        }
+        return (unsigned short)val;
+    }
+    return (unsigned short)__Pyx_PyInt_AsUnsignedLong(x);
+}
+
+static CYTHON_INLINE unsigned int __Pyx_PyInt_AsUnsignedInt(PyObject* x) {
+    const unsigned int neg_one = (unsigned int)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(unsigned int) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(unsigned int)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to unsigned int" :
+                    "value too large to convert to unsigned int");
+            }
+            return (unsigned int)-1;
+        }
+        return (unsigned int)val;
+    }
+    return (unsigned int)__Pyx_PyInt_AsUnsignedLong(x);
+}
+
+static CYTHON_INLINE char __Pyx_PyInt_AsChar(PyObject* x) {
+    const char neg_one = (char)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(char) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(char)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to char" :
+                    "value too large to convert to char");
+            }
+            return (char)-1;
+        }
+        return (char)val;
+    }
+    return (char)__Pyx_PyInt_AsLong(x);
+}
+
+static CYTHON_INLINE short __Pyx_PyInt_AsShort(PyObject* x) {
+    const short neg_one = (short)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(short) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(short)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to short" :
+                    "value too large to convert to short");
+            }
+            return (short)-1;
+        }
+        return (short)val;
+    }
+    return (short)__Pyx_PyInt_AsLong(x);
+}
+
+static CYTHON_INLINE int __Pyx_PyInt_AsInt(PyObject* x) {
+    const int neg_one = (int)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(int) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(int)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to int" :
+                    "value too large to convert to int");
+            }
+            return (int)-1;
+        }
+        return (int)val;
+    }
+    return (int)__Pyx_PyInt_AsLong(x);
+}
+
+static CYTHON_INLINE signed char __Pyx_PyInt_AsSignedChar(PyObject* x) {
+    const signed char neg_one = (signed char)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(signed char) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(signed char)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to signed char" :
+                    "value too large to convert to signed char");
+            }
+            return (signed char)-1;
+        }
+        return (signed char)val;
+    }
+    return (signed char)__Pyx_PyInt_AsSignedLong(x);
+}
+
+static CYTHON_INLINE signed short __Pyx_PyInt_AsSignedShort(PyObject* x) {
+    const signed short neg_one = (signed short)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(signed short) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(signed short)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to signed short" :
+                    "value too large to convert to signed short");
+            }
+            return (signed short)-1;
+        }
+        return (signed short)val;
+    }
+    return (signed short)__Pyx_PyInt_AsSignedLong(x);
+}
+
+static CYTHON_INLINE signed int __Pyx_PyInt_AsSignedInt(PyObject* x) {
+    const signed int neg_one = (signed int)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(signed int) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(signed int)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to signed int" :
+                    "value too large to convert to signed int");
+            }
+            return (signed int)-1;
+        }
+        return (signed int)val;
+    }
+    return (signed int)__Pyx_PyInt_AsSignedLong(x);
+}
+
+static CYTHON_INLINE int __Pyx_PyInt_AsLongDouble(PyObject* x) {
+    const int neg_one = (int)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(int) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(int)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to int" :
+                    "value too large to convert to int");
+            }
+            return (int)-1;
+        }
+        return (int)val;
+    }
+    return (int)__Pyx_PyInt_AsLong(x);
+}
+
+static CYTHON_INLINE unsigned long __Pyx_PyInt_AsUnsignedLong(PyObject* x) {
+    const unsigned long neg_one = (unsigned long)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to unsigned long");
+            return (unsigned long)-1;
+        }
+        return (unsigned long)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to unsigned long");
+                return (unsigned long)-1;
+            }
+            return (unsigned long)PyLong_AsUnsignedLong(x);
+        } else {
+            return (unsigned long)PyLong_AsLong(x);
+        }
+    } else {
+        unsigned long val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (unsigned long)-1;
+        val = __Pyx_PyInt_AsUnsignedLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE unsigned PY_LONG_LONG __Pyx_PyInt_AsUnsignedLongLong(PyObject* x) {
+    const unsigned PY_LONG_LONG neg_one = (unsigned PY_LONG_LONG)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to unsigned PY_LONG_LONG");
+            return (unsigned PY_LONG_LONG)-1;
+        }
+        return (unsigned PY_LONG_LONG)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to unsigned PY_LONG_LONG");
+                return (unsigned PY_LONG_LONG)-1;
+            }
+            return (unsigned PY_LONG_LONG)PyLong_AsUnsignedLongLong(x);
+        } else {
+            return (unsigned PY_LONG_LONG)PyLong_AsLongLong(x);
+        }
+    } else {
+        unsigned PY_LONG_LONG val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (unsigned PY_LONG_LONG)-1;
+        val = __Pyx_PyInt_AsUnsignedLongLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE long __Pyx_PyInt_AsLong(PyObject* x) {
+    const long neg_one = (long)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to long");
+            return (long)-1;
+        }
+        return (long)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to long");
+                return (long)-1;
+            }
+            return (long)PyLong_AsUnsignedLong(x);
+        } else {
+            return (long)PyLong_AsLong(x);
+        }
+    } else {
+        long val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (long)-1;
+        val = __Pyx_PyInt_AsLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE PY_LONG_LONG __Pyx_PyInt_AsLongLong(PyObject* x) {
+    const PY_LONG_LONG neg_one = (PY_LONG_LONG)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to PY_LONG_LONG");
+            return (PY_LONG_LONG)-1;
+        }
+        return (PY_LONG_LONG)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to PY_LONG_LONG");
+                return (PY_LONG_LONG)-1;
+            }
+            return (PY_LONG_LONG)PyLong_AsUnsignedLongLong(x);
+        } else {
+            return (PY_LONG_LONG)PyLong_AsLongLong(x);
+        }
+    } else {
+        PY_LONG_LONG val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (PY_LONG_LONG)-1;
+        val = __Pyx_PyInt_AsLongLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE signed long __Pyx_PyInt_AsSignedLong(PyObject* x) {
+    const signed long neg_one = (signed long)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to signed long");
+            return (signed long)-1;
+        }
+        return (signed long)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to signed long");
+                return (signed long)-1;
+            }
+            return (signed long)PyLong_AsUnsignedLong(x);
+        } else {
+            return (signed long)PyLong_AsLong(x);
+        }
+    } else {
+        signed long val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (signed long)-1;
+        val = __Pyx_PyInt_AsSignedLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE signed PY_LONG_LONG __Pyx_PyInt_AsSignedLongLong(PyObject* x) {
+    const signed PY_LONG_LONG neg_one = (signed PY_LONG_LONG)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to signed PY_LONG_LONG");
+            return (signed PY_LONG_LONG)-1;
+        }
+        return (signed PY_LONG_LONG)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to signed PY_LONG_LONG");
+                return (signed PY_LONG_LONG)-1;
+            }
+            return (signed PY_LONG_LONG)PyLong_AsUnsignedLongLong(x);
+        } else {
+            return (signed PY_LONG_LONG)PyLong_AsLongLong(x);
+        }
+    } else {
+        signed PY_LONG_LONG val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (signed PY_LONG_LONG)-1;
+        val = __Pyx_PyInt_AsSignedLongLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static void __Pyx_WriteUnraisable(const char *name, CYTHON_UNUSED int clineno,
+                                  CYTHON_UNUSED int lineno, CYTHON_UNUSED const char *filename) {
+    PyObject *old_exc, *old_val, *old_tb;
+    PyObject *ctx;
+    __Pyx_ErrFetch(&old_exc, &old_val, &old_tb);
+    #if PY_MAJOR_VERSION < 3
+    ctx = PyString_FromString(name);
+    #else
+    ctx = PyUnicode_FromString(name);
+    #endif
+    __Pyx_ErrRestore(old_exc, old_val, old_tb);
+    if (!ctx) {
+        PyErr_WriteUnraisable(Py_None);
+    } else {
+        PyErr_WriteUnraisable(ctx);
+        Py_DECREF(ctx);
+    }
+}
+
+static CYTHON_INLINE int __Pyx_StrEq(const char *s1, const char *s2) {
+     while (*s1 != '\0' && *s1 == *s2) { s1++; s2++; }
+     return *s1 == *s2;
+}
+
+static int __Pyx_check_binary_version(void) {
+    char ctversion[4], rtversion[4];
+    PyOS_snprintf(ctversion, 4, "%d.%d", PY_MAJOR_VERSION, PY_MINOR_VERSION);
+    PyOS_snprintf(rtversion, 4, "%s", Py_GetVersion());
+    if (ctversion[0] != rtversion[0] || ctversion[2] != rtversion[2]) {
+        char message[200];
+        PyOS_snprintf(message, sizeof(message),
+                      "compiletime version %s of module '%.100s' "
+                      "does not match runtime version %s",
+                      ctversion, __Pyx_MODULE_NAME, rtversion);
+        #if PY_VERSION_HEX < 0x02050000
+        return PyErr_Warn(NULL, message);
+        #else
+        return PyErr_WarnEx(NULL, message, 1);
+        #endif
+    }
+    return 0;
+}
+
+static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
+#if PY_VERSION_HEX >= 0x02070000 && !(PY_MAJOR_VERSION==3&&PY_MINOR_VERSION==0)
+    PyObject *ob = PyCapsule_New(vtable, 0, 0);
+#else
+    PyObject *ob = PyCObject_FromVoidPtr(vtable, 0);
+#endif
+    if (!ob)
+        goto bad;
+    if (PyDict_SetItemString(dict, "__pyx_vtable__", ob) < 0)
+        goto bad;
+    Py_DECREF(ob);
+    return 0;
+bad:
+    Py_XDECREF(ob);
+    return -1;
+}
+
+#ifndef __PYX_HAVE_RT_ImportModule
+#define __PYX_HAVE_RT_ImportModule
+static PyObject *__Pyx_ImportModule(const char *name) {
+    PyObject *py_name = 0;
+    PyObject *py_module = 0;
+    py_name = __Pyx_PyIdentifier_FromString(name);
+    if (!py_name)
+        goto bad;
+    py_module = PyImport_Import(py_name);
+    Py_DECREF(py_name);
+    return py_module;
+bad:
+    Py_XDECREF(py_name);
+    return 0;
+}
+#endif
+
+#ifndef __PYX_HAVE_RT_ImportType
+#define __PYX_HAVE_RT_ImportType
+static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name,
+    size_t size, int strict)
+{
+    PyObject *py_module = 0;
+    PyObject *result = 0;
+    PyObject *py_name = 0;
+    char warning[200];
+    Py_ssize_t basicsize;
+#ifdef Py_LIMITED_API
+    PyObject *py_basicsize;
+#endif
+    py_module = __Pyx_ImportModule(module_name);
+    if (!py_module)
+        goto bad;
+    py_name = __Pyx_PyIdentifier_FromString(class_name);
+    if (!py_name)
+        goto bad;
+    result = PyObject_GetAttr(py_module, py_name);
+    Py_DECREF(py_name);
+    py_name = 0;
+    Py_DECREF(py_module);
+    py_module = 0;
+    if (!result)
+        goto bad;
+    if (!PyType_Check(result)) {
+        PyErr_Format(PyExc_TypeError,
+            "%s.%s is not a type object",
+            module_name, class_name);
+        goto bad;
+    }
+#ifndef Py_LIMITED_API
+    basicsize = ((PyTypeObject *)result)->tp_basicsize;
+#else
+    py_basicsize = PyObject_GetAttrString(result, "__basicsize__");
+    if (!py_basicsize)
+        goto bad;
+    basicsize = PyLong_AsSsize_t(py_basicsize);
+    Py_DECREF(py_basicsize);
+    py_basicsize = 0;
+    if (basicsize == (Py_ssize_t)-1 && PyErr_Occurred())
+        goto bad;
+#endif
+    if (!strict && (size_t)basicsize > size) {
+        PyOS_snprintf(warning, sizeof(warning),
+            "%s.%s size changed, may indicate binary incompatibility",
+            module_name, class_name);
+        #if PY_VERSION_HEX < 0x02050000
+        if (PyErr_Warn(NULL, warning) < 0) goto bad;
+        #else
+        if (PyErr_WarnEx(NULL, warning, 0) < 0) goto bad;
+        #endif
+    }
+    else if ((size_t)basicsize != size) {
+        PyErr_Format(PyExc_ValueError,
+            "%s.%s has the wrong size, try recompiling",
+            module_name, class_name);
+        goto bad;
+    }
+    return (PyTypeObject *)result;
+bad:
+    Py_XDECREF(py_module);
+    Py_XDECREF(result);
+    return NULL;
+}
+#endif
+
+static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) {
+    int start = 0, mid = 0, end = count - 1;
+    if (end >= 0 && code_line > entries[end].code_line) {
+        return count;
+    }
+    while (start < end) {
+        mid = (start + end) / 2;
+        if (code_line < entries[mid].code_line) {
+            end = mid;
+        } else if (code_line > entries[mid].code_line) {
+             start = mid + 1;
+        } else {
+            return mid;
+        }
+    }
+    if (code_line <= entries[mid].code_line) {
+        return mid;
+    } else {
+        return mid + 1;
+    }
+}
+static PyCodeObject *__pyx_find_code_object(int code_line) {
+    PyCodeObject* code_object;
+    int pos;
+    if (unlikely(!code_line) || unlikely(!__pyx_code_cache.entries)) {
+        return NULL;
+    }
+    pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line);
+    if (unlikely(pos >= __pyx_code_cache.count) || unlikely(__pyx_code_cache.entries[pos].code_line != code_line)) {
+        return NULL;
+    }
+    code_object = __pyx_code_cache.entries[pos].code_object;
+    Py_INCREF(code_object);
+    return code_object;
+}
+static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) {
+    int pos, i;
+    __Pyx_CodeObjectCacheEntry* entries = __pyx_code_cache.entries;
+    if (unlikely(!code_line)) {
+        return;
+    }
+    if (unlikely(!entries)) {
+        entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Malloc(64*sizeof(__Pyx_CodeObjectCacheEntry));
+        if (likely(entries)) {
+            __pyx_code_cache.entries = entries;
+            __pyx_code_cache.max_count = 64;
+            __pyx_code_cache.count = 1;
+            entries[0].code_line = code_line;
+            entries[0].code_object = code_object;
+            Py_INCREF(code_object);
+        }
+        return;
+    }
+    pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line);
+    if ((pos < __pyx_code_cache.count) && unlikely(__pyx_code_cache.entries[pos].code_line == code_line)) {
+        PyCodeObject* tmp = entries[pos].code_object;
+        entries[pos].code_object = code_object;
+        Py_DECREF(tmp);
+        return;
+    }
+    if (__pyx_code_cache.count == __pyx_code_cache.max_count) {
+        int new_max = __pyx_code_cache.max_count + 64;
+        entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Realloc(
+            __pyx_code_cache.entries, new_max*sizeof(__Pyx_CodeObjectCacheEntry));
+        if (unlikely(!entries)) {
+            return;
+        }
+        __pyx_code_cache.entries = entries;
+        __pyx_code_cache.max_count = new_max;
+    }
+    for (i=__pyx_code_cache.count; i>pos; i--) {
+        entries[i] = entries[i-1];
+    }
+    entries[pos].code_line = code_line;
+    entries[pos].code_object = code_object;
+    __pyx_code_cache.count++;
+    Py_INCREF(code_object);
+}
+
+#include "compile.h"
+#include "frameobject.h"
+#include "traceback.h"
+static PyCodeObject* __Pyx_CreateCodeObjectForTraceback(
+            const char *funcname, int c_line,
+            int py_line, const char *filename) {
+    PyCodeObject *py_code = 0;
+    PyObject *py_srcfile = 0;
+    PyObject *py_funcname = 0;
+    #if PY_MAJOR_VERSION < 3
+    py_srcfile = PyString_FromString(filename);
+    #else
+    py_srcfile = PyUnicode_FromString(filename);
+    #endif
+    if (!py_srcfile) goto bad;
+    if (c_line) {
+        #if PY_MAJOR_VERSION < 3
+        py_funcname = PyString_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line);
+        #else
+        py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line);
+        #endif
+    }
+    else {
+        #if PY_MAJOR_VERSION < 3
+        py_funcname = PyString_FromString(funcname);
+        #else
+        py_funcname = PyUnicode_FromString(funcname);
+        #endif
+    }
+    if (!py_funcname) goto bad;
+    py_code = __Pyx_PyCode_New(
+        0,            /*int argcount,*/
+        0,            /*int kwonlyargcount,*/
+        0,            /*int nlocals,*/
+        0,            /*int stacksize,*/
+        0,            /*int flags,*/
+        __pyx_empty_bytes, /*PyObject *code,*/
+        __pyx_empty_tuple, /*PyObject *consts,*/
+        __pyx_empty_tuple, /*PyObject *names,*/
+        __pyx_empty_tuple, /*PyObject *varnames,*/
+        __pyx_empty_tuple, /*PyObject *freevars,*/
+        __pyx_empty_tuple, /*PyObject *cellvars,*/
+        py_srcfile,   /*PyObject *filename,*/
+        py_funcname,  /*PyObject *name,*/
+        py_line,      /*int firstlineno,*/
+        __pyx_empty_bytes  /*PyObject *lnotab*/
+    );
+    Py_DECREF(py_srcfile);
+    Py_DECREF(py_funcname);
+    return py_code;
+bad:
+    Py_XDECREF(py_srcfile);
+    Py_XDECREF(py_funcname);
+    return NULL;
+}
+static void __Pyx_AddTraceback(const char *funcname, int c_line,
+                               int py_line, const char *filename) {
+    PyCodeObject *py_code = 0;
+    PyObject *py_globals = 0;
+    PyFrameObject *py_frame = 0;
+    py_code = __pyx_find_code_object(c_line ? c_line : py_line);
+    if (!py_code) {
+        py_code = __Pyx_CreateCodeObjectForTraceback(
+            funcname, c_line, py_line, filename);
+        if (!py_code) goto bad;
+        __pyx_insert_code_object(c_line ? c_line : py_line, py_code);
+    }
+    py_globals = PyModule_GetDict(__pyx_m);
+    if (!py_globals) goto bad;
+    py_frame = PyFrame_New(
+        PyThreadState_GET(), /*PyThreadState *tstate,*/
+        py_code,             /*PyCodeObject *code,*/
+        py_globals,          /*PyObject *globals,*/
+        0                    /*PyObject *locals*/
+    );
+    if (!py_frame) goto bad;
+    py_frame->f_lineno = py_line;
+    PyTraceBack_Here(py_frame);
+bad:
+    Py_XDECREF(py_code);
+    Py_XDECREF(py_frame);
+}
+
+static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
+    while (t->p) {
+        #if PY_MAJOR_VERSION < 3
+        if (t->is_unicode) {
+            *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
+        } else if (t->intern) {
+            *t->p = PyString_InternFromString(t->s);
+        } else {
+            *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
+        }
+        #else  /* Python 3+ has unicode identifiers */
+        if (t->is_unicode | t->is_str) {
+            if (t->intern) {
+                *t->p = PyUnicode_InternFromString(t->s);
+            } else if (t->encoding) {
+                *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL);
+            } else {
+                *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
+            }
+        } else {
+            *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
+        }
+        #endif
+        if (!*t->p)
+            return -1;
+        ++t;
+    }
+    return 0;
+}
+
+static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) {
+   int is_true = x == Py_True;
+   if (is_true | (x == Py_False) | (x == Py_None)) return is_true;
+   else return PyObject_IsTrue(x);
+}
+static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x) {
+  PyNumberMethods *m;
+  const char *name = NULL;
+  PyObject *res = NULL;
+#if PY_VERSION_HEX < 0x03000000
+  if (PyInt_Check(x) || PyLong_Check(x))
+#else
+  if (PyLong_Check(x))
+#endif
+    return Py_INCREF(x), x;
+  m = Py_TYPE(x)->tp_as_number;
+#if PY_VERSION_HEX < 0x03000000
+  if (m && m->nb_int) {
+    name = "int";
+    res = PyNumber_Int(x);
+  }
+  else if (m && m->nb_long) {
+    name = "long";
+    res = PyNumber_Long(x);
+  }
+#else
+  if (m && m->nb_int) {
+    name = "int";
+    res = PyNumber_Long(x);
+  }
+#endif
+  if (res) {
+#if PY_VERSION_HEX < 0x03000000
+    if (!PyInt_Check(res) && !PyLong_Check(res)) {
+#else
+    if (!PyLong_Check(res)) {
+#endif
+      PyErr_Format(PyExc_TypeError,
+                   "__%s__ returned non-%s (type %.200s)",
+                   name, name, Py_TYPE(res)->tp_name);
+      Py_DECREF(res);
+      return NULL;
+    }
+  }
+  else if (!PyErr_Occurred()) {
+    PyErr_SetString(PyExc_TypeError,
+                    "an integer is required");
+  }
+  return res;
+}
+static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) {
+  Py_ssize_t ival;
+  PyObject* x = PyNumber_Index(b);
+  if (!x) return -1;
+  ival = PyInt_AsSsize_t(x);
+  Py_DECREF(x);
+  return ival;
+}
+static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) {
+#if PY_VERSION_HEX < 0x02050000
+   if (ival <= LONG_MAX)
+       return PyInt_FromLong((long)ival);
+   else {
+       unsigned char *bytes = (unsigned char *) &ival;
+       int one = 1; int little = (int)*(unsigned char*)&one;
+       return _PyLong_FromByteArray(bytes, sizeof(size_t), little, 0);
+   }
+#else
+   return PyInt_FromSize_t(ival);
+#endif
+}
+static CYTHON_INLINE size_t __Pyx_PyInt_AsSize_t(PyObject* x) {
+   unsigned PY_LONG_LONG val = __Pyx_PyInt_AsUnsignedLongLong(x);
+   if (unlikely(val == (unsigned PY_LONG_LONG)-1 && PyErr_Occurred())) {
+       return (size_t)-1;
+   } else if (unlikely(val != (unsigned PY_LONG_LONG)(size_t)val)) {
+       PyErr_SetString(PyExc_OverflowError,
+                       "value too large to convert to size_t");
+       return (size_t)-1;
+   }
+   return (size_t)val;
+}
+
+
+#endif /* Py_PYTHON_H */
diff --git a/lib/bx/arrays/array_tree.pyx b/lib/bx/arrays/array_tree.pyx
new file mode 100644
index 0000000..89de0fd
--- /dev/null
+++ b/lib/bx/arrays/array_tree.pyx
@@ -0,0 +1,514 @@
+from __future__ import division
+
+__all__ = [ 'ArrayTree', 'FileArrayTreeDict', 'array_tree_dict_from_reader' ]
+
+import numpy
+from numpy import *
+cimport numpy
+
+cimport bx.arrays.wiggle
+
+from bx.misc.binary_file import BinaryFileWriter, BinaryFileReader
+from bx.misc.cdb import FileCDBDict
+
+"""
+Classes for storing binary data on disk in a tree structure that allows for
+efficient sparse storage (when the data occurs in contiguous blocks), fast
+access to a specific block of data, and fast access to summaries at different
+resolutions.
+
+On disk format
+--------------
+
+Blocks are stored contiguously on disk in level-order. Contents should always be
+network byte order (big endian), however this implementation will byte-swap when
+reading  if necessary. File contents:
+
+- magic:      uint32
+- version:    unit32
+- array size: uint32
+- block size: uint32
+- array type: 4 chars (numpy typecode, currently only simple types represented by one char are supported)
+
+- Internal nodes in level order
+    - Summary
+        - count of valid values in each subtree : sizeof( dtype ) * block_size
+        - frequencies: sizeof ( int32 ) * block_size
+        - min of valid values in each subtree : sizeof( dtype ) * block_size
+        - max of valid values in each subtree : sizeof( dtype ) * block_size
+        - sum of valid values in each subtree : sizeof( dtype ) * block_size
+        - sum of squares of valid values in each subtree : sizeof( dtype ) * block_size
+    - File offsets of each child node: uint64 * block_size
+  
+- Leaf nodes
+    - data points: sizeof( dtype ) * block_size
+    
+- Version 1 reads version 0 and version 1
+
+"""
+
+## Enhancement ideas:
+## 
+##   - Write markers of the number of blocks skipped between blocks. This would
+##     allow fast striding across data or summaries (use the indexes to get to
+##     the start of a block, then just read straight through). Would this help?
+## 
+##   - Compression for blocks?
+
+MAGIC = 0x310ec7dc
+VERSION = 1
+NUM_SUMMARY_ARRAYS = 6
+
+def array_tree_dict_from_reader( reader, sizes, default_size=2147483647, block_size=1000, no_leaves=False ):
+    # Create empty array trees
+    rval = {}
+    ## for key, size in sizes.iteritems():
+    ##    rval[ key ] = ArrayTree( size, 1000 )
+    # Fill
+    last_chrom = None
+    last_array_tree = None
+    for chrom, start, end, _, val in reader:
+        if chrom != last_chrom:
+            if chrom not in rval:
+                rval[chrom] = ArrayTree( sizes.get( chrom, default_size ), block_size, no_leaves=no_leaves )
+            last_array_tree = rval[chrom]
+        last_array_tree.set_range( start, end, val )
+    return rval
+                
+
+cdef class FileArrayTreeDict:
+    """
+    Access to a file containing multiple array trees indexed by a string key.
+    """
+    cdef object io
+    cdef object cdb_dict
+    def __init__( self, file ):
+        self.io = io = BinaryFileReader( file, MAGIC )
+        assert (0 <= io.read_uint32() <= 1) # Check for version 0 or 1
+        self.cdb_dict = FileCDBDict( file, is_little_endian=io.is_little_endian )
+    def __getitem__( self, key ):
+        offset = self.cdb_dict[key]
+        offset = self.io.unpack( "L", offset )[0]
+        self.io.seek( offset )
+        return FileArrayTree( self.io.file, self.io.is_little_endian )
+    
+    @classmethod
+    def dict_to_file( Class, dict, file, is_little_endian=True, no_leaves=False ):
+        """
+        Writes a dictionary of array trees to a file that can then be
+        read efficiently using this class.
+        """
+        io = BinaryFileWriter( file, is_little_endian=is_little_endian )
+        # Write magic number and version
+        io.write_uint32( MAGIC )
+        io.write_uint32( VERSION )
+        # Write cdb index with fake values just to fill space
+        cdb_dict = {}
+        for key in dict.iterkeys():
+            cdb_dict[ key ] = io.pack( "L", 0 )
+        cdb_offset = io.tell()
+        FileCDBDict.to_file( cdb_dict, file, is_little_endian=is_little_endian )
+        # Write each tree and save offset
+        for key, value in dict.iteritems():
+            offset = io.tell()
+            cdb_dict[ key ] = io.pack( "L", offset )
+            value.to_file( file, is_little_endian=is_little_endian, no_leaves=no_leaves )
+        # Go back and write the index again
+        io.seek( cdb_offset )
+        FileCDBDict.to_file( cdb_dict, file, is_little_endian=is_little_endian )
+        
+cdef class FileArrayTree:
+    """
+    Wrapper for ArrayTree stored in file that reads as little as possible
+    """
+    cdef public int max
+    cdef public int block_size
+    cdef public object dtype
+    cdef public int levels
+    cdef public int offset
+    cdef public int root_offset
+    cdef object io
+    
+    def __init__( self, file, is_little_endian=True ):
+        self.io = BinaryFileReader( file, is_little_endian=is_little_endian )
+        self.offset = self.io.tell()
+        # Read basic info about the tree
+        self.max = self.io.read_uint32()
+        self.block_size = self.io.read_uint32()
+        # Read dtype and canonicalize
+        dt = self.io.read( 1 )
+        self.dtype = numpy.dtype( dt )
+        self.io.skip( 3 )
+        # How many levels are needed to cover the entire range?
+        self.levels = 0
+        while ( <long long> self.block_size ) ** ( self.levels + 1 ) < self.max:
+            self.levels += 1
+        # Not yet dealing with the case where the root is a Leaf
+        assert self.levels > 0, "max < block_size not yet handled"
+        # Save offset of root
+        self.root_offset = self.io.tell()
+        
+    def __getitem__( self, index ):
+        min = self.r_seek_to_node( index, 0, self.root_offset, self.levels, 0 )
+        if min < 0:
+            return nan
+        self.io.skip( self.dtype.itemsize * ( index - min ) )
+        return self.io.read_raw_array( self.dtype, 1 )[0]
+        
+    def get_summary( self, index, level ):
+        if level <= 0 or level > self.levels:
+            raise ValueError, "level must be <= self.levels"
+        if self.r_seek_to_node( index, 0, self.root_offset, self.levels, level ) < 0:
+            return None
+        # Read summary arrays
+        s = Summary()
+        s.counts = self.io.read_raw_array( self.dtype, self.block_size )
+        s.frequencies = self.io.read_raw_array( self.dtype, self.block_size )
+        s.sums = self.io.read_raw_array( self.dtype, self.block_size )
+        s.mins = self.io.read_raw_array( self.dtype, self.block_size)
+        s.maxs = self.io.read_raw_array( self.dtype, self.block_size )
+        s.sumsquares = self.io.read_raw_array( self.dtype, self.block_size )
+        return s
+        
+    def get_leaf( self, index ):
+        if self.r_seek_to_node( index, 0, self.root_offset, self.levels, 0 ) < 0:
+            return []
+        return self.io.read_raw_array( self.dtype, self.block_size )
+        
+    cdef int r_seek_to_node( self, int index, int min, long long offset, int level, int desired_level ):
+        """
+        Seek to the start of the node at `desired_level` that contains `index`.
+        Returns the minimum value represented in that node.
+        """
+        cdef int child_size, bin_index, child_min
+        self.io.seek( offset )
+        if level > desired_level:
+            child_size = self.block_size ** level
+            bin_index = ( index - min ) // ( child_size ) 
+            child_min = min + ( bin_index * child_size )
+            # Skip summary arrays -- # arrays * itemsize * block_size
+            self.io.skip( NUM_SUMMARY_ARRAYS * self.dtype.itemsize * self.block_size )
+            # Skip to offset of correct child -- offsets are 8 bytes
+            self.io.skip( 8 * bin_index )
+            # Read offset of child
+            child_offset = self.io.read_uint64()
+            # print "co: %s\tbi: %s\tcm: %s\n" % (child_offset, bin_index, child_min)
+            if child_offset == 0:
+                return -1
+            return self.r_seek_to_node( index, child_min, child_offset, level - 1, desired_level )
+        else:
+            # The file pointer is at the start of the desired node, do nothing
+            return min
+
+cdef class Summary:
+    """
+    Summary for a non-leaf level of the tree, contains arrays of the min, max,
+    valid count, sum, and sum-of-squares for each child.
+    """
+    cdef public object counts
+    cdef public object frequencies
+    cdef public object mins
+    cdef public object maxs
+    cdef public object sums
+    cdef public object sumsquares
+
+cdef class ArrayTreeNode
+cdef class ArrayTreeLeaf
+
+cdef class ArrayTree:
+    """
+    Stores a sparse array of data as a tree.
+    
+    An array of `self.max` values is stored in a tree in which each leaf
+    contains `self.block_size` values and each internal node contains
+    `self.block_size` children.
+    
+    Entirely empty subtrees are not stored. Thus, the storage is efficient for
+    data that is block sparse -- having contiguous chunks of `self.block_size` or
+    larger data. Currently it is not efficient if the data is strided (e.g.
+    one or two data points in every interval of length `self.block_size`).
+    
+    Internal nodes store `Summary` instances for their subtrees. 
+    """
+
+    cdef public int max
+    cdef public int block_size
+    cdef public object dtype
+    cdef public int levels
+    cdef public int no_leaves
+    cdef public ArrayTreeNode root
+
+    def __init__( self, int max, int block_size, dtype=float32, no_leaves=False ):
+        """
+        Create a new array tree of size `max` 
+        """
+        self.max = max
+        self.block_size = block_size
+        self.no_leaves = no_leaves
+        # Force the dtype argument to its canonical dtype object
+        self.dtype = numpy.dtype( dtype )
+        # How many levels are needed to cover the entire range?
+        self.levels = 0
+        while ( <long long> self.block_size ) ** ( self.levels + 1 ) < self.max:
+            self.levels += 1
+        # Not yet dealing with the case where the root is a Leaf
+        assert self.levels > 0, "max < block_size not yet handled"
+        # Create the root node`
+        self.root = ArrayTreeNode( self, 0, max, block_size, self.levels )
+        
+    def __setitem__( self, int index, value ):
+        self.root.set( index, value )
+        
+    def set_range( self, int start, int end, value ):
+        for i from start <= i < end:
+            self.root.set( i, value )
+        
+    def __getitem__( self, int index ):
+        return self.root.get( index )
+        
+    def to_file( self, f, is_little_endian=True, no_leaves=False ):
+        io = BinaryFileWriter( f, is_little_endian=is_little_endian )
+        ## io.write_uint32( VERSION )
+        io.write_uint32( self.max )
+        io.write_uint32( self.block_size )
+        io.write( self.dtype.char )
+        io.write( "\0\0\0" )
+        # Data pass, level order
+        if no_leaves:
+            bottom_level = 0
+        else:
+            bottom_level = -1
+        for level in range( self.levels, bottom_level, -1 ):
+            self.root.to_file_data_pass( io, level )
+        # Offset pass to fix up indexes
+        self.root.to_file_offset_pass( io )
+        
+    @classmethod
+    def from_file( Class, f, is_little_endian=True ):        
+        io = BinaryFileReader( f, is_little_endian=is_little_endian )
+        ## assert io.read_uint32() == VERSION
+        max = io.read_uint32()
+        block_size = io.read_uint32()
+        dt = io.read( 1 )
+        io.read( 3 )
+        tree = Class( max, block_size, dt )
+        tree.root.from_file( io )
+        return tree
+    
+    @classmethod
+    def from_sequence( Class, s, block_size=1000 ):
+        """
+        Build an ArrayTree from a sequence like object (must have at least
+        length and getitem).
+        """
+        tree = Class( len( s ), block_size )
+        for i in range( len( s ) ):
+            tree[i] = s[i]
+        return tree
+        
+cdef class ArrayTreeNode:
+    """
+    Internal node of an ArrayTree. Contains summary data and pointers to
+    subtrees.
+    """
+
+    cdef ArrayTree tree
+    cdef int min
+    cdef int max
+    cdef int block_size
+    cdef int level
+    cdef int child_size
+    cdef object children
+    cdef public Summary summary
+    cdef public long start_offset
+
+    def __init__( self, ArrayTree tree, int min, int max, int block_size, int level ):
+        self.tree = tree
+        self.min = min
+        self.max = max
+        self.block_size = block_size
+        self.level = level
+        # Each of my children represents block_size ** level values
+        self.child_size = self.block_size ** self.level        
+        self.children = [None] * self.block_size
+        self.summary = None
+        self.start_offset = 0
+        
+    cdef inline init_bin( self, int index ):
+        cdef int min = self.min + ( index * self.child_size )
+        cdef int max = min + self.child_size
+        if self.level == 1:
+            self.children[ index ] = ArrayTreeLeaf( self.tree, min, max )
+        else:
+            self.children[ index ] = ArrayTreeNode( self.tree, min, max, self.block_size, self.level - 1 )
+            
+    def set( self, int index, value ):
+        cdef int bin_index = ( index - self.min ) // ( self.child_size )
+        if self.children[ bin_index ] is None:
+            self.init_bin( bin_index )
+        self.children[ bin_index ].set( index, value )
+        
+    def get( self, int index ):
+        cdef int bin_index = ( index - self.min ) // ( self.child_size ) 
+        if self.children[ bin_index ] is None:
+            return nan
+        else:
+            return self.children[ bin_index ].get( index )
+            
+    cpdef build_summary( self ):
+        """
+        Build summary of children. 
+        """
+        counts = empty( self.tree.block_size, self.tree.dtype )
+        frequencies = empty( self.tree.block_size, self.tree.dtype )
+        mins = empty( self.tree.block_size, self.tree.dtype )
+        maxs = empty( self.tree.block_size, self.tree.dtype )
+        sums = empty( self.tree.block_size, self.tree.dtype )
+        sumsquares = empty( self.tree.block_size, self.tree.dtype )
+        for i in range( len( self.children ) ):
+            if self.children[i]:
+                if self.level == 1:
+                    v = self.children[i].values
+                    counts[i] = sum( ~isnan( v ) )
+                    frequencies[i] = self.children[i].frequency
+                    mins[i] = nanmin( v )
+                    maxs[i] = nanmax( v )
+                    sums[i] = nansum( v )
+                    sumsquares[i] = nansum( v ** 2 )
+                else:
+                    c = self.children[i]
+                    c.build_summary()
+                    counts[i] = sum( c.summary.counts )
+                    frequencies[i] = sum( c.summary.frequencies )
+                    mins[i] = nanmin( c.summary.mins )
+                    maxs[i] = nanmax( c.summary.maxs )
+                    sums[i] = nansum( c.summary.sums )
+                    sumsquares[i] = nansum( c.summary.sumsquares )
+            else:
+                counts[i] = 0
+                frequencies[i] = 0
+                mins[i] = nan
+                maxs[i] = nan
+                sums[i] = nan
+                sumsquares[i] = nan
+        s = Summary()
+        s.counts = counts
+        s.frequencies = frequencies
+        s.mins = mins
+        s.maxs = maxs
+        s.sums = sums
+        s.sumsquares = sumsquares
+        self.summary = s
+        
+    def to_file_data_pass( self, io, level ):
+        """
+        First pass of writing to file, writes data and saves position of block.
+        """
+        assert self.summary, "Writing without summaries is currently not supported"
+        # If we are at the current level being written, write a block
+        if self.level == level:
+            # Save file offset where this block starts
+            self.start_offset = io.tell()
+            # Write out summary data
+            io.write_raw_array( self.summary.counts )
+            io.write_raw_array( self.summary.frequencies )
+            io.write_raw_array( self.summary.sums )
+            io.write_raw_array( self.summary.mins )
+            io.write_raw_array( self.summary.maxs )
+            io.write_raw_array( self.summary.sumsquares )
+            # Skip enough room for child offsets (block_size children * 64bits)
+            io.skip( self.tree.block_size * 8 )
+        # Must be writing a lower level, so recurse
+        else:
+            # Write all non-empty children
+            for i in range( len( self.children ) ):
+                if self.children[i] is not None:
+                    self.children[i].to_file_data_pass( io, level )
+                
+    def to_file_offset_pass( self, io ):
+        """
+        Second pass of writing to file, seek to appropriate position and write
+        offsets of children.
+        """
+        # Seek to location of child offfsets (skip over # summary arrays)
+        skip_amount = NUM_SUMMARY_ARRAYS * self.tree.dtype.itemsize * self.block_size
+        io.seek( self.start_offset + skip_amount )
+        # Write the file offset of each child into the index
+        for child in self.children:
+            if child is None:
+                io.write_uint64( 0 )
+            else:
+                io.write_uint64( child.start_offset )
+        # Recursively write offsets in child nodes
+        for child in self.children:
+            if child is not None:
+                child.to_file_offset_pass( io )
+    
+    def from_file( self, io ):
+        """
+        Load entire summary and all children into memory.
+        """
+        dtype = self.tree.dtype
+        block_size = self.tree.block_size
+        # Read summary arrays
+        s = Summary()
+        s.counts = io.read_raw_array( dtype, block_size )
+        s.frequencies = io.read_raw_array( int32, block_size )
+        s.sums = io.read_raw_array( dtype, block_size )
+        s.mins = io.read_raw_array( dtype, block_size)
+        s.maxs = io.read_raw_array( dtype, block_size )
+        s.sumsquares = io.read_raw_array( dtype, block_size )
+        self.summary = s
+        # Read offset of all children
+        child_offsets = [ io.read_uint64() for i in range( block_size ) ]
+        for i in range( block_size ):
+            if child_offsets[i] > 0:
+                self.init_bin( i )
+                io.seek( child_offsets[i] )
+                self.children[i].from_file( io )
+                
+    def get_from_file( self, io, index ):
+        cdef int bin_index = ( index - self.min ) //( self.child_size ) 
+        if self.children[ bin_index ] is None:
+            return nan
+        else:
+            return self.children[ bin_index ].get( index )
+        
+cdef class ArrayTreeLeaf:
+    """
+    Leaf node of an ArrayTree, contains data values.
+    """
+    
+    cdef ArrayTree tree
+    cdef int min
+    cdef int max
+    cdef public int frequency
+    cdef public numpy.ndarray values
+    cdef public long start_offset
+    
+    def __init__( self, ArrayTree tree, int min, int max ):
+        self.tree = tree
+        self.min = min
+        self.max = max
+        self.frequency = 0
+        self.values = empty( max - min, self.tree.dtype )
+        self.values[:] = nan
+        self.start_offset = 0
+        
+    def set( self, index, value ):
+        self.frequency += 1
+        self.values[ index - self.min ] = value
+        
+    def get( self, index ):
+        return self.values[ index - self.min ]
+        
+    def to_file_data_pass( self, io, level ):
+        assert level == 0
+        self.start_offset = io.tell()
+        io.write_raw_array( self.values )
+    
+    def to_file_offset_pass( self, io ):
+        pass
+        
+    def from_file( self, io ):
+        self.values = io.read_raw_array( self.tree.dtype, self.tree.block_size )
diff --git a/lib/bx/arrays/array_tree_tests.py b/lib/bx/arrays/array_tree_tests.py
new file mode 100644
index 0000000..698df25
--- /dev/null
+++ b/lib/bx/arrays/array_tree_tests.py
@@ -0,0 +1,117 @@
+import sys, os
+import unittest
+import tempfile
+try:
+    sys.path.insert(0, os.path.dirname(os.path.dirname(__file__)))
+except:
+    sys.path.insert(0, os.path.dirname(os.path.abspath(".")))
+
+from bx.arrays.array_tree import ArrayTree, FileArrayTree, FileArrayTreeDict, array_tree_dict_from_reader
+from bx.arrays.bed import BedReader
+from bx.arrays.wiggle import WiggleReader
+
+class TestArrayTree(unittest.TestCase):
+    def setUp(self):
+        tree = ArrayTree(10000, 10) # max value of 10000, each block has 10 numbers
+        for i in range(5000):
+            tree[i] = i
+        
+        # Insert extra copies to test frequency
+        for i in range(3000):
+            tree[i] = i
+        
+        tree.set_range(5000, 9001, 100)
+        tree.root.build_summary()
+        
+        d = {'test': tree}
+        f = tempfile.TemporaryFile()
+        FileArrayTreeDict.dict_to_file( d, f )
+        f.seek(0)
+        self.filearraytreedict = FileArrayTreeDict(f)
+        self.filearraytree = self.filearraytreedict['test']
+        
+    def test_get_summary(self):
+        f = self.filearraytree
+        lvl1 = f.get_summary(0, 1)
+        self.assertEqual( map(float, lvl1.sums/lvl1.counts), [4.5, 14.5, 24.5, 34.5, 44.5, 54.5, 64.5, 74.5, 84.5, 94.5])
+        lvl2 = f.get_summary(0, 2)
+        self.assertEqual( map(float, lvl2.sums/lvl2.counts), [49.5, 149.5, 249.5, 349.5, 449.5, 549.5, 649.5, 749.5, 849.5, 949.5])
+        lvl3 = f.get_summary(0, 3)
+        self.assertEqual( map(float, lvl3.sums/lvl3.counts), [499.5, 1499.5, 2499.5, 3499.5, 4499.5, 100.0, 100.0, 100.0, 100.0, 100.0])
+        lvl2_2 = f.get_summary(3000, 2)
+        self.assertEqual( map(float, lvl2_2.sums/lvl2_2.counts), [3049.5, 3149.5, 3249.5, 3349.5, 3449.5, 3549.5, 3649.5, 3749.5, 3849.5, 3949.5])
+        
+    def test_get_leaf(self):
+        f = self.filearraytree
+        from_start = [int(i) for i in f.get_leaf(0)]
+        from_middle = [int(i) for i in f.get_leaf(5)]
+        self.assertEqual(from_start, from_middle)
+        self.assertEqual(from_start, range(10))
+        
+        from_start = [int(i) for i in f.get_leaf(4999)]
+        self.assertEqual(from_start, range(4990, 5000))
+        
+        from_start = [int(i) for i in f.get_leaf(9600)]
+        self.assertEqual(from_start, [])
+        
+    def test_big(self):
+        tree = ArrayTree(2147483647, 1000) # What we use for tracks
+        for i in range(5000):
+            tree[i] = i
+        
+        # Insert extra copies to test frequency
+        for i in range(3000):
+            tree[i] = i
+        
+        tree.set_range(5000, 9001, 100)
+        tree.set_range(14000000, 15000000, 200)
+        tree.root.build_summary()
+        
+        d = {'test': tree}
+        f = tempfile.TemporaryFile()
+        FileArrayTreeDict.dict_to_file( d, f )
+        f.seek(0)
+        at = FileArrayTreeDict(f)['test']
+        
+        lvl1 = at.get_summary(14000000, 1)
+        avgs = map(float, lvl1.sums/lvl1.counts)
+        self.assertEqual( len(avgs), 1000 )
+        self.assertEqual( avgs, [ 200 for i in range(0, 1000)] )
+    
+    
+#    def create_bed(self):
+#        reader = BedReader( open( "22.bed.txt" ) )
+#        temp = tempfile.TemporaryFile()
+#        
+#        d = array_tree_dict_from_reader( reader, {}, block_size = 1000 )
+#
+#        for array_tree in d.itervalues():
+#            array_tree.root.build_summary()
+#
+#        FileArrayTreeDict.dict_to_file( d, open("tree.at", "w"), no_leaves=True ) # just summaries
+#        
+#    def test_bed(self):
+#        # self.create_bed()
+#        print "bed"
+#        at = FileArrayTreeDict( open( "tree.at" ) )['chr22']
+#        print map(, at.get_summary(14000000, 1).frequencies)
+        
+    
+    def test_get_frequencies(self):
+        f = self.filearraytree
+        self.assertEqual( map(float, f.get_summary(0, 1).frequencies), ([20] * 10) )
+        self.assertEqual( map(float, f.get_summary(4000, 1).frequencies), ([10] * 10) )
+        self.assertEqual( map(float, f.get_summary(0, 2).frequencies), ([200] * 10) )
+        self.assertEqual( map(int, f.get_summary(0, 3).frequencies), [2000, 2000, 2000, 1000, 1000, 1000, 1000, 1000, 1000, 1] )
+    
+    def test_wrong_dictkey(self):
+        self.assertRaises(KeyError, self.filearraytreedict.__getitem__, "non-existing")
+        
+    def test_higher_level_than_tree(self):
+        f = self.filearraytree
+        self.assertEqual(3, f.levels)
+        self.assertRaises(ValueError, f.get_summary, 0, 4)
+        
+
+if __name__ == '__main__':
+    unittest.main()
\ No newline at end of file
diff --git a/lib/bx/arrays/bed.c b/lib/bx/arrays/bed.c
new file mode 100644
index 0000000..8695f48
--- /dev/null
+++ b/lib/bx/arrays/bed.c
@@ -0,0 +1,2584 @@
+/* Generated by Cython 0.18 on Mon Jul 15 13:25:44 2013 */
+
+#define PY_SSIZE_T_CLEAN
+#include "Python.h"
+#ifndef Py_PYTHON_H
+    #error Python headers needed to compile C extensions, please install development version of Python.
+#elif PY_VERSION_HEX < 0x02040000
+    #error Cython requires Python 2.4+.
+#else
+#include <stddef.h> /* For offsetof */
+#ifndef offsetof
+#define offsetof(type, member) ( (size_t) & ((type*)0) -> member )
+#endif
+#if !defined(WIN32) && !defined(MS_WINDOWS)
+  #ifndef __stdcall
+    #define __stdcall
+  #endif
+  #ifndef __cdecl
+    #define __cdecl
+  #endif
+  #ifndef __fastcall
+    #define __fastcall
+  #endif
+#endif
+#ifndef DL_IMPORT
+  #define DL_IMPORT(t) t
+#endif
+#ifndef DL_EXPORT
+  #define DL_EXPORT(t) t
+#endif
+#ifndef PY_LONG_LONG
+  #define PY_LONG_LONG LONG_LONG
+#endif
+#ifndef Py_HUGE_VAL
+  #define Py_HUGE_VAL HUGE_VAL
+#endif
+#ifdef PYPY_VERSION
+#define CYTHON_COMPILING_IN_PYPY 1
+#define CYTHON_COMPILING_IN_CPYTHON 0
+#else
+#define CYTHON_COMPILING_IN_PYPY 0
+#define CYTHON_COMPILING_IN_CPYTHON 1
+#endif
+#if PY_VERSION_HEX < 0x02050000
+  typedef int Py_ssize_t;
+  #define PY_SSIZE_T_MAX INT_MAX
+  #define PY_SSIZE_T_MIN INT_MIN
+  #define PY_FORMAT_SIZE_T ""
+  #define CYTHON_FORMAT_SSIZE_T ""
+  #define PyInt_FromSsize_t(z) PyInt_FromLong(z)
+  #define PyInt_AsSsize_t(o)   __Pyx_PyInt_AsInt(o)
+  #define PyNumber_Index(o)    ((PyNumber_Check(o) && !PyFloat_Check(o)) ? PyNumber_Int(o) : \
+                                (PyErr_Format(PyExc_TypeError, \
+                                              "expected index value, got %.200s", Py_TYPE(o)->tp_name), \
+                                 (PyObject*)0))
+  #define __Pyx_PyIndex_Check(o) (PyNumber_Check(o) && !PyFloat_Check(o) && \
+                                  !PyComplex_Check(o))
+  #define PyIndex_Check __Pyx_PyIndex_Check
+  #define PyErr_WarnEx(category, message, stacklevel) PyErr_Warn(category, message)
+  #define __PYX_BUILD_PY_SSIZE_T "i"
+#else
+  #define __PYX_BUILD_PY_SSIZE_T "n"
+  #define CYTHON_FORMAT_SSIZE_T "z"
+  #define __Pyx_PyIndex_Check PyIndex_Check
+#endif
+#if PY_VERSION_HEX < 0x02060000
+  #define Py_REFCNT(ob) (((PyObject*)(ob))->ob_refcnt)
+  #define Py_TYPE(ob)   (((PyObject*)(ob))->ob_type)
+  #define Py_SIZE(ob)   (((PyVarObject*)(ob))->ob_size)
+  #define PyVarObject_HEAD_INIT(type, size) \
+          PyObject_HEAD_INIT(type) size,
+  #define PyType_Modified(t)
+  typedef struct {
+     void *buf;
+     PyObject *obj;
+     Py_ssize_t len;
+     Py_ssize_t itemsize;
+     int readonly;
+     int ndim;
+     char *format;
+     Py_ssize_t *shape;
+     Py_ssize_t *strides;
+     Py_ssize_t *suboffsets;
+     void *internal;
+  } Py_buffer;
+  #define PyBUF_SIMPLE 0
+  #define PyBUF_WRITABLE 0x0001
+  #define PyBUF_FORMAT 0x0004
+  #define PyBUF_ND 0x0008
+  #define PyBUF_STRIDES (0x0010 | PyBUF_ND)
+  #define PyBUF_C_CONTIGUOUS (0x0020 | PyBUF_STRIDES)
+  #define PyBUF_F_CONTIGUOUS (0x0040 | PyBUF_STRIDES)
+  #define PyBUF_ANY_CONTIGUOUS (0x0080 | PyBUF_STRIDES)
+  #define PyBUF_INDIRECT (0x0100 | PyBUF_STRIDES)
+  #define PyBUF_RECORDS (PyBUF_STRIDES | PyBUF_FORMAT | PyBUF_WRITABLE)
+  #define PyBUF_FULL (PyBUF_INDIRECT | PyBUF_FORMAT | PyBUF_WRITABLE)
+  typedef int (*getbufferproc)(PyObject *, Py_buffer *, int);
+  typedef void (*releasebufferproc)(PyObject *, Py_buffer *);
+#endif
+#if PY_MAJOR_VERSION < 3
+  #define __Pyx_BUILTIN_MODULE_NAME "__builtin__"
+  #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \
+          PyCode_New(a, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
+#else
+  #define __Pyx_BUILTIN_MODULE_NAME "builtins"
+  #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \
+          PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
+#endif
+#if PY_MAJOR_VERSION < 3 && PY_MINOR_VERSION < 6
+  #define PyUnicode_FromString(s) PyUnicode_Decode(s, strlen(s), "UTF-8", "strict")
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define Py_TPFLAGS_CHECKTYPES 0
+  #define Py_TPFLAGS_HAVE_INDEX 0
+#endif
+#if (PY_VERSION_HEX < 0x02060000) || (PY_MAJOR_VERSION >= 3)
+  #define Py_TPFLAGS_HAVE_NEWBUFFER 0
+#endif
+#if PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND)
+  #define CYTHON_PEP393_ENABLED 1
+  #define __Pyx_PyUnicode_READY(op)       (likely(PyUnicode_IS_READY(op)) ? \
+                                              0 : _PyUnicode_Ready((PyObject *)(op)))
+  #define __Pyx_PyUnicode_GET_LENGTH(u)   PyUnicode_GET_LENGTH(u)
+  #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_READ_CHAR(u, i)
+  #define __Pyx_PyUnicode_READ(k, d, i)   PyUnicode_READ(k, d, i)
+#else
+  #define CYTHON_PEP393_ENABLED 0
+  #define __Pyx_PyUnicode_READY(op)       (0)
+  #define __Pyx_PyUnicode_GET_LENGTH(u)   PyUnicode_GET_SIZE(u)
+  #define __Pyx_PyUnicode_READ_CHAR(u, i) ((Py_UCS4)(PyUnicode_AS_UNICODE(u)[i]))
+  #define __Pyx_PyUnicode_READ(k, d, i)   ((k=k), (Py_UCS4)(((Py_UNICODE*)d)[i]))
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define PyBaseString_Type            PyUnicode_Type
+  #define PyStringObject               PyUnicodeObject
+  #define PyString_Type                PyUnicode_Type
+  #define PyString_Check               PyUnicode_Check
+  #define PyString_CheckExact          PyUnicode_CheckExact
+#endif
+#if PY_VERSION_HEX < 0x02060000
+  #define PyBytesObject                PyStringObject
+  #define PyBytes_Type                 PyString_Type
+  #define PyBytes_Check                PyString_Check
+  #define PyBytes_CheckExact           PyString_CheckExact
+  #define PyBytes_FromString           PyString_FromString
+  #define PyBytes_FromStringAndSize    PyString_FromStringAndSize
+  #define PyBytes_FromFormat           PyString_FromFormat
+  #define PyBytes_DecodeEscape         PyString_DecodeEscape
+  #define PyBytes_AsString             PyString_AsString
+  #define PyBytes_AsStringAndSize      PyString_AsStringAndSize
+  #define PyBytes_Size                 PyString_Size
+  #define PyBytes_AS_STRING            PyString_AS_STRING
+  #define PyBytes_GET_SIZE             PyString_GET_SIZE
+  #define PyBytes_Repr                 PyString_Repr
+  #define PyBytes_Concat               PyString_Concat
+  #define PyBytes_ConcatAndDel         PyString_ConcatAndDel
+#endif
+#if PY_VERSION_HEX < 0x02060000
+  #define PySet_Check(obj)             PyObject_TypeCheck(obj, &PySet_Type)
+  #define PyFrozenSet_Check(obj)       PyObject_TypeCheck(obj, &PyFrozenSet_Type)
+#endif
+#ifndef PySet_CheckExact
+  #define PySet_CheckExact(obj)        (Py_TYPE(obj) == &PySet_Type)
+#endif
+#define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type)
+#if PY_MAJOR_VERSION >= 3
+  #define PyIntObject                  PyLongObject
+  #define PyInt_Type                   PyLong_Type
+  #define PyInt_Check(op)              PyLong_Check(op)
+  #define PyInt_CheckExact(op)         PyLong_CheckExact(op)
+  #define PyInt_FromString             PyLong_FromString
+  #define PyInt_FromUnicode            PyLong_FromUnicode
+  #define PyInt_FromLong               PyLong_FromLong
+  #define PyInt_FromSize_t             PyLong_FromSize_t
+  #define PyInt_FromSsize_t            PyLong_FromSsize_t
+  #define PyInt_AsLong                 PyLong_AsLong
+  #define PyInt_AS_LONG                PyLong_AS_LONG
+  #define PyInt_AsSsize_t              PyLong_AsSsize_t
+  #define PyInt_AsUnsignedLongMask     PyLong_AsUnsignedLongMask
+  #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define PyBoolObject                 PyLongObject
+#endif
+#if PY_VERSION_HEX < 0x03020000
+  typedef long Py_hash_t;
+  #define __Pyx_PyInt_FromHash_t PyInt_FromLong
+  #define __Pyx_PyInt_AsHash_t   PyInt_AsLong
+#else
+  #define __Pyx_PyInt_FromHash_t PyInt_FromSsize_t
+  #define __Pyx_PyInt_AsHash_t   PyInt_AsSsize_t
+#endif
+#if (PY_MAJOR_VERSION < 3) || (PY_VERSION_HEX >= 0x03010300)
+  #define __Pyx_PySequence_GetSlice(obj, a, b) PySequence_GetSlice(obj, a, b)
+  #define __Pyx_PySequence_SetSlice(obj, a, b, value) PySequence_SetSlice(obj, a, b, value)
+  #define __Pyx_PySequence_DelSlice(obj, a, b) PySequence_DelSlice(obj, a, b)
+#else
+  #define __Pyx_PySequence_GetSlice(obj, a, b) (unlikely(!(obj)) ? \
+        (PyErr_SetString(PyExc_SystemError, "null argument to internal routine"), (PyObject*)0) : \
+        (likely((obj)->ob_type->tp_as_mapping) ? (PySequence_GetSlice(obj, a, b)) : \
+            (PyErr_Format(PyExc_TypeError, "'%.200s' object is unsliceable", (obj)->ob_type->tp_name), (PyObject*)0)))
+  #define __Pyx_PySequence_SetSlice(obj, a, b, value) (unlikely(!(obj)) ? \
+        (PyErr_SetString(PyExc_SystemError, "null argument to internal routine"), -1) : \
+        (likely((obj)->ob_type->tp_as_mapping) ? (PySequence_SetSlice(obj, a, b, value)) : \
+            (PyErr_Format(PyExc_TypeError, "'%.200s' object doesn't support slice assignment", (obj)->ob_type->tp_name), -1)))
+  #define __Pyx_PySequence_DelSlice(obj, a, b) (unlikely(!(obj)) ? \
+        (PyErr_SetString(PyExc_SystemError, "null argument to internal routine"), -1) : \
+        (likely((obj)->ob_type->tp_as_mapping) ? (PySequence_DelSlice(obj, a, b)) : \
+            (PyErr_Format(PyExc_TypeError, "'%.200s' object doesn't support slice deletion", (obj)->ob_type->tp_name), -1)))
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define PyMethod_New(func, self, klass) ((self) ? PyMethod_New(func, self) : PyInstanceMethod_New(func))
+#endif
+#if PY_VERSION_HEX < 0x02050000
+  #define __Pyx_GetAttrString(o,n)   PyObject_GetAttrString((o),((char *)(n)))
+  #define __Pyx_SetAttrString(o,n,a) PyObject_SetAttrString((o),((char *)(n)),(a))
+  #define __Pyx_DelAttrString(o,n)   PyObject_DelAttrString((o),((char *)(n)))
+#else
+  #define __Pyx_GetAttrString(o,n)   PyObject_GetAttrString((o),(n))
+  #define __Pyx_SetAttrString(o,n,a) PyObject_SetAttrString((o),(n),(a))
+  #define __Pyx_DelAttrString(o,n)   PyObject_DelAttrString((o),(n))
+#endif
+#if PY_VERSION_HEX < 0x02050000
+  #define __Pyx_NAMESTR(n) ((char *)(n))
+  #define __Pyx_DOCSTR(n)  ((char *)(n))
+#else
+  #define __Pyx_NAMESTR(n) (n)
+  #define __Pyx_DOCSTR(n)  (n)
+#endif
+
+
+#if PY_MAJOR_VERSION >= 3
+  #define __Pyx_PyNumber_Divide(x,y)         PyNumber_TrueDivide(x,y)
+  #define __Pyx_PyNumber_InPlaceDivide(x,y)  PyNumber_InPlaceTrueDivide(x,y)
+#else
+  #define __Pyx_PyNumber_Divide(x,y)         PyNumber_Divide(x,y)
+  #define __Pyx_PyNumber_InPlaceDivide(x,y)  PyNumber_InPlaceDivide(x,y)
+#endif
+
+#ifndef __PYX_EXTERN_C
+  #ifdef __cplusplus
+    #define __PYX_EXTERN_C extern "C"
+  #else
+    #define __PYX_EXTERN_C extern
+  #endif
+#endif
+
+#if defined(WIN32) || defined(MS_WINDOWS)
+#define _USE_MATH_DEFINES
+#endif
+#include <math.h>
+#define __PYX_HAVE__bx__arrays__bed
+#define __PYX_HAVE_API__bx__arrays__bed
+#ifdef _OPENMP
+#include <omp.h>
+#endif /* _OPENMP */
+
+#ifdef PYREX_WITHOUT_ASSERTIONS
+#define CYTHON_WITHOUT_ASSERTIONS
+#endif
+
+#ifndef CYTHON_INLINE
+  #if defined(__GNUC__)
+    #define CYTHON_INLINE __inline__
+  #elif defined(_MSC_VER)
+    #define CYTHON_INLINE __inline
+  #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+    #define CYTHON_INLINE inline
+  #else
+    #define CYTHON_INLINE
+  #endif
+#endif
+#ifndef CYTHON_UNUSED
+# if defined(__GNUC__)
+#   if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
+#     define CYTHON_UNUSED __attribute__ ((__unused__))
+#   else
+#     define CYTHON_UNUSED
+#   endif
+# elif defined(__ICC) || (defined(__INTEL_COMPILER) && !defined(_MSC_VER))
+#   define CYTHON_UNUSED __attribute__ ((__unused__))
+# else
+#   define CYTHON_UNUSED
+# endif
+#endif
+typedef struct {PyObject **p; char *s; const long n; const char* encoding; const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry; /*proto*/
+
+#define __Pyx_PyBytes_FromUString(s) PyBytes_FromString((char*)s)
+#define __Pyx_PyBytes_AsUString(s)   ((unsigned char*) PyBytes_AsString(s))
+#define __Pyx_Owned_Py_None(b) (Py_INCREF(Py_None), Py_None)
+#define __Pyx_PyBool_FromLong(b) ((b) ? (Py_INCREF(Py_True), Py_True) : (Py_INCREF(Py_False), Py_False))
+static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*);
+static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x);
+static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*);
+static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t);
+static CYTHON_INLINE size_t __Pyx_PyInt_AsSize_t(PyObject*);
+#if CYTHON_COMPILING_IN_CPYTHON
+#define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x))
+#else
+#define __pyx_PyFloat_AsDouble(x) PyFloat_AsDouble(x)
+#endif
+#define __pyx_PyFloat_AsFloat(x) ((float) __pyx_PyFloat_AsDouble(x))
+
+
+#ifdef __GNUC__
+  /* Test for GCC > 2.95 */
+  #if __GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))
+    #define likely(x)   __builtin_expect(!!(x), 1)
+    #define unlikely(x) __builtin_expect(!!(x), 0)
+  #else /* __GNUC__ > 2 ... */
+    #define likely(x)   (x)
+    #define unlikely(x) (x)
+  #endif /* __GNUC__ > 2 ... */
+#else /* __GNUC__ */
+  #define likely(x)   (x)
+  #define unlikely(x) (x)
+#endif /* __GNUC__ */
+    
+static PyObject *__pyx_m;
+static PyObject *__pyx_b;
+static PyObject *__pyx_empty_tuple;
+static PyObject *__pyx_empty_bytes;
+static int __pyx_lineno;
+static int __pyx_clineno = 0;
+static const char * __pyx_cfilenm= __FILE__;
+static const char *__pyx_filename;
+
+
+static const char *__pyx_f[] = {
+  "bed.pyx",
+};
+
+/*--- Type declarations ---*/
+struct __pyx_obj_2bx_6arrays_3bed_BedReader;
+
+/* "bx/arrays/bed.pyx":6
+ * """
+ * 
+ * cdef class BedReader:             # <<<<<<<<<<<<<<
+ *     cdef object f
+ *     def __init__( self, f ):
+ */
+struct __pyx_obj_2bx_6arrays_3bed_BedReader {
+  PyObject_HEAD
+  PyObject *f;
+};
+
+#ifndef CYTHON_REFNANNY
+  #define CYTHON_REFNANNY 0
+#endif
+#if CYTHON_REFNANNY
+  typedef struct {
+    void (*INCREF)(void*, PyObject*, int);
+    void (*DECREF)(void*, PyObject*, int);
+    void (*GOTREF)(void*, PyObject*, int);
+    void (*GIVEREF)(void*, PyObject*, int);
+    void* (*SetupContext)(const char*, int, const char*);
+    void (*FinishContext)(void**);
+  } __Pyx_RefNannyAPIStruct;
+  static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL;
+  static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname); /*proto*/
+  #define __Pyx_RefNannyDeclarations void *__pyx_refnanny = NULL;
+#ifdef WITH_THREAD
+  #define __Pyx_RefNannySetupContext(name, acquire_gil) \
+          if (acquire_gil) { \
+              PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure(); \
+              __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__); \
+              PyGILState_Release(__pyx_gilstate_save); \
+          } else { \
+              __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__); \
+          }
+#else
+  #define __Pyx_RefNannySetupContext(name, acquire_gil) \
+          __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__)
+#endif
+  #define __Pyx_RefNannyFinishContext() \
+          __Pyx_RefNanny->FinishContext(&__pyx_refnanny)
+  #define __Pyx_INCREF(r)  __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_DECREF(r)  __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_GOTREF(r)  __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_XINCREF(r)  do { if((r) != NULL) {__Pyx_INCREF(r); }} while(0)
+  #define __Pyx_XDECREF(r)  do { if((r) != NULL) {__Pyx_DECREF(r); }} while(0)
+  #define __Pyx_XGOTREF(r)  do { if((r) != NULL) {__Pyx_GOTREF(r); }} while(0)
+  #define __Pyx_XGIVEREF(r) do { if((r) != NULL) {__Pyx_GIVEREF(r);}} while(0)
+#else
+  #define __Pyx_RefNannyDeclarations
+  #define __Pyx_RefNannySetupContext(name, acquire_gil)
+  #define __Pyx_RefNannyFinishContext()
+  #define __Pyx_INCREF(r) Py_INCREF(r)
+  #define __Pyx_DECREF(r) Py_DECREF(r)
+  #define __Pyx_GOTREF(r)
+  #define __Pyx_GIVEREF(r)
+  #define __Pyx_XINCREF(r) Py_XINCREF(r)
+  #define __Pyx_XDECREF(r) Py_XDECREF(r)
+  #define __Pyx_XGOTREF(r)
+  #define __Pyx_XGIVEREF(r)
+#endif /* CYTHON_REFNANNY */
+#define __Pyx_CLEAR(r)    do { PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);} while(0)
+#define __Pyx_XCLEAR(r)   do { if((r) != NULL) {PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);}} while(0)
+
+static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/
+
+static void __Pyx_RaiseDoubleKeywordsError(const char* func_name, PyObject* kw_name); /*proto*/
+
+static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
+    PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
+    const char* function_name); /*proto*/
+
+static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
+    Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/
+
+static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
+static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
+
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause); /*proto*/
+
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j) {
+    PyObject *r;
+    if (!j) return NULL;
+    r = PyObject_GetItem(o, j);
+    Py_DECREF(j);
+    return r;
+}
+#define __Pyx_GetItemInt_List(o, i, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \
+                                                    __Pyx_GetItemInt_List_Fast(o, i) : \
+                                                    __Pyx_GetItemInt_Generic(o, to_py_func(i)))
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    if (likely((0 <= i) & (i < PyList_GET_SIZE(o)))) {
+        PyObject *r = PyList_GET_ITEM(o, i);
+        Py_INCREF(r);
+        return r;
+    }
+    else if ((-PyList_GET_SIZE(o) <= i) & (i < 0)) {
+        PyObject *r = PyList_GET_ITEM(o, PyList_GET_SIZE(o) + i);
+        Py_INCREF(r);
+        return r;
+    }
+    return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
+#else
+    return PySequence_GetItem(o, i);
+#endif
+}
+#define __Pyx_GetItemInt_Tuple(o, i, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \
+                                                    __Pyx_GetItemInt_Tuple_Fast(o, i) : \
+                                                    __Pyx_GetItemInt_Generic(o, to_py_func(i)))
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    if (likely((0 <= i) & (i < PyTuple_GET_SIZE(o)))) {
+        PyObject *r = PyTuple_GET_ITEM(o, i);
+        Py_INCREF(r);
+        return r;
+    }
+    else if ((-PyTuple_GET_SIZE(o) <= i) & (i < 0)) {
+        PyObject *r = PyTuple_GET_ITEM(o, PyTuple_GET_SIZE(o) + i);
+        Py_INCREF(r);
+        return r;
+    }
+    return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
+#else
+    return PySequence_GetItem(o, i);
+#endif
+}
+#define __Pyx_GetItemInt(o, i, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \
+                                                    __Pyx_GetItemInt_Fast(o, i) : \
+                                                    __Pyx_GetItemInt_Generic(o, to_py_func(i)))
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    if (PyList_CheckExact(o)) {
+        Py_ssize_t n = (likely(i >= 0)) ? i : i + PyList_GET_SIZE(o);
+        if (likely((n >= 0) & (n < PyList_GET_SIZE(o)))) {
+            PyObject *r = PyList_GET_ITEM(o, n);
+            Py_INCREF(r);
+            return r;
+        }
+    }
+    else if (PyTuple_CheckExact(o)) {
+        Py_ssize_t n = (likely(i >= 0)) ? i : i + PyTuple_GET_SIZE(o);
+        if (likely((n >= 0) & (n < PyTuple_GET_SIZE(o)))) {
+            PyObject *r = PyTuple_GET_ITEM(o, n);
+            Py_INCREF(r);
+            return r;
+        }
+    } else {  /* inlined PySequence_GetItem() */
+        PySequenceMethods *m = Py_TYPE(o)->tp_as_sequence;
+        if (likely(m && m->sq_item)) {
+            if (unlikely(i < 0) && likely(m->sq_length)) {
+                Py_ssize_t l = m->sq_length(o);
+                if (unlikely(l < 0)) return NULL;
+                i += l;
+            }
+            return m->sq_item(o, i);
+        }
+    }
+#else
+    if (PySequence_Check(o)) {
+        return PySequence_GetItem(o, i);
+    }
+#endif
+    return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
+}
+
+static CYTHON_INLINE unsigned char __Pyx_PyInt_AsUnsignedChar(PyObject *);
+
+static CYTHON_INLINE unsigned short __Pyx_PyInt_AsUnsignedShort(PyObject *);
+
+static CYTHON_INLINE unsigned int __Pyx_PyInt_AsUnsignedInt(PyObject *);
+
+static CYTHON_INLINE char __Pyx_PyInt_AsChar(PyObject *);
+
+static CYTHON_INLINE short __Pyx_PyInt_AsShort(PyObject *);
+
+static CYTHON_INLINE int __Pyx_PyInt_AsInt(PyObject *);
+
+static CYTHON_INLINE signed char __Pyx_PyInt_AsSignedChar(PyObject *);
+
+static CYTHON_INLINE signed short __Pyx_PyInt_AsSignedShort(PyObject *);
+
+static CYTHON_INLINE signed int __Pyx_PyInt_AsSignedInt(PyObject *);
+
+static CYTHON_INLINE int __Pyx_PyInt_AsLongDouble(PyObject *);
+
+static CYTHON_INLINE unsigned long __Pyx_PyInt_AsUnsignedLong(PyObject *);
+
+static CYTHON_INLINE unsigned PY_LONG_LONG __Pyx_PyInt_AsUnsignedLongLong(PyObject *);
+
+static CYTHON_INLINE long __Pyx_PyInt_AsLong(PyObject *);
+
+static CYTHON_INLINE PY_LONG_LONG __Pyx_PyInt_AsLongLong(PyObject *);
+
+static CYTHON_INLINE signed long __Pyx_PyInt_AsSignedLong(PyObject *);
+
+static CYTHON_INLINE signed PY_LONG_LONG __Pyx_PyInt_AsSignedLongLong(PyObject *);
+
+static int __Pyx_check_binary_version(void);
+
+typedef struct {
+    int code_line;
+    PyCodeObject* code_object;
+} __Pyx_CodeObjectCacheEntry;
+struct __Pyx_CodeObjectCache {
+    int count;
+    int max_count;
+    __Pyx_CodeObjectCacheEntry* entries;
+};
+static struct __Pyx_CodeObjectCache __pyx_code_cache = {0,0,NULL};
+static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line);
+static PyCodeObject *__pyx_find_code_object(int code_line);
+static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object);
+
+static void __Pyx_AddTraceback(const char *funcname, int c_line,
+                               int py_line, const char *filename); /*proto*/
+
+static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
+
+
+/* Module declarations from 'bx.arrays.bed' */
+static PyTypeObject *__pyx_ptype_2bx_6arrays_3bed_BedReader = 0;
+#define __Pyx_MODULE_NAME "bx.arrays.bed"
+int __pyx_module_is_main_bx__arrays__bed = 0;
+
+/* Implementation of 'bx.arrays.bed' */
+static PyObject *__pyx_builtin_StopIteration;
+static int __pyx_pf_2bx_6arrays_3bed_9BedReader___init__(struct __pyx_obj_2bx_6arrays_3bed_BedReader *__pyx_v_self, PyObject *__pyx_v_f); /* proto */
+static PyObject *__pyx_pf_2bx_6arrays_3bed_9BedReader_2__iter__(struct __pyx_obj_2bx_6arrays_3bed_BedReader *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_2bx_6arrays_3bed_9BedReader_4__next__(struct __pyx_obj_2bx_6arrays_3bed_BedReader *__pyx_v_self); /* proto */
+static char __pyx_k_1[] = "#";
+static char __pyx_k_4[] = "Unexpected input line: %s";
+static char __pyx_k_5[] = "\nIterator for the BED format ( http://genome.ucsc.edu/FAQ/FAQformat.html#format1 )\nReturns chrom, chromStart, chromEnd, name, score\n";
+static char __pyx_k__f[] = "f";
+static char __pyx_k__split[] = "split";
+static char __pyx_k__strip[] = "strip";
+static char __pyx_k__track[] = "track";
+static char __pyx_k__browser[] = "browser";
+static char __pyx_k__isalpha[] = "isalpha";
+static char __pyx_k__isspace[] = "isspace";
+static char __pyx_k____main__[] = "__main__";
+static char __pyx_k____test__[] = "__test__";
+static char __pyx_k__readline[] = "readline";
+static char __pyx_k__startswith[] = "startswith";
+static char __pyx_k__StopIteration[] = "StopIteration";
+static PyObject *__pyx_kp_s_1;
+static PyObject *__pyx_kp_s_4;
+static PyObject *__pyx_n_s__StopIteration;
+static PyObject *__pyx_n_s____main__;
+static PyObject *__pyx_n_s____test__;
+static PyObject *__pyx_n_s__browser;
+static PyObject *__pyx_n_s__f;
+static PyObject *__pyx_n_s__isalpha;
+static PyObject *__pyx_n_s__isspace;
+static PyObject *__pyx_n_s__readline;
+static PyObject *__pyx_n_s__split;
+static PyObject *__pyx_n_s__startswith;
+static PyObject *__pyx_n_s__strip;
+static PyObject *__pyx_n_s__track;
+static PyObject *__pyx_k_tuple_2;
+static PyObject *__pyx_k_tuple_3;
+
+/* Python wrapper */
+static int __pyx_pw_2bx_6arrays_3bed_9BedReader_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static int __pyx_pw_2bx_6arrays_3bed_9BedReader_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_f = 0;
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__init__ (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__f,0};
+    PyObject* values[1] = {0};
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__f)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 8; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else if (PyTuple_GET_SIZE(__pyx_args) != 1) {
+      goto __pyx_L5_argtuple_error;
+    } else {
+      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+    }
+    __pyx_v_f = values[0];
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("__init__", 1, 1, 1, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 8; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.arrays.bed.BedReader.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return -1;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_6arrays_3bed_9BedReader___init__(((struct __pyx_obj_2bx_6arrays_3bed_BedReader *)__pyx_v_self), __pyx_v_f);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/arrays/bed.pyx":8
+ * cdef class BedReader:
+ *     cdef object f
+ *     def __init__( self, f ):             # <<<<<<<<<<<<<<
+ *         self.f = f
+ * 
+ */
+
+static int __pyx_pf_2bx_6arrays_3bed_9BedReader___init__(struct __pyx_obj_2bx_6arrays_3bed_BedReader *__pyx_v_self, PyObject *__pyx_v_f) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__init__", 0);
+
+  /* "bx/arrays/bed.pyx":9
+ *     cdef object f
+ *     def __init__( self, f ):
+ *         self.f = f             # <<<<<<<<<<<<<<
+ * 
+ *     def __iter__( self ):
+ */
+  __Pyx_INCREF(__pyx_v_f);
+  __Pyx_GIVEREF(__pyx_v_f);
+  __Pyx_GOTREF(__pyx_v_self->f);
+  __Pyx_DECREF(__pyx_v_self->f);
+  __pyx_v_self->f = __pyx_v_f;
+
+  __pyx_r = 0;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_6arrays_3bed_9BedReader_3__iter__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_2bx_6arrays_3bed_9BedReader_3__iter__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__iter__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_6arrays_3bed_9BedReader_2__iter__(((struct __pyx_obj_2bx_6arrays_3bed_BedReader *)__pyx_v_self));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/arrays/bed.pyx":11
+ *         self.f = f
+ * 
+ *     def __iter__( self ):             # <<<<<<<<<<<<<<
+ *         return self
+ * 
+ */
+
+static PyObject *__pyx_pf_2bx_6arrays_3bed_9BedReader_2__iter__(struct __pyx_obj_2bx_6arrays_3bed_BedReader *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__iter__", 0);
+
+  /* "bx/arrays/bed.pyx":12
+ * 
+ *     def __iter__( self ):
+ *         return self             # <<<<<<<<<<<<<<
+ * 
+ *     def __next__( self ):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __Pyx_INCREF(((PyObject *)__pyx_v_self));
+  __pyx_r = ((PyObject *)__pyx_v_self);
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_6arrays_3bed_9BedReader_5__next__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_2bx_6arrays_3bed_9BedReader_5__next__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__next__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_6arrays_3bed_9BedReader_4__next__(((struct __pyx_obj_2bx_6arrays_3bed_BedReader *)__pyx_v_self));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/arrays/bed.pyx":14
+ *         return self
+ * 
+ *     def __next__( self ):             # <<<<<<<<<<<<<<
+ *         while True:
+ *             line = self.f.readline()
+ */
+
+static PyObject *__pyx_pf_2bx_6arrays_3bed_9BedReader_4__next__(struct __pyx_obj_2bx_6arrays_3bed_BedReader *__pyx_v_self) {
+  PyObject *__pyx_v_line = NULL;
+  PyObject *__pyx_v_feature = NULL;
+  PyObject *__pyx_v_chrom = NULL;
+  PyObject *__pyx_v_chrom_start = NULL;
+  PyObject *__pyx_v_chrom_end = NULL;
+  PyObject *__pyx_v_name = NULL;
+  PyObject *__pyx_v_score = NULL;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  int __pyx_t_3;
+  int __pyx_t_4;
+  int __pyx_t_5;
+  Py_ssize_t __pyx_t_6;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__next__", 0);
+
+  /* "bx/arrays/bed.pyx":15
+ * 
+ *     def __next__( self ):
+ *         while True:             # <<<<<<<<<<<<<<
+ *             line = self.f.readline()
+ *             if not line:
+ */
+  while (1) {
+    if (!1) break;
+
+    /* "bx/arrays/bed.pyx":16
+ *     def __next__( self ):
+ *         while True:
+ *             line = self.f.readline()             # <<<<<<<<<<<<<<
+ *             if not line:
+ *                 raise StopIteration()
+ */
+    __pyx_t_1 = PyObject_GetAttr(__pyx_v_self->f, __pyx_n_s__readline); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 16; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __pyx_t_2 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 16; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    __Pyx_XDECREF(__pyx_v_line);
+    __pyx_v_line = __pyx_t_2;
+    __pyx_t_2 = 0;
+
+    /* "bx/arrays/bed.pyx":17
+ *         while True:
+ *             line = self.f.readline()
+ *             if not line:             # <<<<<<<<<<<<<<
+ *                 raise StopIteration()
+ *             if line.isspace():
+ */
+    __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_v_line); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = (!__pyx_t_3);
+    if (__pyx_t_4) {
+
+      /* "bx/arrays/bed.pyx":18
+ *             line = self.f.readline()
+ *             if not line:
+ *                 raise StopIteration()             # <<<<<<<<<<<<<<
+ *             if line.isspace():
+ *                 continue
+ */
+      __pyx_t_2 = PyObject_Call(__pyx_builtin_StopIteration, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 18; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_2);
+      __Pyx_Raise(__pyx_t_2, 0, 0, 0);
+      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 18; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      goto __pyx_L5;
+    }
+    __pyx_L5:;
+
+    /* "bx/arrays/bed.pyx":19
+ *             if not line:
+ *                 raise StopIteration()
+ *             if line.isspace():             # <<<<<<<<<<<<<<
+ *                 continue
+ *             if line[0] == "#":
+ */
+    __pyx_t_2 = PyObject_GetAttr(__pyx_v_line, __pyx_n_s__isspace); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 19; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_t_1 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 19; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 19; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    if (__pyx_t_4) {
+
+      /* "bx/arrays/bed.pyx":20
+ *                 raise StopIteration()
+ *             if line.isspace():
+ *                 continue             # <<<<<<<<<<<<<<
+ *             if line[0] == "#":
+ *                 continue
+ */
+      goto __pyx_L3_continue;
+      goto __pyx_L6;
+    }
+    __pyx_L6:;
+
+    /* "bx/arrays/bed.pyx":21
+ *             if line.isspace():
+ *                 continue
+ *             if line[0] == "#":             # <<<<<<<<<<<<<<
+ *                 continue
+ *             if line[0].isalpha():
+ */
+    __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_line, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 21; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __pyx_t_2 = PyObject_RichCompare(__pyx_t_1, ((PyObject *)__pyx_kp_s_1), Py_EQ); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 21; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 21; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    if (__pyx_t_4) {
+
+      /* "bx/arrays/bed.pyx":22
+ *                 continue
+ *             if line[0] == "#":
+ *                 continue             # <<<<<<<<<<<<<<
+ *             if line[0].isalpha():
+ *                 if line.startswith( "track" ) or line.startswith( "browser" ):
+ */
+      goto __pyx_L3_continue;
+      goto __pyx_L7;
+    }
+    __pyx_L7:;
+
+    /* "bx/arrays/bed.pyx":23
+ *             if line[0] == "#":
+ *                 continue
+ *             if line[0].isalpha():             # <<<<<<<<<<<<<<
+ *                 if line.startswith( "track" ) or line.startswith( "browser" ):
+ *                     continue
+ */
+    __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_line, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 23; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_t_1 = PyObject_GetAttr(__pyx_t_2, __pyx_n_s__isalpha); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 23; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    __pyx_t_2 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 23; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 23; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    if (__pyx_t_4) {
+
+      /* "bx/arrays/bed.pyx":24
+ *                 continue
+ *             if line[0].isalpha():
+ *                 if line.startswith( "track" ) or line.startswith( "browser" ):             # <<<<<<<<<<<<<<
+ *                     continue
+ * 
+ */
+      __pyx_t_2 = PyObject_GetAttr(__pyx_v_line, __pyx_n_s__startswith); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 24; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_2);
+      __pyx_t_1 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_k_tuple_2), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 24; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_1);
+      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+      __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 24; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+      if (!__pyx_t_4) {
+        __pyx_t_1 = PyObject_GetAttr(__pyx_v_line, __pyx_n_s__startswith); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 24; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_1);
+        __pyx_t_2 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_k_tuple_3), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 24; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_2);
+        __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+        __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 24; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+        __pyx_t_5 = __pyx_t_3;
+      } else {
+        __pyx_t_5 = __pyx_t_4;
+      }
+      if (__pyx_t_5) {
+
+        /* "bx/arrays/bed.pyx":25
+ *             if line[0].isalpha():
+ *                 if line.startswith( "track" ) or line.startswith( "browser" ):
+ *                     continue             # <<<<<<<<<<<<<<
+ * 
+ *                 feature = line.strip().split()
+ */
+        goto __pyx_L3_continue;
+        goto __pyx_L9;
+      }
+      __pyx_L9:;
+
+      /* "bx/arrays/bed.pyx":27
+ *                     continue
+ * 
+ *                 feature = line.strip().split()             # <<<<<<<<<<<<<<
+ *                 chrom = feature[0]
+ *                 chrom_start = int(feature[1])
+ */
+      __pyx_t_2 = PyObject_GetAttr(__pyx_v_line, __pyx_n_s__strip); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 27; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_2);
+      __pyx_t_1 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 27; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_1);
+      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+      __pyx_t_2 = PyObject_GetAttr(__pyx_t_1, __pyx_n_s__split); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 27; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_2);
+      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+      __pyx_t_1 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 27; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_1);
+      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+      __pyx_v_feature = __pyx_t_1;
+      __pyx_t_1 = 0;
+
+      /* "bx/arrays/bed.pyx":28
+ * 
+ *                 feature = line.strip().split()
+ *                 chrom = feature[0]             # <<<<<<<<<<<<<<
+ *                 chrom_start = int(feature[1])
+ *                 chrom_end = int(feature[2])
+ */
+      __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_feature, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 28; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_1);
+      __pyx_v_chrom = __pyx_t_1;
+      __pyx_t_1 = 0;
+
+      /* "bx/arrays/bed.pyx":29
+ *                 feature = line.strip().split()
+ *                 chrom = feature[0]
+ *                 chrom_start = int(feature[1])             # <<<<<<<<<<<<<<
+ *                 chrom_end = int(feature[2])
+ *                 if len(feature) > 3:
+ */
+      __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_feature, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 29; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_1);
+      __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 29; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_2);
+      PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
+      __Pyx_GIVEREF(__pyx_t_1);
+      __pyx_t_1 = 0;
+      __pyx_t_1 = PyObject_Call(((PyObject *)((PyObject*)(&PyInt_Type))), ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 29; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_1);
+      __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
+      __pyx_v_chrom_start = __pyx_t_1;
+      __pyx_t_1 = 0;
+
+      /* "bx/arrays/bed.pyx":30
+ *                 chrom = feature[0]
+ *                 chrom_start = int(feature[1])
+ *                 chrom_end = int(feature[2])             # <<<<<<<<<<<<<<
+ *                 if len(feature) > 3:
+ *                     name = feature[3]
+ */
+      __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_feature, 2, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 30; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_1);
+      __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 30; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_2);
+      PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
+      __Pyx_GIVEREF(__pyx_t_1);
+      __pyx_t_1 = 0;
+      __pyx_t_1 = PyObject_Call(((PyObject *)((PyObject*)(&PyInt_Type))), ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 30; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_1);
+      __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
+      __pyx_v_chrom_end = __pyx_t_1;
+      __pyx_t_1 = 0;
+
+      /* "bx/arrays/bed.pyx":31
+ *                 chrom_start = int(feature[1])
+ *                 chrom_end = int(feature[2])
+ *                 if len(feature) > 3:             # <<<<<<<<<<<<<<
+ *                     name = feature[3]
+ *                 else:
+ */
+      __pyx_t_6 = PyObject_Length(__pyx_v_feature); if (unlikely(__pyx_t_6 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 31; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_5 = (__pyx_t_6 > 3);
+      if (__pyx_t_5) {
+
+        /* "bx/arrays/bed.pyx":32
+ *                 chrom_end = int(feature[2])
+ *                 if len(feature) > 3:
+ *                     name = feature[3]             # <<<<<<<<<<<<<<
+ *                 else:
+ *                     name = None
+ */
+        __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_feature, 3, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 32; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_1);
+        __pyx_v_name = __pyx_t_1;
+        __pyx_t_1 = 0;
+        goto __pyx_L10;
+      }
+      /*else*/ {
+
+        /* "bx/arrays/bed.pyx":34
+ *                     name = feature[3]
+ *                 else:
+ *                     name = None             # <<<<<<<<<<<<<<
+ * 
+ *                 if len(feature) > 4:
+ */
+        __Pyx_INCREF(Py_None);
+        __pyx_v_name = Py_None;
+      }
+      __pyx_L10:;
+
+      /* "bx/arrays/bed.pyx":36
+ *                     name = None
+ * 
+ *                 if len(feature) > 4:             # <<<<<<<<<<<<<<
+ *                     score = int(feature[4])
+ *                 else:
+ */
+      __pyx_t_6 = PyObject_Length(__pyx_v_feature); if (unlikely(__pyx_t_6 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 36; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_5 = (__pyx_t_6 > 4);
+      if (__pyx_t_5) {
+
+        /* "bx/arrays/bed.pyx":37
+ * 
+ *                 if len(feature) > 4:
+ *                     score = int(feature[4])             # <<<<<<<<<<<<<<
+ *                 else:
+ *                     score = None
+ */
+        __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_feature, 4, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 37; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_1);
+        __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 37; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_2);
+        PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
+        __Pyx_GIVEREF(__pyx_t_1);
+        __pyx_t_1 = 0;
+        __pyx_t_1 = PyObject_Call(((PyObject *)((PyObject*)(&PyInt_Type))), ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 37; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_1);
+        __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
+        __pyx_v_score = __pyx_t_1;
+        __pyx_t_1 = 0;
+        goto __pyx_L11;
+      }
+      /*else*/ {
+
+        /* "bx/arrays/bed.pyx":39
+ *                     score = int(feature[4])
+ *                 else:
+ *                     score = None             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+        __Pyx_INCREF(Py_None);
+        __pyx_v_score = Py_None;
+      }
+      __pyx_L11:;
+
+      /* "bx/arrays/bed.pyx":42
+ * 
+ * 
+ *                 return chrom, chrom_start, chrom_end, name, score             # <<<<<<<<<<<<<<
+ * 
+ *             else:
+ */
+      __Pyx_XDECREF(__pyx_r);
+      __pyx_t_1 = PyTuple_New(5); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 42; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_1);
+      __Pyx_INCREF(__pyx_v_chrom);
+      PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_chrom);
+      __Pyx_GIVEREF(__pyx_v_chrom);
+      __Pyx_INCREF(__pyx_v_chrom_start);
+      PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_v_chrom_start);
+      __Pyx_GIVEREF(__pyx_v_chrom_start);
+      __Pyx_INCREF(__pyx_v_chrom_end);
+      PyTuple_SET_ITEM(__pyx_t_1, 2, __pyx_v_chrom_end);
+      __Pyx_GIVEREF(__pyx_v_chrom_end);
+      __Pyx_INCREF(__pyx_v_name);
+      PyTuple_SET_ITEM(__pyx_t_1, 3, __pyx_v_name);
+      __Pyx_GIVEREF(__pyx_v_name);
+      __Pyx_INCREF(__pyx_v_score);
+      PyTuple_SET_ITEM(__pyx_t_1, 4, __pyx_v_score);
+      __Pyx_GIVEREF(__pyx_v_score);
+      __pyx_r = ((PyObject *)__pyx_t_1);
+      __pyx_t_1 = 0;
+      goto __pyx_L0;
+      goto __pyx_L8;
+    }
+    /*else*/ {
+
+      /* "bx/arrays/bed.pyx":45
+ * 
+ *             else:
+ *                 raise "Unexpected input line: %s" % line.strip()             # <<<<<<<<<<<<<<
+ * 
+ */
+      __pyx_t_1 = PyObject_GetAttr(__pyx_v_line, __pyx_n_s__strip); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 45; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_1);
+      __pyx_t_2 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 45; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_2);
+      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+      __pyx_t_1 = PyNumber_Remainder(((PyObject *)__pyx_kp_s_4), __pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 45; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(((PyObject *)__pyx_t_1));
+      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+      __Pyx_Raise(((PyObject *)__pyx_t_1), 0, 0, 0);
+      __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 45; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+    __pyx_L8:;
+    __pyx_L3_continue:;
+  }
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_AddTraceback("bx.arrays.bed.BedReader.__next__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_line);
+  __Pyx_XDECREF(__pyx_v_feature);
+  __Pyx_XDECREF(__pyx_v_chrom);
+  __Pyx_XDECREF(__pyx_v_chrom_start);
+  __Pyx_XDECREF(__pyx_v_chrom_end);
+  __Pyx_XDECREF(__pyx_v_name);
+  __Pyx_XDECREF(__pyx_v_score);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_tp_new_2bx_6arrays_3bed_BedReader(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) {
+  struct __pyx_obj_2bx_6arrays_3bed_BedReader *p;
+  PyObject *o = (*t->tp_alloc)(t, 0);
+  if (!o) return 0;
+  p = ((struct __pyx_obj_2bx_6arrays_3bed_BedReader *)o);
+  p->f = Py_None; Py_INCREF(Py_None);
+  return o;
+}
+
+static void __pyx_tp_dealloc_2bx_6arrays_3bed_BedReader(PyObject *o) {
+  struct __pyx_obj_2bx_6arrays_3bed_BedReader *p = (struct __pyx_obj_2bx_6arrays_3bed_BedReader *)o;
+  PyObject_GC_UnTrack(o);
+  Py_CLEAR(p->f);
+  PyObject_GC_Track(o);
+  (*Py_TYPE(o)->tp_free)(o);
+}
+
+static int __pyx_tp_traverse_2bx_6arrays_3bed_BedReader(PyObject *o, visitproc v, void *a) {
+  int e;
+  struct __pyx_obj_2bx_6arrays_3bed_BedReader *p = (struct __pyx_obj_2bx_6arrays_3bed_BedReader *)o;
+  if (p->f) {
+    e = (*v)(p->f, a); if (e) return e;
+  }
+  return 0;
+}
+
+static int __pyx_tp_clear_2bx_6arrays_3bed_BedReader(PyObject *o) {
+  struct __pyx_obj_2bx_6arrays_3bed_BedReader *p = (struct __pyx_obj_2bx_6arrays_3bed_BedReader *)o;
+  PyObject* tmp;
+  tmp = ((PyObject*)p->f);
+  p->f = Py_None; Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  return 0;
+}
+
+static PyMethodDef __pyx_methods_2bx_6arrays_3bed_BedReader[] = {
+  {__Pyx_NAMESTR("__next__"), (PyCFunction)__pyx_pw_2bx_6arrays_3bed_9BedReader_5__next__, METH_NOARGS|METH_COEXIST, __Pyx_DOCSTR(0)},
+  {0, 0, 0, 0}
+};
+
+static PyNumberMethods __pyx_tp_as_number_BedReader = {
+  0, /*nb_add*/
+  0, /*nb_subtract*/
+  0, /*nb_multiply*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_divide*/
+  #endif
+  0, /*nb_remainder*/
+  0, /*nb_divmod*/
+  0, /*nb_power*/
+  0, /*nb_negative*/
+  0, /*nb_positive*/
+  0, /*nb_absolute*/
+  0, /*nb_nonzero*/
+  0, /*nb_invert*/
+  0, /*nb_lshift*/
+  0, /*nb_rshift*/
+  0, /*nb_and*/
+  0, /*nb_xor*/
+  0, /*nb_or*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_coerce*/
+  #endif
+  0, /*nb_int*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_long*/
+  #else
+  0, /*reserved*/
+  #endif
+  0, /*nb_float*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_oct*/
+  #endif
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_hex*/
+  #endif
+  0, /*nb_inplace_add*/
+  0, /*nb_inplace_subtract*/
+  0, /*nb_inplace_multiply*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_inplace_divide*/
+  #endif
+  0, /*nb_inplace_remainder*/
+  0, /*nb_inplace_power*/
+  0, /*nb_inplace_lshift*/
+  0, /*nb_inplace_rshift*/
+  0, /*nb_inplace_and*/
+  0, /*nb_inplace_xor*/
+  0, /*nb_inplace_or*/
+  0, /*nb_floor_divide*/
+  0, /*nb_true_divide*/
+  0, /*nb_inplace_floor_divide*/
+  0, /*nb_inplace_true_divide*/
+  #if PY_VERSION_HEX >= 0x02050000
+  0, /*nb_index*/
+  #endif
+};
+
+static PySequenceMethods __pyx_tp_as_sequence_BedReader = {
+  0, /*sq_length*/
+  0, /*sq_concat*/
+  0, /*sq_repeat*/
+  0, /*sq_item*/
+  0, /*sq_slice*/
+  0, /*sq_ass_item*/
+  0, /*sq_ass_slice*/
+  0, /*sq_contains*/
+  0, /*sq_inplace_concat*/
+  0, /*sq_inplace_repeat*/
+};
+
+static PyMappingMethods __pyx_tp_as_mapping_BedReader = {
+  0, /*mp_length*/
+  0, /*mp_subscript*/
+  0, /*mp_ass_subscript*/
+};
+
+static PyBufferProcs __pyx_tp_as_buffer_BedReader = {
+  #if PY_MAJOR_VERSION < 3
+  0, /*bf_getreadbuffer*/
+  #endif
+  #if PY_MAJOR_VERSION < 3
+  0, /*bf_getwritebuffer*/
+  #endif
+  #if PY_MAJOR_VERSION < 3
+  0, /*bf_getsegcount*/
+  #endif
+  #if PY_MAJOR_VERSION < 3
+  0, /*bf_getcharbuffer*/
+  #endif
+  #if PY_VERSION_HEX >= 0x02060000
+  0, /*bf_getbuffer*/
+  #endif
+  #if PY_VERSION_HEX >= 0x02060000
+  0, /*bf_releasebuffer*/
+  #endif
+};
+
+static PyTypeObject __pyx_type_2bx_6arrays_3bed_BedReader = {
+  PyVarObject_HEAD_INIT(0, 0)
+  __Pyx_NAMESTR("bx.arrays.bed.BedReader"), /*tp_name*/
+  sizeof(struct __pyx_obj_2bx_6arrays_3bed_BedReader), /*tp_basicsize*/
+  0, /*tp_itemsize*/
+  __pyx_tp_dealloc_2bx_6arrays_3bed_BedReader, /*tp_dealloc*/
+  0, /*tp_print*/
+  0, /*tp_getattr*/
+  0, /*tp_setattr*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*tp_compare*/
+  #else
+  0, /*reserved*/
+  #endif
+  0, /*tp_repr*/
+  &__pyx_tp_as_number_BedReader, /*tp_as_number*/
+  &__pyx_tp_as_sequence_BedReader, /*tp_as_sequence*/
+  &__pyx_tp_as_mapping_BedReader, /*tp_as_mapping*/
+  0, /*tp_hash*/
+  0, /*tp_call*/
+  0, /*tp_str*/
+  0, /*tp_getattro*/
+  0, /*tp_setattro*/
+  &__pyx_tp_as_buffer_BedReader, /*tp_as_buffer*/
+  Py_TPFLAGS_DEFAULT|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+  0, /*tp_doc*/
+  __pyx_tp_traverse_2bx_6arrays_3bed_BedReader, /*tp_traverse*/
+  __pyx_tp_clear_2bx_6arrays_3bed_BedReader, /*tp_clear*/
+  0, /*tp_richcompare*/
+  0, /*tp_weaklistoffset*/
+  __pyx_pw_2bx_6arrays_3bed_9BedReader_3__iter__, /*tp_iter*/
+  __pyx_pw_2bx_6arrays_3bed_9BedReader_5__next__, /*tp_iternext*/
+  __pyx_methods_2bx_6arrays_3bed_BedReader, /*tp_methods*/
+  0, /*tp_members*/
+  0, /*tp_getset*/
+  0, /*tp_base*/
+  0, /*tp_dict*/
+  0, /*tp_descr_get*/
+  0, /*tp_descr_set*/
+  0, /*tp_dictoffset*/
+  __pyx_pw_2bx_6arrays_3bed_9BedReader_1__init__, /*tp_init*/
+  0, /*tp_alloc*/
+  __pyx_tp_new_2bx_6arrays_3bed_BedReader, /*tp_new*/
+  0, /*tp_free*/
+  0, /*tp_is_gc*/
+  0, /*tp_bases*/
+  0, /*tp_mro*/
+  0, /*tp_cache*/
+  0, /*tp_subclasses*/
+  0, /*tp_weaklist*/
+  0, /*tp_del*/
+  #if PY_VERSION_HEX >= 0x02060000
+  0, /*tp_version_tag*/
+  #endif
+};
+
+static PyMethodDef __pyx_methods[] = {
+  {0, 0, 0, 0}
+};
+
+#if PY_MAJOR_VERSION >= 3
+static struct PyModuleDef __pyx_moduledef = {
+  #if PY_VERSION_HEX < 0x03020000
+    { PyObject_HEAD_INIT(NULL) NULL, 0, NULL },
+  #else
+    PyModuleDef_HEAD_INIT,
+  #endif
+    __Pyx_NAMESTR("bed"),
+    __Pyx_DOCSTR(__pyx_k_5), /* m_doc */
+    -1, /* m_size */
+    __pyx_methods /* m_methods */,
+    NULL, /* m_reload */
+    NULL, /* m_traverse */
+    NULL, /* m_clear */
+    NULL /* m_free */
+};
+#endif
+
+static __Pyx_StringTabEntry __pyx_string_tab[] = {
+  {&__pyx_kp_s_1, __pyx_k_1, sizeof(__pyx_k_1), 0, 0, 1, 0},
+  {&__pyx_kp_s_4, __pyx_k_4, sizeof(__pyx_k_4), 0, 0, 1, 0},
+  {&__pyx_n_s__StopIteration, __pyx_k__StopIteration, sizeof(__pyx_k__StopIteration), 0, 0, 1, 1},
+  {&__pyx_n_s____main__, __pyx_k____main__, sizeof(__pyx_k____main__), 0, 0, 1, 1},
+  {&__pyx_n_s____test__, __pyx_k____test__, sizeof(__pyx_k____test__), 0, 0, 1, 1},
+  {&__pyx_n_s__browser, __pyx_k__browser, sizeof(__pyx_k__browser), 0, 0, 1, 1},
+  {&__pyx_n_s__f, __pyx_k__f, sizeof(__pyx_k__f), 0, 0, 1, 1},
+  {&__pyx_n_s__isalpha, __pyx_k__isalpha, sizeof(__pyx_k__isalpha), 0, 0, 1, 1},
+  {&__pyx_n_s__isspace, __pyx_k__isspace, sizeof(__pyx_k__isspace), 0, 0, 1, 1},
+  {&__pyx_n_s__readline, __pyx_k__readline, sizeof(__pyx_k__readline), 0, 0, 1, 1},
+  {&__pyx_n_s__split, __pyx_k__split, sizeof(__pyx_k__split), 0, 0, 1, 1},
+  {&__pyx_n_s__startswith, __pyx_k__startswith, sizeof(__pyx_k__startswith), 0, 0, 1, 1},
+  {&__pyx_n_s__strip, __pyx_k__strip, sizeof(__pyx_k__strip), 0, 0, 1, 1},
+  {&__pyx_n_s__track, __pyx_k__track, sizeof(__pyx_k__track), 0, 0, 1, 1},
+  {0, 0, 0, 0, 0, 0, 0}
+};
+static int __Pyx_InitCachedBuiltins(void) {
+  __pyx_builtin_StopIteration = __Pyx_GetName(__pyx_b, __pyx_n_s__StopIteration); if (!__pyx_builtin_StopIteration) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 18; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  return 0;
+  __pyx_L1_error:;
+  return -1;
+}
+
+static int __Pyx_InitCachedConstants(void) {
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0);
+
+  /* "bx/arrays/bed.pyx":24
+ *                 continue
+ *             if line[0].isalpha():
+ *                 if line.startswith( "track" ) or line.startswith( "browser" ):             # <<<<<<<<<<<<<<
+ *                     continue
+ * 
+ */
+  __pyx_k_tuple_2 = PyTuple_Pack(1, ((PyObject *)__pyx_n_s__track)); if (unlikely(!__pyx_k_tuple_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 24; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_k_tuple_2);
+  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_2));
+  __pyx_k_tuple_3 = PyTuple_Pack(1, ((PyObject *)__pyx_n_s__browser)); if (unlikely(!__pyx_k_tuple_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 24; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_k_tuple_3);
+  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_3));
+  __Pyx_RefNannyFinishContext();
+  return 0;
+  __pyx_L1_error:;
+  __Pyx_RefNannyFinishContext();
+  return -1;
+}
+
+static int __Pyx_InitGlobals(void) {
+  if (__Pyx_InitStrings(__pyx_string_tab) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  return 0;
+  __pyx_L1_error:;
+  return -1;
+}
+
+#if PY_MAJOR_VERSION < 3
+PyMODINIT_FUNC initbed(void); /*proto*/
+PyMODINIT_FUNC initbed(void)
+#else
+PyMODINIT_FUNC PyInit_bed(void); /*proto*/
+PyMODINIT_FUNC PyInit_bed(void)
+#endif
+{
+  PyObject *__pyx_t_1 = NULL;
+  __Pyx_RefNannyDeclarations
+  #if CYTHON_REFNANNY
+  __Pyx_RefNanny = __Pyx_RefNannyImportAPI("refnanny");
+  if (!__Pyx_RefNanny) {
+      PyErr_Clear();
+      __Pyx_RefNanny = __Pyx_RefNannyImportAPI("Cython.Runtime.refnanny");
+      if (!__Pyx_RefNanny)
+          Py_FatalError("failed to import 'refnanny' module");
+  }
+  #endif
+  __Pyx_RefNannySetupContext("PyMODINIT_FUNC PyInit_bed(void)", 0);
+  if ( __Pyx_check_binary_version() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_bytes)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #ifdef __Pyx_CyFunction_USED
+  if (__Pyx_CyFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #endif
+  #ifdef __Pyx_FusedFunction_USED
+  if (__pyx_FusedFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #endif
+  #ifdef __Pyx_Generator_USED
+  if (__pyx_Generator_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #endif
+  /*--- Library function declarations ---*/
+  /*--- Threads initialization code ---*/
+  #if defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS
+  #ifdef WITH_THREAD /* Python build with threading support? */
+  PyEval_InitThreads();
+  #endif
+  #endif
+  /*--- Module creation code ---*/
+  #if PY_MAJOR_VERSION < 3
+  __pyx_m = Py_InitModule4(__Pyx_NAMESTR("bed"), __pyx_methods, __Pyx_DOCSTR(__pyx_k_5), 0, PYTHON_API_VERSION); Py_XINCREF(__pyx_m);
+  #else
+  __pyx_m = PyModule_Create(&__pyx_moduledef);
+  #endif
+  if (unlikely(!__pyx_m)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #if PY_MAJOR_VERSION >= 3
+  {
+    PyObject *modules = PyImport_GetModuleDict(); if (unlikely(!modules)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (!PyDict_GetItemString(modules, "bx.arrays.bed")) {
+      if (unlikely(PyDict_SetItemString(modules, "bx.arrays.bed", __pyx_m) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+  }
+  #endif
+  __pyx_b = PyImport_AddModule(__Pyx_NAMESTR(__Pyx_BUILTIN_MODULE_NAME)); if (unlikely(!__pyx_b)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #if CYTHON_COMPILING_IN_PYPY
+  Py_INCREF(__pyx_b);
+  #endif
+  if (__Pyx_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  /*--- Initialize various global constants etc. ---*/
+  if (unlikely(__Pyx_InitGlobals() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (__pyx_module_is_main_bx__arrays__bed) {
+    if (__Pyx_SetAttrString(__pyx_m, "__name__", __pyx_n_s____main__) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  }
+  /*--- Builtin init code ---*/
+  if (unlikely(__Pyx_InitCachedBuiltins() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  /*--- Constants init code ---*/
+  if (unlikely(__Pyx_InitCachedConstants() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  /*--- Global init code ---*/
+  /*--- Variable export code ---*/
+  /*--- Function export code ---*/
+  /*--- Type init code ---*/
+  if (PyType_Ready(&__pyx_type_2bx_6arrays_3bed_BedReader) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 6; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (__Pyx_SetAttrString(__pyx_m, "BedReader", (PyObject *)&__pyx_type_2bx_6arrays_3bed_BedReader) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 6; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_2bx_6arrays_3bed_BedReader = &__pyx_type_2bx_6arrays_3bed_BedReader;
+  /*--- Type import code ---*/
+  /*--- Variable import code ---*/
+  /*--- Function import code ---*/
+  /*--- Execution code ---*/
+
+  /* "bx/arrays/bed.pyx":1
+ * """             # <<<<<<<<<<<<<<
+ * Iterator for the BED format ( http://genome.ucsc.edu/FAQ/FAQformat.html#format1 )
+ * Returns chrom, chromStart, chromEnd, name, score
+ */
+  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(((PyObject *)__pyx_t_1));
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s____test__, ((PyObject *)__pyx_t_1)) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  if (__pyx_m) {
+    __Pyx_AddTraceback("init bx.arrays.bed", __pyx_clineno, __pyx_lineno, __pyx_filename);
+    Py_DECREF(__pyx_m); __pyx_m = 0;
+  } else if (!PyErr_Occurred()) {
+    PyErr_SetString(PyExc_ImportError, "init bx.arrays.bed");
+  }
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  #if PY_MAJOR_VERSION < 3
+  return;
+  #else
+  return __pyx_m;
+  #endif
+}
+
+/* Runtime support code */
+#if CYTHON_REFNANNY
+static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) {
+    PyObject *m = NULL, *p = NULL;
+    void *r = NULL;
+    m = PyImport_ImportModule((char *)modname);
+    if (!m) goto end;
+    p = PyObject_GetAttrString(m, (char *)"RefNannyAPI");
+    if (!p) goto end;
+    r = PyLong_AsVoidPtr(p);
+end:
+    Py_XDECREF(p);
+    Py_XDECREF(m);
+    return (__Pyx_RefNannyAPIStruct *)r;
+}
+#endif /* CYTHON_REFNANNY */
+
+static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name) {
+    PyObject *result;
+    result = PyObject_GetAttr(dict, name);
+    if (!result) {
+        if (dict != __pyx_b) {
+            PyErr_Clear();
+            result = PyObject_GetAttr(__pyx_b, name);
+        }
+        if (!result) {
+            PyErr_SetObject(PyExc_NameError, name);
+        }
+    }
+    return result;
+}
+
+static void __Pyx_RaiseDoubleKeywordsError(
+    const char* func_name,
+    PyObject* kw_name)
+{
+    PyErr_Format(PyExc_TypeError,
+        #if PY_MAJOR_VERSION >= 3
+        "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
+        #else
+        "%s() got multiple values for keyword argument '%s'", func_name,
+        PyString_AsString(kw_name));
+        #endif
+}
+
+static int __Pyx_ParseOptionalKeywords(
+    PyObject *kwds,
+    PyObject **argnames[],
+    PyObject *kwds2,
+    PyObject *values[],
+    Py_ssize_t num_pos_args,
+    const char* function_name)
+{
+    PyObject *key = 0, *value = 0;
+    Py_ssize_t pos = 0;
+    PyObject*** name;
+    PyObject*** first_kw_arg = argnames + num_pos_args;
+    while (PyDict_Next(kwds, &pos, &key, &value)) {
+        name = first_kw_arg;
+        while (*name && (**name != key)) name++;
+        if (*name) {
+            values[name-argnames] = value;
+            continue;
+        }
+        name = first_kw_arg;
+        #if PY_MAJOR_VERSION < 3
+        if (likely(PyString_CheckExact(key)) || likely(PyString_Check(key))) {
+            while (*name) {
+                if ((CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**name) == PyString_GET_SIZE(key))
+                        && _PyString_Eq(**name, key)) {
+                    values[name-argnames] = value;
+                    break;
+                }
+                name++;
+            }
+            if (*name) continue;
+            else {
+                PyObject*** argname = argnames;
+                while (argname != first_kw_arg) {
+                    if ((**argname == key) || (
+                            (CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**argname) == PyString_GET_SIZE(key))
+                             && _PyString_Eq(**argname, key))) {
+                        goto arg_passed_twice;
+                    }
+                    argname++;
+                }
+            }
+        } else
+        #endif
+        if (likely(PyUnicode_Check(key))) {
+            while (*name) {
+                int cmp = (**name == key) ? 0 :
+                #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3
+                    (PyUnicode_GET_SIZE(**name) != PyUnicode_GET_SIZE(key)) ? 1 :
+                #endif
+                    PyUnicode_Compare(**name, key);
+                if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad;
+                if (cmp == 0) {
+                    values[name-argnames] = value;
+                    break;
+                }
+                name++;
+            }
+            if (*name) continue;
+            else {
+                PyObject*** argname = argnames;
+                while (argname != first_kw_arg) {
+                    int cmp = (**argname == key) ? 0 :
+                    #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3
+                        (PyUnicode_GET_SIZE(**argname) != PyUnicode_GET_SIZE(key)) ? 1 :
+                    #endif
+                        PyUnicode_Compare(**argname, key);
+                    if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad;
+                    if (cmp == 0) goto arg_passed_twice;
+                    argname++;
+                }
+            }
+        } else
+            goto invalid_keyword_type;
+        if (kwds2) {
+            if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
+        } else {
+            goto invalid_keyword;
+        }
+    }
+    return 0;
+arg_passed_twice:
+    __Pyx_RaiseDoubleKeywordsError(function_name, key);
+    goto bad;
+invalid_keyword_type:
+    PyErr_Format(PyExc_TypeError,
+        "%s() keywords must be strings", function_name);
+    goto bad;
+invalid_keyword:
+    PyErr_Format(PyExc_TypeError,
+    #if PY_MAJOR_VERSION < 3
+        "%s() got an unexpected keyword argument '%s'",
+        function_name, PyString_AsString(key));
+    #else
+        "%s() got an unexpected keyword argument '%U'",
+        function_name, key);
+    #endif
+bad:
+    return -1;
+}
+
+static void __Pyx_RaiseArgtupleInvalid(
+    const char* func_name,
+    int exact,
+    Py_ssize_t num_min,
+    Py_ssize_t num_max,
+    Py_ssize_t num_found)
+{
+    Py_ssize_t num_expected;
+    const char *more_or_less;
+    if (num_found < num_min) {
+        num_expected = num_min;
+        more_or_less = "at least";
+    } else {
+        num_expected = num_max;
+        more_or_less = "at most";
+    }
+    if (exact) {
+        more_or_less = "exactly";
+    }
+    PyErr_Format(PyExc_TypeError,
+                 "%s() takes %s %" CYTHON_FORMAT_SSIZE_T "d positional argument%s (%" CYTHON_FORMAT_SSIZE_T "d given)",
+                 func_name, more_or_less, num_expected,
+                 (num_expected == 1) ? "" : "s", num_found);
+}
+
+static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    PyObject *tmp_type, *tmp_value, *tmp_tb;
+    PyThreadState *tstate = PyThreadState_GET();
+    tmp_type = tstate->curexc_type;
+    tmp_value = tstate->curexc_value;
+    tmp_tb = tstate->curexc_traceback;
+    tstate->curexc_type = type;
+    tstate->curexc_value = value;
+    tstate->curexc_traceback = tb;
+    Py_XDECREF(tmp_type);
+    Py_XDECREF(tmp_value);
+    Py_XDECREF(tmp_tb);
+#else
+    PyErr_Restore(type, value, tb);
+#endif
+}
+static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    PyThreadState *tstate = PyThreadState_GET();
+    *type = tstate->curexc_type;
+    *value = tstate->curexc_value;
+    *tb = tstate->curexc_traceback;
+    tstate->curexc_type = 0;
+    tstate->curexc_value = 0;
+    tstate->curexc_traceback = 0;
+#else
+    PyErr_Fetch(type, value, tb);
+#endif
+}
+
+#if PY_MAJOR_VERSION < 3
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb,
+                        CYTHON_UNUSED PyObject *cause) {
+    Py_XINCREF(type);
+    if (!value || value == Py_None)
+        value = NULL;
+    else
+        Py_INCREF(value);
+    if (!tb || tb == Py_None)
+        tb = NULL;
+    else {
+        Py_INCREF(tb);
+        if (!PyTraceBack_Check(tb)) {
+            PyErr_SetString(PyExc_TypeError,
+                "raise: arg 3 must be a traceback or None");
+            goto raise_error;
+        }
+    }
+    #if PY_VERSION_HEX < 0x02050000
+    if (PyClass_Check(type)) {
+    #else
+    if (PyType_Check(type)) {
+    #endif
+#if CYTHON_COMPILING_IN_PYPY
+        if (!value) {
+            Py_INCREF(Py_None);
+            value = Py_None;
+        }
+#endif
+        PyErr_NormalizeException(&type, &value, &tb);
+    } else {
+        if (value) {
+            PyErr_SetString(PyExc_TypeError,
+                "instance exception may not have a separate value");
+            goto raise_error;
+        }
+        value = type;
+        #if PY_VERSION_HEX < 0x02050000
+            if (PyInstance_Check(type)) {
+                type = (PyObject*) ((PyInstanceObject*)type)->in_class;
+                Py_INCREF(type);
+            }
+            else {
+                type = 0;
+                PyErr_SetString(PyExc_TypeError,
+                    "raise: exception must be an old-style class or instance");
+                goto raise_error;
+            }
+        #else
+            type = (PyObject*) Py_TYPE(type);
+            Py_INCREF(type);
+            if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
+                PyErr_SetString(PyExc_TypeError,
+                    "raise: exception class must be a subclass of BaseException");
+                goto raise_error;
+            }
+        #endif
+    }
+    __Pyx_ErrRestore(type, value, tb);
+    return;
+raise_error:
+    Py_XDECREF(value);
+    Py_XDECREF(type);
+    Py_XDECREF(tb);
+    return;
+}
+#else /* Python 3+ */
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause) {
+    PyObject* owned_instance = NULL;
+    if (tb == Py_None) {
+        tb = 0;
+    } else if (tb && !PyTraceBack_Check(tb)) {
+        PyErr_SetString(PyExc_TypeError,
+            "raise: arg 3 must be a traceback or None");
+        goto bad;
+    }
+    if (value == Py_None)
+        value = 0;
+    if (PyExceptionInstance_Check(type)) {
+        if (value) {
+            PyErr_SetString(PyExc_TypeError,
+                "instance exception may not have a separate value");
+            goto bad;
+        }
+        value = type;
+        type = (PyObject*) Py_TYPE(value);
+    } else if (PyExceptionClass_Check(type)) {
+        PyObject *args;
+        if (!value)
+            args = PyTuple_New(0);
+        else if (PyTuple_Check(value)) {
+            Py_INCREF(value);
+            args = value;
+        }
+        else
+            args = PyTuple_Pack(1, value);
+        if (!args)
+            goto bad;
+        owned_instance = PyEval_CallObject(type, args);
+        Py_DECREF(args);
+        if (!owned_instance)
+            goto bad;
+        value = owned_instance;
+        if (!PyExceptionInstance_Check(value)) {
+            PyErr_Format(PyExc_TypeError,
+                         "calling %R should have returned an instance of "
+                         "BaseException, not %R",
+                         type, Py_TYPE(value));
+            goto bad;
+        }
+    } else {
+        PyErr_SetString(PyExc_TypeError,
+            "raise: exception class must be a subclass of BaseException");
+        goto bad;
+    }
+    if (cause && cause != Py_None) {
+        PyObject *fixed_cause;
+        if (PyExceptionClass_Check(cause)) {
+            fixed_cause = PyObject_CallObject(cause, NULL);
+            if (fixed_cause == NULL)
+                goto bad;
+        }
+        else if (PyExceptionInstance_Check(cause)) {
+            fixed_cause = cause;
+            Py_INCREF(fixed_cause);
+        }
+        else {
+            PyErr_SetString(PyExc_TypeError,
+                            "exception causes must derive from "
+                            "BaseException");
+            goto bad;
+        }
+        PyException_SetCause(value, fixed_cause);
+    }
+    PyErr_SetObject(type, value);
+    if (tb) {
+        PyThreadState *tstate = PyThreadState_GET();
+        PyObject* tmp_tb = tstate->curexc_traceback;
+        if (tb != tmp_tb) {
+            Py_INCREF(tb);
+            tstate->curexc_traceback = tb;
+            Py_XDECREF(tmp_tb);
+        }
+    }
+bad:
+    Py_XDECREF(owned_instance);
+    return;
+}
+#endif
+
+static CYTHON_INLINE unsigned char __Pyx_PyInt_AsUnsignedChar(PyObject* x) {
+    const unsigned char neg_one = (unsigned char)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(unsigned char) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(unsigned char)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to unsigned char" :
+                    "value too large to convert to unsigned char");
+            }
+            return (unsigned char)-1;
+        }
+        return (unsigned char)val;
+    }
+    return (unsigned char)__Pyx_PyInt_AsUnsignedLong(x);
+}
+
+static CYTHON_INLINE unsigned short __Pyx_PyInt_AsUnsignedShort(PyObject* x) {
+    const unsigned short neg_one = (unsigned short)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(unsigned short) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(unsigned short)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to unsigned short" :
+                    "value too large to convert to unsigned short");
+            }
+            return (unsigned short)-1;
+        }
+        return (unsigned short)val;
+    }
+    return (unsigned short)__Pyx_PyInt_AsUnsignedLong(x);
+}
+
+static CYTHON_INLINE unsigned int __Pyx_PyInt_AsUnsignedInt(PyObject* x) {
+    const unsigned int neg_one = (unsigned int)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(unsigned int) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(unsigned int)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to unsigned int" :
+                    "value too large to convert to unsigned int");
+            }
+            return (unsigned int)-1;
+        }
+        return (unsigned int)val;
+    }
+    return (unsigned int)__Pyx_PyInt_AsUnsignedLong(x);
+}
+
+static CYTHON_INLINE char __Pyx_PyInt_AsChar(PyObject* x) {
+    const char neg_one = (char)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(char) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(char)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to char" :
+                    "value too large to convert to char");
+            }
+            return (char)-1;
+        }
+        return (char)val;
+    }
+    return (char)__Pyx_PyInt_AsLong(x);
+}
+
+static CYTHON_INLINE short __Pyx_PyInt_AsShort(PyObject* x) {
+    const short neg_one = (short)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(short) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(short)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to short" :
+                    "value too large to convert to short");
+            }
+            return (short)-1;
+        }
+        return (short)val;
+    }
+    return (short)__Pyx_PyInt_AsLong(x);
+}
+
+static CYTHON_INLINE int __Pyx_PyInt_AsInt(PyObject* x) {
+    const int neg_one = (int)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(int) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(int)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to int" :
+                    "value too large to convert to int");
+            }
+            return (int)-1;
+        }
+        return (int)val;
+    }
+    return (int)__Pyx_PyInt_AsLong(x);
+}
+
+static CYTHON_INLINE signed char __Pyx_PyInt_AsSignedChar(PyObject* x) {
+    const signed char neg_one = (signed char)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(signed char) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(signed char)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to signed char" :
+                    "value too large to convert to signed char");
+            }
+            return (signed char)-1;
+        }
+        return (signed char)val;
+    }
+    return (signed char)__Pyx_PyInt_AsSignedLong(x);
+}
+
+static CYTHON_INLINE signed short __Pyx_PyInt_AsSignedShort(PyObject* x) {
+    const signed short neg_one = (signed short)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(signed short) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(signed short)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to signed short" :
+                    "value too large to convert to signed short");
+            }
+            return (signed short)-1;
+        }
+        return (signed short)val;
+    }
+    return (signed short)__Pyx_PyInt_AsSignedLong(x);
+}
+
+static CYTHON_INLINE signed int __Pyx_PyInt_AsSignedInt(PyObject* x) {
+    const signed int neg_one = (signed int)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(signed int) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(signed int)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to signed int" :
+                    "value too large to convert to signed int");
+            }
+            return (signed int)-1;
+        }
+        return (signed int)val;
+    }
+    return (signed int)__Pyx_PyInt_AsSignedLong(x);
+}
+
+static CYTHON_INLINE int __Pyx_PyInt_AsLongDouble(PyObject* x) {
+    const int neg_one = (int)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(int) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(int)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to int" :
+                    "value too large to convert to int");
+            }
+            return (int)-1;
+        }
+        return (int)val;
+    }
+    return (int)__Pyx_PyInt_AsLong(x);
+}
+
+static CYTHON_INLINE unsigned long __Pyx_PyInt_AsUnsignedLong(PyObject* x) {
+    const unsigned long neg_one = (unsigned long)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to unsigned long");
+            return (unsigned long)-1;
+        }
+        return (unsigned long)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to unsigned long");
+                return (unsigned long)-1;
+            }
+            return (unsigned long)PyLong_AsUnsignedLong(x);
+        } else {
+            return (unsigned long)PyLong_AsLong(x);
+        }
+    } else {
+        unsigned long val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (unsigned long)-1;
+        val = __Pyx_PyInt_AsUnsignedLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE unsigned PY_LONG_LONG __Pyx_PyInt_AsUnsignedLongLong(PyObject* x) {
+    const unsigned PY_LONG_LONG neg_one = (unsigned PY_LONG_LONG)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to unsigned PY_LONG_LONG");
+            return (unsigned PY_LONG_LONG)-1;
+        }
+        return (unsigned PY_LONG_LONG)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to unsigned PY_LONG_LONG");
+                return (unsigned PY_LONG_LONG)-1;
+            }
+            return (unsigned PY_LONG_LONG)PyLong_AsUnsignedLongLong(x);
+        } else {
+            return (unsigned PY_LONG_LONG)PyLong_AsLongLong(x);
+        }
+    } else {
+        unsigned PY_LONG_LONG val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (unsigned PY_LONG_LONG)-1;
+        val = __Pyx_PyInt_AsUnsignedLongLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE long __Pyx_PyInt_AsLong(PyObject* x) {
+    const long neg_one = (long)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to long");
+            return (long)-1;
+        }
+        return (long)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to long");
+                return (long)-1;
+            }
+            return (long)PyLong_AsUnsignedLong(x);
+        } else {
+            return (long)PyLong_AsLong(x);
+        }
+    } else {
+        long val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (long)-1;
+        val = __Pyx_PyInt_AsLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE PY_LONG_LONG __Pyx_PyInt_AsLongLong(PyObject* x) {
+    const PY_LONG_LONG neg_one = (PY_LONG_LONG)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to PY_LONG_LONG");
+            return (PY_LONG_LONG)-1;
+        }
+        return (PY_LONG_LONG)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to PY_LONG_LONG");
+                return (PY_LONG_LONG)-1;
+            }
+            return (PY_LONG_LONG)PyLong_AsUnsignedLongLong(x);
+        } else {
+            return (PY_LONG_LONG)PyLong_AsLongLong(x);
+        }
+    } else {
+        PY_LONG_LONG val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (PY_LONG_LONG)-1;
+        val = __Pyx_PyInt_AsLongLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE signed long __Pyx_PyInt_AsSignedLong(PyObject* x) {
+    const signed long neg_one = (signed long)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to signed long");
+            return (signed long)-1;
+        }
+        return (signed long)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to signed long");
+                return (signed long)-1;
+            }
+            return (signed long)PyLong_AsUnsignedLong(x);
+        } else {
+            return (signed long)PyLong_AsLong(x);
+        }
+    } else {
+        signed long val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (signed long)-1;
+        val = __Pyx_PyInt_AsSignedLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE signed PY_LONG_LONG __Pyx_PyInt_AsSignedLongLong(PyObject* x) {
+    const signed PY_LONG_LONG neg_one = (signed PY_LONG_LONG)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to signed PY_LONG_LONG");
+            return (signed PY_LONG_LONG)-1;
+        }
+        return (signed PY_LONG_LONG)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to signed PY_LONG_LONG");
+                return (signed PY_LONG_LONG)-1;
+            }
+            return (signed PY_LONG_LONG)PyLong_AsUnsignedLongLong(x);
+        } else {
+            return (signed PY_LONG_LONG)PyLong_AsLongLong(x);
+        }
+    } else {
+        signed PY_LONG_LONG val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (signed PY_LONG_LONG)-1;
+        val = __Pyx_PyInt_AsSignedLongLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static int __Pyx_check_binary_version(void) {
+    char ctversion[4], rtversion[4];
+    PyOS_snprintf(ctversion, 4, "%d.%d", PY_MAJOR_VERSION, PY_MINOR_VERSION);
+    PyOS_snprintf(rtversion, 4, "%s", Py_GetVersion());
+    if (ctversion[0] != rtversion[0] || ctversion[2] != rtversion[2]) {
+        char message[200];
+        PyOS_snprintf(message, sizeof(message),
+                      "compiletime version %s of module '%.100s' "
+                      "does not match runtime version %s",
+                      ctversion, __Pyx_MODULE_NAME, rtversion);
+        #if PY_VERSION_HEX < 0x02050000
+        return PyErr_Warn(NULL, message);
+        #else
+        return PyErr_WarnEx(NULL, message, 1);
+        #endif
+    }
+    return 0;
+}
+
+static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) {
+    int start = 0, mid = 0, end = count - 1;
+    if (end >= 0 && code_line > entries[end].code_line) {
+        return count;
+    }
+    while (start < end) {
+        mid = (start + end) / 2;
+        if (code_line < entries[mid].code_line) {
+            end = mid;
+        } else if (code_line > entries[mid].code_line) {
+             start = mid + 1;
+        } else {
+            return mid;
+        }
+    }
+    if (code_line <= entries[mid].code_line) {
+        return mid;
+    } else {
+        return mid + 1;
+    }
+}
+static PyCodeObject *__pyx_find_code_object(int code_line) {
+    PyCodeObject* code_object;
+    int pos;
+    if (unlikely(!code_line) || unlikely(!__pyx_code_cache.entries)) {
+        return NULL;
+    }
+    pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line);
+    if (unlikely(pos >= __pyx_code_cache.count) || unlikely(__pyx_code_cache.entries[pos].code_line != code_line)) {
+        return NULL;
+    }
+    code_object = __pyx_code_cache.entries[pos].code_object;
+    Py_INCREF(code_object);
+    return code_object;
+}
+static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) {
+    int pos, i;
+    __Pyx_CodeObjectCacheEntry* entries = __pyx_code_cache.entries;
+    if (unlikely(!code_line)) {
+        return;
+    }
+    if (unlikely(!entries)) {
+        entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Malloc(64*sizeof(__Pyx_CodeObjectCacheEntry));
+        if (likely(entries)) {
+            __pyx_code_cache.entries = entries;
+            __pyx_code_cache.max_count = 64;
+            __pyx_code_cache.count = 1;
+            entries[0].code_line = code_line;
+            entries[0].code_object = code_object;
+            Py_INCREF(code_object);
+        }
+        return;
+    }
+    pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line);
+    if ((pos < __pyx_code_cache.count) && unlikely(__pyx_code_cache.entries[pos].code_line == code_line)) {
+        PyCodeObject* tmp = entries[pos].code_object;
+        entries[pos].code_object = code_object;
+        Py_DECREF(tmp);
+        return;
+    }
+    if (__pyx_code_cache.count == __pyx_code_cache.max_count) {
+        int new_max = __pyx_code_cache.max_count + 64;
+        entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Realloc(
+            __pyx_code_cache.entries, new_max*sizeof(__Pyx_CodeObjectCacheEntry));
+        if (unlikely(!entries)) {
+            return;
+        }
+        __pyx_code_cache.entries = entries;
+        __pyx_code_cache.max_count = new_max;
+    }
+    for (i=__pyx_code_cache.count; i>pos; i--) {
+        entries[i] = entries[i-1];
+    }
+    entries[pos].code_line = code_line;
+    entries[pos].code_object = code_object;
+    __pyx_code_cache.count++;
+    Py_INCREF(code_object);
+}
+
+#include "compile.h"
+#include "frameobject.h"
+#include "traceback.h"
+static PyCodeObject* __Pyx_CreateCodeObjectForTraceback(
+            const char *funcname, int c_line,
+            int py_line, const char *filename) {
+    PyCodeObject *py_code = 0;
+    PyObject *py_srcfile = 0;
+    PyObject *py_funcname = 0;
+    #if PY_MAJOR_VERSION < 3
+    py_srcfile = PyString_FromString(filename);
+    #else
+    py_srcfile = PyUnicode_FromString(filename);
+    #endif
+    if (!py_srcfile) goto bad;
+    if (c_line) {
+        #if PY_MAJOR_VERSION < 3
+        py_funcname = PyString_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line);
+        #else
+        py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line);
+        #endif
+    }
+    else {
+        #if PY_MAJOR_VERSION < 3
+        py_funcname = PyString_FromString(funcname);
+        #else
+        py_funcname = PyUnicode_FromString(funcname);
+        #endif
+    }
+    if (!py_funcname) goto bad;
+    py_code = __Pyx_PyCode_New(
+        0,            /*int argcount,*/
+        0,            /*int kwonlyargcount,*/
+        0,            /*int nlocals,*/
+        0,            /*int stacksize,*/
+        0,            /*int flags,*/
+        __pyx_empty_bytes, /*PyObject *code,*/
+        __pyx_empty_tuple, /*PyObject *consts,*/
+        __pyx_empty_tuple, /*PyObject *names,*/
+        __pyx_empty_tuple, /*PyObject *varnames,*/
+        __pyx_empty_tuple, /*PyObject *freevars,*/
+        __pyx_empty_tuple, /*PyObject *cellvars,*/
+        py_srcfile,   /*PyObject *filename,*/
+        py_funcname,  /*PyObject *name,*/
+        py_line,      /*int firstlineno,*/
+        __pyx_empty_bytes  /*PyObject *lnotab*/
+    );
+    Py_DECREF(py_srcfile);
+    Py_DECREF(py_funcname);
+    return py_code;
+bad:
+    Py_XDECREF(py_srcfile);
+    Py_XDECREF(py_funcname);
+    return NULL;
+}
+static void __Pyx_AddTraceback(const char *funcname, int c_line,
+                               int py_line, const char *filename) {
+    PyCodeObject *py_code = 0;
+    PyObject *py_globals = 0;
+    PyFrameObject *py_frame = 0;
+    py_code = __pyx_find_code_object(c_line ? c_line : py_line);
+    if (!py_code) {
+        py_code = __Pyx_CreateCodeObjectForTraceback(
+            funcname, c_line, py_line, filename);
+        if (!py_code) goto bad;
+        __pyx_insert_code_object(c_line ? c_line : py_line, py_code);
+    }
+    py_globals = PyModule_GetDict(__pyx_m);
+    if (!py_globals) goto bad;
+    py_frame = PyFrame_New(
+        PyThreadState_GET(), /*PyThreadState *tstate,*/
+        py_code,             /*PyCodeObject *code,*/
+        py_globals,          /*PyObject *globals,*/
+        0                    /*PyObject *locals*/
+    );
+    if (!py_frame) goto bad;
+    py_frame->f_lineno = py_line;
+    PyTraceBack_Here(py_frame);
+bad:
+    Py_XDECREF(py_code);
+    Py_XDECREF(py_frame);
+}
+
+static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
+    while (t->p) {
+        #if PY_MAJOR_VERSION < 3
+        if (t->is_unicode) {
+            *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
+        } else if (t->intern) {
+            *t->p = PyString_InternFromString(t->s);
+        } else {
+            *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
+        }
+        #else  /* Python 3+ has unicode identifiers */
+        if (t->is_unicode | t->is_str) {
+            if (t->intern) {
+                *t->p = PyUnicode_InternFromString(t->s);
+            } else if (t->encoding) {
+                *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL);
+            } else {
+                *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
+            }
+        } else {
+            *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
+        }
+        #endif
+        if (!*t->p)
+            return -1;
+        ++t;
+    }
+    return 0;
+}
+
+static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) {
+   int is_true = x == Py_True;
+   if (is_true | (x == Py_False) | (x == Py_None)) return is_true;
+   else return PyObject_IsTrue(x);
+}
+static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x) {
+  PyNumberMethods *m;
+  const char *name = NULL;
+  PyObject *res = NULL;
+#if PY_VERSION_HEX < 0x03000000
+  if (PyInt_Check(x) || PyLong_Check(x))
+#else
+  if (PyLong_Check(x))
+#endif
+    return Py_INCREF(x), x;
+  m = Py_TYPE(x)->tp_as_number;
+#if PY_VERSION_HEX < 0x03000000
+  if (m && m->nb_int) {
+    name = "int";
+    res = PyNumber_Int(x);
+  }
+  else if (m && m->nb_long) {
+    name = "long";
+    res = PyNumber_Long(x);
+  }
+#else
+  if (m && m->nb_int) {
+    name = "int";
+    res = PyNumber_Long(x);
+  }
+#endif
+  if (res) {
+#if PY_VERSION_HEX < 0x03000000
+    if (!PyInt_Check(res) && !PyLong_Check(res)) {
+#else
+    if (!PyLong_Check(res)) {
+#endif
+      PyErr_Format(PyExc_TypeError,
+                   "__%s__ returned non-%s (type %.200s)",
+                   name, name, Py_TYPE(res)->tp_name);
+      Py_DECREF(res);
+      return NULL;
+    }
+  }
+  else if (!PyErr_Occurred()) {
+    PyErr_SetString(PyExc_TypeError,
+                    "an integer is required");
+  }
+  return res;
+}
+static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) {
+  Py_ssize_t ival;
+  PyObject* x = PyNumber_Index(b);
+  if (!x) return -1;
+  ival = PyInt_AsSsize_t(x);
+  Py_DECREF(x);
+  return ival;
+}
+static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) {
+#if PY_VERSION_HEX < 0x02050000
+   if (ival <= LONG_MAX)
+       return PyInt_FromLong((long)ival);
+   else {
+       unsigned char *bytes = (unsigned char *) &ival;
+       int one = 1; int little = (int)*(unsigned char*)&one;
+       return _PyLong_FromByteArray(bytes, sizeof(size_t), little, 0);
+   }
+#else
+   return PyInt_FromSize_t(ival);
+#endif
+}
+static CYTHON_INLINE size_t __Pyx_PyInt_AsSize_t(PyObject* x) {
+   unsigned PY_LONG_LONG val = __Pyx_PyInt_AsUnsignedLongLong(x);
+   if (unlikely(val == (unsigned PY_LONG_LONG)-1 && PyErr_Occurred())) {
+       return (size_t)-1;
+   } else if (unlikely(val != (unsigned PY_LONG_LONG)(size_t)val)) {
+       PyErr_SetString(PyExc_OverflowError,
+                       "value too large to convert to size_t");
+       return (size_t)-1;
+   }
+   return (size_t)val;
+}
+
+
+#endif /* Py_PYTHON_H */
diff --git a/lib/bx/arrays/bed.pyx b/lib/bx/arrays/bed.pyx
new file mode 100644
index 0000000..a8aeff9
--- /dev/null
+++ b/lib/bx/arrays/bed.pyx
@@ -0,0 +1,46 @@
+"""
+Iterator for the BED format ( http://genome.ucsc.edu/FAQ/FAQformat.html#format1 )
+Returns chrom, chromStart, chromEnd, name, score
+"""
+
+cdef class BedReader:
+    cdef object f
+    def __init__( self, f ):
+        self.f = f
+
+    def __iter__( self ):
+        return self
+
+    def __next__( self ):
+        while True:
+            line = self.f.readline()
+            if not line:
+                raise StopIteration()
+            if line.isspace():
+                continue    
+            if line[0] == "#":
+                continue
+            if line[0].isalpha():
+                if line.startswith( "track" ) or line.startswith( "browser" ):
+                    continue
+                
+                feature = line.strip().split()
+                chrom = feature[0]
+                chrom_start = int(feature[1])
+                chrom_end = int(feature[2])
+                if len(feature) > 3:
+                    name = feature[3]
+                else:
+                    name = None
+                                
+                if len(feature) > 4:
+                    score = int(feature[4])
+                else:
+                    score = None
+                    
+                
+                return chrom, chrom_start, chrom_end, name, score
+                    
+            else:
+                raise "Unexpected input line: %s" % line.strip()
+
diff --git a/lib/bx/arrays/wiggle.c b/lib/bx/arrays/wiggle.c
new file mode 100644
index 0000000..baa92d3
--- /dev/null
+++ b/lib/bx/arrays/wiggle.c
@@ -0,0 +1,3684 @@
+/* Generated by Cython 0.18 on Mon Jul 15 13:25:44 2013 */
+
+#define PY_SSIZE_T_CLEAN
+#include "Python.h"
+#ifndef Py_PYTHON_H
+    #error Python headers needed to compile C extensions, please install development version of Python.
+#elif PY_VERSION_HEX < 0x02040000
+    #error Cython requires Python 2.4+.
+#else
+#include <stddef.h> /* For offsetof */
+#ifndef offsetof
+#define offsetof(type, member) ( (size_t) & ((type*)0) -> member )
+#endif
+#if !defined(WIN32) && !defined(MS_WINDOWS)
+  #ifndef __stdcall
+    #define __stdcall
+  #endif
+  #ifndef __cdecl
+    #define __cdecl
+  #endif
+  #ifndef __fastcall
+    #define __fastcall
+  #endif
+#endif
+#ifndef DL_IMPORT
+  #define DL_IMPORT(t) t
+#endif
+#ifndef DL_EXPORT
+  #define DL_EXPORT(t) t
+#endif
+#ifndef PY_LONG_LONG
+  #define PY_LONG_LONG LONG_LONG
+#endif
+#ifndef Py_HUGE_VAL
+  #define Py_HUGE_VAL HUGE_VAL
+#endif
+#ifdef PYPY_VERSION
+#define CYTHON_COMPILING_IN_PYPY 1
+#define CYTHON_COMPILING_IN_CPYTHON 0
+#else
+#define CYTHON_COMPILING_IN_PYPY 0
+#define CYTHON_COMPILING_IN_CPYTHON 1
+#endif
+#if PY_VERSION_HEX < 0x02050000
+  typedef int Py_ssize_t;
+  #define PY_SSIZE_T_MAX INT_MAX
+  #define PY_SSIZE_T_MIN INT_MIN
+  #define PY_FORMAT_SIZE_T ""
+  #define CYTHON_FORMAT_SSIZE_T ""
+  #define PyInt_FromSsize_t(z) PyInt_FromLong(z)
+  #define PyInt_AsSsize_t(o)   __Pyx_PyInt_AsInt(o)
+  #define PyNumber_Index(o)    ((PyNumber_Check(o) && !PyFloat_Check(o)) ? PyNumber_Int(o) : \
+                                (PyErr_Format(PyExc_TypeError, \
+                                              "expected index value, got %.200s", Py_TYPE(o)->tp_name), \
+                                 (PyObject*)0))
+  #define __Pyx_PyIndex_Check(o) (PyNumber_Check(o) && !PyFloat_Check(o) && \
+                                  !PyComplex_Check(o))
+  #define PyIndex_Check __Pyx_PyIndex_Check
+  #define PyErr_WarnEx(category, message, stacklevel) PyErr_Warn(category, message)
+  #define __PYX_BUILD_PY_SSIZE_T "i"
+#else
+  #define __PYX_BUILD_PY_SSIZE_T "n"
+  #define CYTHON_FORMAT_SSIZE_T "z"
+  #define __Pyx_PyIndex_Check PyIndex_Check
+#endif
+#if PY_VERSION_HEX < 0x02060000
+  #define Py_REFCNT(ob) (((PyObject*)(ob))->ob_refcnt)
+  #define Py_TYPE(ob)   (((PyObject*)(ob))->ob_type)
+  #define Py_SIZE(ob)   (((PyVarObject*)(ob))->ob_size)
+  #define PyVarObject_HEAD_INIT(type, size) \
+          PyObject_HEAD_INIT(type) size,
+  #define PyType_Modified(t)
+  typedef struct {
+     void *buf;
+     PyObject *obj;
+     Py_ssize_t len;
+     Py_ssize_t itemsize;
+     int readonly;
+     int ndim;
+     char *format;
+     Py_ssize_t *shape;
+     Py_ssize_t *strides;
+     Py_ssize_t *suboffsets;
+     void *internal;
+  } Py_buffer;
+  #define PyBUF_SIMPLE 0
+  #define PyBUF_WRITABLE 0x0001
+  #define PyBUF_FORMAT 0x0004
+  #define PyBUF_ND 0x0008
+  #define PyBUF_STRIDES (0x0010 | PyBUF_ND)
+  #define PyBUF_C_CONTIGUOUS (0x0020 | PyBUF_STRIDES)
+  #define PyBUF_F_CONTIGUOUS (0x0040 | PyBUF_STRIDES)
+  #define PyBUF_ANY_CONTIGUOUS (0x0080 | PyBUF_STRIDES)
+  #define PyBUF_INDIRECT (0x0100 | PyBUF_STRIDES)
+  #define PyBUF_RECORDS (PyBUF_STRIDES | PyBUF_FORMAT | PyBUF_WRITABLE)
+  #define PyBUF_FULL (PyBUF_INDIRECT | PyBUF_FORMAT | PyBUF_WRITABLE)
+  typedef int (*getbufferproc)(PyObject *, Py_buffer *, int);
+  typedef void (*releasebufferproc)(PyObject *, Py_buffer *);
+#endif
+#if PY_MAJOR_VERSION < 3
+  #define __Pyx_BUILTIN_MODULE_NAME "__builtin__"
+  #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \
+          PyCode_New(a, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
+#else
+  #define __Pyx_BUILTIN_MODULE_NAME "builtins"
+  #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \
+          PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
+#endif
+#if PY_MAJOR_VERSION < 3 && PY_MINOR_VERSION < 6
+  #define PyUnicode_FromString(s) PyUnicode_Decode(s, strlen(s), "UTF-8", "strict")
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define Py_TPFLAGS_CHECKTYPES 0
+  #define Py_TPFLAGS_HAVE_INDEX 0
+#endif
+#if (PY_VERSION_HEX < 0x02060000) || (PY_MAJOR_VERSION >= 3)
+  #define Py_TPFLAGS_HAVE_NEWBUFFER 0
+#endif
+#if PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND)
+  #define CYTHON_PEP393_ENABLED 1
+  #define __Pyx_PyUnicode_READY(op)       (likely(PyUnicode_IS_READY(op)) ? \
+                                              0 : _PyUnicode_Ready((PyObject *)(op)))
+  #define __Pyx_PyUnicode_GET_LENGTH(u)   PyUnicode_GET_LENGTH(u)
+  #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_READ_CHAR(u, i)
+  #define __Pyx_PyUnicode_READ(k, d, i)   PyUnicode_READ(k, d, i)
+#else
+  #define CYTHON_PEP393_ENABLED 0
+  #define __Pyx_PyUnicode_READY(op)       (0)
+  #define __Pyx_PyUnicode_GET_LENGTH(u)   PyUnicode_GET_SIZE(u)
+  #define __Pyx_PyUnicode_READ_CHAR(u, i) ((Py_UCS4)(PyUnicode_AS_UNICODE(u)[i]))
+  #define __Pyx_PyUnicode_READ(k, d, i)   ((k=k), (Py_UCS4)(((Py_UNICODE*)d)[i]))
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define PyBaseString_Type            PyUnicode_Type
+  #define PyStringObject               PyUnicodeObject
+  #define PyString_Type                PyUnicode_Type
+  #define PyString_Check               PyUnicode_Check
+  #define PyString_CheckExact          PyUnicode_CheckExact
+#endif
+#if PY_VERSION_HEX < 0x02060000
+  #define PyBytesObject                PyStringObject
+  #define PyBytes_Type                 PyString_Type
+  #define PyBytes_Check                PyString_Check
+  #define PyBytes_CheckExact           PyString_CheckExact
+  #define PyBytes_FromString           PyString_FromString
+  #define PyBytes_FromStringAndSize    PyString_FromStringAndSize
+  #define PyBytes_FromFormat           PyString_FromFormat
+  #define PyBytes_DecodeEscape         PyString_DecodeEscape
+  #define PyBytes_AsString             PyString_AsString
+  #define PyBytes_AsStringAndSize      PyString_AsStringAndSize
+  #define PyBytes_Size                 PyString_Size
+  #define PyBytes_AS_STRING            PyString_AS_STRING
+  #define PyBytes_GET_SIZE             PyString_GET_SIZE
+  #define PyBytes_Repr                 PyString_Repr
+  #define PyBytes_Concat               PyString_Concat
+  #define PyBytes_ConcatAndDel         PyString_ConcatAndDel
+#endif
+#if PY_VERSION_HEX < 0x02060000
+  #define PySet_Check(obj)             PyObject_TypeCheck(obj, &PySet_Type)
+  #define PyFrozenSet_Check(obj)       PyObject_TypeCheck(obj, &PyFrozenSet_Type)
+#endif
+#ifndef PySet_CheckExact
+  #define PySet_CheckExact(obj)        (Py_TYPE(obj) == &PySet_Type)
+#endif
+#define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type)
+#if PY_MAJOR_VERSION >= 3
+  #define PyIntObject                  PyLongObject
+  #define PyInt_Type                   PyLong_Type
+  #define PyInt_Check(op)              PyLong_Check(op)
+  #define PyInt_CheckExact(op)         PyLong_CheckExact(op)
+  #define PyInt_FromString             PyLong_FromString
+  #define PyInt_FromUnicode            PyLong_FromUnicode
+  #define PyInt_FromLong               PyLong_FromLong
+  #define PyInt_FromSize_t             PyLong_FromSize_t
+  #define PyInt_FromSsize_t            PyLong_FromSsize_t
+  #define PyInt_AsLong                 PyLong_AsLong
+  #define PyInt_AS_LONG                PyLong_AS_LONG
+  #define PyInt_AsSsize_t              PyLong_AsSsize_t
+  #define PyInt_AsUnsignedLongMask     PyLong_AsUnsignedLongMask
+  #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define PyBoolObject                 PyLongObject
+#endif
+#if PY_VERSION_HEX < 0x03020000
+  typedef long Py_hash_t;
+  #define __Pyx_PyInt_FromHash_t PyInt_FromLong
+  #define __Pyx_PyInt_AsHash_t   PyInt_AsLong
+#else
+  #define __Pyx_PyInt_FromHash_t PyInt_FromSsize_t
+  #define __Pyx_PyInt_AsHash_t   PyInt_AsSsize_t
+#endif
+#if (PY_MAJOR_VERSION < 3) || (PY_VERSION_HEX >= 0x03010300)
+  #define __Pyx_PySequence_GetSlice(obj, a, b) PySequence_GetSlice(obj, a, b)
+  #define __Pyx_PySequence_SetSlice(obj, a, b, value) PySequence_SetSlice(obj, a, b, value)
+  #define __Pyx_PySequence_DelSlice(obj, a, b) PySequence_DelSlice(obj, a, b)
+#else
+  #define __Pyx_PySequence_GetSlice(obj, a, b) (unlikely(!(obj)) ? \
+        (PyErr_SetString(PyExc_SystemError, "null argument to internal routine"), (PyObject*)0) : \
+        (likely((obj)->ob_type->tp_as_mapping) ? (PySequence_GetSlice(obj, a, b)) : \
+            (PyErr_Format(PyExc_TypeError, "'%.200s' object is unsliceable", (obj)->ob_type->tp_name), (PyObject*)0)))
+  #define __Pyx_PySequence_SetSlice(obj, a, b, value) (unlikely(!(obj)) ? \
+        (PyErr_SetString(PyExc_SystemError, "null argument to internal routine"), -1) : \
+        (likely((obj)->ob_type->tp_as_mapping) ? (PySequence_SetSlice(obj, a, b, value)) : \
+            (PyErr_Format(PyExc_TypeError, "'%.200s' object doesn't support slice assignment", (obj)->ob_type->tp_name), -1)))
+  #define __Pyx_PySequence_DelSlice(obj, a, b) (unlikely(!(obj)) ? \
+        (PyErr_SetString(PyExc_SystemError, "null argument to internal routine"), -1) : \
+        (likely((obj)->ob_type->tp_as_mapping) ? (PySequence_DelSlice(obj, a, b)) : \
+            (PyErr_Format(PyExc_TypeError, "'%.200s' object doesn't support slice deletion", (obj)->ob_type->tp_name), -1)))
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define PyMethod_New(func, self, klass) ((self) ? PyMethod_New(func, self) : PyInstanceMethod_New(func))
+#endif
+#if PY_VERSION_HEX < 0x02050000
+  #define __Pyx_GetAttrString(o,n)   PyObject_GetAttrString((o),((char *)(n)))
+  #define __Pyx_SetAttrString(o,n,a) PyObject_SetAttrString((o),((char *)(n)),(a))
+  #define __Pyx_DelAttrString(o,n)   PyObject_DelAttrString((o),((char *)(n)))
+#else
+  #define __Pyx_GetAttrString(o,n)   PyObject_GetAttrString((o),(n))
+  #define __Pyx_SetAttrString(o,n,a) PyObject_SetAttrString((o),(n),(a))
+  #define __Pyx_DelAttrString(o,n)   PyObject_DelAttrString((o),(n))
+#endif
+#if PY_VERSION_HEX < 0x02050000
+  #define __Pyx_NAMESTR(n) ((char *)(n))
+  #define __Pyx_DOCSTR(n)  ((char *)(n))
+#else
+  #define __Pyx_NAMESTR(n) (n)
+  #define __Pyx_DOCSTR(n)  (n)
+#endif
+
+
+#if PY_MAJOR_VERSION >= 3
+  #define __Pyx_PyNumber_Divide(x,y)         PyNumber_TrueDivide(x,y)
+  #define __Pyx_PyNumber_InPlaceDivide(x,y)  PyNumber_InPlaceTrueDivide(x,y)
+#else
+  #define __Pyx_PyNumber_Divide(x,y)         PyNumber_Divide(x,y)
+  #define __Pyx_PyNumber_InPlaceDivide(x,y)  PyNumber_InPlaceDivide(x,y)
+#endif
+
+#ifndef __PYX_EXTERN_C
+  #ifdef __cplusplus
+    #define __PYX_EXTERN_C extern "C"
+  #else
+    #define __PYX_EXTERN_C extern
+  #endif
+#endif
+
+#if defined(WIN32) || defined(MS_WINDOWS)
+#define _USE_MATH_DEFINES
+#endif
+#include <math.h>
+#define __PYX_HAVE__bx__arrays__wiggle
+#define __PYX_HAVE_API__bx__arrays__wiggle
+#ifdef _OPENMP
+#include <omp.h>
+#endif /* _OPENMP */
+
+#ifdef PYREX_WITHOUT_ASSERTIONS
+#define CYTHON_WITHOUT_ASSERTIONS
+#endif
+
+#ifndef CYTHON_INLINE
+  #if defined(__GNUC__)
+    #define CYTHON_INLINE __inline__
+  #elif defined(_MSC_VER)
+    #define CYTHON_INLINE __inline
+  #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+    #define CYTHON_INLINE inline
+  #else
+    #define CYTHON_INLINE
+  #endif
+#endif
+#ifndef CYTHON_UNUSED
+# if defined(__GNUC__)
+#   if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
+#     define CYTHON_UNUSED __attribute__ ((__unused__))
+#   else
+#     define CYTHON_UNUSED
+#   endif
+# elif defined(__ICC) || (defined(__INTEL_COMPILER) && !defined(_MSC_VER))
+#   define CYTHON_UNUSED __attribute__ ((__unused__))
+# else
+#   define CYTHON_UNUSED
+# endif
+#endif
+typedef struct {PyObject **p; char *s; const long n; const char* encoding; const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry; /*proto*/
+
+#define __Pyx_PyBytes_FromUString(s) PyBytes_FromString((char*)s)
+#define __Pyx_PyBytes_AsUString(s)   ((unsigned char*) PyBytes_AsString(s))
+#define __Pyx_Owned_Py_None(b) (Py_INCREF(Py_None), Py_None)
+#define __Pyx_PyBool_FromLong(b) ((b) ? (Py_INCREF(Py_True), Py_True) : (Py_INCREF(Py_False), Py_False))
+static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*);
+static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x);
+static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*);
+static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t);
+static CYTHON_INLINE size_t __Pyx_PyInt_AsSize_t(PyObject*);
+#if CYTHON_COMPILING_IN_CPYTHON
+#define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x))
+#else
+#define __pyx_PyFloat_AsDouble(x) PyFloat_AsDouble(x)
+#endif
+#define __pyx_PyFloat_AsFloat(x) ((float) __pyx_PyFloat_AsDouble(x))
+
+
+#ifdef __GNUC__
+  /* Test for GCC > 2.95 */
+  #if __GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))
+    #define likely(x)   __builtin_expect(!!(x), 1)
+    #define unlikely(x) __builtin_expect(!!(x), 0)
+  #else /* __GNUC__ > 2 ... */
+    #define likely(x)   (x)
+    #define unlikely(x) (x)
+  #endif /* __GNUC__ > 2 ... */
+#else /* __GNUC__ */
+  #define likely(x)   (x)
+  #define unlikely(x) (x)
+#endif /* __GNUC__ */
+    
+static PyObject *__pyx_m;
+static PyObject *__pyx_b;
+static PyObject *__pyx_empty_tuple;
+static PyObject *__pyx_empty_bytes;
+static int __pyx_lineno;
+static int __pyx_clineno = 0;
+static const char * __pyx_cfilenm= __FILE__;
+static const char *__pyx_filename;
+
+
+static const char *__pyx_f[] = {
+  "wiggle.pyx",
+};
+
+/*--- Type declarations ---*/
+struct __pyx_obj_2bx_6arrays_6wiggle_WiggleReader;
+
+/* "bx/arrays/wiggle.pxd":1
+ * cdef enum linemode:             # <<<<<<<<<<<<<<
+ *     MODE_BED
+ *     MODE_FIXED
+ */
+enum __pyx_t_2bx_6arrays_6wiggle_linemode {
+  __pyx_e_2bx_6arrays_6wiggle_MODE_BED,
+  __pyx_e_2bx_6arrays_6wiggle_MODE_FIXED,
+  __pyx_e_2bx_6arrays_6wiggle_MODE_VARIABLE
+};
+
+/* "bx/arrays/wiggle.pxd":6
+ *     MODE_VARIABLE
+ * 
+ * cdef class WiggleReader:             # <<<<<<<<<<<<<<
+ *     cdef object file
+ *     cdef object current_chrom
+ */
+struct __pyx_obj_2bx_6arrays_6wiggle_WiggleReader {
+  PyObject_HEAD
+  PyObject *file;
+  PyObject *current_chrom;
+  long current_pos;
+  long current_step;
+  long current_span;
+  enum __pyx_t_2bx_6arrays_6wiggle_linemode mode;
+};
+
+#ifndef CYTHON_REFNANNY
+  #define CYTHON_REFNANNY 0
+#endif
+#if CYTHON_REFNANNY
+  typedef struct {
+    void (*INCREF)(void*, PyObject*, int);
+    void (*DECREF)(void*, PyObject*, int);
+    void (*GOTREF)(void*, PyObject*, int);
+    void (*GIVEREF)(void*, PyObject*, int);
+    void* (*SetupContext)(const char*, int, const char*);
+    void (*FinishContext)(void**);
+  } __Pyx_RefNannyAPIStruct;
+  static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL;
+  static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname); /*proto*/
+  #define __Pyx_RefNannyDeclarations void *__pyx_refnanny = NULL;
+#ifdef WITH_THREAD
+  #define __Pyx_RefNannySetupContext(name, acquire_gil) \
+          if (acquire_gil) { \
+              PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure(); \
+              __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__); \
+              PyGILState_Release(__pyx_gilstate_save); \
+          } else { \
+              __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__); \
+          }
+#else
+  #define __Pyx_RefNannySetupContext(name, acquire_gil) \
+          __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__)
+#endif
+  #define __Pyx_RefNannyFinishContext() \
+          __Pyx_RefNanny->FinishContext(&__pyx_refnanny)
+  #define __Pyx_INCREF(r)  __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_DECREF(r)  __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_GOTREF(r)  __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_XINCREF(r)  do { if((r) != NULL) {__Pyx_INCREF(r); }} while(0)
+  #define __Pyx_XDECREF(r)  do { if((r) != NULL) {__Pyx_DECREF(r); }} while(0)
+  #define __Pyx_XGOTREF(r)  do { if((r) != NULL) {__Pyx_GOTREF(r); }} while(0)
+  #define __Pyx_XGIVEREF(r) do { if((r) != NULL) {__Pyx_GIVEREF(r);}} while(0)
+#else
+  #define __Pyx_RefNannyDeclarations
+  #define __Pyx_RefNannySetupContext(name, acquire_gil)
+  #define __Pyx_RefNannyFinishContext()
+  #define __Pyx_INCREF(r) Py_INCREF(r)
+  #define __Pyx_DECREF(r) Py_DECREF(r)
+  #define __Pyx_GOTREF(r)
+  #define __Pyx_GIVEREF(r)
+  #define __Pyx_XINCREF(r) Py_XINCREF(r)
+  #define __Pyx_XDECREF(r) Py_XDECREF(r)
+  #define __Pyx_XGOTREF(r)
+  #define __Pyx_XGIVEREF(r)
+#endif /* CYTHON_REFNANNY */
+#define __Pyx_CLEAR(r)    do { PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);} while(0)
+#define __Pyx_XCLEAR(r)   do { if((r) != NULL) {PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);}} while(0)
+
+static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE int __Pyx_PyList_Append(PyObject* list, PyObject* x) {
+    PyListObject* L = (PyListObject*) list;
+    Py_ssize_t len = Py_SIZE(list);
+    if (likely(L->allocated > len)) {
+        Py_INCREF(x);
+        PyList_SET_ITEM(list, len, x);
+        Py_SIZE(list) = len+1;
+        return 0;
+    }
+    return PyList_Append(list, x);
+}
+#else
+#define __Pyx_PyList_Append(L,x) PyList_Append(L,x)
+#endif
+
+static void __Pyx_RaiseDoubleKeywordsError(const char* func_name, PyObject* kw_name); /*proto*/
+
+static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
+    PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
+    const char* function_name); /*proto*/
+
+static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
+    Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/
+
+static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
+static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
+
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause); /*proto*/
+
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j) {
+    PyObject *r;
+    if (!j) return NULL;
+    r = PyObject_GetItem(o, j);
+    Py_DECREF(j);
+    return r;
+}
+#define __Pyx_GetItemInt_List(o, i, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \
+                                                    __Pyx_GetItemInt_List_Fast(o, i) : \
+                                                    __Pyx_GetItemInt_Generic(o, to_py_func(i)))
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    if (likely((0 <= i) & (i < PyList_GET_SIZE(o)))) {
+        PyObject *r = PyList_GET_ITEM(o, i);
+        Py_INCREF(r);
+        return r;
+    }
+    else if ((-PyList_GET_SIZE(o) <= i) & (i < 0)) {
+        PyObject *r = PyList_GET_ITEM(o, PyList_GET_SIZE(o) + i);
+        Py_INCREF(r);
+        return r;
+    }
+    return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
+#else
+    return PySequence_GetItem(o, i);
+#endif
+}
+#define __Pyx_GetItemInt_Tuple(o, i, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \
+                                                    __Pyx_GetItemInt_Tuple_Fast(o, i) : \
+                                                    __Pyx_GetItemInt_Generic(o, to_py_func(i)))
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    if (likely((0 <= i) & (i < PyTuple_GET_SIZE(o)))) {
+        PyObject *r = PyTuple_GET_ITEM(o, i);
+        Py_INCREF(r);
+        return r;
+    }
+    else if ((-PyTuple_GET_SIZE(o) <= i) & (i < 0)) {
+        PyObject *r = PyTuple_GET_ITEM(o, PyTuple_GET_SIZE(o) + i);
+        Py_INCREF(r);
+        return r;
+    }
+    return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
+#else
+    return PySequence_GetItem(o, i);
+#endif
+}
+#define __Pyx_GetItemInt(o, i, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \
+                                                    __Pyx_GetItemInt_Fast(o, i) : \
+                                                    __Pyx_GetItemInt_Generic(o, to_py_func(i)))
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    if (PyList_CheckExact(o)) {
+        Py_ssize_t n = (likely(i >= 0)) ? i : i + PyList_GET_SIZE(o);
+        if (likely((n >= 0) & (n < PyList_GET_SIZE(o)))) {
+            PyObject *r = PyList_GET_ITEM(o, n);
+            Py_INCREF(r);
+            return r;
+        }
+    }
+    else if (PyTuple_CheckExact(o)) {
+        Py_ssize_t n = (likely(i >= 0)) ? i : i + PyTuple_GET_SIZE(o);
+        if (likely((n >= 0) & (n < PyTuple_GET_SIZE(o)))) {
+            PyObject *r = PyTuple_GET_ITEM(o, n);
+            Py_INCREF(r);
+            return r;
+        }
+    } else {  /* inlined PySequence_GetItem() */
+        PySequenceMethods *m = Py_TYPE(o)->tp_as_sequence;
+        if (likely(m && m->sq_item)) {
+            if (unlikely(i < 0) && likely(m->sq_length)) {
+                Py_ssize_t l = m->sq_length(o);
+                if (unlikely(l < 0)) return NULL;
+                i += l;
+            }
+            return m->sq_item(o, i);
+        }
+    }
+#else
+    if (PySequence_Check(o)) {
+        return PySequence_GetItem(o, i);
+    }
+#endif
+    return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
+}
+
+static CYTHON_INLINE int __Pyx_PySequence_Contains(PyObject* item, PyObject* seq, int eq) {
+    int result = PySequence_Contains(seq, item);
+    return unlikely(result < 0) ? result : (result == (eq == Py_EQ));
+}
+
+static double __Pyx__PyObject_AsDouble(PyObject* obj); /* proto */
+#if CYTHON_COMPILING_IN_PYPY
+#define __Pyx_PyObject_AsDouble(obj) \
+(likely(PyFloat_CheckExact(obj)) ? PyFloat_AS_DOUBLE(obj) : \
+ likely(PyInt_CheckExact(obj)) ? \
+ PyFloat_AsDouble(obj) : __Pyx__PyObject_AsDouble(obj))
+#else
+#define __Pyx_PyObject_AsDouble(obj) \
+((likely(PyFloat_CheckExact(obj))) ? \
+ PyFloat_AS_DOUBLE(obj) : __Pyx__PyObject_AsDouble(obj))
+#endif
+
+static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
+
+static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
+static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
+
+static CYTHON_INLINE unsigned char __Pyx_PyInt_AsUnsignedChar(PyObject *);
+
+static CYTHON_INLINE unsigned short __Pyx_PyInt_AsUnsignedShort(PyObject *);
+
+static CYTHON_INLINE unsigned int __Pyx_PyInt_AsUnsignedInt(PyObject *);
+
+static CYTHON_INLINE char __Pyx_PyInt_AsChar(PyObject *);
+
+static CYTHON_INLINE short __Pyx_PyInt_AsShort(PyObject *);
+
+static CYTHON_INLINE int __Pyx_PyInt_AsInt(PyObject *);
+
+static CYTHON_INLINE signed char __Pyx_PyInt_AsSignedChar(PyObject *);
+
+static CYTHON_INLINE signed short __Pyx_PyInt_AsSignedShort(PyObject *);
+
+static CYTHON_INLINE signed int __Pyx_PyInt_AsSignedInt(PyObject *);
+
+static CYTHON_INLINE int __Pyx_PyInt_AsLongDouble(PyObject *);
+
+static CYTHON_INLINE unsigned long __Pyx_PyInt_AsUnsignedLong(PyObject *);
+
+static CYTHON_INLINE unsigned PY_LONG_LONG __Pyx_PyInt_AsUnsignedLongLong(PyObject *);
+
+static CYTHON_INLINE long __Pyx_PyInt_AsLong(PyObject *);
+
+static CYTHON_INLINE PY_LONG_LONG __Pyx_PyInt_AsLongLong(PyObject *);
+
+static CYTHON_INLINE signed long __Pyx_PyInt_AsSignedLong(PyObject *);
+
+static CYTHON_INLINE signed PY_LONG_LONG __Pyx_PyInt_AsSignedLongLong(PyObject *);
+
+static int __Pyx_check_binary_version(void);
+
+typedef struct {
+    int code_line;
+    PyCodeObject* code_object;
+} __Pyx_CodeObjectCacheEntry;
+struct __Pyx_CodeObjectCache {
+    int count;
+    int max_count;
+    __Pyx_CodeObjectCacheEntry* entries;
+};
+static struct __Pyx_CodeObjectCache __pyx_code_cache = {0,0,NULL};
+static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line);
+static PyCodeObject *__pyx_find_code_object(int code_line);
+static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object);
+
+static void __Pyx_AddTraceback(const char *funcname, int c_line,
+                               int py_line, const char *filename); /*proto*/
+
+static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
+
+
+/* Module declarations from 'bx.arrays.wiggle' */
+static PyTypeObject *__pyx_ptype_2bx_6arrays_6wiggle_WiggleReader = 0;
+#define __Pyx_MODULE_NAME "bx.arrays.wiggle"
+int __pyx_module_is_main_bx__arrays__wiggle = 0;
+
+/* Implementation of 'bx.arrays.wiggle' */
+static PyObject *__pyx_builtin_StopIteration;
+static PyObject *__pyx_builtin_ValueError;
+static PyObject *__pyx_pf_2bx_6arrays_6wiggle_parse_header(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_line); /* proto */
+static int __pyx_pf_2bx_6arrays_6wiggle_12WiggleReader___init__(struct __pyx_obj_2bx_6arrays_6wiggle_WiggleReader *__pyx_v_self, PyObject *__pyx_v_file); /* proto */
+static PyObject *__pyx_pf_2bx_6arrays_6wiggle_12WiggleReader_2__iter__(struct __pyx_obj_2bx_6arrays_6wiggle_WiggleReader *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_2bx_6arrays_6wiggle_12WiggleReader_4__next__(struct __pyx_obj_2bx_6arrays_6wiggle_WiggleReader *__pyx_v_self); /* proto */
+static char __pyx_k_1[] = "=";
+static char __pyx_k_3[] = "#";
+static char __pyx_k_8[] = "+";
+static char __pyx_k_9[] = "Unexpected input line: %s";
+static char __pyx_k_10[] = "\nSupport for scores in the `wiggle`_ file format used by the UCSC Genome \nBrowser.\n\nThe positions in the wiggle format are 1-relative, however,\nthe positions returned match the BED/interval format which is zero-based, half-open.\n\n.. _wiggle: http://genome.ucsc.edu/goldenPath/help/wiggle.html\n";
+static char __pyx_k_13[] = "/aut/proj/odenas/software/bx-python/lib/bx/arrays/wiggle.pyx";
+static char __pyx_k_14[] = "bx.arrays.wiggle";
+static char __pyx_k__file[] = "file";
+static char __pyx_k__line[] = "line";
+static char __pyx_k__span[] = "span";
+static char __pyx_k__step[] = "step";
+static char __pyx_k__chrom[] = "chrom";
+static char __pyx_k__field[] = "field";
+static char __pyx_k__split[] = "split";
+static char __pyx_k__start[] = "start";
+static char __pyx_k__strip[] = "strip";
+static char __pyx_k__track[] = "track";
+static char __pyx_k__browser[] = "browser";
+static char __pyx_k__isalpha[] = "isalpha";
+static char __pyx_k__isspace[] = "isspace";
+static char __pyx_k____main__[] = "__main__";
+static char __pyx_k____test__[] = "__test__";
+static char __pyx_k__readline[] = "readline";
+static char __pyx_k__fixedStep[] = "fixedStep";
+static char __pyx_k__ValueError[] = "ValueError";
+static char __pyx_k__startswith[] = "startswith";
+static char __pyx_k__parse_header[] = "parse_header";
+static char __pyx_k__variableStep[] = "variableStep";
+static char __pyx_k__StopIteration[] = "StopIteration";
+static PyObject *__pyx_kp_s_1;
+static PyObject *__pyx_kp_s_13;
+static PyObject *__pyx_n_s_14;
+static PyObject *__pyx_kp_s_3;
+static PyObject *__pyx_kp_s_8;
+static PyObject *__pyx_kp_s_9;
+static PyObject *__pyx_n_s__StopIteration;
+static PyObject *__pyx_n_s__ValueError;
+static PyObject *__pyx_n_s____main__;
+static PyObject *__pyx_n_s____test__;
+static PyObject *__pyx_n_s__browser;
+static PyObject *__pyx_n_s__chrom;
+static PyObject *__pyx_n_s__field;
+static PyObject *__pyx_n_s__file;
+static PyObject *__pyx_n_s__fixedStep;
+static PyObject *__pyx_n_s__isalpha;
+static PyObject *__pyx_n_s__isspace;
+static PyObject *__pyx_n_s__line;
+static PyObject *__pyx_n_s__parse_header;
+static PyObject *__pyx_n_s__readline;
+static PyObject *__pyx_n_s__span;
+static PyObject *__pyx_n_s__split;
+static PyObject *__pyx_n_s__start;
+static PyObject *__pyx_n_s__startswith;
+static PyObject *__pyx_n_s__step;
+static PyObject *__pyx_n_s__strip;
+static PyObject *__pyx_n_s__track;
+static PyObject *__pyx_n_s__variableStep;
+static PyObject *__pyx_int_1;
+static PyObject *__pyx_k_tuple_2;
+static PyObject *__pyx_k_tuple_4;
+static PyObject *__pyx_k_tuple_5;
+static PyObject *__pyx_k_tuple_6;
+static PyObject *__pyx_k_tuple_7;
+static PyObject *__pyx_k_tuple_11;
+static PyObject *__pyx_k_codeobj_12;
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_6arrays_6wiggle_1parse_header(PyObject *__pyx_self, PyObject *__pyx_v_line); /*proto*/
+static PyMethodDef __pyx_mdef_2bx_6arrays_6wiggle_1parse_header = {__Pyx_NAMESTR("parse_header"), (PyCFunction)__pyx_pw_2bx_6arrays_6wiggle_1parse_header, METH_O, __Pyx_DOCSTR(0)};
+static PyObject *__pyx_pw_2bx_6arrays_6wiggle_1parse_header(PyObject *__pyx_self, PyObject *__pyx_v_line) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("parse_header (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_6arrays_6wiggle_parse_header(__pyx_self, ((PyObject *)__pyx_v_line));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/arrays/wiggle.pyx":11
+ * """
+ * 
+ * def parse_header( line ):             # <<<<<<<<<<<<<<
+ *     return dict( [ field.split( '=' ) for field in line.split()[1:] ] )
+ * 
+ */
+
+static PyObject *__pyx_pf_2bx_6arrays_6wiggle_parse_header(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_line) {
+  PyObject *__pyx_v_field = NULL;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  Py_ssize_t __pyx_t_4;
+  PyObject *(*__pyx_t_5)(PyObject *);
+  PyObject *__pyx_t_6 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("parse_header", 0);
+
+  /* "bx/arrays/wiggle.pyx":12
+ * 
+ * def parse_header( line ):
+ *     return dict( [ field.split( '=' ) for field in line.split()[1:] ] )             # <<<<<<<<<<<<<<
+ * 
+ * cdef class WiggleReader:
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 12; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = PyObject_GetAttr(__pyx_v_line, __pyx_n_s__split); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 12; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 12; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_2 = __Pyx_PySequence_GetSlice(__pyx_t_3, 1, PY_SSIZE_T_MAX); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 12; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  if (PyList_CheckExact(__pyx_t_2) || PyTuple_CheckExact(__pyx_t_2)) {
+    __pyx_t_3 = __pyx_t_2; __Pyx_INCREF(__pyx_t_3); __pyx_t_4 = 0;
+    __pyx_t_5 = NULL;
+  } else {
+    __pyx_t_4 = -1; __pyx_t_3 = PyObject_GetIter(__pyx_t_2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 12; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __pyx_t_5 = Py_TYPE(__pyx_t_3)->tp_iternext;
+  }
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  for (;;) {
+    if (!__pyx_t_5 && PyList_CheckExact(__pyx_t_3)) {
+      if (__pyx_t_4 >= PyList_GET_SIZE(__pyx_t_3)) break;
+      #if CYTHON_COMPILING_IN_CPYTHON
+      __pyx_t_2 = PyList_GET_ITEM(__pyx_t_3, __pyx_t_4); __Pyx_INCREF(__pyx_t_2); __pyx_t_4++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 12; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      #else
+      __pyx_t_2 = PySequence_ITEM(__pyx_t_3, __pyx_t_4); __pyx_t_4++; if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 12; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      #endif
+    } else if (!__pyx_t_5 && PyTuple_CheckExact(__pyx_t_3)) {
+      if (__pyx_t_4 >= PyTuple_GET_SIZE(__pyx_t_3)) break;
+      #if CYTHON_COMPILING_IN_CPYTHON
+      __pyx_t_2 = PyTuple_GET_ITEM(__pyx_t_3, __pyx_t_4); __Pyx_INCREF(__pyx_t_2); __pyx_t_4++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 12; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      #else
+      __pyx_t_2 = PySequence_ITEM(__pyx_t_3, __pyx_t_4); __pyx_t_4++; if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 12; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      #endif
+    } else {
+      __pyx_t_2 = __pyx_t_5(__pyx_t_3);
+      if (unlikely(!__pyx_t_2)) {
+        if (PyErr_Occurred()) {
+          if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
+          else {__pyx_filename = __pyx_f[0]; __pyx_lineno = 12; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        }
+        break;
+      }
+      __Pyx_GOTREF(__pyx_t_2);
+    }
+    __Pyx_XDECREF(__pyx_v_field);
+    __pyx_v_field = __pyx_t_2;
+    __pyx_t_2 = 0;
+    __pyx_t_2 = PyObject_GetAttr(__pyx_v_field, __pyx_n_s__split); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 12; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_t_6 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_k_tuple_2), NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 12; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_6);
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    if (unlikely(__Pyx_PyList_Append(__pyx_t_1, (PyObject*)__pyx_t_6))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 12; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+  }
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 12; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_INCREF(((PyObject *)__pyx_t_1));
+  PyTuple_SET_ITEM(__pyx_t_3, 0, ((PyObject *)__pyx_t_1));
+  __Pyx_GIVEREF(((PyObject *)__pyx_t_1));
+  __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+  __pyx_t_1 = PyObject_Call(((PyObject *)((PyObject*)(&PyDict_Type))), ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 12; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_6);
+  __Pyx_AddTraceback("bx.arrays.wiggle.parse_header", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_field);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_2bx_6arrays_6wiggle_12WiggleReader_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static int __pyx_pw_2bx_6arrays_6wiggle_12WiggleReader_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_file = 0;
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__init__ (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__file,0};
+    PyObject* values[1] = {0};
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__file)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 26; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else if (PyTuple_GET_SIZE(__pyx_args) != 1) {
+      goto __pyx_L5_argtuple_error;
+    } else {
+      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+    }
+    __pyx_v_file = values[0];
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("__init__", 1, 1, 1, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 26; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.arrays.wiggle.WiggleReader.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return -1;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_6arrays_6wiggle_12WiggleReader___init__(((struct __pyx_obj_2bx_6arrays_6wiggle_WiggleReader *)__pyx_v_self), __pyx_v_file);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/arrays/wiggle.pyx":26
+ *     #cdef long current_span
+ *     #cdef linemode mode
+ *     def __init__( self, file ):             # <<<<<<<<<<<<<<
+ *         self.file = file
+ *         self.current_chrom = None
+ */
+
+static int __pyx_pf_2bx_6arrays_6wiggle_12WiggleReader___init__(struct __pyx_obj_2bx_6arrays_6wiggle_WiggleReader *__pyx_v_self, PyObject *__pyx_v_file) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__init__", 0);
+
+  /* "bx/arrays/wiggle.pyx":27
+ *     #cdef linemode mode
+ *     def __init__( self, file ):
+ *         self.file = file             # <<<<<<<<<<<<<<
+ *         self.current_chrom = None
+ *         self.current_pos = -1
+ */
+  __Pyx_INCREF(__pyx_v_file);
+  __Pyx_GIVEREF(__pyx_v_file);
+  __Pyx_GOTREF(__pyx_v_self->file);
+  __Pyx_DECREF(__pyx_v_self->file);
+  __pyx_v_self->file = __pyx_v_file;
+
+  /* "bx/arrays/wiggle.pyx":28
+ *     def __init__( self, file ):
+ *         self.file = file
+ *         self.current_chrom = None             # <<<<<<<<<<<<<<
+ *         self.current_pos = -1
+ *         self.current_step = -1
+ */
+  __Pyx_INCREF(Py_None);
+  __Pyx_GIVEREF(Py_None);
+  __Pyx_GOTREF(__pyx_v_self->current_chrom);
+  __Pyx_DECREF(__pyx_v_self->current_chrom);
+  __pyx_v_self->current_chrom = Py_None;
+
+  /* "bx/arrays/wiggle.pyx":29
+ *         self.file = file
+ *         self.current_chrom = None
+ *         self.current_pos = -1             # <<<<<<<<<<<<<<
+ *         self.current_step = -1
+ *         self.current_span = -1
+ */
+  __pyx_v_self->current_pos = -1;
+
+  /* "bx/arrays/wiggle.pyx":30
+ *         self.current_chrom = None
+ *         self.current_pos = -1
+ *         self.current_step = -1             # <<<<<<<<<<<<<<
+ *         self.current_span = -1
+ *         self.mode = MODE_BED
+ */
+  __pyx_v_self->current_step = -1;
+
+  /* "bx/arrays/wiggle.pyx":31
+ *         self.current_pos = -1
+ *         self.current_step = -1
+ *         self.current_span = -1             # <<<<<<<<<<<<<<
+ *         self.mode = MODE_BED
+ * 
+ */
+  __pyx_v_self->current_span = -1;
+
+  /* "bx/arrays/wiggle.pyx":32
+ *         self.current_step = -1
+ *         self.current_span = -1
+ *         self.mode = MODE_BED             # <<<<<<<<<<<<<<
+ * 
+ *     def __iter__( self ):
+ */
+  __pyx_v_self->mode = __pyx_e_2bx_6arrays_6wiggle_MODE_BED;
+
+  __pyx_r = 0;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_6arrays_6wiggle_12WiggleReader_3__iter__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_2bx_6arrays_6wiggle_12WiggleReader_3__iter__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__iter__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_6arrays_6wiggle_12WiggleReader_2__iter__(((struct __pyx_obj_2bx_6arrays_6wiggle_WiggleReader *)__pyx_v_self));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/arrays/wiggle.pyx":34
+ *         self.mode = MODE_BED
+ * 
+ *     def __iter__( self ):             # <<<<<<<<<<<<<<
+ *         return self
+ * 
+ */
+
+static PyObject *__pyx_pf_2bx_6arrays_6wiggle_12WiggleReader_2__iter__(struct __pyx_obj_2bx_6arrays_6wiggle_WiggleReader *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__iter__", 0);
+
+  /* "bx/arrays/wiggle.pyx":35
+ * 
+ *     def __iter__( self ):
+ *         return self             # <<<<<<<<<<<<<<
+ * 
+ *     def __next__( self ):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __Pyx_INCREF(((PyObject *)__pyx_v_self));
+  __pyx_r = ((PyObject *)__pyx_v_self);
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_6arrays_6wiggle_12WiggleReader_5__next__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_2bx_6arrays_6wiggle_12WiggleReader_5__next__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__next__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_6arrays_6wiggle_12WiggleReader_4__next__(((struct __pyx_obj_2bx_6arrays_6wiggle_WiggleReader *)__pyx_v_self));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/arrays/wiggle.pyx":37
+ *         return self
+ * 
+ *     def __next__( self ):             # <<<<<<<<<<<<<<
+ *         while True:
+ *             line = self.file.readline()
+ */
+
+static PyObject *__pyx_pf_2bx_6arrays_6wiggle_12WiggleReader_4__next__(struct __pyx_obj_2bx_6arrays_6wiggle_WiggleReader *__pyx_v_self) {
+  PyObject *__pyx_v_line = NULL;
+  PyObject *__pyx_v_header = NULL;
+  PyObject *__pyx_v_fields = NULL;
+  PyObject *__pyx_v_pos = NULL;
+  double __pyx_v_val;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  int __pyx_t_3;
+  int __pyx_t_4;
+  int __pyx_t_5;
+  PyObject *__pyx_t_6 = NULL;
+  long __pyx_t_7;
+  Py_ssize_t __pyx_t_8;
+  PyObject *__pyx_t_9 = NULL;
+  PyObject *__pyx_t_10 = NULL;
+  double __pyx_t_11;
+  PyObject *__pyx_t_12 = NULL;
+  PyObject *__pyx_t_13 = NULL;
+  PyObject *__pyx_t_14 = NULL;
+  PyObject *__pyx_t_15 = NULL;
+  int __pyx_t_16;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__next__", 0);
+
+  /* "bx/arrays/wiggle.pyx":38
+ * 
+ *     def __next__( self ):
+ *         while True:             # <<<<<<<<<<<<<<
+ *             line = self.file.readline()
+ *             if not line:
+ */
+  while (1) {
+    if (!1) break;
+
+    /* "bx/arrays/wiggle.pyx":39
+ *     def __next__( self ):
+ *         while True:
+ *             line = self.file.readline()             # <<<<<<<<<<<<<<
+ *             if not line:
+ *                 raise StopIteration()
+ */
+    __pyx_t_1 = PyObject_GetAttr(__pyx_v_self->file, __pyx_n_s__readline); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 39; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __pyx_t_2 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 39; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    __Pyx_XDECREF(__pyx_v_line);
+    __pyx_v_line = __pyx_t_2;
+    __pyx_t_2 = 0;
+
+    /* "bx/arrays/wiggle.pyx":40
+ *         while True:
+ *             line = self.file.readline()
+ *             if not line:             # <<<<<<<<<<<<<<
+ *                 raise StopIteration()
+ *             if line.isspace():
+ */
+    __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_v_line); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 40; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = (!__pyx_t_3);
+    if (__pyx_t_4) {
+
+      /* "bx/arrays/wiggle.pyx":41
+ *             line = self.file.readline()
+ *             if not line:
+ *                 raise StopIteration()             # <<<<<<<<<<<<<<
+ *             if line.isspace():
+ *                 continue
+ */
+      __pyx_t_2 = PyObject_Call(__pyx_builtin_StopIteration, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 41; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_2);
+      __Pyx_Raise(__pyx_t_2, 0, 0, 0);
+      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 41; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      goto __pyx_L5;
+    }
+    __pyx_L5:;
+
+    /* "bx/arrays/wiggle.pyx":42
+ *             if not line:
+ *                 raise StopIteration()
+ *             if line.isspace():             # <<<<<<<<<<<<<<
+ *                 continue
+ *             if line[0] == "#":
+ */
+    __pyx_t_2 = PyObject_GetAttr(__pyx_v_line, __pyx_n_s__isspace); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 42; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_t_1 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 42; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 42; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    if (__pyx_t_4) {
+
+      /* "bx/arrays/wiggle.pyx":43
+ *                 raise StopIteration()
+ *             if line.isspace():
+ *                 continue             # <<<<<<<<<<<<<<
+ *             if line[0] == "#":
+ *                 continue
+ */
+      goto __pyx_L3_continue;
+      goto __pyx_L6;
+    }
+    __pyx_L6:;
+
+    /* "bx/arrays/wiggle.pyx":44
+ *             if line.isspace():
+ *                 continue
+ *             if line[0] == "#":             # <<<<<<<<<<<<<<
+ *                 continue
+ *             if line[0].isalpha():
+ */
+    __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_line, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 44; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __pyx_t_2 = PyObject_RichCompare(__pyx_t_1, ((PyObject *)__pyx_kp_s_3), Py_EQ); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 44; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 44; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    if (__pyx_t_4) {
+
+      /* "bx/arrays/wiggle.pyx":45
+ *                 continue
+ *             if line[0] == "#":
+ *                 continue             # <<<<<<<<<<<<<<
+ *             if line[0].isalpha():
+ *                 if line.startswith( "track" ) or line.startswith( "browser" ):
+ */
+      goto __pyx_L3_continue;
+      goto __pyx_L7;
+    }
+    __pyx_L7:;
+
+    /* "bx/arrays/wiggle.pyx":46
+ *             if line[0] == "#":
+ *                 continue
+ *             if line[0].isalpha():             # <<<<<<<<<<<<<<
+ *                 if line.startswith( "track" ) or line.startswith( "browser" ):
+ *                     continue
+ */
+    __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_line, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 46; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_t_1 = PyObject_GetAttr(__pyx_t_2, __pyx_n_s__isalpha); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 46; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    __pyx_t_2 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 46; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 46; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    if (__pyx_t_4) {
+
+      /* "bx/arrays/wiggle.pyx":47
+ *                 continue
+ *             if line[0].isalpha():
+ *                 if line.startswith( "track" ) or line.startswith( "browser" ):             # <<<<<<<<<<<<<<
+ *                     continue
+ *                 elif line.startswith( "variableStep" ):
+ */
+      __pyx_t_2 = PyObject_GetAttr(__pyx_v_line, __pyx_n_s__startswith); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 47; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_2);
+      __pyx_t_1 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_k_tuple_4), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 47; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_1);
+      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+      __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 47; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+      if (!__pyx_t_4) {
+        __pyx_t_1 = PyObject_GetAttr(__pyx_v_line, __pyx_n_s__startswith); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 47; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_1);
+        __pyx_t_2 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_k_tuple_5), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 47; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_2);
+        __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+        __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 47; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+        __pyx_t_5 = __pyx_t_3;
+      } else {
+        __pyx_t_5 = __pyx_t_4;
+      }
+      if (__pyx_t_5) {
+
+        /* "bx/arrays/wiggle.pyx":48
+ *             if line[0].isalpha():
+ *                 if line.startswith( "track" ) or line.startswith( "browser" ):
+ *                     continue             # <<<<<<<<<<<<<<
+ *                 elif line.startswith( "variableStep" ):
+ *                     header = parse_header( line )
+ */
+        goto __pyx_L3_continue;
+        goto __pyx_L9;
+      }
+
+      /* "bx/arrays/wiggle.pyx":49
+ *                 if line.startswith( "track" ) or line.startswith( "browser" ):
+ *                     continue
+ *                 elif line.startswith( "variableStep" ):             # <<<<<<<<<<<<<<
+ *                     header = parse_header( line )
+ *                     self.current_chrom = header['chrom']
+ */
+      __pyx_t_2 = PyObject_GetAttr(__pyx_v_line, __pyx_n_s__startswith); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 49; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_2);
+      __pyx_t_1 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_k_tuple_6), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 49; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_1);
+      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+      __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 49; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+      if (__pyx_t_5) {
+
+        /* "bx/arrays/wiggle.pyx":50
+ *                     continue
+ *                 elif line.startswith( "variableStep" ):
+ *                     header = parse_header( line )             # <<<<<<<<<<<<<<
+ *                     self.current_chrom = header['chrom']
+ *                     self.current_pos = -1
+ */
+        __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__parse_header); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 50; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_1);
+        __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 50; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_2);
+        __Pyx_INCREF(__pyx_v_line);
+        PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_line);
+        __Pyx_GIVEREF(__pyx_v_line);
+        __pyx_t_6 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 50; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_6);
+        __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+        __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
+        __Pyx_XDECREF(__pyx_v_header);
+        __pyx_v_header = __pyx_t_6;
+        __pyx_t_6 = 0;
+
+        /* "bx/arrays/wiggle.pyx":51
+ *                 elif line.startswith( "variableStep" ):
+ *                     header = parse_header( line )
+ *                     self.current_chrom = header['chrom']             # <<<<<<<<<<<<<<
+ *                     self.current_pos = -1
+ *                     self.current_step = -1
+ */
+        __pyx_t_6 = PyObject_GetItem(__pyx_v_header, ((PyObject *)__pyx_n_s__chrom)); if (!__pyx_t_6) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 51; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_6);
+        __Pyx_GIVEREF(__pyx_t_6);
+        __Pyx_GOTREF(__pyx_v_self->current_chrom);
+        __Pyx_DECREF(__pyx_v_self->current_chrom);
+        __pyx_v_self->current_chrom = __pyx_t_6;
+        __pyx_t_6 = 0;
+
+        /* "bx/arrays/wiggle.pyx":52
+ *                     header = parse_header( line )
+ *                     self.current_chrom = header['chrom']
+ *                     self.current_pos = -1             # <<<<<<<<<<<<<<
+ *                     self.current_step = -1
+ *                     if 'span' in header:
+ */
+        __pyx_v_self->current_pos = -1;
+
+        /* "bx/arrays/wiggle.pyx":53
+ *                     self.current_chrom = header['chrom']
+ *                     self.current_pos = -1
+ *                     self.current_step = -1             # <<<<<<<<<<<<<<
+ *                     if 'span' in header:
+ *                         self.current_span = int( header['span'] )
+ */
+        __pyx_v_self->current_step = -1;
+
+        /* "bx/arrays/wiggle.pyx":54
+ *                     self.current_pos = -1
+ *                     self.current_step = -1
+ *                     if 'span' in header:             # <<<<<<<<<<<<<<
+ *                         self.current_span = int( header['span'] )
+ *                     else:
+ */
+        __pyx_t_5 = (__Pyx_PySequence_Contains(((PyObject *)__pyx_n_s__span), __pyx_v_header, Py_EQ)); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 54; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        if (__pyx_t_5) {
+
+          /* "bx/arrays/wiggle.pyx":55
+ *                     self.current_step = -1
+ *                     if 'span' in header:
+ *                         self.current_span = int( header['span'] )             # <<<<<<<<<<<<<<
+ *                     else:
+ *                         self.current_span = 1
+ */
+          __pyx_t_6 = PyObject_GetItem(__pyx_v_header, ((PyObject *)__pyx_n_s__span)); if (!__pyx_t_6) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 55; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __Pyx_GOTREF(__pyx_t_6);
+          __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 55; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __Pyx_GOTREF(__pyx_t_2);
+          PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_6);
+          __Pyx_GIVEREF(__pyx_t_6);
+          __pyx_t_6 = 0;
+          __pyx_t_6 = PyObject_Call(((PyObject *)((PyObject*)(&PyInt_Type))), ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 55; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __Pyx_GOTREF(__pyx_t_6);
+          __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
+          __pyx_t_7 = __Pyx_PyInt_AsLong(__pyx_t_6); if (unlikely((__pyx_t_7 == (long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 55; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+          __pyx_v_self->current_span = __pyx_t_7;
+          goto __pyx_L10;
+        }
+        /*else*/ {
+
+          /* "bx/arrays/wiggle.pyx":57
+ *                         self.current_span = int( header['span'] )
+ *                     else:
+ *                         self.current_span = 1             # <<<<<<<<<<<<<<
+ *                     self.mode = MODE_VARIABLE
+ *                     continue
+ */
+          __pyx_v_self->current_span = 1;
+        }
+        __pyx_L10:;
+
+        /* "bx/arrays/wiggle.pyx":58
+ *                     else:
+ *                         self.current_span = 1
+ *                     self.mode = MODE_VARIABLE             # <<<<<<<<<<<<<<
+ *                     continue
+ *                 elif line.startswith( "fixedStep" ):
+ */
+        __pyx_v_self->mode = __pyx_e_2bx_6arrays_6wiggle_MODE_VARIABLE;
+
+        /* "bx/arrays/wiggle.pyx":59
+ *                         self.current_span = 1
+ *                     self.mode = MODE_VARIABLE
+ *                     continue             # <<<<<<<<<<<<<<
+ *                 elif line.startswith( "fixedStep" ):
+ *                     header = parse_header( line )
+ */
+        goto __pyx_L3_continue;
+        goto __pyx_L9;
+      }
+
+      /* "bx/arrays/wiggle.pyx":60
+ *                     self.mode = MODE_VARIABLE
+ *                     continue
+ *                 elif line.startswith( "fixedStep" ):             # <<<<<<<<<<<<<<
+ *                     header = parse_header( line )
+ *                     self.current_chrom = header['chrom']
+ */
+      __pyx_t_6 = PyObject_GetAttr(__pyx_v_line, __pyx_n_s__startswith); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 60; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_6);
+      __pyx_t_2 = PyObject_Call(__pyx_t_6, ((PyObject *)__pyx_k_tuple_7), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 60; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_2);
+      __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+      __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 60; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+      if (__pyx_t_5) {
+
+        /* "bx/arrays/wiggle.pyx":61
+ *                     continue
+ *                 elif line.startswith( "fixedStep" ):
+ *                     header = parse_header( line )             # <<<<<<<<<<<<<<
+ *                     self.current_chrom = header['chrom']
+ *                     self.current_pos = int( header['start'] ) - 1
+ */
+        __pyx_t_2 = __Pyx_GetName(__pyx_m, __pyx_n_s__parse_header); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 61; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_2);
+        __pyx_t_6 = PyTuple_New(1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 61; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_6);
+        __Pyx_INCREF(__pyx_v_line);
+        PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_v_line);
+        __Pyx_GIVEREF(__pyx_v_line);
+        __pyx_t_1 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_6), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 61; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_1);
+        __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+        __Pyx_DECREF(((PyObject *)__pyx_t_6)); __pyx_t_6 = 0;
+        __Pyx_XDECREF(__pyx_v_header);
+        __pyx_v_header = __pyx_t_1;
+        __pyx_t_1 = 0;
+
+        /* "bx/arrays/wiggle.pyx":62
+ *                 elif line.startswith( "fixedStep" ):
+ *                     header = parse_header( line )
+ *                     self.current_chrom = header['chrom']             # <<<<<<<<<<<<<<
+ *                     self.current_pos = int( header['start'] ) - 1
+ *                     self.current_step = int( header['step'] )
+ */
+        __pyx_t_1 = PyObject_GetItem(__pyx_v_header, ((PyObject *)__pyx_n_s__chrom)); if (!__pyx_t_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 62; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_1);
+        __Pyx_GIVEREF(__pyx_t_1);
+        __Pyx_GOTREF(__pyx_v_self->current_chrom);
+        __Pyx_DECREF(__pyx_v_self->current_chrom);
+        __pyx_v_self->current_chrom = __pyx_t_1;
+        __pyx_t_1 = 0;
+
+        /* "bx/arrays/wiggle.pyx":63
+ *                     header = parse_header( line )
+ *                     self.current_chrom = header['chrom']
+ *                     self.current_pos = int( header['start'] ) - 1             # <<<<<<<<<<<<<<
+ *                     self.current_step = int( header['step'] )
+ *                     if 'span' in header:
+ */
+        __pyx_t_1 = PyObject_GetItem(__pyx_v_header, ((PyObject *)__pyx_n_s__start)); if (!__pyx_t_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 63; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_1);
+        __pyx_t_6 = PyTuple_New(1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 63; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_6);
+        PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_1);
+        __Pyx_GIVEREF(__pyx_t_1);
+        __pyx_t_1 = 0;
+        __pyx_t_1 = PyObject_Call(((PyObject *)((PyObject*)(&PyInt_Type))), ((PyObject *)__pyx_t_6), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 63; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_1);
+        __Pyx_DECREF(((PyObject *)__pyx_t_6)); __pyx_t_6 = 0;
+        __pyx_t_6 = PyNumber_Subtract(__pyx_t_1, __pyx_int_1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 63; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_6);
+        __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+        __pyx_t_7 = __Pyx_PyInt_AsLong(__pyx_t_6); if (unlikely((__pyx_t_7 == (long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 63; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+        __pyx_v_self->current_pos = __pyx_t_7;
+
+        /* "bx/arrays/wiggle.pyx":64
+ *                     self.current_chrom = header['chrom']
+ *                     self.current_pos = int( header['start'] ) - 1
+ *                     self.current_step = int( header['step'] )             # <<<<<<<<<<<<<<
+ *                     if 'span' in header:
+ *                         self.current_span = int( header['span'] )
+ */
+        __pyx_t_6 = PyObject_GetItem(__pyx_v_header, ((PyObject *)__pyx_n_s__step)); if (!__pyx_t_6) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 64; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_6);
+        __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 64; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_1);
+        PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_6);
+        __Pyx_GIVEREF(__pyx_t_6);
+        __pyx_t_6 = 0;
+        __pyx_t_6 = PyObject_Call(((PyObject *)((PyObject*)(&PyInt_Type))), ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 64; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_6);
+        __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+        __pyx_t_7 = __Pyx_PyInt_AsLong(__pyx_t_6); if (unlikely((__pyx_t_7 == (long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 64; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+        __pyx_v_self->current_step = __pyx_t_7;
+
+        /* "bx/arrays/wiggle.pyx":65
+ *                     self.current_pos = int( header['start'] ) - 1
+ *                     self.current_step = int( header['step'] )
+ *                     if 'span' in header:             # <<<<<<<<<<<<<<
+ *                         self.current_span = int( header['span'] )
+ *                     else:
+ */
+        __pyx_t_5 = (__Pyx_PySequence_Contains(((PyObject *)__pyx_n_s__span), __pyx_v_header, Py_EQ)); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 65; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        if (__pyx_t_5) {
+
+          /* "bx/arrays/wiggle.pyx":66
+ *                     self.current_step = int( header['step'] )
+ *                     if 'span' in header:
+ *                         self.current_span = int( header['span'] )             # <<<<<<<<<<<<<<
+ *                     else:
+ *                         self.current_span = 1
+ */
+          __pyx_t_6 = PyObject_GetItem(__pyx_v_header, ((PyObject *)__pyx_n_s__span)); if (!__pyx_t_6) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 66; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __Pyx_GOTREF(__pyx_t_6);
+          __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 66; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __Pyx_GOTREF(__pyx_t_1);
+          PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_6);
+          __Pyx_GIVEREF(__pyx_t_6);
+          __pyx_t_6 = 0;
+          __pyx_t_6 = PyObject_Call(((PyObject *)((PyObject*)(&PyInt_Type))), ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 66; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __Pyx_GOTREF(__pyx_t_6);
+          __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+          __pyx_t_7 = __Pyx_PyInt_AsLong(__pyx_t_6); if (unlikely((__pyx_t_7 == (long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 66; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+          __pyx_v_self->current_span = __pyx_t_7;
+          goto __pyx_L11;
+        }
+        /*else*/ {
+
+          /* "bx/arrays/wiggle.pyx":68
+ *                         self.current_span = int( header['span'] )
+ *                     else:
+ *                         self.current_span = 1             # <<<<<<<<<<<<<<
+ *                     self.mode = MODE_FIXED
+ *                     continue
+ */
+          __pyx_v_self->current_span = 1;
+        }
+        __pyx_L11:;
+
+        /* "bx/arrays/wiggle.pyx":69
+ *                     else:
+ *                         self.current_span = 1
+ *                     self.mode = MODE_FIXED             # <<<<<<<<<<<<<<
+ *                     continue
+ *             elif self.mode == MODE_BED:
+ */
+        __pyx_v_self->mode = __pyx_e_2bx_6arrays_6wiggle_MODE_FIXED;
+
+        /* "bx/arrays/wiggle.pyx":70
+ *                         self.current_span = 1
+ *                     self.mode = MODE_FIXED
+ *                     continue             # <<<<<<<<<<<<<<
+ *             elif self.mode == MODE_BED:
+ *                 fields = line.split()
+ */
+        goto __pyx_L3_continue;
+        goto __pyx_L9;
+      }
+      __pyx_L9:;
+      goto __pyx_L8;
+    }
+
+    /* "bx/arrays/wiggle.pyx":71
+ *                     self.mode = MODE_FIXED
+ *                     continue
+ *             elif self.mode == MODE_BED:             # <<<<<<<<<<<<<<
+ *                 fields = line.split()
+ *                 if len( fields ) > 3:
+ */
+    __pyx_t_5 = (__pyx_v_self->mode == __pyx_e_2bx_6arrays_6wiggle_MODE_BED);
+    if (__pyx_t_5) {
+
+      /* "bx/arrays/wiggle.pyx":72
+ *                     continue
+ *             elif self.mode == MODE_BED:
+ *                 fields = line.split()             # <<<<<<<<<<<<<<
+ *                 if len( fields ) > 3:
+ *                     if len( fields ) > 5:
+ */
+      __pyx_t_6 = PyObject_GetAttr(__pyx_v_line, __pyx_n_s__split); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 72; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_6);
+      __pyx_t_1 = PyObject_Call(__pyx_t_6, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 72; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_1);
+      __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+      __Pyx_XDECREF(__pyx_v_fields);
+      __pyx_v_fields = __pyx_t_1;
+      __pyx_t_1 = 0;
+
+      /* "bx/arrays/wiggle.pyx":73
+ *             elif self.mode == MODE_BED:
+ *                 fields = line.split()
+ *                 if len( fields ) > 3:             # <<<<<<<<<<<<<<
+ *                     if len( fields ) > 5:
+ *                         return fields[0], int( fields[1] ), int( fields[2] ), fields[5], float( fields[3] )
+ */
+      __pyx_t_8 = PyObject_Length(__pyx_v_fields); if (unlikely(__pyx_t_8 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 73; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_5 = (__pyx_t_8 > 3);
+      if (__pyx_t_5) {
+
+        /* "bx/arrays/wiggle.pyx":74
+ *                 fields = line.split()
+ *                 if len( fields ) > 3:
+ *                     if len( fields ) > 5:             # <<<<<<<<<<<<<<
+ *                         return fields[0], int( fields[1] ), int( fields[2] ), fields[5], float( fields[3] )
+ *                     else:
+ */
+        __pyx_t_8 = PyObject_Length(__pyx_v_fields); if (unlikely(__pyx_t_8 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 74; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_5 = (__pyx_t_8 > 5);
+        if (__pyx_t_5) {
+
+          /* "bx/arrays/wiggle.pyx":75
+ *                 if len( fields ) > 3:
+ *                     if len( fields ) > 5:
+ *                         return fields[0], int( fields[1] ), int( fields[2] ), fields[5], float( fields[3] )             # <<<<<<<<<<<<<<
+ *                     else:
+ *                         return fields[0], int( fields[1] ), int( fields[2] ), "+", float( fields[3] )
+ */
+          __Pyx_XDECREF(__pyx_r);
+          __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_fields, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 75; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __Pyx_GOTREF(__pyx_t_1);
+          __pyx_t_6 = __Pyx_GetItemInt(__pyx_v_fields, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_6) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 75; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __Pyx_GOTREF(__pyx_t_6);
+          __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 75; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __Pyx_GOTREF(__pyx_t_2);
+          PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_6);
+          __Pyx_GIVEREF(__pyx_t_6);
+          __pyx_t_6 = 0;
+          __pyx_t_6 = PyObject_Call(((PyObject *)((PyObject*)(&PyInt_Type))), ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 75; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __Pyx_GOTREF(__pyx_t_6);
+          __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
+          __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_fields, 2, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 75; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __Pyx_GOTREF(__pyx_t_2);
+          __pyx_t_9 = PyTuple_New(1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 75; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __Pyx_GOTREF(__pyx_t_9);
+          PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_2);
+          __Pyx_GIVEREF(__pyx_t_2);
+          __pyx_t_2 = 0;
+          __pyx_t_2 = PyObject_Call(((PyObject *)((PyObject*)(&PyInt_Type))), ((PyObject *)__pyx_t_9), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 75; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __Pyx_GOTREF(__pyx_t_2);
+          __Pyx_DECREF(((PyObject *)__pyx_t_9)); __pyx_t_9 = 0;
+          __pyx_t_9 = __Pyx_GetItemInt(__pyx_v_fields, 5, sizeof(long), PyInt_FromLong); if (!__pyx_t_9) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 75; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __Pyx_GOTREF(__pyx_t_9);
+          __pyx_t_10 = __Pyx_GetItemInt(__pyx_v_fields, 3, sizeof(long), PyInt_FromLong); if (!__pyx_t_10) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 75; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __Pyx_GOTREF(__pyx_t_10);
+          __pyx_t_11 = __Pyx_PyObject_AsDouble(__pyx_t_10); if (unlikely(__pyx_t_11 == ((double)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 75; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+          __pyx_t_10 = PyFloat_FromDouble(__pyx_t_11); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 75; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __Pyx_GOTREF(__pyx_t_10);
+          __pyx_t_12 = PyTuple_New(5); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 75; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __Pyx_GOTREF(__pyx_t_12);
+          PyTuple_SET_ITEM(__pyx_t_12, 0, __pyx_t_1);
+          __Pyx_GIVEREF(__pyx_t_1);
+          PyTuple_SET_ITEM(__pyx_t_12, 1, __pyx_t_6);
+          __Pyx_GIVEREF(__pyx_t_6);
+          PyTuple_SET_ITEM(__pyx_t_12, 2, __pyx_t_2);
+          __Pyx_GIVEREF(__pyx_t_2);
+          PyTuple_SET_ITEM(__pyx_t_12, 3, __pyx_t_9);
+          __Pyx_GIVEREF(__pyx_t_9);
+          PyTuple_SET_ITEM(__pyx_t_12, 4, __pyx_t_10);
+          __Pyx_GIVEREF(__pyx_t_10);
+          __pyx_t_1 = 0;
+          __pyx_t_6 = 0;
+          __pyx_t_2 = 0;
+          __pyx_t_9 = 0;
+          __pyx_t_10 = 0;
+          __pyx_r = ((PyObject *)__pyx_t_12);
+          __pyx_t_12 = 0;
+          goto __pyx_L0;
+          goto __pyx_L13;
+        }
+        /*else*/ {
+
+          /* "bx/arrays/wiggle.pyx":77
+ *                         return fields[0], int( fields[1] ), int( fields[2] ), fields[5], float( fields[3] )
+ *                     else:
+ *                         return fields[0], int( fields[1] ), int( fields[2] ), "+", float( fields[3] )             # <<<<<<<<<<<<<<
+ *             elif self.mode == MODE_VARIABLE:
+ *                 fields = line.split()
+ */
+          __Pyx_XDECREF(__pyx_r);
+          __pyx_t_12 = __Pyx_GetItemInt(__pyx_v_fields, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_12) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 77; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __Pyx_GOTREF(__pyx_t_12);
+          __pyx_t_10 = __Pyx_GetItemInt(__pyx_v_fields, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_10) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 77; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __Pyx_GOTREF(__pyx_t_10);
+          __pyx_t_9 = PyTuple_New(1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 77; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __Pyx_GOTREF(__pyx_t_9);
+          PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_10);
+          __Pyx_GIVEREF(__pyx_t_10);
+          __pyx_t_10 = 0;
+          __pyx_t_10 = PyObject_Call(((PyObject *)((PyObject*)(&PyInt_Type))), ((PyObject *)__pyx_t_9), NULL); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 77; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __Pyx_GOTREF(__pyx_t_10);
+          __Pyx_DECREF(((PyObject *)__pyx_t_9)); __pyx_t_9 = 0;
+          __pyx_t_9 = __Pyx_GetItemInt(__pyx_v_fields, 2, sizeof(long), PyInt_FromLong); if (!__pyx_t_9) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 77; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __Pyx_GOTREF(__pyx_t_9);
+          __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 77; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __Pyx_GOTREF(__pyx_t_2);
+          PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_9);
+          __Pyx_GIVEREF(__pyx_t_9);
+          __pyx_t_9 = 0;
+          __pyx_t_9 = PyObject_Call(((PyObject *)((PyObject*)(&PyInt_Type))), ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 77; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __Pyx_GOTREF(__pyx_t_9);
+          __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
+          __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_fields, 3, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 77; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __Pyx_GOTREF(__pyx_t_2);
+          __pyx_t_11 = __Pyx_PyObject_AsDouble(__pyx_t_2); if (unlikely(__pyx_t_11 == ((double)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 77; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+          __pyx_t_2 = PyFloat_FromDouble(__pyx_t_11); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 77; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __Pyx_GOTREF(__pyx_t_2);
+          __pyx_t_6 = PyTuple_New(5); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 77; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __Pyx_GOTREF(__pyx_t_6);
+          PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_12);
+          __Pyx_GIVEREF(__pyx_t_12);
+          PyTuple_SET_ITEM(__pyx_t_6, 1, __pyx_t_10);
+          __Pyx_GIVEREF(__pyx_t_10);
+          PyTuple_SET_ITEM(__pyx_t_6, 2, __pyx_t_9);
+          __Pyx_GIVEREF(__pyx_t_9);
+          __Pyx_INCREF(((PyObject *)__pyx_kp_s_8));
+          PyTuple_SET_ITEM(__pyx_t_6, 3, ((PyObject *)__pyx_kp_s_8));
+          __Pyx_GIVEREF(((PyObject *)__pyx_kp_s_8));
+          PyTuple_SET_ITEM(__pyx_t_6, 4, __pyx_t_2);
+          __Pyx_GIVEREF(__pyx_t_2);
+          __pyx_t_12 = 0;
+          __pyx_t_10 = 0;
+          __pyx_t_9 = 0;
+          __pyx_t_2 = 0;
+          __pyx_r = ((PyObject *)__pyx_t_6);
+          __pyx_t_6 = 0;
+          goto __pyx_L0;
+        }
+        __pyx_L13:;
+        goto __pyx_L12;
+      }
+      __pyx_L12:;
+      goto __pyx_L8;
+    }
+
+    /* "bx/arrays/wiggle.pyx":78
+ *                     else:
+ *                         return fields[0], int( fields[1] ), int( fields[2] ), "+", float( fields[3] )
+ *             elif self.mode == MODE_VARIABLE:             # <<<<<<<<<<<<<<
+ *                 fields = line.split()
+ *                 try:
+ */
+    __pyx_t_5 = (__pyx_v_self->mode == __pyx_e_2bx_6arrays_6wiggle_MODE_VARIABLE);
+    if (__pyx_t_5) {
+
+      /* "bx/arrays/wiggle.pyx":79
+ *                         return fields[0], int( fields[1] ), int( fields[2] ), "+", float( fields[3] )
+ *             elif self.mode == MODE_VARIABLE:
+ *                 fields = line.split()             # <<<<<<<<<<<<<<
+ *                 try:
+ *                     pos = int( fields[0] ) - 1
+ */
+      __pyx_t_6 = PyObject_GetAttr(__pyx_v_line, __pyx_n_s__split); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 79; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_6);
+      __pyx_t_2 = PyObject_Call(__pyx_t_6, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 79; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_2);
+      __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+      __Pyx_XDECREF(__pyx_v_fields);
+      __pyx_v_fields = __pyx_t_2;
+      __pyx_t_2 = 0;
+
+      /* "bx/arrays/wiggle.pyx":80
+ *             elif self.mode == MODE_VARIABLE:
+ *                 fields = line.split()
+ *                 try:             # <<<<<<<<<<<<<<
+ *                     pos = int( fields[0] ) - 1
+ *                     val = float( fields[1] )
+ */
+      {
+        __Pyx_ExceptionSave(&__pyx_t_13, &__pyx_t_14, &__pyx_t_15);
+        __Pyx_XGOTREF(__pyx_t_13);
+        __Pyx_XGOTREF(__pyx_t_14);
+        __Pyx_XGOTREF(__pyx_t_15);
+        /*try:*/ {
+
+          /* "bx/arrays/wiggle.pyx":81
+ *                 fields = line.split()
+ *                 try:
+ *                     pos = int( fields[0] ) - 1             # <<<<<<<<<<<<<<
+ *                     val = float( fields[1] )
+ *                 except ValueError:
+ */
+          __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_fields, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 81; __pyx_clineno = __LINE__; goto __pyx_L14_error;}
+          __Pyx_GOTREF(__pyx_t_2);
+          __pyx_t_6 = PyTuple_New(1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 81; __pyx_clineno = __LINE__; goto __pyx_L14_error;}
+          __Pyx_GOTREF(__pyx_t_6);
+          PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_2);
+          __Pyx_GIVEREF(__pyx_t_2);
+          __pyx_t_2 = 0;
+          __pyx_t_2 = PyObject_Call(((PyObject *)((PyObject*)(&PyInt_Type))), ((PyObject *)__pyx_t_6), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 81; __pyx_clineno = __LINE__; goto __pyx_L14_error;}
+          __Pyx_GOTREF(__pyx_t_2);
+          __Pyx_DECREF(((PyObject *)__pyx_t_6)); __pyx_t_6 = 0;
+          __pyx_t_6 = PyNumber_Subtract(__pyx_t_2, __pyx_int_1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 81; __pyx_clineno = __LINE__; goto __pyx_L14_error;}
+          __Pyx_GOTREF(__pyx_t_6);
+          __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+          __Pyx_XDECREF(__pyx_v_pos);
+          __pyx_v_pos = __pyx_t_6;
+          __pyx_t_6 = 0;
+
+          /* "bx/arrays/wiggle.pyx":82
+ *                 try:
+ *                     pos = int( fields[0] ) - 1
+ *                     val = float( fields[1] )             # <<<<<<<<<<<<<<
+ *                 except ValueError:
+ *                     continue
+ */
+          __pyx_t_6 = __Pyx_GetItemInt(__pyx_v_fields, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_6) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 82; __pyx_clineno = __LINE__; goto __pyx_L14_error;}
+          __Pyx_GOTREF(__pyx_t_6);
+          __pyx_t_11 = __Pyx_PyObject_AsDouble(__pyx_t_6); if (unlikely(__pyx_t_11 == ((double)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 82; __pyx_clineno = __LINE__; goto __pyx_L14_error;}
+          __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+          __pyx_v_val = __pyx_t_11;
+        }
+        __Pyx_XDECREF(__pyx_t_13); __pyx_t_13 = 0;
+        __Pyx_XDECREF(__pyx_t_14); __pyx_t_14 = 0;
+        __Pyx_XDECREF(__pyx_t_15); __pyx_t_15 = 0;
+        goto __pyx_L21_try_end;
+        __pyx_L14_error:;
+        __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0;
+        __Pyx_XDECREF(__pyx_t_12); __pyx_t_12 = 0;
+        __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0;
+        __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0;
+        __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0;
+        __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
+
+        /* "bx/arrays/wiggle.pyx":83
+ *                     pos = int( fields[0] ) - 1
+ *                     val = float( fields[1] )
+ *                 except ValueError:             # <<<<<<<<<<<<<<
+ *                     continue
+ *                 return self.current_chrom, pos, pos + self.current_span, "+", val
+ */
+        __pyx_t_16 = PyErr_ExceptionMatches(__pyx_builtin_ValueError);
+        if (__pyx_t_16) {
+          __Pyx_AddTraceback("bx.arrays.wiggle.WiggleReader.__next__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+          if (__Pyx_GetException(&__pyx_t_6, &__pyx_t_2, &__pyx_t_9) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 83; __pyx_clineno = __LINE__; goto __pyx_L16_except_error;}
+          __Pyx_GOTREF(__pyx_t_6);
+          __Pyx_GOTREF(__pyx_t_2);
+          __Pyx_GOTREF(__pyx_t_9);
+
+          /* "bx/arrays/wiggle.pyx":84
+ *                     val = float( fields[1] )
+ *                 except ValueError:
+ *                     continue             # <<<<<<<<<<<<<<
+ *                 return self.current_chrom, pos, pos + self.current_span, "+", val
+ *             elif self.mode == MODE_FIXED:
+ */
+          goto __pyx_L23_except_continue;
+          __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+          __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+          __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+          goto __pyx_L15_exception_handled;
+          __pyx_L23_except_continue:;
+          __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+          __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+          __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+          goto __pyx_L20_try_continue;
+        }
+        __pyx_L16_except_error:;
+        __Pyx_XGIVEREF(__pyx_t_13);
+        __Pyx_XGIVEREF(__pyx_t_14);
+        __Pyx_XGIVEREF(__pyx_t_15);
+        __Pyx_ExceptionReset(__pyx_t_13, __pyx_t_14, __pyx_t_15);
+        goto __pyx_L1_error;
+        __pyx_L20_try_continue:;
+        __Pyx_XGIVEREF(__pyx_t_13);
+        __Pyx_XGIVEREF(__pyx_t_14);
+        __Pyx_XGIVEREF(__pyx_t_15);
+        __Pyx_ExceptionReset(__pyx_t_13, __pyx_t_14, __pyx_t_15);
+        goto __pyx_L3_continue;
+        __pyx_L15_exception_handled:;
+        __Pyx_XGIVEREF(__pyx_t_13);
+        __Pyx_XGIVEREF(__pyx_t_14);
+        __Pyx_XGIVEREF(__pyx_t_15);
+        __Pyx_ExceptionReset(__pyx_t_13, __pyx_t_14, __pyx_t_15);
+        __pyx_L21_try_end:;
+      }
+
+      /* "bx/arrays/wiggle.pyx":85
+ *                 except ValueError:
+ *                     continue
+ *                 return self.current_chrom, pos, pos + self.current_span, "+", val             # <<<<<<<<<<<<<<
+ *             elif self.mode == MODE_FIXED:
+ *                 fields = line.split()
+ */
+      __Pyx_XDECREF(__pyx_r);
+      __pyx_t_9 = PyInt_FromLong(__pyx_v_self->current_span); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 85; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_9);
+      __pyx_t_2 = PyNumber_Add(__pyx_v_pos, __pyx_t_9); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 85; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_2);
+      __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+      __pyx_t_9 = PyFloat_FromDouble(__pyx_v_val); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 85; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_9);
+      __pyx_t_6 = PyTuple_New(5); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 85; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_6);
+      __Pyx_INCREF(__pyx_v_self->current_chrom);
+      PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_v_self->current_chrom);
+      __Pyx_GIVEREF(__pyx_v_self->current_chrom);
+      __Pyx_INCREF(__pyx_v_pos);
+      PyTuple_SET_ITEM(__pyx_t_6, 1, __pyx_v_pos);
+      __Pyx_GIVEREF(__pyx_v_pos);
+      PyTuple_SET_ITEM(__pyx_t_6, 2, __pyx_t_2);
+      __Pyx_GIVEREF(__pyx_t_2);
+      __Pyx_INCREF(((PyObject *)__pyx_kp_s_8));
+      PyTuple_SET_ITEM(__pyx_t_6, 3, ((PyObject *)__pyx_kp_s_8));
+      __Pyx_GIVEREF(((PyObject *)__pyx_kp_s_8));
+      PyTuple_SET_ITEM(__pyx_t_6, 4, __pyx_t_9);
+      __Pyx_GIVEREF(__pyx_t_9);
+      __pyx_t_2 = 0;
+      __pyx_t_9 = 0;
+      __pyx_r = ((PyObject *)__pyx_t_6);
+      __pyx_t_6 = 0;
+      goto __pyx_L0;
+      goto __pyx_L8;
+    }
+
+    /* "bx/arrays/wiggle.pyx":86
+ *                     continue
+ *                 return self.current_chrom, pos, pos + self.current_span, "+", val
+ *             elif self.mode == MODE_FIXED:             # <<<<<<<<<<<<<<
+ *                 fields = line.split()
+ *                 try:
+ */
+    __pyx_t_5 = (__pyx_v_self->mode == __pyx_e_2bx_6arrays_6wiggle_MODE_FIXED);
+    if (__pyx_t_5) {
+
+      /* "bx/arrays/wiggle.pyx":87
+ *                 return self.current_chrom, pos, pos + self.current_span, "+", val
+ *             elif self.mode == MODE_FIXED:
+ *                 fields = line.split()             # <<<<<<<<<<<<<<
+ *                 try:
+ *                     val = float( fields[0] )
+ */
+      __pyx_t_6 = PyObject_GetAttr(__pyx_v_line, __pyx_n_s__split); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 87; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_6);
+      __pyx_t_9 = PyObject_Call(__pyx_t_6, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 87; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_9);
+      __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+      __Pyx_XDECREF(__pyx_v_fields);
+      __pyx_v_fields = __pyx_t_9;
+      __pyx_t_9 = 0;
+
+      /* "bx/arrays/wiggle.pyx":88
+ *             elif self.mode == MODE_FIXED:
+ *                 fields = line.split()
+ *                 try:             # <<<<<<<<<<<<<<
+ *                     val = float( fields[0] )
+ *                 except ValueError:
+ */
+      {
+        __Pyx_ExceptionSave(&__pyx_t_15, &__pyx_t_14, &__pyx_t_13);
+        __Pyx_XGOTREF(__pyx_t_15);
+        __Pyx_XGOTREF(__pyx_t_14);
+        __Pyx_XGOTREF(__pyx_t_13);
+        /*try:*/ {
+
+          /* "bx/arrays/wiggle.pyx":89
+ *                 fields = line.split()
+ *                 try:
+ *                     val = float( fields[0] )             # <<<<<<<<<<<<<<
+ *                 except ValueError:
+ *                     continue
+ */
+          __pyx_t_9 = __Pyx_GetItemInt(__pyx_v_fields, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_9) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 89; __pyx_clineno = __LINE__; goto __pyx_L24_error;}
+          __Pyx_GOTREF(__pyx_t_9);
+          __pyx_t_11 = __Pyx_PyObject_AsDouble(__pyx_t_9); if (unlikely(__pyx_t_11 == ((double)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 89; __pyx_clineno = __LINE__; goto __pyx_L24_error;}
+          __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+          __pyx_v_val = __pyx_t_11;
+        }
+        __Pyx_XDECREF(__pyx_t_15); __pyx_t_15 = 0;
+        __Pyx_XDECREF(__pyx_t_14); __pyx_t_14 = 0;
+        __Pyx_XDECREF(__pyx_t_13); __pyx_t_13 = 0;
+        goto __pyx_L31_try_end;
+        __pyx_L24_error:;
+        __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0;
+        __Pyx_XDECREF(__pyx_t_12); __pyx_t_12 = 0;
+        __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0;
+        __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0;
+        __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
+        __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0;
+
+        /* "bx/arrays/wiggle.pyx":90
+ *                 try:
+ *                     val = float( fields[0] )
+ *                 except ValueError:             # <<<<<<<<<<<<<<
+ *                     continue
+ *                 return self.current_chrom, self.current_pos, self.current_pos + self.current_span, "+", val
+ */
+        __pyx_t_16 = PyErr_ExceptionMatches(__pyx_builtin_ValueError);
+        if (__pyx_t_16) {
+          __Pyx_AddTraceback("bx.arrays.wiggle.WiggleReader.__next__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+          if (__Pyx_GetException(&__pyx_t_9, &__pyx_t_6, &__pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 90; __pyx_clineno = __LINE__; goto __pyx_L26_except_error;}
+          __Pyx_GOTREF(__pyx_t_9);
+          __Pyx_GOTREF(__pyx_t_6);
+          __Pyx_GOTREF(__pyx_t_2);
+
+          /* "bx/arrays/wiggle.pyx":91
+ *                     val = float( fields[0] )
+ *                 except ValueError:
+ *                     continue             # <<<<<<<<<<<<<<
+ *                 return self.current_chrom, self.current_pos, self.current_pos + self.current_span, "+", val
+ *                 # FIXME: unreachable! need to test this and fix!
+ */
+          goto __pyx_L33_except_continue;
+          __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+          __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+          __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+          goto __pyx_L25_exception_handled;
+          __pyx_L33_except_continue:;
+          __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+          __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+          __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+          goto __pyx_L30_try_continue;
+        }
+        __pyx_L26_except_error:;
+        __Pyx_XGIVEREF(__pyx_t_15);
+        __Pyx_XGIVEREF(__pyx_t_14);
+        __Pyx_XGIVEREF(__pyx_t_13);
+        __Pyx_ExceptionReset(__pyx_t_15, __pyx_t_14, __pyx_t_13);
+        goto __pyx_L1_error;
+        __pyx_L30_try_continue:;
+        __Pyx_XGIVEREF(__pyx_t_15);
+        __Pyx_XGIVEREF(__pyx_t_14);
+        __Pyx_XGIVEREF(__pyx_t_13);
+        __Pyx_ExceptionReset(__pyx_t_15, __pyx_t_14, __pyx_t_13);
+        goto __pyx_L3_continue;
+        __pyx_L25_exception_handled:;
+        __Pyx_XGIVEREF(__pyx_t_15);
+        __Pyx_XGIVEREF(__pyx_t_14);
+        __Pyx_XGIVEREF(__pyx_t_13);
+        __Pyx_ExceptionReset(__pyx_t_15, __pyx_t_14, __pyx_t_13);
+        __pyx_L31_try_end:;
+      }
+
+      /* "bx/arrays/wiggle.pyx":92
+ *                 except ValueError:
+ *                     continue
+ *                 return self.current_chrom, self.current_pos, self.current_pos + self.current_span, "+", val             # <<<<<<<<<<<<<<
+ *                 # FIXME: unreachable! need to test this and fix!
+ *                 self.current_pos += self.current_step
+ */
+      __Pyx_XDECREF(__pyx_r);
+      __pyx_t_2 = PyInt_FromLong(__pyx_v_self->current_pos); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 92; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_2);
+      __pyx_t_6 = PyInt_FromLong((__pyx_v_self->current_pos + __pyx_v_self->current_span)); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 92; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_6);
+      __pyx_t_9 = PyFloat_FromDouble(__pyx_v_val); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 92; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_9);
+      __pyx_t_10 = PyTuple_New(5); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 92; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_10);
+      __Pyx_INCREF(__pyx_v_self->current_chrom);
+      PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_v_self->current_chrom);
+      __Pyx_GIVEREF(__pyx_v_self->current_chrom);
+      PyTuple_SET_ITEM(__pyx_t_10, 1, __pyx_t_2);
+      __Pyx_GIVEREF(__pyx_t_2);
+      PyTuple_SET_ITEM(__pyx_t_10, 2, __pyx_t_6);
+      __Pyx_GIVEREF(__pyx_t_6);
+      __Pyx_INCREF(((PyObject *)__pyx_kp_s_8));
+      PyTuple_SET_ITEM(__pyx_t_10, 3, ((PyObject *)__pyx_kp_s_8));
+      __Pyx_GIVEREF(((PyObject *)__pyx_kp_s_8));
+      PyTuple_SET_ITEM(__pyx_t_10, 4, __pyx_t_9);
+      __Pyx_GIVEREF(__pyx_t_9);
+      __pyx_t_2 = 0;
+      __pyx_t_6 = 0;
+      __pyx_t_9 = 0;
+      __pyx_r = ((PyObject *)__pyx_t_10);
+      __pyx_t_10 = 0;
+      goto __pyx_L0;
+      goto __pyx_L8;
+    }
+    /*else*/ {
+
+      /* "bx/arrays/wiggle.pyx":96
+ *                 self.current_pos += self.current_step
+ *             else:
+ *                 raise "Unexpected input line: %s" % line.strip()             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+      __pyx_t_10 = PyObject_GetAttr(__pyx_v_line, __pyx_n_s__strip); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 96; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_10);
+      __pyx_t_9 = PyObject_Call(__pyx_t_10, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 96; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_9);
+      __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+      __pyx_t_10 = PyNumber_Remainder(((PyObject *)__pyx_kp_s_9), __pyx_t_9); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 96; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(((PyObject *)__pyx_t_10));
+      __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+      __Pyx_Raise(((PyObject *)__pyx_t_10), 0, 0, 0);
+      __Pyx_DECREF(((PyObject *)__pyx_t_10)); __pyx_t_10 = 0;
+      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 96; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+    __pyx_L8:;
+    __pyx_L3_continue:;
+  }
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_6);
+  __Pyx_XDECREF(__pyx_t_9);
+  __Pyx_XDECREF(__pyx_t_10);
+  __Pyx_XDECREF(__pyx_t_12);
+  __Pyx_AddTraceback("bx.arrays.wiggle.WiggleReader.__next__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_line);
+  __Pyx_XDECREF(__pyx_v_header);
+  __Pyx_XDECREF(__pyx_v_fields);
+  __Pyx_XDECREF(__pyx_v_pos);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_tp_new_2bx_6arrays_6wiggle_WiggleReader(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) {
+  struct __pyx_obj_2bx_6arrays_6wiggle_WiggleReader *p;
+  PyObject *o = (*t->tp_alloc)(t, 0);
+  if (!o) return 0;
+  p = ((struct __pyx_obj_2bx_6arrays_6wiggle_WiggleReader *)o);
+  p->file = Py_None; Py_INCREF(Py_None);
+  p->current_chrom = Py_None; Py_INCREF(Py_None);
+  return o;
+}
+
+static void __pyx_tp_dealloc_2bx_6arrays_6wiggle_WiggleReader(PyObject *o) {
+  struct __pyx_obj_2bx_6arrays_6wiggle_WiggleReader *p = (struct __pyx_obj_2bx_6arrays_6wiggle_WiggleReader *)o;
+  PyObject_GC_UnTrack(o);
+  Py_CLEAR(p->file);
+  Py_CLEAR(p->current_chrom);
+  PyObject_GC_Track(o);
+  (*Py_TYPE(o)->tp_free)(o);
+}
+
+static int __pyx_tp_traverse_2bx_6arrays_6wiggle_WiggleReader(PyObject *o, visitproc v, void *a) {
+  int e;
+  struct __pyx_obj_2bx_6arrays_6wiggle_WiggleReader *p = (struct __pyx_obj_2bx_6arrays_6wiggle_WiggleReader *)o;
+  if (p->file) {
+    e = (*v)(p->file, a); if (e) return e;
+  }
+  if (p->current_chrom) {
+    e = (*v)(p->current_chrom, a); if (e) return e;
+  }
+  return 0;
+}
+
+static int __pyx_tp_clear_2bx_6arrays_6wiggle_WiggleReader(PyObject *o) {
+  struct __pyx_obj_2bx_6arrays_6wiggle_WiggleReader *p = (struct __pyx_obj_2bx_6arrays_6wiggle_WiggleReader *)o;
+  PyObject* tmp;
+  tmp = ((PyObject*)p->file);
+  p->file = Py_None; Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  tmp = ((PyObject*)p->current_chrom);
+  p->current_chrom = Py_None; Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  return 0;
+}
+
+static PyMethodDef __pyx_methods_2bx_6arrays_6wiggle_WiggleReader[] = {
+  {__Pyx_NAMESTR("__next__"), (PyCFunction)__pyx_pw_2bx_6arrays_6wiggle_12WiggleReader_5__next__, METH_NOARGS|METH_COEXIST, __Pyx_DOCSTR(0)},
+  {0, 0, 0, 0}
+};
+
+static PyNumberMethods __pyx_tp_as_number_WiggleReader = {
+  0, /*nb_add*/
+  0, /*nb_subtract*/
+  0, /*nb_multiply*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_divide*/
+  #endif
+  0, /*nb_remainder*/
+  0, /*nb_divmod*/
+  0, /*nb_power*/
+  0, /*nb_negative*/
+  0, /*nb_positive*/
+  0, /*nb_absolute*/
+  0, /*nb_nonzero*/
+  0, /*nb_invert*/
+  0, /*nb_lshift*/
+  0, /*nb_rshift*/
+  0, /*nb_and*/
+  0, /*nb_xor*/
+  0, /*nb_or*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_coerce*/
+  #endif
+  0, /*nb_int*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_long*/
+  #else
+  0, /*reserved*/
+  #endif
+  0, /*nb_float*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_oct*/
+  #endif
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_hex*/
+  #endif
+  0, /*nb_inplace_add*/
+  0, /*nb_inplace_subtract*/
+  0, /*nb_inplace_multiply*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_inplace_divide*/
+  #endif
+  0, /*nb_inplace_remainder*/
+  0, /*nb_inplace_power*/
+  0, /*nb_inplace_lshift*/
+  0, /*nb_inplace_rshift*/
+  0, /*nb_inplace_and*/
+  0, /*nb_inplace_xor*/
+  0, /*nb_inplace_or*/
+  0, /*nb_floor_divide*/
+  0, /*nb_true_divide*/
+  0, /*nb_inplace_floor_divide*/
+  0, /*nb_inplace_true_divide*/
+  #if PY_VERSION_HEX >= 0x02050000
+  0, /*nb_index*/
+  #endif
+};
+
+static PySequenceMethods __pyx_tp_as_sequence_WiggleReader = {
+  0, /*sq_length*/
+  0, /*sq_concat*/
+  0, /*sq_repeat*/
+  0, /*sq_item*/
+  0, /*sq_slice*/
+  0, /*sq_ass_item*/
+  0, /*sq_ass_slice*/
+  0, /*sq_contains*/
+  0, /*sq_inplace_concat*/
+  0, /*sq_inplace_repeat*/
+};
+
+static PyMappingMethods __pyx_tp_as_mapping_WiggleReader = {
+  0, /*mp_length*/
+  0, /*mp_subscript*/
+  0, /*mp_ass_subscript*/
+};
+
+static PyBufferProcs __pyx_tp_as_buffer_WiggleReader = {
+  #if PY_MAJOR_VERSION < 3
+  0, /*bf_getreadbuffer*/
+  #endif
+  #if PY_MAJOR_VERSION < 3
+  0, /*bf_getwritebuffer*/
+  #endif
+  #if PY_MAJOR_VERSION < 3
+  0, /*bf_getsegcount*/
+  #endif
+  #if PY_MAJOR_VERSION < 3
+  0, /*bf_getcharbuffer*/
+  #endif
+  #if PY_VERSION_HEX >= 0x02060000
+  0, /*bf_getbuffer*/
+  #endif
+  #if PY_VERSION_HEX >= 0x02060000
+  0, /*bf_releasebuffer*/
+  #endif
+};
+
+static PyTypeObject __pyx_type_2bx_6arrays_6wiggle_WiggleReader = {
+  PyVarObject_HEAD_INIT(0, 0)
+  __Pyx_NAMESTR("bx.arrays.wiggle.WiggleReader"), /*tp_name*/
+  sizeof(struct __pyx_obj_2bx_6arrays_6wiggle_WiggleReader), /*tp_basicsize*/
+  0, /*tp_itemsize*/
+  __pyx_tp_dealloc_2bx_6arrays_6wiggle_WiggleReader, /*tp_dealloc*/
+  0, /*tp_print*/
+  0, /*tp_getattr*/
+  0, /*tp_setattr*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*tp_compare*/
+  #else
+  0, /*reserved*/
+  #endif
+  0, /*tp_repr*/
+  &__pyx_tp_as_number_WiggleReader, /*tp_as_number*/
+  &__pyx_tp_as_sequence_WiggleReader, /*tp_as_sequence*/
+  &__pyx_tp_as_mapping_WiggleReader, /*tp_as_mapping*/
+  0, /*tp_hash*/
+  0, /*tp_call*/
+  0, /*tp_str*/
+  0, /*tp_getattro*/
+  0, /*tp_setattro*/
+  &__pyx_tp_as_buffer_WiggleReader, /*tp_as_buffer*/
+  Py_TPFLAGS_DEFAULT|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+  __Pyx_DOCSTR("\n    Iterator yielding chrom, start, end, strand, value.\n    Values are zero-based, half-open.\n    Regions which lack a score are ignored.\n    "), /*tp_doc*/
+  __pyx_tp_traverse_2bx_6arrays_6wiggle_WiggleReader, /*tp_traverse*/
+  __pyx_tp_clear_2bx_6arrays_6wiggle_WiggleReader, /*tp_clear*/
+  0, /*tp_richcompare*/
+  0, /*tp_weaklistoffset*/
+  __pyx_pw_2bx_6arrays_6wiggle_12WiggleReader_3__iter__, /*tp_iter*/
+  __pyx_pw_2bx_6arrays_6wiggle_12WiggleReader_5__next__, /*tp_iternext*/
+  __pyx_methods_2bx_6arrays_6wiggle_WiggleReader, /*tp_methods*/
+  0, /*tp_members*/
+  0, /*tp_getset*/
+  0, /*tp_base*/
+  0, /*tp_dict*/
+  0, /*tp_descr_get*/
+  0, /*tp_descr_set*/
+  0, /*tp_dictoffset*/
+  __pyx_pw_2bx_6arrays_6wiggle_12WiggleReader_1__init__, /*tp_init*/
+  0, /*tp_alloc*/
+  __pyx_tp_new_2bx_6arrays_6wiggle_WiggleReader, /*tp_new*/
+  0, /*tp_free*/
+  0, /*tp_is_gc*/
+  0, /*tp_bases*/
+  0, /*tp_mro*/
+  0, /*tp_cache*/
+  0, /*tp_subclasses*/
+  0, /*tp_weaklist*/
+  0, /*tp_del*/
+  #if PY_VERSION_HEX >= 0x02060000
+  0, /*tp_version_tag*/
+  #endif
+};
+
+static PyMethodDef __pyx_methods[] = {
+  {0, 0, 0, 0}
+};
+
+#if PY_MAJOR_VERSION >= 3
+static struct PyModuleDef __pyx_moduledef = {
+  #if PY_VERSION_HEX < 0x03020000
+    { PyObject_HEAD_INIT(NULL) NULL, 0, NULL },
+  #else
+    PyModuleDef_HEAD_INIT,
+  #endif
+    __Pyx_NAMESTR("wiggle"),
+    __Pyx_DOCSTR(__pyx_k_10), /* m_doc */
+    -1, /* m_size */
+    __pyx_methods /* m_methods */,
+    NULL, /* m_reload */
+    NULL, /* m_traverse */
+    NULL, /* m_clear */
+    NULL /* m_free */
+};
+#endif
+
+static __Pyx_StringTabEntry __pyx_string_tab[] = {
+  {&__pyx_kp_s_1, __pyx_k_1, sizeof(__pyx_k_1), 0, 0, 1, 0},
+  {&__pyx_kp_s_13, __pyx_k_13, sizeof(__pyx_k_13), 0, 0, 1, 0},
+  {&__pyx_n_s_14, __pyx_k_14, sizeof(__pyx_k_14), 0, 0, 1, 1},
+  {&__pyx_kp_s_3, __pyx_k_3, sizeof(__pyx_k_3), 0, 0, 1, 0},
+  {&__pyx_kp_s_8, __pyx_k_8, sizeof(__pyx_k_8), 0, 0, 1, 0},
+  {&__pyx_kp_s_9, __pyx_k_9, sizeof(__pyx_k_9), 0, 0, 1, 0},
+  {&__pyx_n_s__StopIteration, __pyx_k__StopIteration, sizeof(__pyx_k__StopIteration), 0, 0, 1, 1},
+  {&__pyx_n_s__ValueError, __pyx_k__ValueError, sizeof(__pyx_k__ValueError), 0, 0, 1, 1},
+  {&__pyx_n_s____main__, __pyx_k____main__, sizeof(__pyx_k____main__), 0, 0, 1, 1},
+  {&__pyx_n_s____test__, __pyx_k____test__, sizeof(__pyx_k____test__), 0, 0, 1, 1},
+  {&__pyx_n_s__browser, __pyx_k__browser, sizeof(__pyx_k__browser), 0, 0, 1, 1},
+  {&__pyx_n_s__chrom, __pyx_k__chrom, sizeof(__pyx_k__chrom), 0, 0, 1, 1},
+  {&__pyx_n_s__field, __pyx_k__field, sizeof(__pyx_k__field), 0, 0, 1, 1},
+  {&__pyx_n_s__file, __pyx_k__file, sizeof(__pyx_k__file), 0, 0, 1, 1},
+  {&__pyx_n_s__fixedStep, __pyx_k__fixedStep, sizeof(__pyx_k__fixedStep), 0, 0, 1, 1},
+  {&__pyx_n_s__isalpha, __pyx_k__isalpha, sizeof(__pyx_k__isalpha), 0, 0, 1, 1},
+  {&__pyx_n_s__isspace, __pyx_k__isspace, sizeof(__pyx_k__isspace), 0, 0, 1, 1},
+  {&__pyx_n_s__line, __pyx_k__line, sizeof(__pyx_k__line), 0, 0, 1, 1},
+  {&__pyx_n_s__parse_header, __pyx_k__parse_header, sizeof(__pyx_k__parse_header), 0, 0, 1, 1},
+  {&__pyx_n_s__readline, __pyx_k__readline, sizeof(__pyx_k__readline), 0, 0, 1, 1},
+  {&__pyx_n_s__span, __pyx_k__span, sizeof(__pyx_k__span), 0, 0, 1, 1},
+  {&__pyx_n_s__split, __pyx_k__split, sizeof(__pyx_k__split), 0, 0, 1, 1},
+  {&__pyx_n_s__start, __pyx_k__start, sizeof(__pyx_k__start), 0, 0, 1, 1},
+  {&__pyx_n_s__startswith, __pyx_k__startswith, sizeof(__pyx_k__startswith), 0, 0, 1, 1},
+  {&__pyx_n_s__step, __pyx_k__step, sizeof(__pyx_k__step), 0, 0, 1, 1},
+  {&__pyx_n_s__strip, __pyx_k__strip, sizeof(__pyx_k__strip), 0, 0, 1, 1},
+  {&__pyx_n_s__track, __pyx_k__track, sizeof(__pyx_k__track), 0, 0, 1, 1},
+  {&__pyx_n_s__variableStep, __pyx_k__variableStep, sizeof(__pyx_k__variableStep), 0, 0, 1, 1},
+  {0, 0, 0, 0, 0, 0, 0}
+};
+static int __Pyx_InitCachedBuiltins(void) {
+  __pyx_builtin_StopIteration = __Pyx_GetName(__pyx_b, __pyx_n_s__StopIteration); if (!__pyx_builtin_StopIteration) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 41; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_builtin_ValueError = __Pyx_GetName(__pyx_b, __pyx_n_s__ValueError); if (!__pyx_builtin_ValueError) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 83; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  return 0;
+  __pyx_L1_error:;
+  return -1;
+}
+
+static int __Pyx_InitCachedConstants(void) {
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0);
+
+  /* "bx/arrays/wiggle.pyx":12
+ * 
+ * def parse_header( line ):
+ *     return dict( [ field.split( '=' ) for field in line.split()[1:] ] )             # <<<<<<<<<<<<<<
+ * 
+ * cdef class WiggleReader:
+ */
+  __pyx_k_tuple_2 = PyTuple_Pack(1, ((PyObject *)__pyx_kp_s_1)); if (unlikely(!__pyx_k_tuple_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 12; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_k_tuple_2);
+  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_2));
+
+  /* "bx/arrays/wiggle.pyx":47
+ *                 continue
+ *             if line[0].isalpha():
+ *                 if line.startswith( "track" ) or line.startswith( "browser" ):             # <<<<<<<<<<<<<<
+ *                     continue
+ *                 elif line.startswith( "variableStep" ):
+ */
+  __pyx_k_tuple_4 = PyTuple_Pack(1, ((PyObject *)__pyx_n_s__track)); if (unlikely(!__pyx_k_tuple_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 47; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_k_tuple_4);
+  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_4));
+  __pyx_k_tuple_5 = PyTuple_Pack(1, ((PyObject *)__pyx_n_s__browser)); if (unlikely(!__pyx_k_tuple_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 47; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_k_tuple_5);
+  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_5));
+
+  /* "bx/arrays/wiggle.pyx":49
+ *                 if line.startswith( "track" ) or line.startswith( "browser" ):
+ *                     continue
+ *                 elif line.startswith( "variableStep" ):             # <<<<<<<<<<<<<<
+ *                     header = parse_header( line )
+ *                     self.current_chrom = header['chrom']
+ */
+  __pyx_k_tuple_6 = PyTuple_Pack(1, ((PyObject *)__pyx_n_s__variableStep)); if (unlikely(!__pyx_k_tuple_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 49; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_k_tuple_6);
+  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_6));
+
+  /* "bx/arrays/wiggle.pyx":60
+ *                     self.mode = MODE_VARIABLE
+ *                     continue
+ *                 elif line.startswith( "fixedStep" ):             # <<<<<<<<<<<<<<
+ *                     header = parse_header( line )
+ *                     self.current_chrom = header['chrom']
+ */
+  __pyx_k_tuple_7 = PyTuple_Pack(1, ((PyObject *)__pyx_n_s__fixedStep)); if (unlikely(!__pyx_k_tuple_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 60; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_k_tuple_7);
+  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_7));
+
+  /* "bx/arrays/wiggle.pyx":11
+ * """
+ * 
+ * def parse_header( line ):             # <<<<<<<<<<<<<<
+ *     return dict( [ field.split( '=' ) for field in line.split()[1:] ] )
+ * 
+ */
+  __pyx_k_tuple_11 = PyTuple_Pack(2, ((PyObject *)__pyx_n_s__line), ((PyObject *)__pyx_n_s__field)); if (unlikely(!__pyx_k_tuple_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 11; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_k_tuple_11);
+  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_11));
+  __pyx_k_codeobj_12 = (PyObject*)__Pyx_PyCode_New(1, 0, 2, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_k_tuple_11, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_13, __pyx_n_s__parse_header, 11, __pyx_empty_bytes); if (unlikely(!__pyx_k_codeobj_12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 11; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_RefNannyFinishContext();
+  return 0;
+  __pyx_L1_error:;
+  __Pyx_RefNannyFinishContext();
+  return -1;
+}
+
+static int __Pyx_InitGlobals(void) {
+  if (__Pyx_InitStrings(__pyx_string_tab) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  __pyx_int_1 = PyInt_FromLong(1); if (unlikely(!__pyx_int_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  return 0;
+  __pyx_L1_error:;
+  return -1;
+}
+
+#if PY_MAJOR_VERSION < 3
+PyMODINIT_FUNC initwiggle(void); /*proto*/
+PyMODINIT_FUNC initwiggle(void)
+#else
+PyMODINIT_FUNC PyInit_wiggle(void); /*proto*/
+PyMODINIT_FUNC PyInit_wiggle(void)
+#endif
+{
+  PyObject *__pyx_t_1 = NULL;
+  __Pyx_RefNannyDeclarations
+  #if CYTHON_REFNANNY
+  __Pyx_RefNanny = __Pyx_RefNannyImportAPI("refnanny");
+  if (!__Pyx_RefNanny) {
+      PyErr_Clear();
+      __Pyx_RefNanny = __Pyx_RefNannyImportAPI("Cython.Runtime.refnanny");
+      if (!__Pyx_RefNanny)
+          Py_FatalError("failed to import 'refnanny' module");
+  }
+  #endif
+  __Pyx_RefNannySetupContext("PyMODINIT_FUNC PyInit_wiggle(void)", 0);
+  if ( __Pyx_check_binary_version() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_bytes)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #ifdef __Pyx_CyFunction_USED
+  if (__Pyx_CyFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #endif
+  #ifdef __Pyx_FusedFunction_USED
+  if (__pyx_FusedFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #endif
+  #ifdef __Pyx_Generator_USED
+  if (__pyx_Generator_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #endif
+  /*--- Library function declarations ---*/
+  /*--- Threads initialization code ---*/
+  #if defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS
+  #ifdef WITH_THREAD /* Python build with threading support? */
+  PyEval_InitThreads();
+  #endif
+  #endif
+  /*--- Module creation code ---*/
+  #if PY_MAJOR_VERSION < 3
+  __pyx_m = Py_InitModule4(__Pyx_NAMESTR("wiggle"), __pyx_methods, __Pyx_DOCSTR(__pyx_k_10), 0, PYTHON_API_VERSION); Py_XINCREF(__pyx_m);
+  #else
+  __pyx_m = PyModule_Create(&__pyx_moduledef);
+  #endif
+  if (unlikely(!__pyx_m)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #if PY_MAJOR_VERSION >= 3
+  {
+    PyObject *modules = PyImport_GetModuleDict(); if (unlikely(!modules)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (!PyDict_GetItemString(modules, "bx.arrays.wiggle")) {
+      if (unlikely(PyDict_SetItemString(modules, "bx.arrays.wiggle", __pyx_m) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+  }
+  #endif
+  __pyx_b = PyImport_AddModule(__Pyx_NAMESTR(__Pyx_BUILTIN_MODULE_NAME)); if (unlikely(!__pyx_b)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #if CYTHON_COMPILING_IN_PYPY
+  Py_INCREF(__pyx_b);
+  #endif
+  if (__Pyx_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  /*--- Initialize various global constants etc. ---*/
+  if (unlikely(__Pyx_InitGlobals() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (__pyx_module_is_main_bx__arrays__wiggle) {
+    if (__Pyx_SetAttrString(__pyx_m, "__name__", __pyx_n_s____main__) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  }
+  /*--- Builtin init code ---*/
+  if (unlikely(__Pyx_InitCachedBuiltins() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  /*--- Constants init code ---*/
+  if (unlikely(__Pyx_InitCachedConstants() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  /*--- Global init code ---*/
+  /*--- Variable export code ---*/
+  /*--- Function export code ---*/
+  /*--- Type init code ---*/
+  if (PyType_Ready(&__pyx_type_2bx_6arrays_6wiggle_WiggleReader) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 14; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (__Pyx_SetAttrString(__pyx_m, "WiggleReader", (PyObject *)&__pyx_type_2bx_6arrays_6wiggle_WiggleReader) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 14; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_2bx_6arrays_6wiggle_WiggleReader = &__pyx_type_2bx_6arrays_6wiggle_WiggleReader;
+  /*--- Type import code ---*/
+  /*--- Variable import code ---*/
+  /*--- Function import code ---*/
+  /*--- Execution code ---*/
+
+  /* "bx/arrays/wiggle.pyx":11
+ * """
+ * 
+ * def parse_header( line ):             # <<<<<<<<<<<<<<
+ *     return dict( [ field.split( '=' ) for field in line.split()[1:] ] )
+ * 
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_2bx_6arrays_6wiggle_1parse_header, NULL, __pyx_n_s_14); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 11; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s__parse_header, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 11; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "bx/arrays/wiggle.pyx":1
+ * """             # <<<<<<<<<<<<<<
+ * Support for scores in the `wiggle`_ file format used by the UCSC Genome
+ * Browser.
+ */
+  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(((PyObject *)__pyx_t_1));
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s____test__, ((PyObject *)__pyx_t_1)) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  if (__pyx_m) {
+    __Pyx_AddTraceback("init bx.arrays.wiggle", __pyx_clineno, __pyx_lineno, __pyx_filename);
+    Py_DECREF(__pyx_m); __pyx_m = 0;
+  } else if (!PyErr_Occurred()) {
+    PyErr_SetString(PyExc_ImportError, "init bx.arrays.wiggle");
+  }
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  #if PY_MAJOR_VERSION < 3
+  return;
+  #else
+  return __pyx_m;
+  #endif
+}
+
+/* Runtime support code */
+#if CYTHON_REFNANNY
+static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) {
+    PyObject *m = NULL, *p = NULL;
+    void *r = NULL;
+    m = PyImport_ImportModule((char *)modname);
+    if (!m) goto end;
+    p = PyObject_GetAttrString(m, (char *)"RefNannyAPI");
+    if (!p) goto end;
+    r = PyLong_AsVoidPtr(p);
+end:
+    Py_XDECREF(p);
+    Py_XDECREF(m);
+    return (__Pyx_RefNannyAPIStruct *)r;
+}
+#endif /* CYTHON_REFNANNY */
+
+static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name) {
+    PyObject *result;
+    result = PyObject_GetAttr(dict, name);
+    if (!result) {
+        if (dict != __pyx_b) {
+            PyErr_Clear();
+            result = PyObject_GetAttr(__pyx_b, name);
+        }
+        if (!result) {
+            PyErr_SetObject(PyExc_NameError, name);
+        }
+    }
+    return result;
+}
+
+static void __Pyx_RaiseDoubleKeywordsError(
+    const char* func_name,
+    PyObject* kw_name)
+{
+    PyErr_Format(PyExc_TypeError,
+        #if PY_MAJOR_VERSION >= 3
+        "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
+        #else
+        "%s() got multiple values for keyword argument '%s'", func_name,
+        PyString_AsString(kw_name));
+        #endif
+}
+
+static int __Pyx_ParseOptionalKeywords(
+    PyObject *kwds,
+    PyObject **argnames[],
+    PyObject *kwds2,
+    PyObject *values[],
+    Py_ssize_t num_pos_args,
+    const char* function_name)
+{
+    PyObject *key = 0, *value = 0;
+    Py_ssize_t pos = 0;
+    PyObject*** name;
+    PyObject*** first_kw_arg = argnames + num_pos_args;
+    while (PyDict_Next(kwds, &pos, &key, &value)) {
+        name = first_kw_arg;
+        while (*name && (**name != key)) name++;
+        if (*name) {
+            values[name-argnames] = value;
+            continue;
+        }
+        name = first_kw_arg;
+        #if PY_MAJOR_VERSION < 3
+        if (likely(PyString_CheckExact(key)) || likely(PyString_Check(key))) {
+            while (*name) {
+                if ((CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**name) == PyString_GET_SIZE(key))
+                        && _PyString_Eq(**name, key)) {
+                    values[name-argnames] = value;
+                    break;
+                }
+                name++;
+            }
+            if (*name) continue;
+            else {
+                PyObject*** argname = argnames;
+                while (argname != first_kw_arg) {
+                    if ((**argname == key) || (
+                            (CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**argname) == PyString_GET_SIZE(key))
+                             && _PyString_Eq(**argname, key))) {
+                        goto arg_passed_twice;
+                    }
+                    argname++;
+                }
+            }
+        } else
+        #endif
+        if (likely(PyUnicode_Check(key))) {
+            while (*name) {
+                int cmp = (**name == key) ? 0 :
+                #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3
+                    (PyUnicode_GET_SIZE(**name) != PyUnicode_GET_SIZE(key)) ? 1 :
+                #endif
+                    PyUnicode_Compare(**name, key);
+                if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad;
+                if (cmp == 0) {
+                    values[name-argnames] = value;
+                    break;
+                }
+                name++;
+            }
+            if (*name) continue;
+            else {
+                PyObject*** argname = argnames;
+                while (argname != first_kw_arg) {
+                    int cmp = (**argname == key) ? 0 :
+                    #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3
+                        (PyUnicode_GET_SIZE(**argname) != PyUnicode_GET_SIZE(key)) ? 1 :
+                    #endif
+                        PyUnicode_Compare(**argname, key);
+                    if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad;
+                    if (cmp == 0) goto arg_passed_twice;
+                    argname++;
+                }
+            }
+        } else
+            goto invalid_keyword_type;
+        if (kwds2) {
+            if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
+        } else {
+            goto invalid_keyword;
+        }
+    }
+    return 0;
+arg_passed_twice:
+    __Pyx_RaiseDoubleKeywordsError(function_name, key);
+    goto bad;
+invalid_keyword_type:
+    PyErr_Format(PyExc_TypeError,
+        "%s() keywords must be strings", function_name);
+    goto bad;
+invalid_keyword:
+    PyErr_Format(PyExc_TypeError,
+    #if PY_MAJOR_VERSION < 3
+        "%s() got an unexpected keyword argument '%s'",
+        function_name, PyString_AsString(key));
+    #else
+        "%s() got an unexpected keyword argument '%U'",
+        function_name, key);
+    #endif
+bad:
+    return -1;
+}
+
+static void __Pyx_RaiseArgtupleInvalid(
+    const char* func_name,
+    int exact,
+    Py_ssize_t num_min,
+    Py_ssize_t num_max,
+    Py_ssize_t num_found)
+{
+    Py_ssize_t num_expected;
+    const char *more_or_less;
+    if (num_found < num_min) {
+        num_expected = num_min;
+        more_or_less = "at least";
+    } else {
+        num_expected = num_max;
+        more_or_less = "at most";
+    }
+    if (exact) {
+        more_or_less = "exactly";
+    }
+    PyErr_Format(PyExc_TypeError,
+                 "%s() takes %s %" CYTHON_FORMAT_SSIZE_T "d positional argument%s (%" CYTHON_FORMAT_SSIZE_T "d given)",
+                 func_name, more_or_less, num_expected,
+                 (num_expected == 1) ? "" : "s", num_found);
+}
+
+static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    PyObject *tmp_type, *tmp_value, *tmp_tb;
+    PyThreadState *tstate = PyThreadState_GET();
+    tmp_type = tstate->curexc_type;
+    tmp_value = tstate->curexc_value;
+    tmp_tb = tstate->curexc_traceback;
+    tstate->curexc_type = type;
+    tstate->curexc_value = value;
+    tstate->curexc_traceback = tb;
+    Py_XDECREF(tmp_type);
+    Py_XDECREF(tmp_value);
+    Py_XDECREF(tmp_tb);
+#else
+    PyErr_Restore(type, value, tb);
+#endif
+}
+static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    PyThreadState *tstate = PyThreadState_GET();
+    *type = tstate->curexc_type;
+    *value = tstate->curexc_value;
+    *tb = tstate->curexc_traceback;
+    tstate->curexc_type = 0;
+    tstate->curexc_value = 0;
+    tstate->curexc_traceback = 0;
+#else
+    PyErr_Fetch(type, value, tb);
+#endif
+}
+
+#if PY_MAJOR_VERSION < 3
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb,
+                        CYTHON_UNUSED PyObject *cause) {
+    Py_XINCREF(type);
+    if (!value || value == Py_None)
+        value = NULL;
+    else
+        Py_INCREF(value);
+    if (!tb || tb == Py_None)
+        tb = NULL;
+    else {
+        Py_INCREF(tb);
+        if (!PyTraceBack_Check(tb)) {
+            PyErr_SetString(PyExc_TypeError,
+                "raise: arg 3 must be a traceback or None");
+            goto raise_error;
+        }
+    }
+    #if PY_VERSION_HEX < 0x02050000
+    if (PyClass_Check(type)) {
+    #else
+    if (PyType_Check(type)) {
+    #endif
+#if CYTHON_COMPILING_IN_PYPY
+        if (!value) {
+            Py_INCREF(Py_None);
+            value = Py_None;
+        }
+#endif
+        PyErr_NormalizeException(&type, &value, &tb);
+    } else {
+        if (value) {
+            PyErr_SetString(PyExc_TypeError,
+                "instance exception may not have a separate value");
+            goto raise_error;
+        }
+        value = type;
+        #if PY_VERSION_HEX < 0x02050000
+            if (PyInstance_Check(type)) {
+                type = (PyObject*) ((PyInstanceObject*)type)->in_class;
+                Py_INCREF(type);
+            }
+            else {
+                type = 0;
+                PyErr_SetString(PyExc_TypeError,
+                    "raise: exception must be an old-style class or instance");
+                goto raise_error;
+            }
+        #else
+            type = (PyObject*) Py_TYPE(type);
+            Py_INCREF(type);
+            if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
+                PyErr_SetString(PyExc_TypeError,
+                    "raise: exception class must be a subclass of BaseException");
+                goto raise_error;
+            }
+        #endif
+    }
+    __Pyx_ErrRestore(type, value, tb);
+    return;
+raise_error:
+    Py_XDECREF(value);
+    Py_XDECREF(type);
+    Py_XDECREF(tb);
+    return;
+}
+#else /* Python 3+ */
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause) {
+    PyObject* owned_instance = NULL;
+    if (tb == Py_None) {
+        tb = 0;
+    } else if (tb && !PyTraceBack_Check(tb)) {
+        PyErr_SetString(PyExc_TypeError,
+            "raise: arg 3 must be a traceback or None");
+        goto bad;
+    }
+    if (value == Py_None)
+        value = 0;
+    if (PyExceptionInstance_Check(type)) {
+        if (value) {
+            PyErr_SetString(PyExc_TypeError,
+                "instance exception may not have a separate value");
+            goto bad;
+        }
+        value = type;
+        type = (PyObject*) Py_TYPE(value);
+    } else if (PyExceptionClass_Check(type)) {
+        PyObject *args;
+        if (!value)
+            args = PyTuple_New(0);
+        else if (PyTuple_Check(value)) {
+            Py_INCREF(value);
+            args = value;
+        }
+        else
+            args = PyTuple_Pack(1, value);
+        if (!args)
+            goto bad;
+        owned_instance = PyEval_CallObject(type, args);
+        Py_DECREF(args);
+        if (!owned_instance)
+            goto bad;
+        value = owned_instance;
+        if (!PyExceptionInstance_Check(value)) {
+            PyErr_Format(PyExc_TypeError,
+                         "calling %R should have returned an instance of "
+                         "BaseException, not %R",
+                         type, Py_TYPE(value));
+            goto bad;
+        }
+    } else {
+        PyErr_SetString(PyExc_TypeError,
+            "raise: exception class must be a subclass of BaseException");
+        goto bad;
+    }
+    if (cause && cause != Py_None) {
+        PyObject *fixed_cause;
+        if (PyExceptionClass_Check(cause)) {
+            fixed_cause = PyObject_CallObject(cause, NULL);
+            if (fixed_cause == NULL)
+                goto bad;
+        }
+        else if (PyExceptionInstance_Check(cause)) {
+            fixed_cause = cause;
+            Py_INCREF(fixed_cause);
+        }
+        else {
+            PyErr_SetString(PyExc_TypeError,
+                            "exception causes must derive from "
+                            "BaseException");
+            goto bad;
+        }
+        PyException_SetCause(value, fixed_cause);
+    }
+    PyErr_SetObject(type, value);
+    if (tb) {
+        PyThreadState *tstate = PyThreadState_GET();
+        PyObject* tmp_tb = tstate->curexc_traceback;
+        if (tb != tmp_tb) {
+            Py_INCREF(tb);
+            tstate->curexc_traceback = tb;
+            Py_XDECREF(tmp_tb);
+        }
+    }
+bad:
+    Py_XDECREF(owned_instance);
+    return;
+}
+#endif
+
+static double __Pyx__PyObject_AsDouble(PyObject* obj) {
+    PyObject* float_value;
+#if CYTHON_COMPILING_IN_PYPY
+    float_value = PyNumber_Float(obj);
+#else
+    if (Py_TYPE(obj)->tp_as_number && Py_TYPE(obj)->tp_as_number->nb_float) {
+        return PyFloat_AsDouble(obj);
+    } else if (PyUnicode_CheckExact(obj) || PyBytes_CheckExact(obj)) {
+#if PY_MAJOR_VERSION >= 3
+        float_value = PyFloat_FromString(obj);
+#else
+        float_value = PyFloat_FromString(obj, 0);
+#endif
+    } else {
+        PyObject* args = PyTuple_New(1);
+        if (unlikely(!args)) goto bad;
+        PyTuple_SET_ITEM(args, 0, obj);
+        float_value = PyObject_Call((PyObject*)&PyFloat_Type, args, 0);
+        PyTuple_SET_ITEM(args, 0, 0);
+        Py_DECREF(args);
+    }
+#endif
+    if (likely(float_value)) {
+        double value = PyFloat_AS_DOUBLE(float_value);
+        Py_DECREF(float_value);
+        return value;
+    }
+bad:
+    return (double)-1;
+}
+
+static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) {
+    PyObject *local_type, *local_value, *local_tb;
+#if CYTHON_COMPILING_IN_CPYTHON
+    PyObject *tmp_type, *tmp_value, *tmp_tb;
+    PyThreadState *tstate = PyThreadState_GET();
+    local_type = tstate->curexc_type;
+    local_value = tstate->curexc_value;
+    local_tb = tstate->curexc_traceback;
+    tstate->curexc_type = 0;
+    tstate->curexc_value = 0;
+    tstate->curexc_traceback = 0;
+#else
+    PyErr_Fetch(&local_type, &local_value, &local_tb);
+#endif
+    PyErr_NormalizeException(&local_type, &local_value, &local_tb);
+#if CYTHON_COMPILING_IN_CPYTHON
+    if (unlikely(tstate->curexc_type))
+#else
+    if (unlikely(PyErr_Occurred()))
+#endif
+        goto bad;
+    #if PY_MAJOR_VERSION >= 3
+    if (unlikely(PyException_SetTraceback(local_value, local_tb) < 0))
+        goto bad;
+    #endif
+    Py_INCREF(local_type);
+    Py_INCREF(local_value);
+    Py_INCREF(local_tb);
+    *type = local_type;
+    *value = local_value;
+    *tb = local_tb;
+#if CYTHON_COMPILING_IN_CPYTHON
+    tmp_type = tstate->exc_type;
+    tmp_value = tstate->exc_value;
+    tmp_tb = tstate->exc_traceback;
+    tstate->exc_type = local_type;
+    tstate->exc_value = local_value;
+    tstate->exc_traceback = local_tb;
+    /* Make sure tstate is in a consistent state when we XDECREF
+       these objects (DECREF may run arbitrary code). */
+    Py_XDECREF(tmp_type);
+    Py_XDECREF(tmp_value);
+    Py_XDECREF(tmp_tb);
+#else
+    PyErr_SetExcInfo(local_type, local_value, local_tb);
+#endif
+    return 0;
+bad:
+    *type = 0;
+    *value = 0;
+    *tb = 0;
+    Py_XDECREF(local_type);
+    Py_XDECREF(local_value);
+    Py_XDECREF(local_tb);
+    return -1;
+}
+
+static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    PyThreadState *tstate = PyThreadState_GET();
+    *type = tstate->exc_type;
+    *value = tstate->exc_value;
+    *tb = tstate->exc_traceback;
+    Py_XINCREF(*type);
+    Py_XINCREF(*value);
+    Py_XINCREF(*tb);
+#else
+    PyErr_GetExcInfo(type, value, tb);
+#endif
+}
+static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    PyObject *tmp_type, *tmp_value, *tmp_tb;
+    PyThreadState *tstate = PyThreadState_GET();
+    tmp_type = tstate->exc_type;
+    tmp_value = tstate->exc_value;
+    tmp_tb = tstate->exc_traceback;
+    tstate->exc_type = type;
+    tstate->exc_value = value;
+    tstate->exc_traceback = tb;
+    Py_XDECREF(tmp_type);
+    Py_XDECREF(tmp_value);
+    Py_XDECREF(tmp_tb);
+#else
+    PyErr_SetExcInfo(type, value, tb);
+#endif
+}
+
+static CYTHON_INLINE unsigned char __Pyx_PyInt_AsUnsignedChar(PyObject* x) {
+    const unsigned char neg_one = (unsigned char)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(unsigned char) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(unsigned char)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to unsigned char" :
+                    "value too large to convert to unsigned char");
+            }
+            return (unsigned char)-1;
+        }
+        return (unsigned char)val;
+    }
+    return (unsigned char)__Pyx_PyInt_AsUnsignedLong(x);
+}
+
+static CYTHON_INLINE unsigned short __Pyx_PyInt_AsUnsignedShort(PyObject* x) {
+    const unsigned short neg_one = (unsigned short)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(unsigned short) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(unsigned short)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to unsigned short" :
+                    "value too large to convert to unsigned short");
+            }
+            return (unsigned short)-1;
+        }
+        return (unsigned short)val;
+    }
+    return (unsigned short)__Pyx_PyInt_AsUnsignedLong(x);
+}
+
+static CYTHON_INLINE unsigned int __Pyx_PyInt_AsUnsignedInt(PyObject* x) {
+    const unsigned int neg_one = (unsigned int)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(unsigned int) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(unsigned int)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to unsigned int" :
+                    "value too large to convert to unsigned int");
+            }
+            return (unsigned int)-1;
+        }
+        return (unsigned int)val;
+    }
+    return (unsigned int)__Pyx_PyInt_AsUnsignedLong(x);
+}
+
+static CYTHON_INLINE char __Pyx_PyInt_AsChar(PyObject* x) {
+    const char neg_one = (char)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(char) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(char)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to char" :
+                    "value too large to convert to char");
+            }
+            return (char)-1;
+        }
+        return (char)val;
+    }
+    return (char)__Pyx_PyInt_AsLong(x);
+}
+
+static CYTHON_INLINE short __Pyx_PyInt_AsShort(PyObject* x) {
+    const short neg_one = (short)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(short) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(short)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to short" :
+                    "value too large to convert to short");
+            }
+            return (short)-1;
+        }
+        return (short)val;
+    }
+    return (short)__Pyx_PyInt_AsLong(x);
+}
+
+static CYTHON_INLINE int __Pyx_PyInt_AsInt(PyObject* x) {
+    const int neg_one = (int)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(int) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(int)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to int" :
+                    "value too large to convert to int");
+            }
+            return (int)-1;
+        }
+        return (int)val;
+    }
+    return (int)__Pyx_PyInt_AsLong(x);
+}
+
+static CYTHON_INLINE signed char __Pyx_PyInt_AsSignedChar(PyObject* x) {
+    const signed char neg_one = (signed char)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(signed char) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(signed char)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to signed char" :
+                    "value too large to convert to signed char");
+            }
+            return (signed char)-1;
+        }
+        return (signed char)val;
+    }
+    return (signed char)__Pyx_PyInt_AsSignedLong(x);
+}
+
+static CYTHON_INLINE signed short __Pyx_PyInt_AsSignedShort(PyObject* x) {
+    const signed short neg_one = (signed short)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(signed short) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(signed short)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to signed short" :
+                    "value too large to convert to signed short");
+            }
+            return (signed short)-1;
+        }
+        return (signed short)val;
+    }
+    return (signed short)__Pyx_PyInt_AsSignedLong(x);
+}
+
+static CYTHON_INLINE signed int __Pyx_PyInt_AsSignedInt(PyObject* x) {
+    const signed int neg_one = (signed int)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(signed int) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(signed int)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to signed int" :
+                    "value too large to convert to signed int");
+            }
+            return (signed int)-1;
+        }
+        return (signed int)val;
+    }
+    return (signed int)__Pyx_PyInt_AsSignedLong(x);
+}
+
+static CYTHON_INLINE int __Pyx_PyInt_AsLongDouble(PyObject* x) {
+    const int neg_one = (int)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(int) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(int)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to int" :
+                    "value too large to convert to int");
+            }
+            return (int)-1;
+        }
+        return (int)val;
+    }
+    return (int)__Pyx_PyInt_AsLong(x);
+}
+
+static CYTHON_INLINE unsigned long __Pyx_PyInt_AsUnsignedLong(PyObject* x) {
+    const unsigned long neg_one = (unsigned long)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to unsigned long");
+            return (unsigned long)-1;
+        }
+        return (unsigned long)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to unsigned long");
+                return (unsigned long)-1;
+            }
+            return (unsigned long)PyLong_AsUnsignedLong(x);
+        } else {
+            return (unsigned long)PyLong_AsLong(x);
+        }
+    } else {
+        unsigned long val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (unsigned long)-1;
+        val = __Pyx_PyInt_AsUnsignedLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE unsigned PY_LONG_LONG __Pyx_PyInt_AsUnsignedLongLong(PyObject* x) {
+    const unsigned PY_LONG_LONG neg_one = (unsigned PY_LONG_LONG)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to unsigned PY_LONG_LONG");
+            return (unsigned PY_LONG_LONG)-1;
+        }
+        return (unsigned PY_LONG_LONG)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to unsigned PY_LONG_LONG");
+                return (unsigned PY_LONG_LONG)-1;
+            }
+            return (unsigned PY_LONG_LONG)PyLong_AsUnsignedLongLong(x);
+        } else {
+            return (unsigned PY_LONG_LONG)PyLong_AsLongLong(x);
+        }
+    } else {
+        unsigned PY_LONG_LONG val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (unsigned PY_LONG_LONG)-1;
+        val = __Pyx_PyInt_AsUnsignedLongLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE long __Pyx_PyInt_AsLong(PyObject* x) {
+    const long neg_one = (long)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to long");
+            return (long)-1;
+        }
+        return (long)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to long");
+                return (long)-1;
+            }
+            return (long)PyLong_AsUnsignedLong(x);
+        } else {
+            return (long)PyLong_AsLong(x);
+        }
+    } else {
+        long val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (long)-1;
+        val = __Pyx_PyInt_AsLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE PY_LONG_LONG __Pyx_PyInt_AsLongLong(PyObject* x) {
+    const PY_LONG_LONG neg_one = (PY_LONG_LONG)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to PY_LONG_LONG");
+            return (PY_LONG_LONG)-1;
+        }
+        return (PY_LONG_LONG)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to PY_LONG_LONG");
+                return (PY_LONG_LONG)-1;
+            }
+            return (PY_LONG_LONG)PyLong_AsUnsignedLongLong(x);
+        } else {
+            return (PY_LONG_LONG)PyLong_AsLongLong(x);
+        }
+    } else {
+        PY_LONG_LONG val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (PY_LONG_LONG)-1;
+        val = __Pyx_PyInt_AsLongLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE signed long __Pyx_PyInt_AsSignedLong(PyObject* x) {
+    const signed long neg_one = (signed long)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to signed long");
+            return (signed long)-1;
+        }
+        return (signed long)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to signed long");
+                return (signed long)-1;
+            }
+            return (signed long)PyLong_AsUnsignedLong(x);
+        } else {
+            return (signed long)PyLong_AsLong(x);
+        }
+    } else {
+        signed long val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (signed long)-1;
+        val = __Pyx_PyInt_AsSignedLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE signed PY_LONG_LONG __Pyx_PyInt_AsSignedLongLong(PyObject* x) {
+    const signed PY_LONG_LONG neg_one = (signed PY_LONG_LONG)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to signed PY_LONG_LONG");
+            return (signed PY_LONG_LONG)-1;
+        }
+        return (signed PY_LONG_LONG)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to signed PY_LONG_LONG");
+                return (signed PY_LONG_LONG)-1;
+            }
+            return (signed PY_LONG_LONG)PyLong_AsUnsignedLongLong(x);
+        } else {
+            return (signed PY_LONG_LONG)PyLong_AsLongLong(x);
+        }
+    } else {
+        signed PY_LONG_LONG val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (signed PY_LONG_LONG)-1;
+        val = __Pyx_PyInt_AsSignedLongLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static int __Pyx_check_binary_version(void) {
+    char ctversion[4], rtversion[4];
+    PyOS_snprintf(ctversion, 4, "%d.%d", PY_MAJOR_VERSION, PY_MINOR_VERSION);
+    PyOS_snprintf(rtversion, 4, "%s", Py_GetVersion());
+    if (ctversion[0] != rtversion[0] || ctversion[2] != rtversion[2]) {
+        char message[200];
+        PyOS_snprintf(message, sizeof(message),
+                      "compiletime version %s of module '%.100s' "
+                      "does not match runtime version %s",
+                      ctversion, __Pyx_MODULE_NAME, rtversion);
+        #if PY_VERSION_HEX < 0x02050000
+        return PyErr_Warn(NULL, message);
+        #else
+        return PyErr_WarnEx(NULL, message, 1);
+        #endif
+    }
+    return 0;
+}
+
+static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) {
+    int start = 0, mid = 0, end = count - 1;
+    if (end >= 0 && code_line > entries[end].code_line) {
+        return count;
+    }
+    while (start < end) {
+        mid = (start + end) / 2;
+        if (code_line < entries[mid].code_line) {
+            end = mid;
+        } else if (code_line > entries[mid].code_line) {
+             start = mid + 1;
+        } else {
+            return mid;
+        }
+    }
+    if (code_line <= entries[mid].code_line) {
+        return mid;
+    } else {
+        return mid + 1;
+    }
+}
+static PyCodeObject *__pyx_find_code_object(int code_line) {
+    PyCodeObject* code_object;
+    int pos;
+    if (unlikely(!code_line) || unlikely(!__pyx_code_cache.entries)) {
+        return NULL;
+    }
+    pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line);
+    if (unlikely(pos >= __pyx_code_cache.count) || unlikely(__pyx_code_cache.entries[pos].code_line != code_line)) {
+        return NULL;
+    }
+    code_object = __pyx_code_cache.entries[pos].code_object;
+    Py_INCREF(code_object);
+    return code_object;
+}
+static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) {
+    int pos, i;
+    __Pyx_CodeObjectCacheEntry* entries = __pyx_code_cache.entries;
+    if (unlikely(!code_line)) {
+        return;
+    }
+    if (unlikely(!entries)) {
+        entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Malloc(64*sizeof(__Pyx_CodeObjectCacheEntry));
+        if (likely(entries)) {
+            __pyx_code_cache.entries = entries;
+            __pyx_code_cache.max_count = 64;
+            __pyx_code_cache.count = 1;
+            entries[0].code_line = code_line;
+            entries[0].code_object = code_object;
+            Py_INCREF(code_object);
+        }
+        return;
+    }
+    pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line);
+    if ((pos < __pyx_code_cache.count) && unlikely(__pyx_code_cache.entries[pos].code_line == code_line)) {
+        PyCodeObject* tmp = entries[pos].code_object;
+        entries[pos].code_object = code_object;
+        Py_DECREF(tmp);
+        return;
+    }
+    if (__pyx_code_cache.count == __pyx_code_cache.max_count) {
+        int new_max = __pyx_code_cache.max_count + 64;
+        entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Realloc(
+            __pyx_code_cache.entries, new_max*sizeof(__Pyx_CodeObjectCacheEntry));
+        if (unlikely(!entries)) {
+            return;
+        }
+        __pyx_code_cache.entries = entries;
+        __pyx_code_cache.max_count = new_max;
+    }
+    for (i=__pyx_code_cache.count; i>pos; i--) {
+        entries[i] = entries[i-1];
+    }
+    entries[pos].code_line = code_line;
+    entries[pos].code_object = code_object;
+    __pyx_code_cache.count++;
+    Py_INCREF(code_object);
+}
+
+#include "compile.h"
+#include "frameobject.h"
+#include "traceback.h"
+static PyCodeObject* __Pyx_CreateCodeObjectForTraceback(
+            const char *funcname, int c_line,
+            int py_line, const char *filename) {
+    PyCodeObject *py_code = 0;
+    PyObject *py_srcfile = 0;
+    PyObject *py_funcname = 0;
+    #if PY_MAJOR_VERSION < 3
+    py_srcfile = PyString_FromString(filename);
+    #else
+    py_srcfile = PyUnicode_FromString(filename);
+    #endif
+    if (!py_srcfile) goto bad;
+    if (c_line) {
+        #if PY_MAJOR_VERSION < 3
+        py_funcname = PyString_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line);
+        #else
+        py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line);
+        #endif
+    }
+    else {
+        #if PY_MAJOR_VERSION < 3
+        py_funcname = PyString_FromString(funcname);
+        #else
+        py_funcname = PyUnicode_FromString(funcname);
+        #endif
+    }
+    if (!py_funcname) goto bad;
+    py_code = __Pyx_PyCode_New(
+        0,            /*int argcount,*/
+        0,            /*int kwonlyargcount,*/
+        0,            /*int nlocals,*/
+        0,            /*int stacksize,*/
+        0,            /*int flags,*/
+        __pyx_empty_bytes, /*PyObject *code,*/
+        __pyx_empty_tuple, /*PyObject *consts,*/
+        __pyx_empty_tuple, /*PyObject *names,*/
+        __pyx_empty_tuple, /*PyObject *varnames,*/
+        __pyx_empty_tuple, /*PyObject *freevars,*/
+        __pyx_empty_tuple, /*PyObject *cellvars,*/
+        py_srcfile,   /*PyObject *filename,*/
+        py_funcname,  /*PyObject *name,*/
+        py_line,      /*int firstlineno,*/
+        __pyx_empty_bytes  /*PyObject *lnotab*/
+    );
+    Py_DECREF(py_srcfile);
+    Py_DECREF(py_funcname);
+    return py_code;
+bad:
+    Py_XDECREF(py_srcfile);
+    Py_XDECREF(py_funcname);
+    return NULL;
+}
+static void __Pyx_AddTraceback(const char *funcname, int c_line,
+                               int py_line, const char *filename) {
+    PyCodeObject *py_code = 0;
+    PyObject *py_globals = 0;
+    PyFrameObject *py_frame = 0;
+    py_code = __pyx_find_code_object(c_line ? c_line : py_line);
+    if (!py_code) {
+        py_code = __Pyx_CreateCodeObjectForTraceback(
+            funcname, c_line, py_line, filename);
+        if (!py_code) goto bad;
+        __pyx_insert_code_object(c_line ? c_line : py_line, py_code);
+    }
+    py_globals = PyModule_GetDict(__pyx_m);
+    if (!py_globals) goto bad;
+    py_frame = PyFrame_New(
+        PyThreadState_GET(), /*PyThreadState *tstate,*/
+        py_code,             /*PyCodeObject *code,*/
+        py_globals,          /*PyObject *globals,*/
+        0                    /*PyObject *locals*/
+    );
+    if (!py_frame) goto bad;
+    py_frame->f_lineno = py_line;
+    PyTraceBack_Here(py_frame);
+bad:
+    Py_XDECREF(py_code);
+    Py_XDECREF(py_frame);
+}
+
+static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
+    while (t->p) {
+        #if PY_MAJOR_VERSION < 3
+        if (t->is_unicode) {
+            *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
+        } else if (t->intern) {
+            *t->p = PyString_InternFromString(t->s);
+        } else {
+            *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
+        }
+        #else  /* Python 3+ has unicode identifiers */
+        if (t->is_unicode | t->is_str) {
+            if (t->intern) {
+                *t->p = PyUnicode_InternFromString(t->s);
+            } else if (t->encoding) {
+                *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL);
+            } else {
+                *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
+            }
+        } else {
+            *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
+        }
+        #endif
+        if (!*t->p)
+            return -1;
+        ++t;
+    }
+    return 0;
+}
+
+static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) {
+   int is_true = x == Py_True;
+   if (is_true | (x == Py_False) | (x == Py_None)) return is_true;
+   else return PyObject_IsTrue(x);
+}
+static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x) {
+  PyNumberMethods *m;
+  const char *name = NULL;
+  PyObject *res = NULL;
+#if PY_VERSION_HEX < 0x03000000
+  if (PyInt_Check(x) || PyLong_Check(x))
+#else
+  if (PyLong_Check(x))
+#endif
+    return Py_INCREF(x), x;
+  m = Py_TYPE(x)->tp_as_number;
+#if PY_VERSION_HEX < 0x03000000
+  if (m && m->nb_int) {
+    name = "int";
+    res = PyNumber_Int(x);
+  }
+  else if (m && m->nb_long) {
+    name = "long";
+    res = PyNumber_Long(x);
+  }
+#else
+  if (m && m->nb_int) {
+    name = "int";
+    res = PyNumber_Long(x);
+  }
+#endif
+  if (res) {
+#if PY_VERSION_HEX < 0x03000000
+    if (!PyInt_Check(res) && !PyLong_Check(res)) {
+#else
+    if (!PyLong_Check(res)) {
+#endif
+      PyErr_Format(PyExc_TypeError,
+                   "__%s__ returned non-%s (type %.200s)",
+                   name, name, Py_TYPE(res)->tp_name);
+      Py_DECREF(res);
+      return NULL;
+    }
+  }
+  else if (!PyErr_Occurred()) {
+    PyErr_SetString(PyExc_TypeError,
+                    "an integer is required");
+  }
+  return res;
+}
+static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) {
+  Py_ssize_t ival;
+  PyObject* x = PyNumber_Index(b);
+  if (!x) return -1;
+  ival = PyInt_AsSsize_t(x);
+  Py_DECREF(x);
+  return ival;
+}
+static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) {
+#if PY_VERSION_HEX < 0x02050000
+   if (ival <= LONG_MAX)
+       return PyInt_FromLong((long)ival);
+   else {
+       unsigned char *bytes = (unsigned char *) &ival;
+       int one = 1; int little = (int)*(unsigned char*)&one;
+       return _PyLong_FromByteArray(bytes, sizeof(size_t), little, 0);
+   }
+#else
+   return PyInt_FromSize_t(ival);
+#endif
+}
+static CYTHON_INLINE size_t __Pyx_PyInt_AsSize_t(PyObject* x) {
+   unsigned PY_LONG_LONG val = __Pyx_PyInt_AsUnsignedLongLong(x);
+   if (unlikely(val == (unsigned PY_LONG_LONG)-1 && PyErr_Occurred())) {
+       return (size_t)-1;
+   } else if (unlikely(val != (unsigned PY_LONG_LONG)(size_t)val)) {
+       PyErr_SetString(PyExc_OverflowError,
+                       "value too large to convert to size_t");
+       return (size_t)-1;
+   }
+   return (size_t)val;
+}
+
+
+#endif /* Py_PYTHON_H */
diff --git a/lib/bx/arrays/wiggle.pxd b/lib/bx/arrays/wiggle.pxd
new file mode 100644
index 0000000..067d85b
--- /dev/null
+++ b/lib/bx/arrays/wiggle.pxd
@@ -0,0 +1,13 @@
+cdef enum linemode:
+    MODE_BED
+    MODE_FIXED
+    MODE_VARIABLE
+
+cdef class WiggleReader:
+    cdef object file
+    cdef object current_chrom
+    cdef long current_pos
+    cdef long current_step
+    cdef long current_span
+    cdef linemode mode
+  
\ No newline at end of file
diff --git a/lib/bx/arrays/wiggle.pyx b/lib/bx/arrays/wiggle.pyx
new file mode 100644
index 0000000..425daa4
--- /dev/null
+++ b/lib/bx/arrays/wiggle.pyx
@@ -0,0 +1,98 @@
+"""
+Support for scores in the `wiggle`_ file format used by the UCSC Genome 
+Browser.
+
+The positions in the wiggle format are 1-relative, however,
+the positions returned match the BED/interval format which is zero-based, half-open.
+
+.. _wiggle: http://genome.ucsc.edu/goldenPath/help/wiggle.html
+"""
+
+def parse_header( line ):
+    return dict( [ field.split( '=' ) for field in line.split()[1:] ] )
+
+cdef class WiggleReader:
+    """
+    Iterator yielding chrom, start, end, strand, value.
+    Values are zero-based, half-open.
+    Regions which lack a score are ignored.
+    """
+    #cdef object file
+    #cdef object current_chrom
+    #cdef long current_pos
+    #cdef long current_step
+    #cdef long current_span
+    #cdef linemode mode
+    def __init__( self, file ):
+        self.file = file
+        self.current_chrom = None
+        self.current_pos = -1
+        self.current_step = -1
+        self.current_span = -1
+        self.mode = MODE_BED
+
+    def __iter__( self ):
+        return self
+
+    def __next__( self ):
+        while True:
+            line = self.file.readline()
+            if not line:
+                raise StopIteration()
+            if line.isspace():
+                continue    
+            if line[0] == "#":
+                continue
+            if line[0].isalpha():
+                if line.startswith( "track" ) or line.startswith( "browser" ):
+                    continue
+                elif line.startswith( "variableStep" ):
+                    header = parse_header( line )
+                    self.current_chrom = header['chrom']
+                    self.current_pos = -1
+                    self.current_step = -1
+                    if 'span' in header:
+                        self.current_span = int( header['span'] )
+                    else:
+                        self.current_span = 1
+                    self.mode = MODE_VARIABLE
+                    continue
+                elif line.startswith( "fixedStep" ):
+                    header = parse_header( line )
+                    self.current_chrom = header['chrom']
+                    self.current_pos = int( header['start'] ) - 1
+                    self.current_step = int( header['step'] )
+                    if 'span' in header:
+                        self.current_span = int( header['span'] )
+                    else:
+                        self.current_span = 1
+                    self.mode = MODE_FIXED
+                    continue
+            elif self.mode == MODE_BED:
+                fields = line.split()
+                if len( fields ) > 3:
+                    if len( fields ) > 5:
+                        return fields[0], int( fields[1] ), int( fields[2] ), fields[5], float( fields[3] )
+                    else:
+                        return fields[0], int( fields[1] ), int( fields[2] ), "+", float( fields[3] )
+            elif self.mode == MODE_VARIABLE: 
+                fields = line.split()
+                try:
+                    pos = int( fields[0] ) - 1
+                    val = float( fields[1] )
+                except ValueError:
+                    continue
+                return self.current_chrom, pos, pos + self.current_span, "+", val
+            elif self.mode == MODE_FIXED:
+                fields = line.split()
+                try:
+                    val = float( fields[0] )
+                except ValueError:
+                    continue
+                return self.current_chrom, self.current_pos, self.current_pos + self.current_span, "+", val
+                # FIXME: unreachable! need to test this and fix!
+                self.current_pos += self.current_step
+            else:
+                raise "Unexpected input line: %s" % line.strip()
+
+
diff --git a/lib/bx/bbi/__init__.py b/lib/bx/bbi/__init__.py
new file mode 100644
index 0000000..ef7f873
--- /dev/null
+++ b/lib/bx/bbi/__init__.py
@@ -0,0 +1,3 @@
+"""
+Support for the UCSC "Big Binary Indexed" file formats (bigWig and bigBed)
+"""
diff --git a/lib/bx/bbi/bbi_file.c b/lib/bx/bbi/bbi_file.c
new file mode 100644
index 0000000..7fefe6a
--- /dev/null
+++ b/lib/bx/bbi/bbi_file.c
@@ -0,0 +1,15626 @@
+/* Generated by Cython 0.22 */
+
+#define PY_SSIZE_T_CLEAN
+#ifndef CYTHON_USE_PYLONG_INTERNALS
+#ifdef PYLONG_BITS_IN_DIGIT
+#define CYTHON_USE_PYLONG_INTERNALS 0
+#else
+#include "pyconfig.h"
+#ifdef PYLONG_BITS_IN_DIGIT
+#define CYTHON_USE_PYLONG_INTERNALS 1
+#else
+#define CYTHON_USE_PYLONG_INTERNALS 0
+#endif
+#endif
+#endif
+#include "Python.h"
+#ifndef Py_PYTHON_H
+    #error Python headers needed to compile C extensions, please install development version of Python.
+#elif PY_VERSION_HEX < 0x02060000 || (0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03020000)
+    #error Cython requires Python 2.6+ or Python 3.2+.
+#else
+#define CYTHON_ABI "0_22"
+#include <stddef.h>
+#ifndef offsetof
+#define offsetof(type, member) ( (size_t) & ((type*)0) -> member )
+#endif
+#if !defined(WIN32) && !defined(MS_WINDOWS)
+  #ifndef __stdcall
+    #define __stdcall
+  #endif
+  #ifndef __cdecl
+    #define __cdecl
+  #endif
+  #ifndef __fastcall
+    #define __fastcall
+  #endif
+#endif
+#ifndef DL_IMPORT
+  #define DL_IMPORT(t) t
+#endif
+#ifndef DL_EXPORT
+  #define DL_EXPORT(t) t
+#endif
+#ifndef PY_LONG_LONG
+  #define PY_LONG_LONG LONG_LONG
+#endif
+#ifndef Py_HUGE_VAL
+  #define Py_HUGE_VAL HUGE_VAL
+#endif
+#ifdef PYPY_VERSION
+#define CYTHON_COMPILING_IN_PYPY 1
+#define CYTHON_COMPILING_IN_CPYTHON 0
+#else
+#define CYTHON_COMPILING_IN_PYPY 0
+#define CYTHON_COMPILING_IN_CPYTHON 1
+#endif
+#if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX < 0x02070600 && !defined(Py_OptimizeFlag)
+#define Py_OptimizeFlag 0
+#endif
+#define __PYX_BUILD_PY_SSIZE_T "n"
+#define CYTHON_FORMAT_SSIZE_T "z"
+#if PY_MAJOR_VERSION < 3
+  #define __Pyx_BUILTIN_MODULE_NAME "__builtin__"
+  #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \
+          PyCode_New(a+k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
+  #define __Pyx_DefaultClassType PyClass_Type
+#else
+  #define __Pyx_BUILTIN_MODULE_NAME "builtins"
+  #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \
+          PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
+  #define __Pyx_DefaultClassType PyType_Type
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define Py_TPFLAGS_CHECKTYPES 0
+  #define Py_TPFLAGS_HAVE_INDEX 0
+  #define Py_TPFLAGS_HAVE_NEWBUFFER 0
+#endif
+#if PY_VERSION_HEX < 0x030400a1 && !defined(Py_TPFLAGS_HAVE_FINALIZE)
+  #define Py_TPFLAGS_HAVE_FINALIZE 0
+#endif
+#if PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND)
+  #define CYTHON_PEP393_ENABLED 1
+  #define __Pyx_PyUnicode_READY(op)       (likely(PyUnicode_IS_READY(op)) ? \
+                                              0 : _PyUnicode_Ready((PyObject *)(op)))
+  #define __Pyx_PyUnicode_GET_LENGTH(u)   PyUnicode_GET_LENGTH(u)
+  #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_READ_CHAR(u, i)
+  #define __Pyx_PyUnicode_KIND(u)         PyUnicode_KIND(u)
+  #define __Pyx_PyUnicode_DATA(u)         PyUnicode_DATA(u)
+  #define __Pyx_PyUnicode_READ(k, d, i)   PyUnicode_READ(k, d, i)
+#else
+  #define CYTHON_PEP393_ENABLED 0
+  #define __Pyx_PyUnicode_READY(op)       (0)
+  #define __Pyx_PyUnicode_GET_LENGTH(u)   PyUnicode_GET_SIZE(u)
+  #define __Pyx_PyUnicode_READ_CHAR(u, i) ((Py_UCS4)(PyUnicode_AS_UNICODE(u)[i]))
+  #define __Pyx_PyUnicode_KIND(u)         (sizeof(Py_UNICODE))
+  #define __Pyx_PyUnicode_DATA(u)         ((void*)PyUnicode_AS_UNICODE(u))
+  #define __Pyx_PyUnicode_READ(k, d, i)   ((void)(k), (Py_UCS4)(((Py_UNICODE*)d)[i]))
+#endif
+#if CYTHON_COMPILING_IN_PYPY
+  #define __Pyx_PyUnicode_Concat(a, b)      PyNumber_Add(a, b)
+  #define __Pyx_PyUnicode_ConcatSafe(a, b)  PyNumber_Add(a, b)
+  #define __Pyx_PyFrozenSet_Size(s)         PyObject_Size(s)
+#else
+  #define __Pyx_PyUnicode_Concat(a, b)      PyUnicode_Concat(a, b)
+  #define __Pyx_PyUnicode_ConcatSafe(a, b)  ((unlikely((a) == Py_None) || unlikely((b) == Py_None)) ? \
+      PyNumber_Add(a, b) : __Pyx_PyUnicode_Concat(a, b))
+  #define __Pyx_PyFrozenSet_Size(s)         PySet_Size(s)
+#endif
+#define __Pyx_PyString_FormatSafe(a, b)   ((unlikely((a) == Py_None)) ? PyNumber_Remainder(a, b) : __Pyx_PyString_Format(a, b))
+#define __Pyx_PyUnicode_FormatSafe(a, b)  ((unlikely((a) == Py_None)) ? PyNumber_Remainder(a, b) : PyUnicode_Format(a, b))
+#if PY_MAJOR_VERSION >= 3
+  #define __Pyx_PyString_Format(a, b)  PyUnicode_Format(a, b)
+#else
+  #define __Pyx_PyString_Format(a, b)  PyString_Format(a, b)
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define PyBaseString_Type            PyUnicode_Type
+  #define PyStringObject               PyUnicodeObject
+  #define PyString_Type                PyUnicode_Type
+  #define PyString_Check               PyUnicode_Check
+  #define PyString_CheckExact          PyUnicode_CheckExact
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define __Pyx_PyBaseString_Check(obj) PyUnicode_Check(obj)
+  #define __Pyx_PyBaseString_CheckExact(obj) PyUnicode_CheckExact(obj)
+#else
+  #define __Pyx_PyBaseString_Check(obj) (PyString_Check(obj) || PyUnicode_Check(obj))
+  #define __Pyx_PyBaseString_CheckExact(obj) (PyString_CheckExact(obj) || PyUnicode_CheckExact(obj))
+#endif
+#ifndef PySet_CheckExact
+  #define PySet_CheckExact(obj)        (Py_TYPE(obj) == &PySet_Type)
+#endif
+#define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type)
+#if PY_MAJOR_VERSION >= 3
+  #define PyIntObject                  PyLongObject
+  #define PyInt_Type                   PyLong_Type
+  #define PyInt_Check(op)              PyLong_Check(op)
+  #define PyInt_CheckExact(op)         PyLong_CheckExact(op)
+  #define PyInt_FromString             PyLong_FromString
+  #define PyInt_FromUnicode            PyLong_FromUnicode
+  #define PyInt_FromLong               PyLong_FromLong
+  #define PyInt_FromSize_t             PyLong_FromSize_t
+  #define PyInt_FromSsize_t            PyLong_FromSsize_t
+  #define PyInt_AsLong                 PyLong_AsLong
+  #define PyInt_AS_LONG                PyLong_AS_LONG
+  #define PyInt_AsSsize_t              PyLong_AsSsize_t
+  #define PyInt_AsUnsignedLongMask     PyLong_AsUnsignedLongMask
+  #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask
+  #define PyNumber_Int                 PyNumber_Long
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define PyBoolObject                 PyLongObject
+#endif
+#if PY_MAJOR_VERSION >= 3 && CYTHON_COMPILING_IN_PYPY
+  #ifndef PyUnicode_InternFromString
+    #define PyUnicode_InternFromString(s) PyUnicode_FromString(s)
+  #endif
+#endif
+#if PY_VERSION_HEX < 0x030200A4
+  typedef long Py_hash_t;
+  #define __Pyx_PyInt_FromHash_t PyInt_FromLong
+  #define __Pyx_PyInt_AsHash_t   PyInt_AsLong
+#else
+  #define __Pyx_PyInt_FromHash_t PyInt_FromSsize_t
+  #define __Pyx_PyInt_AsHash_t   PyInt_AsSsize_t
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define __Pyx_PyMethod_New(func, self, klass) ((self) ? PyMethod_New(func, self) : PyInstanceMethod_New(func))
+#else
+  #define __Pyx_PyMethod_New(func, self, klass) PyMethod_New(func, self, klass)
+#endif
+#ifndef CYTHON_INLINE
+  #if defined(__GNUC__)
+    #define CYTHON_INLINE __inline__
+  #elif defined(_MSC_VER)
+    #define CYTHON_INLINE __inline
+  #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+    #define CYTHON_INLINE inline
+  #else
+    #define CYTHON_INLINE
+  #endif
+#endif
+#ifndef CYTHON_RESTRICT
+  #if defined(__GNUC__)
+    #define CYTHON_RESTRICT __restrict__
+  #elif defined(_MSC_VER) && _MSC_VER >= 1400
+    #define CYTHON_RESTRICT __restrict
+  #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+    #define CYTHON_RESTRICT restrict
+  #else
+    #define CYTHON_RESTRICT
+  #endif
+#endif
+#ifdef NAN
+#define __PYX_NAN() ((float) NAN)
+#else
+static CYTHON_INLINE float __PYX_NAN() {
+  /* Initialize NaN. The sign is irrelevant, an exponent with all bits 1 and
+   a nonzero mantissa means NaN. If the first bit in the mantissa is 1, it is
+   a quiet NaN. */
+  float value;
+  memset(&value, 0xFF, sizeof(value));
+  return value;
+}
+#endif
+#define __Pyx_void_to_None(void_result) (void_result, Py_INCREF(Py_None), Py_None)
+#ifdef __cplusplus
+template<typename T>
+void __Pyx_call_destructor(T* x) {
+    x->~T();
+}
+template<typename T>
+class __Pyx_FakeReference {
+  public:
+    __Pyx_FakeReference() : ptr(NULL) { }
+    __Pyx_FakeReference(T& ref) : ptr(&ref) { }
+    T *operator->() { return ptr; }
+    operator T&() { return *ptr; }
+  private:
+    T *ptr;
+};
+#endif
+
+
+#if PY_MAJOR_VERSION >= 3
+  #define __Pyx_PyNumber_Divide(x,y)         PyNumber_TrueDivide(x,y)
+  #define __Pyx_PyNumber_InPlaceDivide(x,y)  PyNumber_InPlaceTrueDivide(x,y)
+#else
+  #define __Pyx_PyNumber_Divide(x,y)         PyNumber_Divide(x,y)
+  #define __Pyx_PyNumber_InPlaceDivide(x,y)  PyNumber_InPlaceDivide(x,y)
+#endif
+
+#ifndef __PYX_EXTERN_C
+  #ifdef __cplusplus
+    #define __PYX_EXTERN_C extern "C"
+  #else
+    #define __PYX_EXTERN_C extern
+  #endif
+#endif
+
+#if defined(WIN32) || defined(MS_WINDOWS)
+#define _USE_MATH_DEFINES
+#endif
+#include <math.h>
+#define __PYX_HAVE__bx__bbi__bbi_file
+#define __PYX_HAVE_API__bx__bbi__bbi_file
+#include "string.h"
+#include "stdio.h"
+#include "stdlib.h"
+#include "numpy/arrayobject.h"
+#include "numpy/ufuncobject.h"
+#include "limits.h"
+#ifdef _OPENMP
+#include <omp.h>
+#endif /* _OPENMP */
+
+#ifdef PYREX_WITHOUT_ASSERTIONS
+#define CYTHON_WITHOUT_ASSERTIONS
+#endif
+
+#ifndef CYTHON_UNUSED
+# if defined(__GNUC__)
+#   if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
+#     define CYTHON_UNUSED __attribute__ ((__unused__))
+#   else
+#     define CYTHON_UNUSED
+#   endif
+# elif defined(__ICC) || (defined(__INTEL_COMPILER) && !defined(_MSC_VER))
+#   define CYTHON_UNUSED __attribute__ ((__unused__))
+# else
+#   define CYTHON_UNUSED
+# endif
+#endif
+typedef struct {PyObject **p; char *s; const Py_ssize_t n; const char* encoding;
+                const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry;
+
+#define __PYX_DEFAULT_STRING_ENCODING_IS_ASCII 0
+#define __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT 0
+#define __PYX_DEFAULT_STRING_ENCODING ""
+#define __Pyx_PyObject_FromString __Pyx_PyBytes_FromString
+#define __Pyx_PyObject_FromStringAndSize __Pyx_PyBytes_FromStringAndSize
+#define __Pyx_fits_Py_ssize_t(v, type, is_signed)  (    \
+    (sizeof(type) < sizeof(Py_ssize_t))  ||             \
+    (sizeof(type) > sizeof(Py_ssize_t) &&               \
+          likely(v < (type)PY_SSIZE_T_MAX ||            \
+                 v == (type)PY_SSIZE_T_MAX)  &&         \
+          (!is_signed || likely(v > (type)PY_SSIZE_T_MIN ||       \
+                                v == (type)PY_SSIZE_T_MIN)))  ||  \
+    (sizeof(type) == sizeof(Py_ssize_t) &&              \
+          (is_signed || likely(v < (type)PY_SSIZE_T_MAX ||        \
+                               v == (type)PY_SSIZE_T_MAX)))  )
+static CYTHON_INLINE char* __Pyx_PyObject_AsString(PyObject*);
+static CYTHON_INLINE char* __Pyx_PyObject_AsStringAndSize(PyObject*, Py_ssize_t* length);
+#define __Pyx_PyByteArray_FromString(s) PyByteArray_FromStringAndSize((const char*)s, strlen((const char*)s))
+#define __Pyx_PyByteArray_FromStringAndSize(s, l) PyByteArray_FromStringAndSize((const char*)s, l)
+#define __Pyx_PyBytes_FromString        PyBytes_FromString
+#define __Pyx_PyBytes_FromStringAndSize PyBytes_FromStringAndSize
+static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char*);
+#if PY_MAJOR_VERSION < 3
+    #define __Pyx_PyStr_FromString        __Pyx_PyBytes_FromString
+    #define __Pyx_PyStr_FromStringAndSize __Pyx_PyBytes_FromStringAndSize
+#else
+    #define __Pyx_PyStr_FromString        __Pyx_PyUnicode_FromString
+    #define __Pyx_PyStr_FromStringAndSize __Pyx_PyUnicode_FromStringAndSize
+#endif
+#define __Pyx_PyObject_AsSString(s)    ((signed char*) __Pyx_PyObject_AsString(s))
+#define __Pyx_PyObject_AsUString(s)    ((unsigned char*) __Pyx_PyObject_AsString(s))
+#define __Pyx_PyObject_FromCString(s)  __Pyx_PyObject_FromString((const char*)s)
+#define __Pyx_PyBytes_FromCString(s)   __Pyx_PyBytes_FromString((const char*)s)
+#define __Pyx_PyByteArray_FromCString(s)   __Pyx_PyByteArray_FromString((const char*)s)
+#define __Pyx_PyStr_FromCString(s)     __Pyx_PyStr_FromString((const char*)s)
+#define __Pyx_PyUnicode_FromCString(s) __Pyx_PyUnicode_FromString((const char*)s)
+#if PY_MAJOR_VERSION < 3
+static CYTHON_INLINE size_t __Pyx_Py_UNICODE_strlen(const Py_UNICODE *u)
+{
+    const Py_UNICODE *u_end = u;
+    while (*u_end++) ;
+    return (size_t)(u_end - u - 1);
+}
+#else
+#define __Pyx_Py_UNICODE_strlen Py_UNICODE_strlen
+#endif
+#define __Pyx_PyUnicode_FromUnicode(u)       PyUnicode_FromUnicode(u, __Pyx_Py_UNICODE_strlen(u))
+#define __Pyx_PyUnicode_FromUnicodeAndLength PyUnicode_FromUnicode
+#define __Pyx_PyUnicode_AsUnicode            PyUnicode_AsUnicode
+#define __Pyx_Owned_Py_None(b) (Py_INCREF(Py_None), Py_None)
+#define __Pyx_PyBool_FromLong(b) ((b) ? (Py_INCREF(Py_True), Py_True) : (Py_INCREF(Py_False), Py_False))
+static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*);
+static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x);
+static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*);
+static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t);
+#if CYTHON_COMPILING_IN_CPYTHON
+#define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x))
+#else
+#define __pyx_PyFloat_AsDouble(x) PyFloat_AsDouble(x)
+#endif
+#define __pyx_PyFloat_AsFloat(x) ((float) __pyx_PyFloat_AsDouble(x))
+#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII
+static int __Pyx_sys_getdefaultencoding_not_ascii;
+static int __Pyx_init_sys_getdefaultencoding_params(void) {
+    PyObject* sys;
+    PyObject* default_encoding = NULL;
+    PyObject* ascii_chars_u = NULL;
+    PyObject* ascii_chars_b = NULL;
+    const char* default_encoding_c;
+    sys = PyImport_ImportModule("sys");
+    if (!sys) goto bad;
+    default_encoding = PyObject_CallMethod(sys, (char*) "getdefaultencoding", NULL);
+    Py_DECREF(sys);
+    if (!default_encoding) goto bad;
+    default_encoding_c = PyBytes_AsString(default_encoding);
+    if (!default_encoding_c) goto bad;
+    if (strcmp(default_encoding_c, "ascii") == 0) {
+        __Pyx_sys_getdefaultencoding_not_ascii = 0;
+    } else {
+        char ascii_chars[128];
+        int c;
+        for (c = 0; c < 128; c++) {
+            ascii_chars[c] = c;
+        }
+        __Pyx_sys_getdefaultencoding_not_ascii = 1;
+        ascii_chars_u = PyUnicode_DecodeASCII(ascii_chars, 128, NULL);
+        if (!ascii_chars_u) goto bad;
+        ascii_chars_b = PyUnicode_AsEncodedString(ascii_chars_u, default_encoding_c, NULL);
+        if (!ascii_chars_b || !PyBytes_Check(ascii_chars_b) || memcmp(ascii_chars, PyBytes_AS_STRING(ascii_chars_b), 128) != 0) {
+            PyErr_Format(
+                PyExc_ValueError,
+                "This module compiled with c_string_encoding=ascii, but default encoding '%.200s' is not a superset of ascii.",
+                default_encoding_c);
+            goto bad;
+        }
+        Py_DECREF(ascii_chars_u);
+        Py_DECREF(ascii_chars_b);
+    }
+    Py_DECREF(default_encoding);
+    return 0;
+bad:
+    Py_XDECREF(default_encoding);
+    Py_XDECREF(ascii_chars_u);
+    Py_XDECREF(ascii_chars_b);
+    return -1;
+}
+#endif
+#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT && PY_MAJOR_VERSION >= 3
+#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_DecodeUTF8(c_str, size, NULL)
+#else
+#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_Decode(c_str, size, __PYX_DEFAULT_STRING_ENCODING, NULL)
+#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT
+static char* __PYX_DEFAULT_STRING_ENCODING;
+static int __Pyx_init_sys_getdefaultencoding_params(void) {
+    PyObject* sys;
+    PyObject* default_encoding = NULL;
+    char* default_encoding_c;
+    sys = PyImport_ImportModule("sys");
+    if (!sys) goto bad;
+    default_encoding = PyObject_CallMethod(sys, (char*) (const char*) "getdefaultencoding", NULL);
+    Py_DECREF(sys);
+    if (!default_encoding) goto bad;
+    default_encoding_c = PyBytes_AsString(default_encoding);
+    if (!default_encoding_c) goto bad;
+    __PYX_DEFAULT_STRING_ENCODING = (char*) malloc(strlen(default_encoding_c));
+    if (!__PYX_DEFAULT_STRING_ENCODING) goto bad;
+    strcpy(__PYX_DEFAULT_STRING_ENCODING, default_encoding_c);
+    Py_DECREF(default_encoding);
+    return 0;
+bad:
+    Py_XDECREF(default_encoding);
+    return -1;
+}
+#endif
+#endif
+
+
+/* Test for GCC > 2.95 */
+#if defined(__GNUC__)     && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95)))
+  #define likely(x)   __builtin_expect(!!(x), 1)
+  #define unlikely(x) __builtin_expect(!!(x), 0)
+#else /* !__GNUC__ or GCC < 2.95 */
+  #define likely(x)   (x)
+  #define unlikely(x) (x)
+#endif /* __GNUC__ */
+
+static PyObject *__pyx_m;
+static PyObject *__pyx_d;
+static PyObject *__pyx_b;
+static PyObject *__pyx_empty_tuple;
+static PyObject *__pyx_empty_bytes;
+static int __pyx_lineno;
+static int __pyx_clineno = 0;
+static const char * __pyx_cfilenm= __FILE__;
+static const char *__pyx_filename;
+
+#if !defined(CYTHON_CCOMPLEX)
+  #if defined(__cplusplus)
+    #define CYTHON_CCOMPLEX 1
+  #elif defined(_Complex_I)
+    #define CYTHON_CCOMPLEX 1
+  #else
+    #define CYTHON_CCOMPLEX 0
+  #endif
+#endif
+#if CYTHON_CCOMPLEX
+  #ifdef __cplusplus
+    #include <complex>
+  #else
+    #include <complex.h>
+  #endif
+#endif
+#if CYTHON_CCOMPLEX && !defined(__cplusplus) && defined(__sun__) && defined(__GNUC__)
+  #undef _Complex_I
+  #define _Complex_I 1.0fj
+#endif
+
+
+static const char *__pyx_f[] = {
+  "bx/bbi/bbi_file.pyx",
+  "bx/bbi/bbi_file.pxd",
+  "__init__.pxd",
+  "bx/bbi/bpt_file.pxd",
+  "bx/bbi/cirtree_file.pxd",
+  "type.pxd",
+};
+#define IS_UNSIGNED(type) (((type) -1) > 0)
+struct __Pyx_StructField_;
+#define __PYX_BUF_FLAGS_PACKED_STRUCT (1 << 0)
+typedef struct {
+  const char* name;
+  struct __Pyx_StructField_* fields;
+  size_t size;
+  size_t arraysize[8];
+  int ndim;
+  char typegroup;
+  char is_unsigned;
+  int flags;
+} __Pyx_TypeInfo;
+typedef struct __Pyx_StructField_ {
+  __Pyx_TypeInfo* type;
+  const char* name;
+  size_t offset;
+} __Pyx_StructField;
+typedef struct {
+  __Pyx_StructField* field;
+  size_t parent_offset;
+} __Pyx_BufFmt_StackElem;
+typedef struct {
+  __Pyx_StructField root;
+  __Pyx_BufFmt_StackElem* head;
+  size_t fmt_offset;
+  size_t new_count, enc_count;
+  size_t struct_alignment;
+  int is_complex;
+  char enc_type;
+  char new_packmode;
+  char enc_packmode;
+  char is_valid_array;
+} __Pyx_BufFmt_Context;
+
+
+/* "types.pxd":1
+ * ctypedef unsigned char UBYTE             # <<<<<<<<<<<<<<
+ * ctypedef signed char BYTE
+ * ctypedef unsigned short UWORD
+ */
+typedef unsigned char __pyx_t_2bx_3bbi_5types_UBYTE;
+
+/* "types.pxd":2
+ * ctypedef unsigned char UBYTE
+ * ctypedef signed char BYTE             # <<<<<<<<<<<<<<
+ * ctypedef unsigned short UWORD
+ * ctypedef short WORD
+ */
+typedef signed char __pyx_t_2bx_3bbi_5types_BYTE;
+
+/* "types.pxd":3
+ * ctypedef unsigned char UBYTE
+ * ctypedef signed char BYTE
+ * ctypedef unsigned short UWORD             # <<<<<<<<<<<<<<
+ * ctypedef short WORD
+ * ctypedef unsigned long long bits64
+ */
+typedef unsigned short __pyx_t_2bx_3bbi_5types_UWORD;
+
+/* "types.pxd":4
+ * ctypedef signed char BYTE
+ * ctypedef unsigned short UWORD
+ * ctypedef short WORD             # <<<<<<<<<<<<<<
+ * ctypedef unsigned long long bits64
+ * ctypedef unsigned bits32
+ */
+typedef short __pyx_t_2bx_3bbi_5types_WORD;
+
+/* "types.pxd":5
+ * ctypedef unsigned short UWORD
+ * ctypedef short WORD
+ * ctypedef unsigned long long bits64             # <<<<<<<<<<<<<<
+ * ctypedef unsigned bits32
+ * ctypedef unsigned short bits16
+ */
+typedef unsigned PY_LONG_LONG __pyx_t_2bx_3bbi_5types_bits64;
+
+/* "types.pxd":6
+ * ctypedef short WORD
+ * ctypedef unsigned long long bits64
+ * ctypedef unsigned bits32             # <<<<<<<<<<<<<<
+ * ctypedef unsigned short bits16
+ * ctypedef unsigned char bits8
+ */
+typedef unsigned int __pyx_t_2bx_3bbi_5types_bits32;
+
+/* "types.pxd":7
+ * ctypedef unsigned long long bits64
+ * ctypedef unsigned bits32
+ * ctypedef unsigned short bits16             # <<<<<<<<<<<<<<
+ * ctypedef unsigned char bits8
+ * ctypedef int signed32
+ */
+typedef unsigned short __pyx_t_2bx_3bbi_5types_bits16;
+
+/* "types.pxd":8
+ * ctypedef unsigned bits32
+ * ctypedef unsigned short bits16
+ * ctypedef unsigned char bits8             # <<<<<<<<<<<<<<
+ * ctypedef int signed32
+ * 
+ */
+typedef unsigned char __pyx_t_2bx_3bbi_5types_bits8;
+
+/* "types.pxd":9
+ * ctypedef unsigned short bits16
+ * ctypedef unsigned char bits8
+ * ctypedef int signed32             # <<<<<<<<<<<<<<
+ * 
+ * ctypedef bint boolean
+ */
+typedef int __pyx_t_2bx_3bbi_5types_signed32;
+
+/* "types.pxd":11
+ * ctypedef int signed32
+ * 
+ * ctypedef bint boolean             # <<<<<<<<<<<<<<
+ * 
+ */
+typedef int __pyx_t_2bx_3bbi_5types_boolean;
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":726
+ * # in Cython to enable them only on the right systems.
+ * 
+ * ctypedef npy_int8       int8_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_int16      int16_t
+ * ctypedef npy_int32      int32_t
+ */
+typedef npy_int8 __pyx_t_5numpy_int8_t;
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":727
+ * 
+ * ctypedef npy_int8       int8_t
+ * ctypedef npy_int16      int16_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_int32      int32_t
+ * ctypedef npy_int64      int64_t
+ */
+typedef npy_int16 __pyx_t_5numpy_int16_t;
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":728
+ * ctypedef npy_int8       int8_t
+ * ctypedef npy_int16      int16_t
+ * ctypedef npy_int32      int32_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_int64      int64_t
+ * #ctypedef npy_int96      int96_t
+ */
+typedef npy_int32 __pyx_t_5numpy_int32_t;
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":729
+ * ctypedef npy_int16      int16_t
+ * ctypedef npy_int32      int32_t
+ * ctypedef npy_int64      int64_t             # <<<<<<<<<<<<<<
+ * #ctypedef npy_int96      int96_t
+ * #ctypedef npy_int128     int128_t
+ */
+typedef npy_int64 __pyx_t_5numpy_int64_t;
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":733
+ * #ctypedef npy_int128     int128_t
+ * 
+ * ctypedef npy_uint8      uint8_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_uint16     uint16_t
+ * ctypedef npy_uint32     uint32_t
+ */
+typedef npy_uint8 __pyx_t_5numpy_uint8_t;
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":734
+ * 
+ * ctypedef npy_uint8      uint8_t
+ * ctypedef npy_uint16     uint16_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_uint32     uint32_t
+ * ctypedef npy_uint64     uint64_t
+ */
+typedef npy_uint16 __pyx_t_5numpy_uint16_t;
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":735
+ * ctypedef npy_uint8      uint8_t
+ * ctypedef npy_uint16     uint16_t
+ * ctypedef npy_uint32     uint32_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_uint64     uint64_t
+ * #ctypedef npy_uint96     uint96_t
+ */
+typedef npy_uint32 __pyx_t_5numpy_uint32_t;
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":736
+ * ctypedef npy_uint16     uint16_t
+ * ctypedef npy_uint32     uint32_t
+ * ctypedef npy_uint64     uint64_t             # <<<<<<<<<<<<<<
+ * #ctypedef npy_uint96     uint96_t
+ * #ctypedef npy_uint128    uint128_t
+ */
+typedef npy_uint64 __pyx_t_5numpy_uint64_t;
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":740
+ * #ctypedef npy_uint128    uint128_t
+ * 
+ * ctypedef npy_float32    float32_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_float64    float64_t
+ * #ctypedef npy_float80    float80_t
+ */
+typedef npy_float32 __pyx_t_5numpy_float32_t;
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":741
+ * 
+ * ctypedef npy_float32    float32_t
+ * ctypedef npy_float64    float64_t             # <<<<<<<<<<<<<<
+ * #ctypedef npy_float80    float80_t
+ * #ctypedef npy_float128   float128_t
+ */
+typedef npy_float64 __pyx_t_5numpy_float64_t;
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":750
+ * # The int types are mapped a bit surprising --
+ * # numpy.int corresponds to 'l' and numpy.long to 'q'
+ * ctypedef npy_long       int_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_longlong   long_t
+ * ctypedef npy_longlong   longlong_t
+ */
+typedef npy_long __pyx_t_5numpy_int_t;
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":751
+ * # numpy.int corresponds to 'l' and numpy.long to 'q'
+ * ctypedef npy_long       int_t
+ * ctypedef npy_longlong   long_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_longlong   longlong_t
+ * 
+ */
+typedef npy_longlong __pyx_t_5numpy_long_t;
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":752
+ * ctypedef npy_long       int_t
+ * ctypedef npy_longlong   long_t
+ * ctypedef npy_longlong   longlong_t             # <<<<<<<<<<<<<<
+ * 
+ * ctypedef npy_ulong      uint_t
+ */
+typedef npy_longlong __pyx_t_5numpy_longlong_t;
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":754
+ * ctypedef npy_longlong   longlong_t
+ * 
+ * ctypedef npy_ulong      uint_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_ulonglong  ulong_t
+ * ctypedef npy_ulonglong  ulonglong_t
+ */
+typedef npy_ulong __pyx_t_5numpy_uint_t;
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":755
+ * 
+ * ctypedef npy_ulong      uint_t
+ * ctypedef npy_ulonglong  ulong_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_ulonglong  ulonglong_t
+ * 
+ */
+typedef npy_ulonglong __pyx_t_5numpy_ulong_t;
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":756
+ * ctypedef npy_ulong      uint_t
+ * ctypedef npy_ulonglong  ulong_t
+ * ctypedef npy_ulonglong  ulonglong_t             # <<<<<<<<<<<<<<
+ * 
+ * ctypedef npy_intp       intp_t
+ */
+typedef npy_ulonglong __pyx_t_5numpy_ulonglong_t;
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":758
+ * ctypedef npy_ulonglong  ulonglong_t
+ * 
+ * ctypedef npy_intp       intp_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_uintp      uintp_t
+ * 
+ */
+typedef npy_intp __pyx_t_5numpy_intp_t;
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":759
+ * 
+ * ctypedef npy_intp       intp_t
+ * ctypedef npy_uintp      uintp_t             # <<<<<<<<<<<<<<
+ * 
+ * ctypedef npy_double     float_t
+ */
+typedef npy_uintp __pyx_t_5numpy_uintp_t;
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":761
+ * ctypedef npy_uintp      uintp_t
+ * 
+ * ctypedef npy_double     float_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_double     double_t
+ * ctypedef npy_longdouble longdouble_t
+ */
+typedef npy_double __pyx_t_5numpy_float_t;
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":762
+ * 
+ * ctypedef npy_double     float_t
+ * ctypedef npy_double     double_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_longdouble longdouble_t
+ * 
+ */
+typedef npy_double __pyx_t_5numpy_double_t;
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":763
+ * ctypedef npy_double     float_t
+ * ctypedef npy_double     double_t
+ * ctypedef npy_longdouble longdouble_t             # <<<<<<<<<<<<<<
+ * 
+ * ctypedef npy_cfloat      cfloat_t
+ */
+typedef npy_longdouble __pyx_t_5numpy_longdouble_t;
+#if CYTHON_CCOMPLEX
+  #ifdef __cplusplus
+    typedef ::std::complex< float > __pyx_t_float_complex;
+  #else
+    typedef float _Complex __pyx_t_float_complex;
+  #endif
+#else
+    typedef struct { float real, imag; } __pyx_t_float_complex;
+#endif
+
+#if CYTHON_CCOMPLEX
+  #ifdef __cplusplus
+    typedef ::std::complex< double > __pyx_t_double_complex;
+  #else
+    typedef double _Complex __pyx_t_double_complex;
+  #endif
+#else
+    typedef struct { double real, imag; } __pyx_t_double_complex;
+#endif
+
+
+/*--- Type declarations ---*/
+struct __pyx_obj_2bx_3bbi_8bpt_file_BPTFile;
+struct __pyx_obj_2bx_3bbi_12cirtree_file_CIRTreeFile;
+struct __pyx_obj_2bx_3bbi_8bbi_file_SummaryBlock;
+struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData;
+struct __pyx_obj_2bx_3bbi_8bbi_file_BlockHandler;
+struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile;
+struct __pyx_obj_2bx_3bbi_8bbi_file_ZoomLevel;
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":765
+ * ctypedef npy_longdouble longdouble_t
+ * 
+ * ctypedef npy_cfloat      cfloat_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_cdouble     cdouble_t
+ * ctypedef npy_clongdouble clongdouble_t
+ */
+typedef npy_cfloat __pyx_t_5numpy_cfloat_t;
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":766
+ * 
+ * ctypedef npy_cfloat      cfloat_t
+ * ctypedef npy_cdouble     cdouble_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_clongdouble clongdouble_t
+ * 
+ */
+typedef npy_cdouble __pyx_t_5numpy_cdouble_t;
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":767
+ * ctypedef npy_cfloat      cfloat_t
+ * ctypedef npy_cdouble     cdouble_t
+ * ctypedef npy_clongdouble clongdouble_t             # <<<<<<<<<<<<<<
+ * 
+ * ctypedef npy_cdouble     complex_t
+ */
+typedef npy_clongdouble __pyx_t_5numpy_clongdouble_t;
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":769
+ * ctypedef npy_clongdouble clongdouble_t
+ * 
+ * ctypedef npy_cdouble     complex_t             # <<<<<<<<<<<<<<
+ * 
+ * cdef inline object PyArray_MultiIterNew1(a):
+ */
+typedef npy_cdouble __pyx_t_5numpy_complex_t;
+
+/* "bx/bbi/bbi_file.pyx":45
+ * cdef inline int imin(int a, int b): return a if a <= b else b
+ * 
+ * cdef enum summary_type:             # <<<<<<<<<<<<<<
+ *     summary_type_mean = 0
+ *     summary_type_max = 1
+ */
+enum __pyx_t_2bx_3bbi_8bbi_file_summary_type {
+  __pyx_e_2bx_3bbi_8bbi_file_summary_type_mean = 0,
+  __pyx_e_2bx_3bbi_8bbi_file_summary_type_max = 1,
+  __pyx_e_2bx_3bbi_8bbi_file_summary_type_min = 2,
+  __pyx_e_2bx_3bbi_8bbi_file_summary_type_coverage = 3,
+  __pyx_e_2bx_3bbi_8bbi_file_summary_type_sd = 4
+};
+
+/* "bpt_file.pxd":5
+ * from types cimport *
+ * 
+ * cdef class BPTFile:             # <<<<<<<<<<<<<<
+ *     """
+ *     On disk B+ tree compatible with Jim Kent's bPlusTree.c
+ */
+struct __pyx_obj_2bx_3bbi_8bpt_file_BPTFile {
+  PyObject_HEAD
+  PyObject *file;
+  PyObject *reader;
+  __pyx_t_2bx_3bbi_5types_boolean is_byteswapped;
+  __pyx_t_2bx_3bbi_5types_bits32 block_size;
+  __pyx_t_2bx_3bbi_5types_bits32 key_size;
+  __pyx_t_2bx_3bbi_5types_bits32 value_size;
+  __pyx_t_2bx_3bbi_5types_bits64 item_count;
+  __pyx_t_2bx_3bbi_5types_bits64 root_offset;
+};
+
+
+/* "cirtree_file.pxd":3
+ * from types cimport *
+ * 
+ * cdef class CIRTreeFile:             # <<<<<<<<<<<<<<
+ *     cdef object file
+ *     cdef object reader
+ */
+struct __pyx_obj_2bx_3bbi_12cirtree_file_CIRTreeFile {
+  PyObject_HEAD
+  PyObject *file;
+  PyObject *reader;
+  __pyx_t_2bx_3bbi_5types_boolean is_byteswapped;
+  __pyx_t_2bx_3bbi_5types_bits64 root_offset;
+  __pyx_t_2bx_3bbi_5types_bits32 block_size;
+  __pyx_t_2bx_3bbi_5types_bits64 item_count;
+  __pyx_t_2bx_3bbi_5types_bits32 start_chrom_ix;
+  __pyx_t_2bx_3bbi_5types_bits32 start_base;
+  __pyx_t_2bx_3bbi_5types_bits32 end_chrom_ix;
+  __pyx_t_2bx_3bbi_5types_bits32 end_base;
+  __pyx_t_2bx_3bbi_5types_bits64 file_size;
+  __pyx_t_2bx_3bbi_5types_bits32 items_per_slot;
+};
+
+
+/* "bx/bbi/bbi_file.pxd":8
+ * cimport numpy
+ * 
+ * cdef class SummaryBlock:             # <<<<<<<<<<<<<<
+ *     """
+ *     A block of summary data from disk
+ */
+struct __pyx_obj_2bx_3bbi_8bbi_file_SummaryBlock {
+  PyObject_HEAD
+  __pyx_t_2bx_3bbi_5types_bits32 chrom_id;
+  __pyx_t_2bx_3bbi_5types_bits32 start;
+  __pyx_t_2bx_3bbi_5types_bits32 end;
+  __pyx_t_2bx_3bbi_5types_bits32 valid_count;
+  double min_val;
+  double max_val;
+  double sum_data;
+  double sum_squares;
+};
+
+
+/* "bx/bbi/bbi_file.pxd":21
+ *     cdef public double sum_squares
+ * 
+ * cdef class SummarizedData:             # <<<<<<<<<<<<<<
+ *     """
+ *     The result of using SummaryBlocks read from the file to produce a
+ */
+struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData {
+  PyObject_HEAD
+  struct __pyx_vtabstruct_2bx_3bbi_8bbi_file_SummarizedData *__pyx_vtab;
+  __pyx_t_2bx_3bbi_5types_bits32 start;
+  __pyx_t_2bx_3bbi_5types_bits32 end;
+  int size;
+  PyArrayObject *valid_count;
+  PyArrayObject *min_val;
+  PyArrayObject *max_val;
+  PyArrayObject *sum_data;
+  PyArrayObject *sum_squares;
+};
+
+
+/* "bx/bbi/bbi_file.pxd":39
+ * cdef class BBIFile
+ * 
+ * cdef class BlockHandler:             # <<<<<<<<<<<<<<
+ *     """
+ *     Callback for `BBIFile.visit_blocks_in_region`
+ */
+struct __pyx_obj_2bx_3bbi_8bbi_file_BlockHandler {
+  PyObject_HEAD
+  struct __pyx_vtabstruct_2bx_3bbi_8bbi_file_BlockHandler *__pyx_vtab;
+};
+
+
+/* "bx/bbi/bbi_file.pxd":37
+ *     cdef accumulate_interval_value( self, bits32 s, bits32 e, float val )
+ * 
+ * cdef class BBIFile             # <<<<<<<<<<<<<<
+ * 
+ * cdef class BlockHandler:
+ */
+struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile {
+  PyObject_HEAD
+  struct __pyx_vtabstruct_2bx_3bbi_8bbi_file_BBIFile *__pyx_vtab;
+  PyObject *file;
+  PyObject *reader;
+  __pyx_t_2bx_3bbi_5types_bits32 magic;
+  __pyx_t_2bx_3bbi_5types_boolean is_byteswapped;
+  struct __pyx_obj_2bx_3bbi_8bpt_file_BPTFile *chrom_bpt;
+  __pyx_t_2bx_3bbi_5types_bits16 version;
+  __pyx_t_2bx_3bbi_5types_bits16 zoom_levels;
+  __pyx_t_2bx_3bbi_5types_bits64 chrom_tree_offset;
+  __pyx_t_2bx_3bbi_5types_bits64 unzoomed_data_offset;
+  __pyx_t_2bx_3bbi_5types_bits64 unzoomed_index_offset;
+  __pyx_t_2bx_3bbi_5types_bits16 field_count;
+  __pyx_t_2bx_3bbi_5types_bits16 defined_field_count;
+  __pyx_t_2bx_3bbi_5types_bits64 as_offset;
+  __pyx_t_2bx_3bbi_5types_bits64 total_summary_offset;
+  __pyx_t_2bx_3bbi_5types_bits32 uncompress_buf_size;
+  PyObject *level_list;
+};
+
+
+/* "bx/bbi/bbi_file.pyx":281
+ *         return closest_level
+ * 
+ * cdef class ZoomLevel:             # <<<<<<<<<<<<<<
+ *     cdef BBIFile bbi_file
+ *     cdef public bits32 reduction_level
+ */
+struct __pyx_obj_2bx_3bbi_8bbi_file_ZoomLevel {
+  PyObject_HEAD
+  struct __pyx_vtabstruct_2bx_3bbi_8bbi_file_ZoomLevel *__pyx_vtab;
+  struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *bbi_file;
+  __pyx_t_2bx_3bbi_5types_bits32 reduction_level;
+  __pyx_t_2bx_3bbi_5types_bits32 reserved;
+  __pyx_t_2bx_3bbi_5types_bits64 data_offset;
+  __pyx_t_2bx_3bbi_5types_bits64 index_offset;
+  int item_count;
+};
+
+
+
+/* "bx/bbi/bbi_file.pyx":58
+ *     pass
+ * 
+ * cdef class SummarizedData:             # <<<<<<<<<<<<<<
+ *     """
+ *     The result of using SummaryBlocks read from the file to produce a
+ */
+
+struct __pyx_vtabstruct_2bx_3bbi_8bbi_file_SummarizedData {
+  PyObject *(*accumulate_interval_value)(struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData *, __pyx_t_2bx_3bbi_5types_bits32, __pyx_t_2bx_3bbi_5types_bits32, float);
+};
+static struct __pyx_vtabstruct_2bx_3bbi_8bbi_file_SummarizedData *__pyx_vtabptr_2bx_3bbi_8bbi_file_SummarizedData;
+
+
+/* "bx/bbi/bbi_file.pyx":112
+ *         pass
+ * 
+ * cdef class BBIFile:             # <<<<<<<<<<<<<<
+ *     """
+ *     A "big binary indexed" file. Stores blocks of raw data and numeric
+ */
+
+struct __pyx_vtabstruct_2bx_3bbi_8bbi_file_BBIFile {
+  PyObject *(*visit_blocks_in_region)(struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *, __pyx_t_2bx_3bbi_5types_bits32, __pyx_t_2bx_3bbi_5types_bits32, __pyx_t_2bx_3bbi_5types_bits32, struct __pyx_obj_2bx_3bbi_8bbi_file_BlockHandler *);
+  PyObject *(*_get_chrom_id_and_size)(struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *, char *);
+  PyObject *(*_best_zoom_level)(struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *, int);
+  PyObject *(*summarize)(struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *, char *, __pyx_t_2bx_3bbi_5types_bits32, __pyx_t_2bx_3bbi_5types_bits32, int, int __pyx_skip_dispatch);
+  PyObject *(*summarize_from_full)(struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *, char *, __pyx_t_2bx_3bbi_5types_bits32, __pyx_t_2bx_3bbi_5types_bits32, int, int __pyx_skip_dispatch);
+  PyObject *(*query)(struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *, char *, __pyx_t_2bx_3bbi_5types_bits32, __pyx_t_2bx_3bbi_5types_bits32, int, int __pyx_skip_dispatch);
+  PyObject *(*_summarize_from_full)(struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *, __pyx_t_2bx_3bbi_5types_bits32, __pyx_t_2bx_3bbi_5types_bits32, __pyx_t_2bx_3bbi_5types_bits32, int);
+};
+static struct __pyx_vtabstruct_2bx_3bbi_8bbi_file_BBIFile *__pyx_vtabptr_2bx_3bbi_8bbi_file_BBIFile;
+
+
+/* "bx/bbi/bbi_file.pyx":105
+ *                     min_val[j] = val
+ * 
+ * cdef class BlockHandler:             # <<<<<<<<<<<<<<
+ *     """
+ *     Callback for `BBIFile.visit_blocks_in_region`
+ */
+
+struct __pyx_vtabstruct_2bx_3bbi_8bbi_file_BlockHandler {
+  PyObject *(*handle_block)(struct __pyx_obj_2bx_3bbi_8bbi_file_BlockHandler *, PyObject *, struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *);
+};
+static struct __pyx_vtabstruct_2bx_3bbi_8bbi_file_BlockHandler *__pyx_vtabptr_2bx_3bbi_8bbi_file_BlockHandler;
+
+
+/* "bx/bbi/bbi_file.pyx":281
+ *         return closest_level
+ * 
+ * cdef class ZoomLevel:             # <<<<<<<<<<<<<<
+ *     cdef BBIFile bbi_file
+ *     cdef public bits32 reduction_level
+ */
+
+struct __pyx_vtabstruct_2bx_3bbi_8bbi_file_ZoomLevel {
+  PyObject *(*_get_summary_slice)(struct __pyx_obj_2bx_3bbi_8bbi_file_ZoomLevel *, __pyx_t_2bx_3bbi_5types_bits32, __pyx_t_2bx_3bbi_5types_bits32, PyObject *);
+  PyObject *(*_summarize)(struct __pyx_obj_2bx_3bbi_8bbi_file_ZoomLevel *, __pyx_t_2bx_3bbi_5types_bits32, __pyx_t_2bx_3bbi_5types_bits32, __pyx_t_2bx_3bbi_5types_bits32, int);
+};
+static struct __pyx_vtabstruct_2bx_3bbi_8bbi_file_ZoomLevel *__pyx_vtabptr_2bx_3bbi_8bbi_file_ZoomLevel;
+
+/* --- Runtime support code (head) --- */
+#ifndef CYTHON_REFNANNY
+  #define CYTHON_REFNANNY 0
+#endif
+#if CYTHON_REFNANNY
+  typedef struct {
+    void (*INCREF)(void*, PyObject*, int);
+    void (*DECREF)(void*, PyObject*, int);
+    void (*GOTREF)(void*, PyObject*, int);
+    void (*GIVEREF)(void*, PyObject*, int);
+    void* (*SetupContext)(const char*, int, const char*);
+    void (*FinishContext)(void**);
+  } __Pyx_RefNannyAPIStruct;
+  static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL;
+  static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname);
+  #define __Pyx_RefNannyDeclarations void *__pyx_refnanny = NULL;
+#ifdef WITH_THREAD
+  #define __Pyx_RefNannySetupContext(name, acquire_gil) \
+          if (acquire_gil) { \
+              PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure(); \
+              __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__); \
+              PyGILState_Release(__pyx_gilstate_save); \
+          } else { \
+              __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__); \
+          }
+#else
+  #define __Pyx_RefNannySetupContext(name, acquire_gil) \
+          __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__)
+#endif
+  #define __Pyx_RefNannyFinishContext() \
+          __Pyx_RefNanny->FinishContext(&__pyx_refnanny)
+  #define __Pyx_INCREF(r)  __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_DECREF(r)  __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_GOTREF(r)  __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_XINCREF(r)  do { if((r) != NULL) {__Pyx_INCREF(r); }} while(0)
+  #define __Pyx_XDECREF(r)  do { if((r) != NULL) {__Pyx_DECREF(r); }} while(0)
+  #define __Pyx_XGOTREF(r)  do { if((r) != NULL) {__Pyx_GOTREF(r); }} while(0)
+  #define __Pyx_XGIVEREF(r) do { if((r) != NULL) {__Pyx_GIVEREF(r);}} while(0)
+#else
+  #define __Pyx_RefNannyDeclarations
+  #define __Pyx_RefNannySetupContext(name, acquire_gil)
+  #define __Pyx_RefNannyFinishContext()
+  #define __Pyx_INCREF(r) Py_INCREF(r)
+  #define __Pyx_DECREF(r) Py_DECREF(r)
+  #define __Pyx_GOTREF(r)
+  #define __Pyx_GIVEREF(r)
+  #define __Pyx_XINCREF(r) Py_XINCREF(r)
+  #define __Pyx_XDECREF(r) Py_XDECREF(r)
+  #define __Pyx_XGOTREF(r)
+  #define __Pyx_XGIVEREF(r)
+#endif
+#define __Pyx_XDECREF_SET(r, v) do {                            \
+        PyObject *tmp = (PyObject *) r;                         \
+        r = v; __Pyx_XDECREF(tmp);                              \
+    } while (0)
+#define __Pyx_DECREF_SET(r, v) do {                             \
+        PyObject *tmp = (PyObject *) r;                         \
+        r = v; __Pyx_DECREF(tmp);                               \
+    } while (0)
+#define __Pyx_CLEAR(r)    do { PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);} while(0)
+#define __Pyx_XCLEAR(r)   do { if((r) != NULL) {PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);}} while(0)
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name) {
+    PyTypeObject* tp = Py_TYPE(obj);
+    if (likely(tp->tp_getattro))
+        return tp->tp_getattro(obj, attr_name);
+#if PY_MAJOR_VERSION < 3
+    if (likely(tp->tp_getattr))
+        return tp->tp_getattr(obj, PyString_AS_STRING(attr_name));
+#endif
+    return PyObject_GetAttr(obj, attr_name);
+}
+#else
+#define __Pyx_PyObject_GetAttrStr(o,n) PyObject_GetAttr(o,n)
+#endif
+
+static PyObject *__Pyx_GetBuiltinName(PyObject *name);
+
+static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
+    Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found);
+
+static void __Pyx_RaiseDoubleKeywordsError(const char* func_name, PyObject* kw_name);
+
+static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
+    PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
+    const char* function_name);
+
+static CYTHON_INLINE PyObject *__Pyx_GetModuleGlobalName(PyObject *name);
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw);
+#else
+#define __Pyx_PyObject_Call(func, arg, kw) PyObject_Call(func, arg, kw)
+#endif
+
+static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type);
+
+static CYTHON_INLINE int  __Pyx_GetBufferAndValidate(Py_buffer* buf, PyObject* obj,
+    __Pyx_TypeInfo* dtype, int flags, int nd, int cast, __Pyx_BufFmt_StackElem* stack);
+static CYTHON_INLINE void __Pyx_SafeReleaseBuffer(Py_buffer* info);
+
+#ifndef __PYX_FORCE_INIT_THREADS
+  #define __PYX_FORCE_INIT_THREADS 0
+#endif
+
+static void __Pyx_RaiseBufferIndexError(int axis);
+
+#define __Pyx_BufPtrStrided1d(type, buf, i0, s0) (type)((char*)buf + i0 * s0)
+static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb);
+static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb);
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg);
+#endif
+
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg);
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func);
+#else
+#define __Pyx_PyObject_CallNoArg(func) __Pyx_PyObject_Call(func, __pyx_empty_tuple, NULL)
+#endif
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE int __Pyx_PyList_Append(PyObject* list, PyObject* x) {
+    PyListObject* L = (PyListObject*) list;
+    Py_ssize_t len = Py_SIZE(list);
+    if (likely(L->allocated > len) & likely(len > (L->allocated >> 1))) {
+        Py_INCREF(x);
+        PyList_SET_ITEM(list, len, x);
+        Py_SIZE(list) = len+1;
+        return 0;
+    }
+    return PyList_Append(list, x);
+}
+#else
+#define __Pyx_PyList_Append(L,x) PyList_Append(L,x)
+#endif
+
+static PyObject* __Pyx_PyObject_CallMethod1(PyObject* obj, PyObject* method_name, PyObject* arg);
+
+static CYTHON_INLINE int __Pyx_PyObject_Append(PyObject* L, PyObject* x);
+
+static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected);
+
+static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index);
+
+static CYTHON_INLINE int __Pyx_IterFinish(void);
+
+static int __Pyx_IternextUnpackEndCheck(PyObject *retval, Py_ssize_t expected);
+
+static CYTHON_INLINE long __Pyx_div_long(long, long); /* proto */
+
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause);
+
+#define __Pyx_GetItemInt(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck) \
+    (__Pyx_fits_Py_ssize_t(i, type, is_signed) ? \
+    __Pyx_GetItemInt_Fast(o, (Py_ssize_t)i, is_list, wraparound, boundscheck) : \
+    (is_list ? (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL) : \
+               __Pyx_GetItemInt_Generic(o, to_py_func(i))))
+#define __Pyx_GetItemInt_List(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck) \
+    (__Pyx_fits_Py_ssize_t(i, type, is_signed) ? \
+    __Pyx_GetItemInt_List_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) : \
+    (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL))
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i,
+                                                              int wraparound, int boundscheck);
+#define __Pyx_GetItemInt_Tuple(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck) \
+    (__Pyx_fits_Py_ssize_t(i, type, is_signed) ? \
+    __Pyx_GetItemInt_Tuple_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) : \
+    (PyErr_SetString(PyExc_IndexError, "tuple index out of range"), (PyObject*)NULL))
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i,
+                                                              int wraparound, int boundscheck);
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j);
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i,
+                                                     int is_list, int wraparound, int boundscheck);
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE int __Pyx_ListComp_Append(PyObject* list, PyObject* x) {
+    PyListObject* L = (PyListObject*) list;
+    Py_ssize_t len = Py_SIZE(list);
+    if (likely(L->allocated > len)) {
+        Py_INCREF(x);
+        PyList_SET_ITEM(list, len, x);
+        Py_SIZE(list) = len+1;
+        return 0;
+    }
+    return PyList_Append(list, x);
+}
+#else
+#define __Pyx_ListComp_Append(L,x) PyList_Append(L,x)
+#endif
+
+#if PY_MAJOR_VERSION >= 3
+static PyObject *__Pyx_PyDict_GetItem(PyObject *d, PyObject* key) {
+    PyObject *value;
+    value = PyDict_GetItemWithError(d, key);
+    if (unlikely(!value)) {
+        if (!PyErr_Occurred()) {
+            PyObject* args = PyTuple_Pack(1, key);
+            if (likely(args))
+                PyErr_SetObject(PyExc_KeyError, args);
+            Py_XDECREF(args);
+        }
+        return NULL;
+    }
+    Py_INCREF(value);
+    return value;
+}
+#else
+    #define __Pyx_PyDict_GetItem(d, key) PyObject_GetItem(d, key)
+#endif
+
+static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void);
+
+static int __Pyx_SetVtable(PyObject *dict, void *vtable);
+
+static PyObject* __Pyx_ImportFrom(PyObject* module, PyObject* name);
+
+typedef struct {
+    int code_line;
+    PyCodeObject* code_object;
+} __Pyx_CodeObjectCacheEntry;
+struct __Pyx_CodeObjectCache {
+    int count;
+    int max_count;
+    __Pyx_CodeObjectCacheEntry* entries;
+};
+static struct __Pyx_CodeObjectCache __pyx_code_cache = {0,0,NULL};
+static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line);
+static PyCodeObject *__pyx_find_code_object(int code_line);
+static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object);
+
+static void __Pyx_AddTraceback(const char *funcname, int c_line,
+                               int py_line, const char *filename);
+
+static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level);
+
+typedef struct {
+  Py_ssize_t shape, strides, suboffsets;
+} __Pyx_Buf_DimInfo;
+typedef struct {
+  size_t refcount;
+  Py_buffer pybuffer;
+} __Pyx_Buffer;
+typedef struct {
+  __Pyx_Buffer *rcbuffer;
+  char *data;
+  __Pyx_Buf_DimInfo diminfo[8];
+} __Pyx_LocalBuf_ND;
+
+#if PY_MAJOR_VERSION < 3
+    static int __Pyx_GetBuffer(PyObject *obj, Py_buffer *view, int flags);
+    static void __Pyx_ReleaseBuffer(Py_buffer *view);
+#else
+    #define __Pyx_GetBuffer PyObject_GetBuffer
+    #define __Pyx_ReleaseBuffer PyBuffer_Release
+#endif
+
+
+static Py_ssize_t __Pyx_zeros[] = {0, 0, 0, 0, 0, 0, 0, 0};
+static Py_ssize_t __Pyx_minusones[] = {-1, -1, -1, -1, -1, -1, -1, -1};
+
+static CYTHON_INLINE unsigned int __Pyx_PyInt_As_unsigned_int(PyObject *);
+
+static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *);
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_unsigned_int(unsigned int value);
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value);
+
+static CYTHON_INLINE unsigned short __Pyx_PyInt_As_unsigned_short(PyObject *);
+
+static CYTHON_INLINE unsigned PY_LONG_LONG __Pyx_PyInt_As_unsigned_PY_LONG_LONG(PyObject *);
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_unsigned_PY_LONG_LONG(unsigned PY_LONG_LONG value);
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value);
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_unsigned_short(unsigned short value);
+
+#if CYTHON_CCOMPLEX
+  #ifdef __cplusplus
+    #define __Pyx_CREAL(z) ((z).real())
+    #define __Pyx_CIMAG(z) ((z).imag())
+  #else
+    #define __Pyx_CREAL(z) (__real__(z))
+    #define __Pyx_CIMAG(z) (__imag__(z))
+  #endif
+#else
+    #define __Pyx_CREAL(z) ((z).real)
+    #define __Pyx_CIMAG(z) ((z).imag)
+#endif
+#if (defined(_WIN32) || defined(__clang__)) && defined(__cplusplus) && CYTHON_CCOMPLEX
+    #define __Pyx_SET_CREAL(z,x) ((z).real(x))
+    #define __Pyx_SET_CIMAG(z,y) ((z).imag(y))
+#else
+    #define __Pyx_SET_CREAL(z,x) __Pyx_CREAL(z) = (x)
+    #define __Pyx_SET_CIMAG(z,y) __Pyx_CIMAG(z) = (y)
+#endif
+
+static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float, float);
+
+#if CYTHON_CCOMPLEX
+    #define __Pyx_c_eqf(a, b)   ((a)==(b))
+    #define __Pyx_c_sumf(a, b)  ((a)+(b))
+    #define __Pyx_c_difff(a, b) ((a)-(b))
+    #define __Pyx_c_prodf(a, b) ((a)*(b))
+    #define __Pyx_c_quotf(a, b) ((a)/(b))
+    #define __Pyx_c_negf(a)     (-(a))
+  #ifdef __cplusplus
+    #define __Pyx_c_is_zerof(z) ((z)==(float)0)
+    #define __Pyx_c_conjf(z)    (::std::conj(z))
+    #if 1
+        #define __Pyx_c_absf(z)     (::std::abs(z))
+        #define __Pyx_c_powf(a, b)  (::std::pow(a, b))
+    #endif
+  #else
+    #define __Pyx_c_is_zerof(z) ((z)==0)
+    #define __Pyx_c_conjf(z)    (conjf(z))
+    #if 1
+        #define __Pyx_c_absf(z)     (cabsf(z))
+        #define __Pyx_c_powf(a, b)  (cpowf(a, b))
+    #endif
+ #endif
+#else
+    static CYTHON_INLINE int __Pyx_c_eqf(__pyx_t_float_complex, __pyx_t_float_complex);
+    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_sumf(__pyx_t_float_complex, __pyx_t_float_complex);
+    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_difff(__pyx_t_float_complex, __pyx_t_float_complex);
+    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_prodf(__pyx_t_float_complex, __pyx_t_float_complex);
+    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_quotf(__pyx_t_float_complex, __pyx_t_float_complex);
+    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_negf(__pyx_t_float_complex);
+    static CYTHON_INLINE int __Pyx_c_is_zerof(__pyx_t_float_complex);
+    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_conjf(__pyx_t_float_complex);
+    #if 1
+        static CYTHON_INLINE float __Pyx_c_absf(__pyx_t_float_complex);
+        static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_powf(__pyx_t_float_complex, __pyx_t_float_complex);
+    #endif
+#endif
+
+static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double, double);
+
+#if CYTHON_CCOMPLEX
+    #define __Pyx_c_eq(a, b)   ((a)==(b))
+    #define __Pyx_c_sum(a, b)  ((a)+(b))
+    #define __Pyx_c_diff(a, b) ((a)-(b))
+    #define __Pyx_c_prod(a, b) ((a)*(b))
+    #define __Pyx_c_quot(a, b) ((a)/(b))
+    #define __Pyx_c_neg(a)     (-(a))
+  #ifdef __cplusplus
+    #define __Pyx_c_is_zero(z) ((z)==(double)0)
+    #define __Pyx_c_conj(z)    (::std::conj(z))
+    #if 1
+        #define __Pyx_c_abs(z)     (::std::abs(z))
+        #define __Pyx_c_pow(a, b)  (::std::pow(a, b))
+    #endif
+  #else
+    #define __Pyx_c_is_zero(z) ((z)==0)
+    #define __Pyx_c_conj(z)    (conj(z))
+    #if 1
+        #define __Pyx_c_abs(z)     (cabs(z))
+        #define __Pyx_c_pow(a, b)  (cpow(a, b))
+    #endif
+ #endif
+#else
+    static CYTHON_INLINE int __Pyx_c_eq(__pyx_t_double_complex, __pyx_t_double_complex);
+    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_sum(__pyx_t_double_complex, __pyx_t_double_complex);
+    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_diff(__pyx_t_double_complex, __pyx_t_double_complex);
+    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_prod(__pyx_t_double_complex, __pyx_t_double_complex);
+    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_quot(__pyx_t_double_complex, __pyx_t_double_complex);
+    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_neg(__pyx_t_double_complex);
+    static CYTHON_INLINE int __Pyx_c_is_zero(__pyx_t_double_complex);
+    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_conj(__pyx_t_double_complex);
+    #if 1
+        static CYTHON_INLINE double __Pyx_c_abs(__pyx_t_double_complex);
+        static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_pow(__pyx_t_double_complex, __pyx_t_double_complex);
+    #endif
+#endif
+
+static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *);
+
+static int __Pyx_check_binary_version(void);
+
+#if !defined(__Pyx_PyIdentifier_FromString)
+#if PY_MAJOR_VERSION < 3
+  #define __Pyx_PyIdentifier_FromString(s) PyString_FromString(s)
+#else
+  #define __Pyx_PyIdentifier_FromString(s) PyUnicode_FromString(s)
+#endif
+#endif
+
+static PyObject *__Pyx_ImportModule(const char *name);
+
+static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name, size_t size, int strict);
+
+static int __Pyx_InitStrings(__Pyx_StringTabEntry *t);
+
+static PyObject *__pyx_f_2bx_3bbi_8bbi_file_14SummarizedData_accumulate_interval_value(struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData *__pyx_v_self, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_s, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_e, float __pyx_v_val); /* proto*/
+static PyObject *__pyx_f_2bx_3bbi_8bbi_file_12BlockHandler_handle_block(CYTHON_UNUSED struct __pyx_obj_2bx_3bbi_8bbi_file_BlockHandler *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v_block_data, CYTHON_UNUSED struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *__pyx_v_bbi_file); /* proto*/
+static PyObject *__pyx_f_2bx_3bbi_8bbi_file_7BBIFile_visit_blocks_in_region(struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *__pyx_v_self, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_chrom_id, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_start, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_end, struct __pyx_obj_2bx_3bbi_8bbi_file_BlockHandler *__pyx_v_handler); /* proto*/
+static PyObject *__pyx_f_2bx_3bbi_8bbi_file_7BBIFile_summarize(struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *__pyx_v_self, char *__pyx_v_chrom, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_start, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_end, int __pyx_v_summary_size, int __pyx_skip_dispatch); /* proto*/
+static PyObject *__pyx_f_2bx_3bbi_8bbi_file_7BBIFile_summarize_from_full(struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *__pyx_v_self, char *__pyx_v_chrom, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_start, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_end, int __pyx_v_summary_size, int __pyx_skip_dispatch); /* proto*/
+static PyObject *__pyx_f_2bx_3bbi_8bbi_file_7BBIFile_query(struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *__pyx_v_self, char *__pyx_v_chrom, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_start, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_end, int __pyx_v_summary_size, int __pyx_skip_dispatch); /* proto*/
+static PyObject *__pyx_f_2bx_3bbi_8bbi_file_7BBIFile__get_chrom_id_and_size(struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *__pyx_v_self, char *__pyx_v_chrom); /* proto*/
+static PyObject *__pyx_f_2bx_3bbi_8bbi_file_7BBIFile__summarize_from_full(CYTHON_UNUSED struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *__pyx_v_self, CYTHON_UNUSED __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_chrom_id, CYTHON_UNUSED __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_start, CYTHON_UNUSED __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_end, CYTHON_UNUSED int __pyx_v_summary_size); /* proto*/
+static PyObject *__pyx_f_2bx_3bbi_8bbi_file_7BBIFile__best_zoom_level(struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *__pyx_v_self, int __pyx_v_desired_reduction); /* proto*/
+static PyObject *__pyx_f_2bx_3bbi_8bbi_file_9ZoomLevel__get_summary_slice(CYTHON_UNUSED struct __pyx_obj_2bx_3bbi_8bbi_file_ZoomLevel *__pyx_v_self, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_base_start, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_base_end, PyObject *__pyx_v_summaries); /* proto*/
+static PyObject *__pyx_f_2bx_3bbi_8bbi_file_9ZoomLevel__summarize(CYTHON_UNUSED struct __pyx_obj_2bx_3bbi_8bbi_file_ZoomLevel *__pyx_v_self, CYTHON_UNUSED __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_chrom_id, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_start, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_end, int __pyx_v_summary_size); /* proto*/
+
+/* Module declarations from 'bx.bbi.types' */
+
+/* Module declarations from 'bx.bbi.bpt_file' */
+static PyTypeObject *__pyx_ptype_2bx_3bbi_8bpt_file_BPTFile = 0;
+
+/* Module declarations from 'bx.bbi.cirtree_file' */
+static PyTypeObject *__pyx_ptype_2bx_3bbi_12cirtree_file_CIRTreeFile = 0;
+
+/* Module declarations from 'cpython.buffer' */
+
+/* Module declarations from 'cpython.ref' */
+
+/* Module declarations from 'libc.string' */
+
+/* Module declarations from 'libc.stdio' */
+
+/* Module declarations from 'cpython.object' */
+
+/* Module declarations from '__builtin__' */
+
+/* Module declarations from 'cpython.type' */
+static PyTypeObject *__pyx_ptype_7cpython_4type_type = 0;
+
+/* Module declarations from 'libc.stdlib' */
+
+/* Module declarations from 'numpy' */
+
+/* Module declarations from 'numpy' */
+static PyTypeObject *__pyx_ptype_5numpy_dtype = 0;
+static PyTypeObject *__pyx_ptype_5numpy_flatiter = 0;
+static PyTypeObject *__pyx_ptype_5numpy_broadcast = 0;
+static PyTypeObject *__pyx_ptype_5numpy_ndarray = 0;
+static PyTypeObject *__pyx_ptype_5numpy_ufunc = 0;
+static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *, char *, char *, int *); /*proto*/
+
+/* Module declarations from 'cython' */
+
+/* Module declarations from 'libc' */
+
+/* Module declarations from 'libc.limits' */
+
+/* Module declarations from 'bx.bbi.bbi_file' */
+static PyTypeObject *__pyx_ptype_2bx_3bbi_8bbi_file_SummaryBlock = 0;
+static PyTypeObject *__pyx_ptype_2bx_3bbi_8bbi_file_SummarizedData = 0;
+static PyTypeObject *__pyx_ptype_2bx_3bbi_8bbi_file_BBIFile = 0;
+static PyTypeObject *__pyx_ptype_2bx_3bbi_8bbi_file_BlockHandler = 0;
+static PyTypeObject *__pyx_ptype_2bx_3bbi_8bbi_file_ZoomLevel = 0;
+__PYX_EXTERN_C DL_EXPORT(int) big_wig_sig;
+__PYX_EXTERN_C DL_EXPORT(int) big_bed_sig;
+static CYTHON_INLINE int __pyx_f_2bx_3bbi_8bbi_file_range_intersection(int, int, int, int); /*proto*/
+static __Pyx_TypeInfo __Pyx_TypeInfo_nn___pyx_t_5numpy_float64_t = { "float64_t", NULL, sizeof(__pyx_t_5numpy_float64_t), { 0 }, 0, 'R', 0, 0 };
+#define __Pyx_MODULE_NAME "bx.bbi.bbi_file"
+int __pyx_module_is_main_bx__bbi__bbi_file = 0;
+
+/* Implementation of 'bx.bbi.bbi_file' */
+static PyObject *__pyx_builtin_ValueError;
+static PyObject *__pyx_builtin_range;
+static PyObject *__pyx_builtin_zip;
+static PyObject *__pyx_builtin_RuntimeError;
+static PyObject *__pyx_pf_2bx_3bbi_8bbi_file_12SummaryBlock_8chrom_id___get__(struct __pyx_obj_2bx_3bbi_8bbi_file_SummaryBlock *__pyx_v_self); /* proto */
+static int __pyx_pf_2bx_3bbi_8bbi_file_12SummaryBlock_8chrom_id_2__set__(struct __pyx_obj_2bx_3bbi_8bbi_file_SummaryBlock *__pyx_v_self, PyObject *__pyx_v_value); /* proto */
+static PyObject *__pyx_pf_2bx_3bbi_8bbi_file_12SummaryBlock_5start___get__(struct __pyx_obj_2bx_3bbi_8bbi_file_SummaryBlock *__pyx_v_self); /* proto */
+static int __pyx_pf_2bx_3bbi_8bbi_file_12SummaryBlock_5start_2__set__(struct __pyx_obj_2bx_3bbi_8bbi_file_SummaryBlock *__pyx_v_self, PyObject *__pyx_v_value); /* proto */
+static PyObject *__pyx_pf_2bx_3bbi_8bbi_file_12SummaryBlock_3end___get__(struct __pyx_obj_2bx_3bbi_8bbi_file_SummaryBlock *__pyx_v_self); /* proto */
+static int __pyx_pf_2bx_3bbi_8bbi_file_12SummaryBlock_3end_2__set__(struct __pyx_obj_2bx_3bbi_8bbi_file_SummaryBlock *__pyx_v_self, PyObject *__pyx_v_value); /* proto */
+static PyObject *__pyx_pf_2bx_3bbi_8bbi_file_12SummaryBlock_11valid_count___get__(struct __pyx_obj_2bx_3bbi_8bbi_file_SummaryBlock *__pyx_v_self); /* proto */
+static int __pyx_pf_2bx_3bbi_8bbi_file_12SummaryBlock_11valid_count_2__set__(struct __pyx_obj_2bx_3bbi_8bbi_file_SummaryBlock *__pyx_v_self, PyObject *__pyx_v_value); /* proto */
+static PyObject *__pyx_pf_2bx_3bbi_8bbi_file_12SummaryBlock_7min_val___get__(struct __pyx_obj_2bx_3bbi_8bbi_file_SummaryBlock *__pyx_v_self); /* proto */
+static int __pyx_pf_2bx_3bbi_8bbi_file_12SummaryBlock_7min_val_2__set__(struct __pyx_obj_2bx_3bbi_8bbi_file_SummaryBlock *__pyx_v_self, PyObject *__pyx_v_value); /* proto */
+static PyObject *__pyx_pf_2bx_3bbi_8bbi_file_12SummaryBlock_7max_val___get__(struct __pyx_obj_2bx_3bbi_8bbi_file_SummaryBlock *__pyx_v_self); /* proto */
+static int __pyx_pf_2bx_3bbi_8bbi_file_12SummaryBlock_7max_val_2__set__(struct __pyx_obj_2bx_3bbi_8bbi_file_SummaryBlock *__pyx_v_self, PyObject *__pyx_v_value); /* proto */
+static PyObject *__pyx_pf_2bx_3bbi_8bbi_file_12SummaryBlock_8sum_data___get__(struct __pyx_obj_2bx_3bbi_8bbi_file_SummaryBlock *__pyx_v_self); /* proto */
+static int __pyx_pf_2bx_3bbi_8bbi_file_12SummaryBlock_8sum_data_2__set__(struct __pyx_obj_2bx_3bbi_8bbi_file_SummaryBlock *__pyx_v_self, PyObject *__pyx_v_value); /* proto */
+static PyObject *__pyx_pf_2bx_3bbi_8bbi_file_12SummaryBlock_11sum_squares___get__(struct __pyx_obj_2bx_3bbi_8bbi_file_SummaryBlock *__pyx_v_self); /* proto */
+static int __pyx_pf_2bx_3bbi_8bbi_file_12SummaryBlock_11sum_squares_2__set__(struct __pyx_obj_2bx_3bbi_8bbi_file_SummaryBlock *__pyx_v_self, PyObject *__pyx_v_value); /* proto */
+static int __pyx_pf_2bx_3bbi_8bbi_file_14SummarizedData___init__(struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData *__pyx_v_self, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_start, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_end, int __pyx_v_size); /* proto */
+static PyObject *__pyx_pf_2bx_3bbi_8bbi_file_14SummarizedData_5start___get__(struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData *__pyx_v_self); /* proto */
+static int __pyx_pf_2bx_3bbi_8bbi_file_14SummarizedData_5start_2__set__(struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData *__pyx_v_self, PyObject *__pyx_v_value); /* proto */
+static PyObject *__pyx_pf_2bx_3bbi_8bbi_file_14SummarizedData_3end___get__(struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData *__pyx_v_self); /* proto */
+static int __pyx_pf_2bx_3bbi_8bbi_file_14SummarizedData_3end_2__set__(struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData *__pyx_v_self, PyObject *__pyx_v_value); /* proto */
+static PyObject *__pyx_pf_2bx_3bbi_8bbi_file_14SummarizedData_4size___get__(struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData *__pyx_v_self); /* proto */
+static int __pyx_pf_2bx_3bbi_8bbi_file_14SummarizedData_4size_2__set__(struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData *__pyx_v_self, PyObject *__pyx_v_value); /* proto */
+static PyObject *__pyx_pf_2bx_3bbi_8bbi_file_14SummarizedData_11valid_count___get__(struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData *__pyx_v_self); /* proto */
+static int __pyx_pf_2bx_3bbi_8bbi_file_14SummarizedData_11valid_count_2__set__(struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData *__pyx_v_self, PyObject *__pyx_v_value); /* proto */
+static int __pyx_pf_2bx_3bbi_8bbi_file_14SummarizedData_11valid_count_4__del__(struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_2bx_3bbi_8bbi_file_14SummarizedData_7min_val___get__(struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData *__pyx_v_self); /* proto */
+static int __pyx_pf_2bx_3bbi_8bbi_file_14SummarizedData_7min_val_2__set__(struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData *__pyx_v_self, PyObject *__pyx_v_value); /* proto */
+static int __pyx_pf_2bx_3bbi_8bbi_file_14SummarizedData_7min_val_4__del__(struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_2bx_3bbi_8bbi_file_14SummarizedData_7max_val___get__(struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData *__pyx_v_self); /* proto */
+static int __pyx_pf_2bx_3bbi_8bbi_file_14SummarizedData_7max_val_2__set__(struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData *__pyx_v_self, PyObject *__pyx_v_value); /* proto */
+static int __pyx_pf_2bx_3bbi_8bbi_file_14SummarizedData_7max_val_4__del__(struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_2bx_3bbi_8bbi_file_14SummarizedData_8sum_data___get__(struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData *__pyx_v_self); /* proto */
+static int __pyx_pf_2bx_3bbi_8bbi_file_14SummarizedData_8sum_data_2__set__(struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData *__pyx_v_self, PyObject *__pyx_v_value); /* proto */
+static int __pyx_pf_2bx_3bbi_8bbi_file_14SummarizedData_8sum_data_4__del__(struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_2bx_3bbi_8bbi_file_14SummarizedData_11sum_squares___get__(struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData *__pyx_v_self); /* proto */
+static int __pyx_pf_2bx_3bbi_8bbi_file_14SummarizedData_11sum_squares_2__set__(struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData *__pyx_v_self, PyObject *__pyx_v_value); /* proto */
+static int __pyx_pf_2bx_3bbi_8bbi_file_14SummarizedData_11sum_squares_4__del__(struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData *__pyx_v_self); /* proto */
+static int __pyx_pf_2bx_3bbi_8bbi_file_7BBIFile___init__(struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *__pyx_v_self, PyObject *__pyx_v_file, PyObject *__pyx_v_expected_sig, PyObject *__pyx_v_type_name); /* proto */
+static PyObject *__pyx_pf_2bx_3bbi_8bbi_file_7BBIFile_2open(struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *__pyx_v_self, PyObject *__pyx_v_file, PyObject *__pyx_v_expected_sig, CYTHON_UNUSED PyObject *__pyx_v_type_name); /* proto */
+static PyObject *__pyx_pf_2bx_3bbi_8bbi_file_7BBIFile_4summarize(struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *__pyx_v_self, char *__pyx_v_chrom, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_start, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_end, int __pyx_v_summary_size); /* proto */
+static PyObject *__pyx_pf_2bx_3bbi_8bbi_file_7BBIFile_6summarize_from_full(struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *__pyx_v_self, char *__pyx_v_chrom, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_start, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_end, int __pyx_v_summary_size); /* proto */
+static PyObject *__pyx_pf_2bx_3bbi_8bbi_file_7BBIFile_8query(struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *__pyx_v_self, char *__pyx_v_chrom, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_start, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_end, int __pyx_v_summary_size); /* proto */
+static PyObject *__pyx_pf_2bx_3bbi_8bbi_file_7BBIFile_5magic___get__(struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *__pyx_v_self); /* proto */
+static int __pyx_pf_2bx_3bbi_8bbi_file_7BBIFile_5magic_2__set__(struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *__pyx_v_self, PyObject *__pyx_v_value); /* proto */
+static PyObject *__pyx_pf_2bx_3bbi_8bbi_file_7BBIFile_7version___get__(struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *__pyx_v_self); /* proto */
+static int __pyx_pf_2bx_3bbi_8bbi_file_7BBIFile_7version_2__set__(struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *__pyx_v_self, PyObject *__pyx_v_value); /* proto */
+static PyObject *__pyx_pf_2bx_3bbi_8bbi_file_7BBIFile_11zoom_levels___get__(struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *__pyx_v_self); /* proto */
+static int __pyx_pf_2bx_3bbi_8bbi_file_7BBIFile_11zoom_levels_2__set__(struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *__pyx_v_self, PyObject *__pyx_v_value); /* proto */
+static PyObject *__pyx_pf_2bx_3bbi_8bbi_file_7BBIFile_10level_list___get__(struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *__pyx_v_self); /* proto */
+static int __pyx_pf_2bx_3bbi_8bbi_file_7BBIFile_10level_list_2__set__(struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *__pyx_v_self, PyObject *__pyx_v_value); /* proto */
+static int __pyx_pf_2bx_3bbi_8bbi_file_7BBIFile_10level_list_4__del__(struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_2bx_3bbi_8bbi_file_9ZoomLevel__summary_blocks_in_region(struct __pyx_obj_2bx_3bbi_8bbi_file_ZoomLevel *__pyx_v_self, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_chrom_id, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_start, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_end); /* proto */
+static PyObject *__pyx_pf_2bx_3bbi_8bbi_file_9ZoomLevel_15reduction_level___get__(struct __pyx_obj_2bx_3bbi_8bbi_file_ZoomLevel *__pyx_v_self); /* proto */
+static int __pyx_pf_2bx_3bbi_8bbi_file_9ZoomLevel_15reduction_level_2__set__(struct __pyx_obj_2bx_3bbi_8bbi_file_ZoomLevel *__pyx_v_self, PyObject *__pyx_v_value); /* proto */
+static PyObject *__pyx_pf_2bx_3bbi_8bbi_file_9ZoomLevel_11data_offset___get__(struct __pyx_obj_2bx_3bbi_8bbi_file_ZoomLevel *__pyx_v_self); /* proto */
+static int __pyx_pf_2bx_3bbi_8bbi_file_9ZoomLevel_11data_offset_2__set__(struct __pyx_obj_2bx_3bbi_8bbi_file_ZoomLevel *__pyx_v_self, PyObject *__pyx_v_value); /* proto */
+static PyObject *__pyx_pf_2bx_3bbi_8bbi_file_9ZoomLevel_12index_offset___get__(struct __pyx_obj_2bx_3bbi_8bbi_file_ZoomLevel *__pyx_v_self); /* proto */
+static int __pyx_pf_2bx_3bbi_8bbi_file_9ZoomLevel_12index_offset_2__set__(struct __pyx_obj_2bx_3bbi_8bbi_file_ZoomLevel *__pyx_v_self, PyObject *__pyx_v_value); /* proto */
+static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /* proto */
+static void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info); /* proto */
+static PyObject *__pyx_tp_new_2bx_3bbi_8bbi_file_SummaryBlock(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
+static PyObject *__pyx_tp_new_2bx_3bbi_8bbi_file_SummarizedData(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
+static PyObject *__pyx_tp_new_2bx_3bbi_8bbi_file_BBIFile(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
+static PyObject *__pyx_tp_new_2bx_3bbi_8bbi_file_BlockHandler(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
+static PyObject *__pyx_tp_new_2bx_3bbi_8bbi_file_ZoomLevel(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
+static char __pyx_k_B[] = "B";
+static char __pyx_k_H[] = "H";
+static char __pyx_k_I[] = "I";
+static char __pyx_k_L[] = "L";
+static char __pyx_k_O[] = "O";
+static char __pyx_k_Q[] = "Q";
+static char __pyx_k_b[] = "b";
+static char __pyx_k_d[] = "d";
+static char __pyx_k_f[] = "f";
+static char __pyx_k_g[] = "g";
+static char __pyx_k_h[] = "h";
+static char __pyx_k_i[] = "i";
+static char __pyx_k_l[] = "l";
+static char __pyx_k_q[] = "q";
+static char __pyx_k_II[] = "II";
+static char __pyx_k_Zd[] = "Zd";
+static char __pyx_k_Zf[] = "Zf";
+static char __pyx_k_Zg[] = "Zg";
+static char __pyx_k_np[] = "np";
+static char __pyx_k_end[] = "end";
+static char __pyx_k_max[] = "max";
+static char __pyx_k_min[] = "min";
+static char __pyx_k_nan[] = "nan";
+static char __pyx_k_zip[] = "zip";
+static char __pyx_k_file[] = "file";
+static char __pyx_k_find[] = "find";
+static char __pyx_k_main[] = "__main__";
+static char __pyx_k_math[] = "math";
+static char __pyx_k_mean[] = "mean";
+static char __pyx_k_open[] = "open";
+static char __pyx_k_read[] = "read";
+static char __pyx_k_seek[] = "seek";
+static char __pyx_k_size[] = "size";
+static char __pyx_k_sqrt[] = "sqrt";
+static char __pyx_k_test[] = "__test__";
+static char __pyx_k_zlib[] = "zlib";
+static char __pyx_k_chrom[] = "chrom";
+static char __pyx_k_deque[] = "deque";
+static char __pyx_k_dtype[] = "dtype";
+static char __pyx_k_names[] = "names";
+static char __pyx_k_numpy[] = "numpy";
+static char __pyx_k_query[] = "query";
+static char __pyx_k_range[] = "range";
+static char __pyx_k_start[] = "start";
+static char __pyx_k_zeros[] = "zeros";
+static char __pyx_k_append[] = "append";
+static char __pyx_k_extend[] = "extend";
+static char __pyx_k_import[] = "__import__";
+static char __pyx_k_uint32[] = "uint32";
+static char __pyx_k_unpack[] = "unpack";
+static char __pyx_k_float32[] = "float32";
+static char __pyx_k_float64[] = "float64";
+static char __pyx_k_max_val[] = "max_val";
+static char __pyx_k_min_val[] = "min_val";
+static char __pyx_k_std_dev[] = "std_dev";
+static char __pyx_k_StringIO[] = "StringIO";
+static char __pyx_k_chrom_id[] = "chrom_id";
+static char __pyx_k_coverage[] = "coverage";
+static char __pyx_k_sum_data[] = "sum_data";
+static char __pyx_k_cStringIO[] = "cStringIO";
+static char __pyx_k_summarize[] = "summarize";
+static char __pyx_k_type_name[] = "type_name";
+static char __pyx_k_ValueError[] = "ValueError";
+static char __pyx_k_decompress[] = "decompress";
+static char __pyx_k_fromstring[] = "fromstring";
+static char __pyx_k_pyx_vtable[] = "__pyx_vtable__";
+static char __pyx_k_collections[] = "collections";
+static char __pyx_k_read_uint16[] = "read_uint16";
+static char __pyx_k_read_uint32[] = "read_uint32";
+static char __pyx_k_read_uint64[] = "read_uint64";
+static char __pyx_k_sum_squares[] = "sum_squares";
+static char __pyx_k_valid_count[] = "valid_count";
+static char __pyx_k_RuntimeError[] = "RuntimeError";
+static char __pyx_k_expected_sig[] = "expected_sig";
+static char __pyx_k_summary_size[] = "summary_size";
+static char __pyx_k_byteswap_needed[] = "byteswap_needed";
+static char __pyx_k_BinaryFileReader[] = "BinaryFileReader";
+static char __pyx_k_bx_misc_binary_file[] = "bx.misc.binary_file";
+static char __pyx_k_summarize_from_full[] = "summarize_from_full";
+static char __pyx_k_find_overlapping_blocks[] = "find_overlapping_blocks";
+static char __pyx_k_ndarray_is_not_C_contiguous[] = "ndarray is not C contiguous";
+static char __pyx_k_Core_implementation_for_reading[] = "\nCore implementation for reading UCSC \"big binary indexed\" files.\n\nThere isn't really any specification for the format beyond the code, so this\nmirrors Jim Kent's 'bbiRead.c' mostly. \n";
+static char __pyx_k_unknown_dtype_code_in_numpy_pxd[] = "unknown dtype code in numpy.pxd (%d)";
+static char __pyx_k_Format_string_allocated_too_shor[] = "Format string allocated too short, see comment in numpy.pxd";
+static char __pyx_k_Non_native_byte_order_not_suppor[] = "Non-native byte order not supported";
+static char __pyx_k_ndarray_is_not_Fortran_contiguou[] = "ndarray is not Fortran contiguous";
+static char __pyx_k_Format_string_allocated_too_shor_2[] = "Format string allocated too short.";
+static PyObject *__pyx_n_s_BinaryFileReader;
+static PyObject *__pyx_kp_u_Format_string_allocated_too_shor;
+static PyObject *__pyx_kp_u_Format_string_allocated_too_shor_2;
+static PyObject *__pyx_n_s_II;
+static PyObject *__pyx_kp_u_Non_native_byte_order_not_suppor;
+static PyObject *__pyx_n_s_RuntimeError;
+static PyObject *__pyx_n_s_StringIO;
+static PyObject *__pyx_n_s_ValueError;
+static PyObject *__pyx_n_s_append;
+static PyObject *__pyx_n_s_bx_misc_binary_file;
+static PyObject *__pyx_n_s_byteswap_needed;
+static PyObject *__pyx_n_s_cStringIO;
+static PyObject *__pyx_n_s_chrom;
+static PyObject *__pyx_n_s_chrom_id;
+static PyObject *__pyx_n_s_collections;
+static PyObject *__pyx_n_s_coverage;
+static PyObject *__pyx_n_s_decompress;
+static PyObject *__pyx_n_s_deque;
+static PyObject *__pyx_n_s_dtype;
+static PyObject *__pyx_n_s_end;
+static PyObject *__pyx_n_s_expected_sig;
+static PyObject *__pyx_n_s_extend;
+static PyObject *__pyx_n_s_file;
+static PyObject *__pyx_n_s_find;
+static PyObject *__pyx_n_s_find_overlapping_blocks;
+static PyObject *__pyx_n_s_float32;
+static PyObject *__pyx_n_s_float64;
+static PyObject *__pyx_n_s_fromstring;
+static PyObject *__pyx_n_s_import;
+static PyObject *__pyx_n_s_main;
+static PyObject *__pyx_n_s_math;
+static PyObject *__pyx_n_s_max;
+static PyObject *__pyx_n_s_max_val;
+static PyObject *__pyx_n_s_mean;
+static PyObject *__pyx_n_s_min;
+static PyObject *__pyx_n_s_min_val;
+static PyObject *__pyx_n_s_names;
+static PyObject *__pyx_n_s_nan;
+static PyObject *__pyx_kp_u_ndarray_is_not_C_contiguous;
+static PyObject *__pyx_kp_u_ndarray_is_not_Fortran_contiguou;
+static PyObject *__pyx_n_s_np;
+static PyObject *__pyx_n_s_numpy;
+static PyObject *__pyx_n_s_open;
+static PyObject *__pyx_n_s_pyx_vtable;
+static PyObject *__pyx_n_s_query;
+static PyObject *__pyx_n_s_range;
+static PyObject *__pyx_n_s_read;
+static PyObject *__pyx_n_s_read_uint16;
+static PyObject *__pyx_n_s_read_uint32;
+static PyObject *__pyx_n_s_read_uint64;
+static PyObject *__pyx_n_s_seek;
+static PyObject *__pyx_n_s_size;
+static PyObject *__pyx_n_s_sqrt;
+static PyObject *__pyx_n_s_start;
+static PyObject *__pyx_n_s_std_dev;
+static PyObject *__pyx_n_s_sum_data;
+static PyObject *__pyx_n_s_sum_squares;
+static PyObject *__pyx_n_s_summarize;
+static PyObject *__pyx_n_s_summarize_from_full;
+static PyObject *__pyx_n_s_summary_size;
+static PyObject *__pyx_n_s_test;
+static PyObject *__pyx_n_s_type_name;
+static PyObject *__pyx_n_s_uint32;
+static PyObject *__pyx_kp_u_unknown_dtype_code_in_numpy_pxd;
+static PyObject *__pyx_n_s_unpack;
+static PyObject *__pyx_n_s_valid_count;
+static PyObject *__pyx_n_s_zeros;
+static PyObject *__pyx_n_s_zip;
+static PyObject *__pyx_n_s_zlib;
+static PyObject *__pyx_int_0;
+static PyObject *__pyx_int_1;
+static PyObject *__pyx_int_32;
+static PyObject *__pyx_int_64;
+static PyObject *__pyx_tuple_;
+static PyObject *__pyx_tuple__2;
+static PyObject *__pyx_tuple__3;
+static PyObject *__pyx_tuple__4;
+static PyObject *__pyx_tuple__5;
+static PyObject *__pyx_tuple__6;
+static PyObject *__pyx_tuple__7;
+static PyObject *__pyx_tuple__8;
+int big_wig_sig;
+int big_bed_sig;
+
+/* "bx/bbi/bbi_file.pyx":37
+ * 
+ * @cython.profile(False)
+ * cdef inline int range_intersection( int start1, int end1, int start2, int end2 ):             # <<<<<<<<<<<<<<
+ *     return min( end1, end2 ) - max( start1, start2 )
+ * 
+ */
+
+static CYTHON_INLINE int __pyx_f_2bx_3bbi_8bbi_file_range_intersection(int __pyx_v_start1, int __pyx_v_end1, int __pyx_v_start2, int __pyx_v_end2) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  int __pyx_t_2;
+  int __pyx_t_3;
+  int __pyx_t_4;
+  __Pyx_RefNannySetupContext("range_intersection", 0);
+
+  /* "bx/bbi/bbi_file.pyx":38
+ * @cython.profile(False)
+ * cdef inline int range_intersection( int start1, int end1, int start2, int end2 ):
+ *     return min( end1, end2 ) - max( start1, start2 )             # <<<<<<<<<<<<<<
+ * 
+ * @cython.profile(False)
+ */
+  __pyx_t_1 = __pyx_v_end2;
+  __pyx_t_2 = __pyx_v_end1;
+  if (((__pyx_t_1 < __pyx_t_2) != 0)) {
+    __pyx_t_3 = __pyx_t_1;
+  } else {
+    __pyx_t_3 = __pyx_t_2;
+  }
+  __pyx_t_1 = __pyx_v_start2;
+  __pyx_t_2 = __pyx_v_start1;
+  if (((__pyx_t_1 > __pyx_t_2) != 0)) {
+    __pyx_t_4 = __pyx_t_1;
+  } else {
+    __pyx_t_4 = __pyx_t_2;
+  }
+  __pyx_r = (__pyx_t_3 - __pyx_t_4);
+  goto __pyx_L0;
+
+  /* "bx/bbi/bbi_file.pyx":37
+ * 
+ * @cython.profile(False)
+ * cdef inline int range_intersection( int start1, int end1, int start2, int end2 ):             # <<<<<<<<<<<<<<
+ *     return min( end1, end2 ) - max( start1, start2 )
+ * 
+ */
+
+  /* function exit code */
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bbi/bbi_file.pyx":41
+ * 
+ * @cython.profile(False)
+ * cdef inline int imax(int a, int b): return a if a >= b else b             # <<<<<<<<<<<<<<
+ * @cython.profile(False)
+ * cdef inline int imin(int a, int b): return a if a <= b else b
+ */
+
+static CYTHON_INLINE int __pyx_f_2bx_3bbi_8bbi_file_imax(int __pyx_v_a, int __pyx_v_b) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("imax", 0);
+  if (((__pyx_v_a >= __pyx_v_b) != 0)) {
+    __pyx_t_1 = __pyx_v_a;
+  } else {
+    __pyx_t_1 = __pyx_v_b;
+  }
+  __pyx_r = __pyx_t_1;
+  goto __pyx_L0;
+
+  /* function exit code */
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bbi/bbi_file.pyx":43
+ * cdef inline int imax(int a, int b): return a if a >= b else b
+ * @cython.profile(False)
+ * cdef inline int imin(int a, int b): return a if a <= b else b             # <<<<<<<<<<<<<<
+ * 
+ * cdef enum summary_type:
+ */
+
+static CYTHON_INLINE int __pyx_f_2bx_3bbi_8bbi_file_imin(int __pyx_v_a, int __pyx_v_b) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("imin", 0);
+  if (((__pyx_v_a <= __pyx_v_b) != 0)) {
+    __pyx_t_1 = __pyx_v_a;
+  } else {
+    __pyx_t_1 = __pyx_v_b;
+  }
+  __pyx_r = __pyx_t_1;
+  goto __pyx_L0;
+
+  /* function exit code */
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bbi/bbi_file.pxd":12
+ *     A block of summary data from disk
+ *     """
+ *     cdef public bits32 chrom_id             # <<<<<<<<<<<<<<
+ *     cdef public bits32 start
+ *     cdef public bits32 end
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_3bbi_8bbi_file_12SummaryBlock_8chrom_id_1__get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_2bx_3bbi_8bbi_file_12SummaryBlock_8chrom_id_1__get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_3bbi_8bbi_file_12SummaryBlock_8chrom_id___get__(((struct __pyx_obj_2bx_3bbi_8bbi_file_SummaryBlock *)__pyx_v_self));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_2bx_3bbi_8bbi_file_12SummaryBlock_8chrom_id___get__(struct __pyx_obj_2bx_3bbi_8bbi_file_SummaryBlock *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__get__", 0);
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = __Pyx_PyInt_From_unsigned_int(__pyx_v_self->chrom_id); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 12; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("bx.bbi.bbi_file.SummaryBlock.chrom_id.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_2bx_3bbi_8bbi_file_12SummaryBlock_8chrom_id_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value); /*proto*/
+static int __pyx_pw_2bx_3bbi_8bbi_file_12SummaryBlock_8chrom_id_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__set__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_3bbi_8bbi_file_12SummaryBlock_8chrom_id_2__set__(((struct __pyx_obj_2bx_3bbi_8bbi_file_SummaryBlock *)__pyx_v_self), ((PyObject *)__pyx_v_value));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_2bx_3bbi_8bbi_file_12SummaryBlock_8chrom_id_2__set__(struct __pyx_obj_2bx_3bbi_8bbi_file_SummaryBlock *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __pyx_t_2bx_3bbi_5types_bits32 __pyx_t_1;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__set__", 0);
+  __pyx_t_1 = __Pyx_PyInt_As_unsigned_int(__pyx_v_value); if (unlikely((__pyx_t_1 == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 12; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_v_self->chrom_id = __pyx_t_1;
+
+  /* function exit code */
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_AddTraceback("bx.bbi.bbi_file.SummaryBlock.chrom_id.__set__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = -1;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bbi/bbi_file.pxd":13
+ *     """
+ *     cdef public bits32 chrom_id
+ *     cdef public bits32 start             # <<<<<<<<<<<<<<
+ *     cdef public bits32 end
+ *     cdef public bits32 valid_count
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_3bbi_8bbi_file_12SummaryBlock_5start_1__get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_2bx_3bbi_8bbi_file_12SummaryBlock_5start_1__get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_3bbi_8bbi_file_12SummaryBlock_5start___get__(((struct __pyx_obj_2bx_3bbi_8bbi_file_SummaryBlock *)__pyx_v_self));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_2bx_3bbi_8bbi_file_12SummaryBlock_5start___get__(struct __pyx_obj_2bx_3bbi_8bbi_file_SummaryBlock *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__get__", 0);
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = __Pyx_PyInt_From_unsigned_int(__pyx_v_self->start); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 13; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("bx.bbi.bbi_file.SummaryBlock.start.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_2bx_3bbi_8bbi_file_12SummaryBlock_5start_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value); /*proto*/
+static int __pyx_pw_2bx_3bbi_8bbi_file_12SummaryBlock_5start_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__set__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_3bbi_8bbi_file_12SummaryBlock_5start_2__set__(((struct __pyx_obj_2bx_3bbi_8bbi_file_SummaryBlock *)__pyx_v_self), ((PyObject *)__pyx_v_value));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_2bx_3bbi_8bbi_file_12SummaryBlock_5start_2__set__(struct __pyx_obj_2bx_3bbi_8bbi_file_SummaryBlock *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __pyx_t_2bx_3bbi_5types_bits32 __pyx_t_1;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__set__", 0);
+  __pyx_t_1 = __Pyx_PyInt_As_unsigned_int(__pyx_v_value); if (unlikely((__pyx_t_1 == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 13; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_v_self->start = __pyx_t_1;
+
+  /* function exit code */
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_AddTraceback("bx.bbi.bbi_file.SummaryBlock.start.__set__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = -1;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bbi/bbi_file.pxd":14
+ *     cdef public bits32 chrom_id
+ *     cdef public bits32 start
+ *     cdef public bits32 end             # <<<<<<<<<<<<<<
+ *     cdef public bits32 valid_count
+ *     cdef public double min_val
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_3bbi_8bbi_file_12SummaryBlock_3end_1__get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_2bx_3bbi_8bbi_file_12SummaryBlock_3end_1__get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_3bbi_8bbi_file_12SummaryBlock_3end___get__(((struct __pyx_obj_2bx_3bbi_8bbi_file_SummaryBlock *)__pyx_v_self));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_2bx_3bbi_8bbi_file_12SummaryBlock_3end___get__(struct __pyx_obj_2bx_3bbi_8bbi_file_SummaryBlock *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__get__", 0);
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = __Pyx_PyInt_From_unsigned_int(__pyx_v_self->end); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 14; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("bx.bbi.bbi_file.SummaryBlock.end.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_2bx_3bbi_8bbi_file_12SummaryBlock_3end_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value); /*proto*/
+static int __pyx_pw_2bx_3bbi_8bbi_file_12SummaryBlock_3end_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__set__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_3bbi_8bbi_file_12SummaryBlock_3end_2__set__(((struct __pyx_obj_2bx_3bbi_8bbi_file_SummaryBlock *)__pyx_v_self), ((PyObject *)__pyx_v_value));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_2bx_3bbi_8bbi_file_12SummaryBlock_3end_2__set__(struct __pyx_obj_2bx_3bbi_8bbi_file_SummaryBlock *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __pyx_t_2bx_3bbi_5types_bits32 __pyx_t_1;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__set__", 0);
+  __pyx_t_1 = __Pyx_PyInt_As_unsigned_int(__pyx_v_value); if (unlikely((__pyx_t_1 == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 14; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_v_self->end = __pyx_t_1;
+
+  /* function exit code */
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_AddTraceback("bx.bbi.bbi_file.SummaryBlock.end.__set__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = -1;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bbi/bbi_file.pxd":15
+ *     cdef public bits32 start
+ *     cdef public bits32 end
+ *     cdef public bits32 valid_count             # <<<<<<<<<<<<<<
+ *     cdef public double min_val
+ *     cdef public double max_val
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_3bbi_8bbi_file_12SummaryBlock_11valid_count_1__get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_2bx_3bbi_8bbi_file_12SummaryBlock_11valid_count_1__get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_3bbi_8bbi_file_12SummaryBlock_11valid_count___get__(((struct __pyx_obj_2bx_3bbi_8bbi_file_SummaryBlock *)__pyx_v_self));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_2bx_3bbi_8bbi_file_12SummaryBlock_11valid_count___get__(struct __pyx_obj_2bx_3bbi_8bbi_file_SummaryBlock *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__get__", 0);
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = __Pyx_PyInt_From_unsigned_int(__pyx_v_self->valid_count); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 15; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("bx.bbi.bbi_file.SummaryBlock.valid_count.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_2bx_3bbi_8bbi_file_12SummaryBlock_11valid_count_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value); /*proto*/
+static int __pyx_pw_2bx_3bbi_8bbi_file_12SummaryBlock_11valid_count_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__set__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_3bbi_8bbi_file_12SummaryBlock_11valid_count_2__set__(((struct __pyx_obj_2bx_3bbi_8bbi_file_SummaryBlock *)__pyx_v_self), ((PyObject *)__pyx_v_value));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_2bx_3bbi_8bbi_file_12SummaryBlock_11valid_count_2__set__(struct __pyx_obj_2bx_3bbi_8bbi_file_SummaryBlock *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __pyx_t_2bx_3bbi_5types_bits32 __pyx_t_1;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__set__", 0);
+  __pyx_t_1 = __Pyx_PyInt_As_unsigned_int(__pyx_v_value); if (unlikely((__pyx_t_1 == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 15; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_v_self->valid_count = __pyx_t_1;
+
+  /* function exit code */
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_AddTraceback("bx.bbi.bbi_file.SummaryBlock.valid_count.__set__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = -1;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bbi/bbi_file.pxd":16
+ *     cdef public bits32 end
+ *     cdef public bits32 valid_count
+ *     cdef public double min_val             # <<<<<<<<<<<<<<
+ *     cdef public double max_val
+ *     cdef public double sum_data
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_3bbi_8bbi_file_12SummaryBlock_7min_val_1__get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_2bx_3bbi_8bbi_file_12SummaryBlock_7min_val_1__get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_3bbi_8bbi_file_12SummaryBlock_7min_val___get__(((struct __pyx_obj_2bx_3bbi_8bbi_file_SummaryBlock *)__pyx_v_self));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_2bx_3bbi_8bbi_file_12SummaryBlock_7min_val___get__(struct __pyx_obj_2bx_3bbi_8bbi_file_SummaryBlock *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__get__", 0);
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = PyFloat_FromDouble(__pyx_v_self->min_val); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 16; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("bx.bbi.bbi_file.SummaryBlock.min_val.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_2bx_3bbi_8bbi_file_12SummaryBlock_7min_val_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value); /*proto*/
+static int __pyx_pw_2bx_3bbi_8bbi_file_12SummaryBlock_7min_val_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__set__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_3bbi_8bbi_file_12SummaryBlock_7min_val_2__set__(((struct __pyx_obj_2bx_3bbi_8bbi_file_SummaryBlock *)__pyx_v_self), ((PyObject *)__pyx_v_value));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_2bx_3bbi_8bbi_file_12SummaryBlock_7min_val_2__set__(struct __pyx_obj_2bx_3bbi_8bbi_file_SummaryBlock *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  double __pyx_t_1;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__set__", 0);
+  __pyx_t_1 = __pyx_PyFloat_AsDouble(__pyx_v_value); if (unlikely((__pyx_t_1 == (double)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 16; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_v_self->min_val = __pyx_t_1;
+
+  /* function exit code */
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_AddTraceback("bx.bbi.bbi_file.SummaryBlock.min_val.__set__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = -1;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bbi/bbi_file.pxd":17
+ *     cdef public bits32 valid_count
+ *     cdef public double min_val
+ *     cdef public double max_val             # <<<<<<<<<<<<<<
+ *     cdef public double sum_data
+ *     cdef public double sum_squares
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_3bbi_8bbi_file_12SummaryBlock_7max_val_1__get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_2bx_3bbi_8bbi_file_12SummaryBlock_7max_val_1__get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_3bbi_8bbi_file_12SummaryBlock_7max_val___get__(((struct __pyx_obj_2bx_3bbi_8bbi_file_SummaryBlock *)__pyx_v_self));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_2bx_3bbi_8bbi_file_12SummaryBlock_7max_val___get__(struct __pyx_obj_2bx_3bbi_8bbi_file_SummaryBlock *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__get__", 0);
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = PyFloat_FromDouble(__pyx_v_self->max_val); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 17; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("bx.bbi.bbi_file.SummaryBlock.max_val.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_2bx_3bbi_8bbi_file_12SummaryBlock_7max_val_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value); /*proto*/
+static int __pyx_pw_2bx_3bbi_8bbi_file_12SummaryBlock_7max_val_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__set__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_3bbi_8bbi_file_12SummaryBlock_7max_val_2__set__(((struct __pyx_obj_2bx_3bbi_8bbi_file_SummaryBlock *)__pyx_v_self), ((PyObject *)__pyx_v_value));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_2bx_3bbi_8bbi_file_12SummaryBlock_7max_val_2__set__(struct __pyx_obj_2bx_3bbi_8bbi_file_SummaryBlock *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  double __pyx_t_1;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__set__", 0);
+  __pyx_t_1 = __pyx_PyFloat_AsDouble(__pyx_v_value); if (unlikely((__pyx_t_1 == (double)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 17; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_v_self->max_val = __pyx_t_1;
+
+  /* function exit code */
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_AddTraceback("bx.bbi.bbi_file.SummaryBlock.max_val.__set__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = -1;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bbi/bbi_file.pxd":18
+ *     cdef public double min_val
+ *     cdef public double max_val
+ *     cdef public double sum_data             # <<<<<<<<<<<<<<
+ *     cdef public double sum_squares
+ * 
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_3bbi_8bbi_file_12SummaryBlock_8sum_data_1__get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_2bx_3bbi_8bbi_file_12SummaryBlock_8sum_data_1__get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_3bbi_8bbi_file_12SummaryBlock_8sum_data___get__(((struct __pyx_obj_2bx_3bbi_8bbi_file_SummaryBlock *)__pyx_v_self));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_2bx_3bbi_8bbi_file_12SummaryBlock_8sum_data___get__(struct __pyx_obj_2bx_3bbi_8bbi_file_SummaryBlock *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__get__", 0);
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = PyFloat_FromDouble(__pyx_v_self->sum_data); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 18; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("bx.bbi.bbi_file.SummaryBlock.sum_data.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_2bx_3bbi_8bbi_file_12SummaryBlock_8sum_data_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value); /*proto*/
+static int __pyx_pw_2bx_3bbi_8bbi_file_12SummaryBlock_8sum_data_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__set__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_3bbi_8bbi_file_12SummaryBlock_8sum_data_2__set__(((struct __pyx_obj_2bx_3bbi_8bbi_file_SummaryBlock *)__pyx_v_self), ((PyObject *)__pyx_v_value));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_2bx_3bbi_8bbi_file_12SummaryBlock_8sum_data_2__set__(struct __pyx_obj_2bx_3bbi_8bbi_file_SummaryBlock *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  double __pyx_t_1;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__set__", 0);
+  __pyx_t_1 = __pyx_PyFloat_AsDouble(__pyx_v_value); if (unlikely((__pyx_t_1 == (double)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 18; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_v_self->sum_data = __pyx_t_1;
+
+  /* function exit code */
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_AddTraceback("bx.bbi.bbi_file.SummaryBlock.sum_data.__set__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = -1;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bbi/bbi_file.pxd":19
+ *     cdef public double max_val
+ *     cdef public double sum_data
+ *     cdef public double sum_squares             # <<<<<<<<<<<<<<
+ * 
+ * cdef class SummarizedData:
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_3bbi_8bbi_file_12SummaryBlock_11sum_squares_1__get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_2bx_3bbi_8bbi_file_12SummaryBlock_11sum_squares_1__get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_3bbi_8bbi_file_12SummaryBlock_11sum_squares___get__(((struct __pyx_obj_2bx_3bbi_8bbi_file_SummaryBlock *)__pyx_v_self));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_2bx_3bbi_8bbi_file_12SummaryBlock_11sum_squares___get__(struct __pyx_obj_2bx_3bbi_8bbi_file_SummaryBlock *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__get__", 0);
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = PyFloat_FromDouble(__pyx_v_self->sum_squares); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 19; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("bx.bbi.bbi_file.SummaryBlock.sum_squares.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_2bx_3bbi_8bbi_file_12SummaryBlock_11sum_squares_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value); /*proto*/
+static int __pyx_pw_2bx_3bbi_8bbi_file_12SummaryBlock_11sum_squares_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__set__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_3bbi_8bbi_file_12SummaryBlock_11sum_squares_2__set__(((struct __pyx_obj_2bx_3bbi_8bbi_file_SummaryBlock *)__pyx_v_self), ((PyObject *)__pyx_v_value));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_2bx_3bbi_8bbi_file_12SummaryBlock_11sum_squares_2__set__(struct __pyx_obj_2bx_3bbi_8bbi_file_SummaryBlock *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  double __pyx_t_1;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__set__", 0);
+  __pyx_t_1 = __pyx_PyFloat_AsDouble(__pyx_v_value); if (unlikely((__pyx_t_1 == (double)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 19; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_v_self->sum_squares = __pyx_t_1;
+
+  /* function exit code */
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_AddTraceback("bx.bbi.bbi_file.SummaryBlock.sum_squares.__set__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = -1;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bbi/bbi_file.pyx":63
+ *     aggregation over a particular range and resolution
+ *     """
+ *     def __init__( self, bits32 start, bits32 end, int size ):             # <<<<<<<<<<<<<<
+ *         self.start = start
+ *         self.end = end
+ */
+
+/* Python wrapper */
+static int __pyx_pw_2bx_3bbi_8bbi_file_14SummarizedData_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static int __pyx_pw_2bx_3bbi_8bbi_file_14SummarizedData_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_start;
+  __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_end;
+  int __pyx_v_size;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__init__ (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_start,&__pyx_n_s_end,&__pyx_n_s_size,0};
+    PyObject* values[3] = {0,0,0};
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_start)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_end)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("__init__", 1, 3, 3, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 63; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+        case  2:
+        if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_size)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("__init__", 1, 3, 3, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 63; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 63; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else if (PyTuple_GET_SIZE(__pyx_args) != 3) {
+      goto __pyx_L5_argtuple_error;
+    } else {
+      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+      values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+    }
+    __pyx_v_start = __Pyx_PyInt_As_unsigned_int(values[0]); if (unlikely((__pyx_v_start == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 63; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_end = __Pyx_PyInt_As_unsigned_int(values[1]); if (unlikely((__pyx_v_end == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 63; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_size = __Pyx_PyInt_As_int(values[2]); if (unlikely((__pyx_v_size == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 63; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("__init__", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 63; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.bbi.bbi_file.SummarizedData.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return -1;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_3bbi_8bbi_file_14SummarizedData___init__(((struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData *)__pyx_v_self), __pyx_v_start, __pyx_v_end, __pyx_v_size);
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_2bx_3bbi_8bbi_file_14SummarizedData___init__(struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData *__pyx_v_self, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_start, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_end, int __pyx_v_size) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  PyObject *__pyx_t_5 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__init__", 0);
+
+  /* "bx/bbi/bbi_file.pyx":64
+ *     """
+ *     def __init__( self, bits32 start, bits32 end, int size ):
+ *         self.start = start             # <<<<<<<<<<<<<<
+ *         self.end = end
+ *         self.size = size
+ */
+  __pyx_v_self->start = __pyx_v_start;
+
+  /* "bx/bbi/bbi_file.pyx":65
+ *     def __init__( self, bits32 start, bits32 end, int size ):
+ *         self.start = start
+ *         self.end = end             # <<<<<<<<<<<<<<
+ *         self.size = size
+ *         self.valid_count = numpy.zeros( self.size, dtype=numpy.float64 )
+ */
+  __pyx_v_self->end = __pyx_v_end;
+
+  /* "bx/bbi/bbi_file.pyx":66
+ *         self.start = start
+ *         self.end = end
+ *         self.size = size             # <<<<<<<<<<<<<<
+ *         self.valid_count = numpy.zeros( self.size, dtype=numpy.float64 )
+ *         self.min_val = numpy.zeros( self.size, dtype=numpy.float64 )
+ */
+  __pyx_v_self->size = __pyx_v_size;
+
+  /* "bx/bbi/bbi_file.pyx":67
+ *         self.end = end
+ *         self.size = size
+ *         self.valid_count = numpy.zeros( self.size, dtype=numpy.float64 )             # <<<<<<<<<<<<<<
+ *         self.min_val = numpy.zeros( self.size, dtype=numpy.float64 )
+ *         self.max_val = numpy.zeros( self.size, dtype=numpy.float64 )
+ */
+  __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 67; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_zeros); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 67; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_self->size); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 67; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 67; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1);
+  __Pyx_GIVEREF(__pyx_t_1);
+  __pyx_t_1 = 0;
+  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 67; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 67; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_float64); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 67; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_dtype, __pyx_t_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 67; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+  __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_3, __pyx_t_1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 67; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  if (!(likely(((__pyx_t_5) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_5, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 67; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GIVEREF(__pyx_t_5);
+  __Pyx_GOTREF(__pyx_v_self->valid_count);
+  __Pyx_DECREF(((PyObject *)__pyx_v_self->valid_count));
+  __pyx_v_self->valid_count = ((PyArrayObject *)__pyx_t_5);
+  __pyx_t_5 = 0;
+
+  /* "bx/bbi/bbi_file.pyx":68
+ *         self.size = size
+ *         self.valid_count = numpy.zeros( self.size, dtype=numpy.float64 )
+ *         self.min_val = numpy.zeros( self.size, dtype=numpy.float64 )             # <<<<<<<<<<<<<<
+ *         self.max_val = numpy.zeros( self.size, dtype=numpy.float64 )
+ *         self.sum_data = numpy.zeros( self.size, dtype=numpy.float64 )
+ */
+  __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 68; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_zeros); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 68; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+  __pyx_t_5 = __Pyx_PyInt_From_int(__pyx_v_self->size); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 68; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 68; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_5);
+  __Pyx_GIVEREF(__pyx_t_5);
+  __pyx_t_5 = 0;
+  __pyx_t_5 = PyDict_New(); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 68; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 68; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_float64); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 68; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_dtype, __pyx_t_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 68; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_3, __pyx_t_5); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 68; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+  if (!(likely(((__pyx_t_4) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_4, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 68; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GIVEREF(__pyx_t_4);
+  __Pyx_GOTREF(__pyx_v_self->min_val);
+  __Pyx_DECREF(((PyObject *)__pyx_v_self->min_val));
+  __pyx_v_self->min_val = ((PyArrayObject *)__pyx_t_4);
+  __pyx_t_4 = 0;
+
+  /* "bx/bbi/bbi_file.pyx":69
+ *         self.valid_count = numpy.zeros( self.size, dtype=numpy.float64 )
+ *         self.min_val = numpy.zeros( self.size, dtype=numpy.float64 )
+ *         self.max_val = numpy.zeros( self.size, dtype=numpy.float64 )             # <<<<<<<<<<<<<<
+ *         self.sum_data = numpy.zeros( self.size, dtype=numpy.float64 )
+ *         self.sum_squares = numpy.zeros( self.size, dtype=numpy.float64 )
+ */
+  __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 69; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_zeros); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 69; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  __pyx_t_4 = __Pyx_PyInt_From_int(__pyx_v_self->size); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 69; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 69; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_4);
+  __Pyx_GIVEREF(__pyx_t_4);
+  __pyx_t_4 = 0;
+  __pyx_t_4 = PyDict_New(); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 69; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 69; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_float64); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 69; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_dtype, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 69; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 69; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 69; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GIVEREF(__pyx_t_2);
+  __Pyx_GOTREF(__pyx_v_self->max_val);
+  __Pyx_DECREF(((PyObject *)__pyx_v_self->max_val));
+  __pyx_v_self->max_val = ((PyArrayObject *)__pyx_t_2);
+  __pyx_t_2 = 0;
+
+  /* "bx/bbi/bbi_file.pyx":70
+ *         self.min_val = numpy.zeros( self.size, dtype=numpy.float64 )
+ *         self.max_val = numpy.zeros( self.size, dtype=numpy.float64 )
+ *         self.sum_data = numpy.zeros( self.size, dtype=numpy.float64 )             # <<<<<<<<<<<<<<
+ *         self.sum_squares = numpy.zeros( self.size, dtype=numpy.float64 )
+ *     cdef accumulate_interval_value( self, bits32 s, bits32 e, float val ):
+ */
+  __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 70; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_zeros); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 70; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_2 = __Pyx_PyInt_From_int(__pyx_v_self->size); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 70; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 70; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_2);
+  __Pyx_GIVEREF(__pyx_t_2);
+  __pyx_t_2 = 0;
+  __pyx_t_2 = PyDict_New(); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 70; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 70; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_float64); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 70; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+  if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_dtype, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 70; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_3, __pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 70; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 70; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GIVEREF(__pyx_t_1);
+  __Pyx_GOTREF(__pyx_v_self->sum_data);
+  __Pyx_DECREF(((PyObject *)__pyx_v_self->sum_data));
+  __pyx_v_self->sum_data = ((PyArrayObject *)__pyx_t_1);
+  __pyx_t_1 = 0;
+
+  /* "bx/bbi/bbi_file.pyx":71
+ *         self.max_val = numpy.zeros( self.size, dtype=numpy.float64 )
+ *         self.sum_data = numpy.zeros( self.size, dtype=numpy.float64 )
+ *         self.sum_squares = numpy.zeros( self.size, dtype=numpy.float64 )             # <<<<<<<<<<<<<<
+ *     cdef accumulate_interval_value( self, bits32 s, bits32 e, float val ):
+ *         cdef int base_start, base_end, base_step, overlap, j, interval_size
+ */
+  __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 71; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_zeros); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 71; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_self->size); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 71; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 71; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1);
+  __Pyx_GIVEREF(__pyx_t_1);
+  __pyx_t_1 = 0;
+  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 71; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 71; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_float64); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 71; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_dtype, __pyx_t_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 71; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+  __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_3, __pyx_t_1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 71; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  if (!(likely(((__pyx_t_5) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_5, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 71; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GIVEREF(__pyx_t_5);
+  __Pyx_GOTREF(__pyx_v_self->sum_squares);
+  __Pyx_DECREF(((PyObject *)__pyx_v_self->sum_squares));
+  __pyx_v_self->sum_squares = ((PyArrayObject *)__pyx_t_5);
+  __pyx_t_5 = 0;
+
+  /* "bx/bbi/bbi_file.pyx":63
+ *     aggregation over a particular range and resolution
+ *     """
+ *     def __init__( self, bits32 start, bits32 end, int size ):             # <<<<<<<<<<<<<<
+ *         self.start = start
+ *         self.end = end
+ */
+
+  /* function exit code */
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_XDECREF(__pyx_t_5);
+  __Pyx_AddTraceback("bx.bbi.bbi_file.SummarizedData.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = -1;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bbi/bbi_file.pyx":72
+ *         self.sum_data = numpy.zeros( self.size, dtype=numpy.float64 )
+ *         self.sum_squares = numpy.zeros( self.size, dtype=numpy.float64 )
+ *     cdef accumulate_interval_value( self, bits32 s, bits32 e, float val ):             # <<<<<<<<<<<<<<
+ *         cdef int base_start, base_end, base_step, overlap, j, interval_size
+ *         cdef double overlap_factor, interval_weight
+ */
+
+static PyObject *__pyx_f_2bx_3bbi_8bbi_file_14SummarizedData_accumulate_interval_value(struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData *__pyx_v_self, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_s, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_e, float __pyx_v_val) {
+  int __pyx_v_base_start;
+  int __pyx_v_base_end;
+  int __pyx_v_base_step;
+  int __pyx_v_overlap;
+  int __pyx_v_j;
+  int __pyx_v_interval_size;
+  double __pyx_v_overlap_factor;
+  double __pyx_v_interval_weight;
+  PyArrayObject *__pyx_v_valid_count = 0;
+  PyArrayObject *__pyx_v_min_val = 0;
+  PyArrayObject *__pyx_v_max_val = 0;
+  PyArrayObject *__pyx_v_sum_data = 0;
+  PyArrayObject *__pyx_v_sum_squares = 0;
+  __Pyx_LocalBuf_ND __pyx_pybuffernd_max_val;
+  __Pyx_Buffer __pyx_pybuffer_max_val;
+  __Pyx_LocalBuf_ND __pyx_pybuffernd_min_val;
+  __Pyx_Buffer __pyx_pybuffer_min_val;
+  __Pyx_LocalBuf_ND __pyx_pybuffernd_sum_data;
+  __Pyx_Buffer __pyx_pybuffer_sum_data;
+  __Pyx_LocalBuf_ND __pyx_pybuffernd_sum_squares;
+  __Pyx_Buffer __pyx_pybuffer_sum_squares;
+  __Pyx_LocalBuf_ND __pyx_pybuffernd_valid_count;
+  __Pyx_Buffer __pyx_pybuffer_valid_count;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_t_2;
+  __pyx_t_2bx_3bbi_5types_bits32 __pyx_t_3;
+  int __pyx_t_4;
+  int __pyx_t_5;
+  int __pyx_t_6;
+  int __pyx_t_7;
+  int __pyx_t_8;
+  int __pyx_t_9;
+  int __pyx_t_10;
+  int __pyx_t_11;
+  int __pyx_t_12;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("accumulate_interval_value", 0);
+  __pyx_pybuffer_valid_count.pybuffer.buf = NULL;
+  __pyx_pybuffer_valid_count.refcount = 0;
+  __pyx_pybuffernd_valid_count.data = NULL;
+  __pyx_pybuffernd_valid_count.rcbuffer = &__pyx_pybuffer_valid_count;
+  __pyx_pybuffer_min_val.pybuffer.buf = NULL;
+  __pyx_pybuffer_min_val.refcount = 0;
+  __pyx_pybuffernd_min_val.data = NULL;
+  __pyx_pybuffernd_min_val.rcbuffer = &__pyx_pybuffer_min_val;
+  __pyx_pybuffer_max_val.pybuffer.buf = NULL;
+  __pyx_pybuffer_max_val.refcount = 0;
+  __pyx_pybuffernd_max_val.data = NULL;
+  __pyx_pybuffernd_max_val.rcbuffer = &__pyx_pybuffer_max_val;
+  __pyx_pybuffer_sum_data.pybuffer.buf = NULL;
+  __pyx_pybuffer_sum_data.refcount = 0;
+  __pyx_pybuffernd_sum_data.data = NULL;
+  __pyx_pybuffernd_sum_data.rcbuffer = &__pyx_pybuffer_sum_data;
+  __pyx_pybuffer_sum_squares.pybuffer.buf = NULL;
+  __pyx_pybuffer_sum_squares.refcount = 0;
+  __pyx_pybuffernd_sum_squares.data = NULL;
+  __pyx_pybuffernd_sum_squares.rcbuffer = &__pyx_pybuffer_sum_squares;
+
+  /* "bx/bbi/bbi_file.pyx":76
+ *         cdef double overlap_factor, interval_weight
+ *         # We locally cdef the arrays so all indexing will be at C speeds
+ *         cdef numpy.ndarray[numpy.float64_t, ndim=1] valid_count = self.valid_count             # <<<<<<<<<<<<<<
+ *         cdef numpy.ndarray[numpy.float64_t, ndim=1] min_val = self.min_val
+ *         cdef numpy.ndarray[numpy.float64_t, ndim=1] max_val = self.max_val
+ */
+  __pyx_t_1 = ((PyObject *)__pyx_v_self->valid_count);
+  __Pyx_INCREF(__pyx_t_1);
+  {
+    __Pyx_BufFmt_StackElem __pyx_stack[1];
+    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_valid_count.rcbuffer->pybuffer, (PyObject*)((PyArrayObject *)__pyx_t_1), &__Pyx_TypeInfo_nn___pyx_t_5numpy_float64_t, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 1, 0, __pyx_stack) == -1)) {
+      __pyx_v_valid_count = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_valid_count.rcbuffer->pybuffer.buf = NULL;
+      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 76; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    } else {__pyx_pybuffernd_valid_count.diminfo[0].strides = __pyx_pybuffernd_valid_count.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_valid_count.diminfo[0].shape = __pyx_pybuffernd_valid_count.rcbuffer->pybuffer.shape[0];
+    }
+  }
+  __pyx_v_valid_count = ((PyArrayObject *)__pyx_t_1);
+  __pyx_t_1 = 0;
+
+  /* "bx/bbi/bbi_file.pyx":77
+ *         # We locally cdef the arrays so all indexing will be at C speeds
+ *         cdef numpy.ndarray[numpy.float64_t, ndim=1] valid_count = self.valid_count
+ *         cdef numpy.ndarray[numpy.float64_t, ndim=1] min_val = self.min_val             # <<<<<<<<<<<<<<
+ *         cdef numpy.ndarray[numpy.float64_t, ndim=1] max_val = self.max_val
+ *         cdef numpy.ndarray[numpy.float64_t, ndim=1] sum_data = self.sum_data
+ */
+  __pyx_t_1 = ((PyObject *)__pyx_v_self->min_val);
+  __Pyx_INCREF(__pyx_t_1);
+  {
+    __Pyx_BufFmt_StackElem __pyx_stack[1];
+    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_min_val.rcbuffer->pybuffer, (PyObject*)((PyArrayObject *)__pyx_t_1), &__Pyx_TypeInfo_nn___pyx_t_5numpy_float64_t, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 1, 0, __pyx_stack) == -1)) {
+      __pyx_v_min_val = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_min_val.rcbuffer->pybuffer.buf = NULL;
+      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 77; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    } else {__pyx_pybuffernd_min_val.diminfo[0].strides = __pyx_pybuffernd_min_val.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_min_val.diminfo[0].shape = __pyx_pybuffernd_min_val.rcbuffer->pybuffer.shape[0];
+    }
+  }
+  __pyx_v_min_val = ((PyArrayObject *)__pyx_t_1);
+  __pyx_t_1 = 0;
+
+  /* "bx/bbi/bbi_file.pyx":78
+ *         cdef numpy.ndarray[numpy.float64_t, ndim=1] valid_count = self.valid_count
+ *         cdef numpy.ndarray[numpy.float64_t, ndim=1] min_val = self.min_val
+ *         cdef numpy.ndarray[numpy.float64_t, ndim=1] max_val = self.max_val             # <<<<<<<<<<<<<<
+ *         cdef numpy.ndarray[numpy.float64_t, ndim=1] sum_data = self.sum_data
+ *         cdef numpy.ndarray[numpy.float64_t, ndim=1] sum_squares = self.sum_squares
+ */
+  __pyx_t_1 = ((PyObject *)__pyx_v_self->max_val);
+  __Pyx_INCREF(__pyx_t_1);
+  {
+    __Pyx_BufFmt_StackElem __pyx_stack[1];
+    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_max_val.rcbuffer->pybuffer, (PyObject*)((PyArrayObject *)__pyx_t_1), &__Pyx_TypeInfo_nn___pyx_t_5numpy_float64_t, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 1, 0, __pyx_stack) == -1)) {
+      __pyx_v_max_val = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_max_val.rcbuffer->pybuffer.buf = NULL;
+      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 78; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    } else {__pyx_pybuffernd_max_val.diminfo[0].strides = __pyx_pybuffernd_max_val.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_max_val.diminfo[0].shape = __pyx_pybuffernd_max_val.rcbuffer->pybuffer.shape[0];
+    }
+  }
+  __pyx_v_max_val = ((PyArrayObject *)__pyx_t_1);
+  __pyx_t_1 = 0;
+
+  /* "bx/bbi/bbi_file.pyx":79
+ *         cdef numpy.ndarray[numpy.float64_t, ndim=1] min_val = self.min_val
+ *         cdef numpy.ndarray[numpy.float64_t, ndim=1] max_val = self.max_val
+ *         cdef numpy.ndarray[numpy.float64_t, ndim=1] sum_data = self.sum_data             # <<<<<<<<<<<<<<
+ *         cdef numpy.ndarray[numpy.float64_t, ndim=1] sum_squares = self.sum_squares
+ *         # Trim interval down to region of interest
+ */
+  __pyx_t_1 = ((PyObject *)__pyx_v_self->sum_data);
+  __Pyx_INCREF(__pyx_t_1);
+  {
+    __Pyx_BufFmt_StackElem __pyx_stack[1];
+    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_sum_data.rcbuffer->pybuffer, (PyObject*)((PyArrayObject *)__pyx_t_1), &__Pyx_TypeInfo_nn___pyx_t_5numpy_float64_t, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 1, 0, __pyx_stack) == -1)) {
+      __pyx_v_sum_data = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_sum_data.rcbuffer->pybuffer.buf = NULL;
+      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 79; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    } else {__pyx_pybuffernd_sum_data.diminfo[0].strides = __pyx_pybuffernd_sum_data.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_sum_data.diminfo[0].shape = __pyx_pybuffernd_sum_data.rcbuffer->pybuffer.shape[0];
+    }
+  }
+  __pyx_v_sum_data = ((PyArrayObject *)__pyx_t_1);
+  __pyx_t_1 = 0;
+
+  /* "bx/bbi/bbi_file.pyx":80
+ *         cdef numpy.ndarray[numpy.float64_t, ndim=1] max_val = self.max_val
+ *         cdef numpy.ndarray[numpy.float64_t, ndim=1] sum_data = self.sum_data
+ *         cdef numpy.ndarray[numpy.float64_t, ndim=1] sum_squares = self.sum_squares             # <<<<<<<<<<<<<<
+ *         # Trim interval down to region of interest
+ *         if s < self.start:
+ */
+  __pyx_t_1 = ((PyObject *)__pyx_v_self->sum_squares);
+  __Pyx_INCREF(__pyx_t_1);
+  {
+    __Pyx_BufFmt_StackElem __pyx_stack[1];
+    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_sum_squares.rcbuffer->pybuffer, (PyObject*)((PyArrayObject *)__pyx_t_1), &__Pyx_TypeInfo_nn___pyx_t_5numpy_float64_t, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 1, 0, __pyx_stack) == -1)) {
+      __pyx_v_sum_squares = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_sum_squares.rcbuffer->pybuffer.buf = NULL;
+      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 80; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    } else {__pyx_pybuffernd_sum_squares.diminfo[0].strides = __pyx_pybuffernd_sum_squares.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_sum_squares.diminfo[0].shape = __pyx_pybuffernd_sum_squares.rcbuffer->pybuffer.shape[0];
+    }
+  }
+  __pyx_v_sum_squares = ((PyArrayObject *)__pyx_t_1);
+  __pyx_t_1 = 0;
+
+  /* "bx/bbi/bbi_file.pyx":82
+ *         cdef numpy.ndarray[numpy.float64_t, ndim=1] sum_squares = self.sum_squares
+ *         # Trim interval down to region of interest
+ *         if s < self.start:             # <<<<<<<<<<<<<<
+ *             s = self.start
+ *         if e > self.end:
+ */
+  __pyx_t_2 = ((__pyx_v_s < __pyx_v_self->start) != 0);
+  if (__pyx_t_2) {
+
+    /* "bx/bbi/bbi_file.pyx":83
+ *         # Trim interval down to region of interest
+ *         if s < self.start:
+ *             s = self.start             # <<<<<<<<<<<<<<
+ *         if e > self.end:
+ *             e = self.end
+ */
+    __pyx_t_3 = __pyx_v_self->start;
+    __pyx_v_s = __pyx_t_3;
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  /* "bx/bbi/bbi_file.pyx":84
+ *         if s < self.start:
+ *             s = self.start
+ *         if e > self.end:             # <<<<<<<<<<<<<<
+ *             e = self.end
+ *         if s >= e:
+ */
+  __pyx_t_2 = ((__pyx_v_e > __pyx_v_self->end) != 0);
+  if (__pyx_t_2) {
+
+    /* "bx/bbi/bbi_file.pyx":85
+ *             s = self.start
+ *         if e > self.end:
+ *             e = self.end             # <<<<<<<<<<<<<<
+ *         if s >= e:
+ *             return
+ */
+    __pyx_t_3 = __pyx_v_self->end;
+    __pyx_v_e = __pyx_t_3;
+    goto __pyx_L4;
+  }
+  __pyx_L4:;
+
+  /* "bx/bbi/bbi_file.pyx":86
+ *         if e > self.end:
+ *             e = self.end
+ *         if s >= e:             # <<<<<<<<<<<<<<
+ *             return
+ *         base_step = ( self.end - self.start ) / self.size
+ */
+  __pyx_t_2 = ((__pyx_v_s >= __pyx_v_e) != 0);
+  if (__pyx_t_2) {
+
+    /* "bx/bbi/bbi_file.pyx":87
+ *             e = self.end
+ *         if s >= e:
+ *             return             # <<<<<<<<<<<<<<
+ *         base_step = ( self.end - self.start ) / self.size
+ *         for j from 0 <= j < self.size:
+ */
+    __Pyx_XDECREF(__pyx_r);
+    __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+    goto __pyx_L0;
+  }
+
+  /* "bx/bbi/bbi_file.pyx":88
+ *         if s >= e:
+ *             return
+ *         base_step = ( self.end - self.start ) / self.size             # <<<<<<<<<<<<<<
+ *         for j from 0 <= j < self.size:
+ *             base_start = self.start + ( base_step * j )
+ */
+  __pyx_t_3 = (__pyx_v_self->end - __pyx_v_self->start);
+  if (unlikely(__pyx_v_self->size == 0)) {
+    #ifdef WITH_THREAD
+    PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+    #endif
+    PyErr_SetString(PyExc_ZeroDivisionError, "integer division or modulo by zero");
+    #ifdef WITH_THREAD
+    PyGILState_Release(__pyx_gilstate_save);
+    #endif
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 88; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  __pyx_v_base_step = (__pyx_t_3 / __pyx_v_self->size);
+
+  /* "bx/bbi/bbi_file.pyx":89
+ *             return
+ *         base_step = ( self.end - self.start ) / self.size
+ *         for j from 0 <= j < self.size:             # <<<<<<<<<<<<<<
+ *             base_start = self.start + ( base_step * j )
+ *             base_end = base_start + base_step
+ */
+  __pyx_t_4 = __pyx_v_self->size;
+  for (__pyx_v_j = 0; __pyx_v_j < __pyx_t_4; __pyx_v_j++) {
+
+    /* "bx/bbi/bbi_file.pyx":90
+ *         base_step = ( self.end - self.start ) / self.size
+ *         for j from 0 <= j < self.size:
+ *             base_start = self.start + ( base_step * j )             # <<<<<<<<<<<<<<
+ *             base_end = base_start + base_step
+ *             overlap = range_intersection( base_start, base_end, s, e )
+ */
+    __pyx_v_base_start = (__pyx_v_self->start + (__pyx_v_base_step * __pyx_v_j));
+
+    /* "bx/bbi/bbi_file.pyx":91
+ *         for j from 0 <= j < self.size:
+ *             base_start = self.start + ( base_step * j )
+ *             base_end = base_start + base_step             # <<<<<<<<<<<<<<
+ *             overlap = range_intersection( base_start, base_end, s, e )
+ *             if overlap > 0:
+ */
+    __pyx_v_base_end = (__pyx_v_base_start + __pyx_v_base_step);
+
+    /* "bx/bbi/bbi_file.pyx":92
+ *             base_start = self.start + ( base_step * j )
+ *             base_end = base_start + base_step
+ *             overlap = range_intersection( base_start, base_end, s, e )             # <<<<<<<<<<<<<<
+ *             if overlap > 0:
+ *                 interval_size = e - s
+ */
+    __pyx_v_overlap = __pyx_f_2bx_3bbi_8bbi_file_range_intersection(__pyx_v_base_start, __pyx_v_base_end, __pyx_v_s, __pyx_v_e);
+
+    /* "bx/bbi/bbi_file.pyx":93
+ *             base_end = base_start + base_step
+ *             overlap = range_intersection( base_start, base_end, s, e )
+ *             if overlap > 0:             # <<<<<<<<<<<<<<
+ *                 interval_size = e - s
+ *                 overlap_factor = <double> overlap / interval_size
+ */
+    __pyx_t_2 = ((__pyx_v_overlap > 0) != 0);
+    if (__pyx_t_2) {
+
+      /* "bx/bbi/bbi_file.pyx":94
+ *             overlap = range_intersection( base_start, base_end, s, e )
+ *             if overlap > 0:
+ *                 interval_size = e - s             # <<<<<<<<<<<<<<
+ *                 overlap_factor = <double> overlap / interval_size
+ *                 interval_weight = interval_size * overlap_factor
+ */
+      __pyx_v_interval_size = (__pyx_v_e - __pyx_v_s);
+
+      /* "bx/bbi/bbi_file.pyx":95
+ *             if overlap > 0:
+ *                 interval_size = e - s
+ *                 overlap_factor = <double> overlap / interval_size             # <<<<<<<<<<<<<<
+ *                 interval_weight = interval_size * overlap_factor
+ *                 valid_count[j] += interval_weight
+ */
+      if (unlikely(__pyx_v_interval_size == 0)) {
+        #ifdef WITH_THREAD
+        PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+        #endif
+        PyErr_SetString(PyExc_ZeroDivisionError, "float division");
+        #ifdef WITH_THREAD
+        PyGILState_Release(__pyx_gilstate_save);
+        #endif
+        {__pyx_filename = __pyx_f[0]; __pyx_lineno = 95; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      }
+      __pyx_v_overlap_factor = (((double)__pyx_v_overlap) / __pyx_v_interval_size);
+
+      /* "bx/bbi/bbi_file.pyx":96
+ *                 interval_size = e - s
+ *                 overlap_factor = <double> overlap / interval_size
+ *                 interval_weight = interval_size * overlap_factor             # <<<<<<<<<<<<<<
+ *                 valid_count[j] += interval_weight
+ *                 sum_data[j] += val * interval_weight
+ */
+      __pyx_v_interval_weight = (__pyx_v_interval_size * __pyx_v_overlap_factor);
+
+      /* "bx/bbi/bbi_file.pyx":97
+ *                 overlap_factor = <double> overlap / interval_size
+ *                 interval_weight = interval_size * overlap_factor
+ *                 valid_count[j] += interval_weight             # <<<<<<<<<<<<<<
+ *                 sum_data[j] += val * interval_weight
+ *                 sum_squares[j] += val * val * interval_weight
+ */
+      __pyx_t_5 = __pyx_v_j;
+      __pyx_t_6 = -1;
+      if (__pyx_t_5 < 0) {
+        __pyx_t_5 += __pyx_pybuffernd_valid_count.diminfo[0].shape;
+        if (unlikely(__pyx_t_5 < 0)) __pyx_t_6 = 0;
+      } else if (unlikely(__pyx_t_5 >= __pyx_pybuffernd_valid_count.diminfo[0].shape)) __pyx_t_6 = 0;
+      if (unlikely(__pyx_t_6 != -1)) {
+        __Pyx_RaiseBufferIndexError(__pyx_t_6);
+        {__pyx_filename = __pyx_f[0]; __pyx_lineno = 97; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      }
+      *__Pyx_BufPtrStrided1d(__pyx_t_5numpy_float64_t *, __pyx_pybuffernd_valid_count.rcbuffer->pybuffer.buf, __pyx_t_5, __pyx_pybuffernd_valid_count.diminfo[0].strides) += __pyx_v_interval_weight;
+
+      /* "bx/bbi/bbi_file.pyx":98
+ *                 interval_weight = interval_size * overlap_factor
+ *                 valid_count[j] += interval_weight
+ *                 sum_data[j] += val * interval_weight             # <<<<<<<<<<<<<<
+ *                 sum_squares[j] += val * val * interval_weight
+ *                 if max_val[j] < val:
+ */
+      __pyx_t_6 = __pyx_v_j;
+      __pyx_t_7 = -1;
+      if (__pyx_t_6 < 0) {
+        __pyx_t_6 += __pyx_pybuffernd_sum_data.diminfo[0].shape;
+        if (unlikely(__pyx_t_6 < 0)) __pyx_t_7 = 0;
+      } else if (unlikely(__pyx_t_6 >= __pyx_pybuffernd_sum_data.diminfo[0].shape)) __pyx_t_7 = 0;
+      if (unlikely(__pyx_t_7 != -1)) {
+        __Pyx_RaiseBufferIndexError(__pyx_t_7);
+        {__pyx_filename = __pyx_f[0]; __pyx_lineno = 98; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      }
+      *__Pyx_BufPtrStrided1d(__pyx_t_5numpy_float64_t *, __pyx_pybuffernd_sum_data.rcbuffer->pybuffer.buf, __pyx_t_6, __pyx_pybuffernd_sum_data.diminfo[0].strides) += (__pyx_v_val * __pyx_v_interval_weight);
+
+      /* "bx/bbi/bbi_file.pyx":99
+ *                 valid_count[j] += interval_weight
+ *                 sum_data[j] += val * interval_weight
+ *                 sum_squares[j] += val * val * interval_weight             # <<<<<<<<<<<<<<
+ *                 if max_val[j] < val:
+ *                     max_val[j] = val
+ */
+      __pyx_t_7 = __pyx_v_j;
+      __pyx_t_8 = -1;
+      if (__pyx_t_7 < 0) {
+        __pyx_t_7 += __pyx_pybuffernd_sum_squares.diminfo[0].shape;
+        if (unlikely(__pyx_t_7 < 0)) __pyx_t_8 = 0;
+      } else if (unlikely(__pyx_t_7 >= __pyx_pybuffernd_sum_squares.diminfo[0].shape)) __pyx_t_8 = 0;
+      if (unlikely(__pyx_t_8 != -1)) {
+        __Pyx_RaiseBufferIndexError(__pyx_t_8);
+        {__pyx_filename = __pyx_f[0]; __pyx_lineno = 99; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      }
+      *__Pyx_BufPtrStrided1d(__pyx_t_5numpy_float64_t *, __pyx_pybuffernd_sum_squares.rcbuffer->pybuffer.buf, __pyx_t_7, __pyx_pybuffernd_sum_squares.diminfo[0].strides) += ((__pyx_v_val * __pyx_v_val) * __pyx_v_interval_weight);
+
+      /* "bx/bbi/bbi_file.pyx":100
+ *                 sum_data[j] += val * interval_weight
+ *                 sum_squares[j] += val * val * interval_weight
+ *                 if max_val[j] < val:             # <<<<<<<<<<<<<<
+ *                     max_val[j] = val
+ *                 if min_val[j] > val:
+ */
+      __pyx_t_8 = __pyx_v_j;
+      __pyx_t_9 = -1;
+      if (__pyx_t_8 < 0) {
+        __pyx_t_8 += __pyx_pybuffernd_max_val.diminfo[0].shape;
+        if (unlikely(__pyx_t_8 < 0)) __pyx_t_9 = 0;
+      } else if (unlikely(__pyx_t_8 >= __pyx_pybuffernd_max_val.diminfo[0].shape)) __pyx_t_9 = 0;
+      if (unlikely(__pyx_t_9 != -1)) {
+        __Pyx_RaiseBufferIndexError(__pyx_t_9);
+        {__pyx_filename = __pyx_f[0]; __pyx_lineno = 100; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      }
+      __pyx_t_2 = (((*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_float64_t *, __pyx_pybuffernd_max_val.rcbuffer->pybuffer.buf, __pyx_t_8, __pyx_pybuffernd_max_val.diminfo[0].strides)) < __pyx_v_val) != 0);
+      if (__pyx_t_2) {
+
+        /* "bx/bbi/bbi_file.pyx":101
+ *                 sum_squares[j] += val * val * interval_weight
+ *                 if max_val[j] < val:
+ *                     max_val[j] = val             # <<<<<<<<<<<<<<
+ *                 if min_val[j] > val:
+ *                     min_val[j] = val
+ */
+        __pyx_t_9 = __pyx_v_j;
+        __pyx_t_10 = -1;
+        if (__pyx_t_9 < 0) {
+          __pyx_t_9 += __pyx_pybuffernd_max_val.diminfo[0].shape;
+          if (unlikely(__pyx_t_9 < 0)) __pyx_t_10 = 0;
+        } else if (unlikely(__pyx_t_9 >= __pyx_pybuffernd_max_val.diminfo[0].shape)) __pyx_t_10 = 0;
+        if (unlikely(__pyx_t_10 != -1)) {
+          __Pyx_RaiseBufferIndexError(__pyx_t_10);
+          {__pyx_filename = __pyx_f[0]; __pyx_lineno = 101; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        }
+        *__Pyx_BufPtrStrided1d(__pyx_t_5numpy_float64_t *, __pyx_pybuffernd_max_val.rcbuffer->pybuffer.buf, __pyx_t_9, __pyx_pybuffernd_max_val.diminfo[0].strides) = __pyx_v_val;
+        goto __pyx_L9;
+      }
+      __pyx_L9:;
+
+      /* "bx/bbi/bbi_file.pyx":102
+ *                 if max_val[j] < val:
+ *                     max_val[j] = val
+ *                 if min_val[j] > val:             # <<<<<<<<<<<<<<
+ *                     min_val[j] = val
+ * 
+ */
+      __pyx_t_10 = __pyx_v_j;
+      __pyx_t_11 = -1;
+      if (__pyx_t_10 < 0) {
+        __pyx_t_10 += __pyx_pybuffernd_min_val.diminfo[0].shape;
+        if (unlikely(__pyx_t_10 < 0)) __pyx_t_11 = 0;
+      } else if (unlikely(__pyx_t_10 >= __pyx_pybuffernd_min_val.diminfo[0].shape)) __pyx_t_11 = 0;
+      if (unlikely(__pyx_t_11 != -1)) {
+        __Pyx_RaiseBufferIndexError(__pyx_t_11);
+        {__pyx_filename = __pyx_f[0]; __pyx_lineno = 102; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      }
+      __pyx_t_2 = (((*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_float64_t *, __pyx_pybuffernd_min_val.rcbuffer->pybuffer.buf, __pyx_t_10, __pyx_pybuffernd_min_val.diminfo[0].strides)) > __pyx_v_val) != 0);
+      if (__pyx_t_2) {
+
+        /* "bx/bbi/bbi_file.pyx":103
+ *                     max_val[j] = val
+ *                 if min_val[j] > val:
+ *                     min_val[j] = val             # <<<<<<<<<<<<<<
+ * 
+ * cdef class BlockHandler:
+ */
+        __pyx_t_11 = __pyx_v_j;
+        __pyx_t_12 = -1;
+        if (__pyx_t_11 < 0) {
+          __pyx_t_11 += __pyx_pybuffernd_min_val.diminfo[0].shape;
+          if (unlikely(__pyx_t_11 < 0)) __pyx_t_12 = 0;
+        } else if (unlikely(__pyx_t_11 >= __pyx_pybuffernd_min_val.diminfo[0].shape)) __pyx_t_12 = 0;
+        if (unlikely(__pyx_t_12 != -1)) {
+          __Pyx_RaiseBufferIndexError(__pyx_t_12);
+          {__pyx_filename = __pyx_f[0]; __pyx_lineno = 103; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        }
+        *__Pyx_BufPtrStrided1d(__pyx_t_5numpy_float64_t *, __pyx_pybuffernd_min_val.rcbuffer->pybuffer.buf, __pyx_t_11, __pyx_pybuffernd_min_val.diminfo[0].strides) = __pyx_v_val;
+        goto __pyx_L10;
+      }
+      __pyx_L10:;
+      goto __pyx_L8;
+    }
+    __pyx_L8:;
+  }
+
+  /* "bx/bbi/bbi_file.pyx":72
+ *         self.sum_data = numpy.zeros( self.size, dtype=numpy.float64 )
+ *         self.sum_squares = numpy.zeros( self.size, dtype=numpy.float64 )
+ *     cdef accumulate_interval_value( self, bits32 s, bits32 e, float val ):             # <<<<<<<<<<<<<<
+ *         cdef int base_start, base_end, base_step, overlap, j, interval_size
+ *         cdef double overlap_factor, interval_weight
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
+    __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
+    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_max_val.rcbuffer->pybuffer);
+    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_min_val.rcbuffer->pybuffer);
+    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_sum_data.rcbuffer->pybuffer);
+    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_sum_squares.rcbuffer->pybuffer);
+    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_valid_count.rcbuffer->pybuffer);
+  __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}
+  __Pyx_AddTraceback("bx.bbi.bbi_file.SummarizedData.accumulate_interval_value", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  goto __pyx_L2;
+  __pyx_L0:;
+  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_max_val.rcbuffer->pybuffer);
+  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_min_val.rcbuffer->pybuffer);
+  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_sum_data.rcbuffer->pybuffer);
+  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_sum_squares.rcbuffer->pybuffer);
+  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_valid_count.rcbuffer->pybuffer);
+  __pyx_L2:;
+  __Pyx_XDECREF((PyObject *)__pyx_v_valid_count);
+  __Pyx_XDECREF((PyObject *)__pyx_v_min_val);
+  __Pyx_XDECREF((PyObject *)__pyx_v_max_val);
+  __Pyx_XDECREF((PyObject *)__pyx_v_sum_data);
+  __Pyx_XDECREF((PyObject *)__pyx_v_sum_squares);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bbi/bbi_file.pxd":26
+ *     aggregation over a particular range and resolution
+ *     """
+ *     cdef public bits32 start             # <<<<<<<<<<<<<<
+ *     cdef public bits32 end
+ *     cdef public int size
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_3bbi_8bbi_file_14SummarizedData_5start_1__get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_2bx_3bbi_8bbi_file_14SummarizedData_5start_1__get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_3bbi_8bbi_file_14SummarizedData_5start___get__(((struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData *)__pyx_v_self));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_2bx_3bbi_8bbi_file_14SummarizedData_5start___get__(struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__get__", 0);
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = __Pyx_PyInt_From_unsigned_int(__pyx_v_self->start); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 26; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("bx.bbi.bbi_file.SummarizedData.start.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_2bx_3bbi_8bbi_file_14SummarizedData_5start_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value); /*proto*/
+static int __pyx_pw_2bx_3bbi_8bbi_file_14SummarizedData_5start_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__set__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_3bbi_8bbi_file_14SummarizedData_5start_2__set__(((struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData *)__pyx_v_self), ((PyObject *)__pyx_v_value));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_2bx_3bbi_8bbi_file_14SummarizedData_5start_2__set__(struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __pyx_t_2bx_3bbi_5types_bits32 __pyx_t_1;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__set__", 0);
+  __pyx_t_1 = __Pyx_PyInt_As_unsigned_int(__pyx_v_value); if (unlikely((__pyx_t_1 == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 26; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_v_self->start = __pyx_t_1;
+
+  /* function exit code */
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_AddTraceback("bx.bbi.bbi_file.SummarizedData.start.__set__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = -1;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bbi/bbi_file.pxd":27
+ *     """
+ *     cdef public bits32 start
+ *     cdef public bits32 end             # <<<<<<<<<<<<<<
+ *     cdef public int size
+ *     cdef public numpy.ndarray valid_count
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_3bbi_8bbi_file_14SummarizedData_3end_1__get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_2bx_3bbi_8bbi_file_14SummarizedData_3end_1__get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_3bbi_8bbi_file_14SummarizedData_3end___get__(((struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData *)__pyx_v_self));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_2bx_3bbi_8bbi_file_14SummarizedData_3end___get__(struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__get__", 0);
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = __Pyx_PyInt_From_unsigned_int(__pyx_v_self->end); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 27; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("bx.bbi.bbi_file.SummarizedData.end.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_2bx_3bbi_8bbi_file_14SummarizedData_3end_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value); /*proto*/
+static int __pyx_pw_2bx_3bbi_8bbi_file_14SummarizedData_3end_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__set__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_3bbi_8bbi_file_14SummarizedData_3end_2__set__(((struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData *)__pyx_v_self), ((PyObject *)__pyx_v_value));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_2bx_3bbi_8bbi_file_14SummarizedData_3end_2__set__(struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __pyx_t_2bx_3bbi_5types_bits32 __pyx_t_1;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__set__", 0);
+  __pyx_t_1 = __Pyx_PyInt_As_unsigned_int(__pyx_v_value); if (unlikely((__pyx_t_1 == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 27; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_v_self->end = __pyx_t_1;
+
+  /* function exit code */
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_AddTraceback("bx.bbi.bbi_file.SummarizedData.end.__set__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = -1;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bbi/bbi_file.pxd":28
+ *     cdef public bits32 start
+ *     cdef public bits32 end
+ *     cdef public int size             # <<<<<<<<<<<<<<
+ *     cdef public numpy.ndarray valid_count
+ *     cdef public numpy.ndarray min_val
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_3bbi_8bbi_file_14SummarizedData_4size_1__get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_2bx_3bbi_8bbi_file_14SummarizedData_4size_1__get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_3bbi_8bbi_file_14SummarizedData_4size___get__(((struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData *)__pyx_v_self));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_2bx_3bbi_8bbi_file_14SummarizedData_4size___get__(struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__get__", 0);
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_self->size); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 28; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("bx.bbi.bbi_file.SummarizedData.size.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_2bx_3bbi_8bbi_file_14SummarizedData_4size_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value); /*proto*/
+static int __pyx_pw_2bx_3bbi_8bbi_file_14SummarizedData_4size_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__set__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_3bbi_8bbi_file_14SummarizedData_4size_2__set__(((struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData *)__pyx_v_self), ((PyObject *)__pyx_v_value));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_2bx_3bbi_8bbi_file_14SummarizedData_4size_2__set__(struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__set__", 0);
+  __pyx_t_1 = __Pyx_PyInt_As_int(__pyx_v_value); if (unlikely((__pyx_t_1 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 28; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_v_self->size = __pyx_t_1;
+
+  /* function exit code */
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_AddTraceback("bx.bbi.bbi_file.SummarizedData.size.__set__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = -1;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bbi/bbi_file.pxd":29
+ *     cdef public bits32 end
+ *     cdef public int size
+ *     cdef public numpy.ndarray valid_count             # <<<<<<<<<<<<<<
+ *     cdef public numpy.ndarray min_val
+ *     cdef public numpy.ndarray max_val
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_3bbi_8bbi_file_14SummarizedData_11valid_count_1__get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_2bx_3bbi_8bbi_file_14SummarizedData_11valid_count_1__get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_3bbi_8bbi_file_14SummarizedData_11valid_count___get__(((struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData *)__pyx_v_self));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_2bx_3bbi_8bbi_file_14SummarizedData_11valid_count___get__(struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__get__", 0);
+  __Pyx_XDECREF(__pyx_r);
+  __Pyx_INCREF(((PyObject *)__pyx_v_self->valid_count));
+  __pyx_r = ((PyObject *)__pyx_v_self->valid_count);
+  goto __pyx_L0;
+
+  /* function exit code */
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_2bx_3bbi_8bbi_file_14SummarizedData_11valid_count_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value); /*proto*/
+static int __pyx_pw_2bx_3bbi_8bbi_file_14SummarizedData_11valid_count_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__set__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_3bbi_8bbi_file_14SummarizedData_11valid_count_2__set__(((struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData *)__pyx_v_self), ((PyObject *)__pyx_v_value));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_2bx_3bbi_8bbi_file_14SummarizedData_11valid_count_2__set__(struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__set__", 0);
+  if (!(likely(((__pyx_v_value) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_value, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 29; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = __pyx_v_value;
+  __Pyx_INCREF(__pyx_t_1);
+  __Pyx_GIVEREF(__pyx_t_1);
+  __Pyx_GOTREF(__pyx_v_self->valid_count);
+  __Pyx_DECREF(((PyObject *)__pyx_v_self->valid_count));
+  __pyx_v_self->valid_count = ((PyArrayObject *)__pyx_t_1);
+  __pyx_t_1 = 0;
+
+  /* function exit code */
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("bx.bbi.bbi_file.SummarizedData.valid_count.__set__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = -1;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_2bx_3bbi_8bbi_file_14SummarizedData_11valid_count_5__del__(PyObject *__pyx_v_self); /*proto*/
+static int __pyx_pw_2bx_3bbi_8bbi_file_14SummarizedData_11valid_count_5__del__(PyObject *__pyx_v_self) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__del__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_3bbi_8bbi_file_14SummarizedData_11valid_count_4__del__(((struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData *)__pyx_v_self));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_2bx_3bbi_8bbi_file_14SummarizedData_11valid_count_4__del__(struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData *__pyx_v_self) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__del__", 0);
+  __Pyx_INCREF(Py_None);
+  __Pyx_GIVEREF(Py_None);
+  __Pyx_GOTREF(__pyx_v_self->valid_count);
+  __Pyx_DECREF(((PyObject *)__pyx_v_self->valid_count));
+  __pyx_v_self->valid_count = ((PyArrayObject *)Py_None);
+
+  /* function exit code */
+  __pyx_r = 0;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bbi/bbi_file.pxd":30
+ *     cdef public int size
+ *     cdef public numpy.ndarray valid_count
+ *     cdef public numpy.ndarray min_val             # <<<<<<<<<<<<<<
+ *     cdef public numpy.ndarray max_val
+ *     cdef public numpy.ndarray sum_data
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_3bbi_8bbi_file_14SummarizedData_7min_val_1__get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_2bx_3bbi_8bbi_file_14SummarizedData_7min_val_1__get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_3bbi_8bbi_file_14SummarizedData_7min_val___get__(((struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData *)__pyx_v_self));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_2bx_3bbi_8bbi_file_14SummarizedData_7min_val___get__(struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__get__", 0);
+  __Pyx_XDECREF(__pyx_r);
+  __Pyx_INCREF(((PyObject *)__pyx_v_self->min_val));
+  __pyx_r = ((PyObject *)__pyx_v_self->min_val);
+  goto __pyx_L0;
+
+  /* function exit code */
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_2bx_3bbi_8bbi_file_14SummarizedData_7min_val_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value); /*proto*/
+static int __pyx_pw_2bx_3bbi_8bbi_file_14SummarizedData_7min_val_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__set__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_3bbi_8bbi_file_14SummarizedData_7min_val_2__set__(((struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData *)__pyx_v_self), ((PyObject *)__pyx_v_value));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_2bx_3bbi_8bbi_file_14SummarizedData_7min_val_2__set__(struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__set__", 0);
+  if (!(likely(((__pyx_v_value) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_value, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 30; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = __pyx_v_value;
+  __Pyx_INCREF(__pyx_t_1);
+  __Pyx_GIVEREF(__pyx_t_1);
+  __Pyx_GOTREF(__pyx_v_self->min_val);
+  __Pyx_DECREF(((PyObject *)__pyx_v_self->min_val));
+  __pyx_v_self->min_val = ((PyArrayObject *)__pyx_t_1);
+  __pyx_t_1 = 0;
+
+  /* function exit code */
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("bx.bbi.bbi_file.SummarizedData.min_val.__set__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = -1;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_2bx_3bbi_8bbi_file_14SummarizedData_7min_val_5__del__(PyObject *__pyx_v_self); /*proto*/
+static int __pyx_pw_2bx_3bbi_8bbi_file_14SummarizedData_7min_val_5__del__(PyObject *__pyx_v_self) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__del__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_3bbi_8bbi_file_14SummarizedData_7min_val_4__del__(((struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData *)__pyx_v_self));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_2bx_3bbi_8bbi_file_14SummarizedData_7min_val_4__del__(struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData *__pyx_v_self) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__del__", 0);
+  __Pyx_INCREF(Py_None);
+  __Pyx_GIVEREF(Py_None);
+  __Pyx_GOTREF(__pyx_v_self->min_val);
+  __Pyx_DECREF(((PyObject *)__pyx_v_self->min_val));
+  __pyx_v_self->min_val = ((PyArrayObject *)Py_None);
+
+  /* function exit code */
+  __pyx_r = 0;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bbi/bbi_file.pxd":31
+ *     cdef public numpy.ndarray valid_count
+ *     cdef public numpy.ndarray min_val
+ *     cdef public numpy.ndarray max_val             # <<<<<<<<<<<<<<
+ *     cdef public numpy.ndarray sum_data
+ *     cdef public numpy.ndarray sum_squares
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_3bbi_8bbi_file_14SummarizedData_7max_val_1__get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_2bx_3bbi_8bbi_file_14SummarizedData_7max_val_1__get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_3bbi_8bbi_file_14SummarizedData_7max_val___get__(((struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData *)__pyx_v_self));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_2bx_3bbi_8bbi_file_14SummarizedData_7max_val___get__(struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__get__", 0);
+  __Pyx_XDECREF(__pyx_r);
+  __Pyx_INCREF(((PyObject *)__pyx_v_self->max_val));
+  __pyx_r = ((PyObject *)__pyx_v_self->max_val);
+  goto __pyx_L0;
+
+  /* function exit code */
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_2bx_3bbi_8bbi_file_14SummarizedData_7max_val_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value); /*proto*/
+static int __pyx_pw_2bx_3bbi_8bbi_file_14SummarizedData_7max_val_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__set__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_3bbi_8bbi_file_14SummarizedData_7max_val_2__set__(((struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData *)__pyx_v_self), ((PyObject *)__pyx_v_value));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_2bx_3bbi_8bbi_file_14SummarizedData_7max_val_2__set__(struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__set__", 0);
+  if (!(likely(((__pyx_v_value) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_value, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 31; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = __pyx_v_value;
+  __Pyx_INCREF(__pyx_t_1);
+  __Pyx_GIVEREF(__pyx_t_1);
+  __Pyx_GOTREF(__pyx_v_self->max_val);
+  __Pyx_DECREF(((PyObject *)__pyx_v_self->max_val));
+  __pyx_v_self->max_val = ((PyArrayObject *)__pyx_t_1);
+  __pyx_t_1 = 0;
+
+  /* function exit code */
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("bx.bbi.bbi_file.SummarizedData.max_val.__set__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = -1;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_2bx_3bbi_8bbi_file_14SummarizedData_7max_val_5__del__(PyObject *__pyx_v_self); /*proto*/
+static int __pyx_pw_2bx_3bbi_8bbi_file_14SummarizedData_7max_val_5__del__(PyObject *__pyx_v_self) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__del__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_3bbi_8bbi_file_14SummarizedData_7max_val_4__del__(((struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData *)__pyx_v_self));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_2bx_3bbi_8bbi_file_14SummarizedData_7max_val_4__del__(struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData *__pyx_v_self) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__del__", 0);
+  __Pyx_INCREF(Py_None);
+  __Pyx_GIVEREF(Py_None);
+  __Pyx_GOTREF(__pyx_v_self->max_val);
+  __Pyx_DECREF(((PyObject *)__pyx_v_self->max_val));
+  __pyx_v_self->max_val = ((PyArrayObject *)Py_None);
+
+  /* function exit code */
+  __pyx_r = 0;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bbi/bbi_file.pxd":32
+ *     cdef public numpy.ndarray min_val
+ *     cdef public numpy.ndarray max_val
+ *     cdef public numpy.ndarray sum_data             # <<<<<<<<<<<<<<
+ *     cdef public numpy.ndarray sum_squares
+ * 
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_3bbi_8bbi_file_14SummarizedData_8sum_data_1__get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_2bx_3bbi_8bbi_file_14SummarizedData_8sum_data_1__get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_3bbi_8bbi_file_14SummarizedData_8sum_data___get__(((struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData *)__pyx_v_self));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_2bx_3bbi_8bbi_file_14SummarizedData_8sum_data___get__(struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__get__", 0);
+  __Pyx_XDECREF(__pyx_r);
+  __Pyx_INCREF(((PyObject *)__pyx_v_self->sum_data));
+  __pyx_r = ((PyObject *)__pyx_v_self->sum_data);
+  goto __pyx_L0;
+
+  /* function exit code */
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_2bx_3bbi_8bbi_file_14SummarizedData_8sum_data_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value); /*proto*/
+static int __pyx_pw_2bx_3bbi_8bbi_file_14SummarizedData_8sum_data_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__set__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_3bbi_8bbi_file_14SummarizedData_8sum_data_2__set__(((struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData *)__pyx_v_self), ((PyObject *)__pyx_v_value));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_2bx_3bbi_8bbi_file_14SummarizedData_8sum_data_2__set__(struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__set__", 0);
+  if (!(likely(((__pyx_v_value) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_value, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 32; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = __pyx_v_value;
+  __Pyx_INCREF(__pyx_t_1);
+  __Pyx_GIVEREF(__pyx_t_1);
+  __Pyx_GOTREF(__pyx_v_self->sum_data);
+  __Pyx_DECREF(((PyObject *)__pyx_v_self->sum_data));
+  __pyx_v_self->sum_data = ((PyArrayObject *)__pyx_t_1);
+  __pyx_t_1 = 0;
+
+  /* function exit code */
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("bx.bbi.bbi_file.SummarizedData.sum_data.__set__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = -1;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_2bx_3bbi_8bbi_file_14SummarizedData_8sum_data_5__del__(PyObject *__pyx_v_self); /*proto*/
+static int __pyx_pw_2bx_3bbi_8bbi_file_14SummarizedData_8sum_data_5__del__(PyObject *__pyx_v_self) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__del__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_3bbi_8bbi_file_14SummarizedData_8sum_data_4__del__(((struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData *)__pyx_v_self));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_2bx_3bbi_8bbi_file_14SummarizedData_8sum_data_4__del__(struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData *__pyx_v_self) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__del__", 0);
+  __Pyx_INCREF(Py_None);
+  __Pyx_GIVEREF(Py_None);
+  __Pyx_GOTREF(__pyx_v_self->sum_data);
+  __Pyx_DECREF(((PyObject *)__pyx_v_self->sum_data));
+  __pyx_v_self->sum_data = ((PyArrayObject *)Py_None);
+
+  /* function exit code */
+  __pyx_r = 0;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bbi/bbi_file.pxd":33
+ *     cdef public numpy.ndarray max_val
+ *     cdef public numpy.ndarray sum_data
+ *     cdef public numpy.ndarray sum_squares             # <<<<<<<<<<<<<<
+ * 
+ *     cdef accumulate_interval_value( self, bits32 s, bits32 e, float val )
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_3bbi_8bbi_file_14SummarizedData_11sum_squares_1__get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_2bx_3bbi_8bbi_file_14SummarizedData_11sum_squares_1__get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_3bbi_8bbi_file_14SummarizedData_11sum_squares___get__(((struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData *)__pyx_v_self));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_2bx_3bbi_8bbi_file_14SummarizedData_11sum_squares___get__(struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__get__", 0);
+  __Pyx_XDECREF(__pyx_r);
+  __Pyx_INCREF(((PyObject *)__pyx_v_self->sum_squares));
+  __pyx_r = ((PyObject *)__pyx_v_self->sum_squares);
+  goto __pyx_L0;
+
+  /* function exit code */
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_2bx_3bbi_8bbi_file_14SummarizedData_11sum_squares_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value); /*proto*/
+static int __pyx_pw_2bx_3bbi_8bbi_file_14SummarizedData_11sum_squares_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__set__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_3bbi_8bbi_file_14SummarizedData_11sum_squares_2__set__(((struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData *)__pyx_v_self), ((PyObject *)__pyx_v_value));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_2bx_3bbi_8bbi_file_14SummarizedData_11sum_squares_2__set__(struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__set__", 0);
+  if (!(likely(((__pyx_v_value) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_value, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 33; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = __pyx_v_value;
+  __Pyx_INCREF(__pyx_t_1);
+  __Pyx_GIVEREF(__pyx_t_1);
+  __Pyx_GOTREF(__pyx_v_self->sum_squares);
+  __Pyx_DECREF(((PyObject *)__pyx_v_self->sum_squares));
+  __pyx_v_self->sum_squares = ((PyArrayObject *)__pyx_t_1);
+  __pyx_t_1 = 0;
+
+  /* function exit code */
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("bx.bbi.bbi_file.SummarizedData.sum_squares.__set__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = -1;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_2bx_3bbi_8bbi_file_14SummarizedData_11sum_squares_5__del__(PyObject *__pyx_v_self); /*proto*/
+static int __pyx_pw_2bx_3bbi_8bbi_file_14SummarizedData_11sum_squares_5__del__(PyObject *__pyx_v_self) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__del__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_3bbi_8bbi_file_14SummarizedData_11sum_squares_4__del__(((struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData *)__pyx_v_self));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_2bx_3bbi_8bbi_file_14SummarizedData_11sum_squares_4__del__(struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData *__pyx_v_self) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__del__", 0);
+  __Pyx_INCREF(Py_None);
+  __Pyx_GIVEREF(Py_None);
+  __Pyx_GOTREF(__pyx_v_self->sum_squares);
+  __Pyx_DECREF(((PyObject *)__pyx_v_self->sum_squares));
+  __pyx_v_self->sum_squares = ((PyArrayObject *)Py_None);
+
+  /* function exit code */
+  __pyx_r = 0;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bbi/bbi_file.pyx":109
+ *     Callback for `BBIFile.visit_blocks_in_region`
+ *     """
+ *     cdef handle_block( self, str block_data, BBIFile bbi_file ):             # <<<<<<<<<<<<<<
+ *         pass
+ * 
+ */
+
+static PyObject *__pyx_f_2bx_3bbi_8bbi_file_12BlockHandler_handle_block(CYTHON_UNUSED struct __pyx_obj_2bx_3bbi_8bbi_file_BlockHandler *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v_block_data, CYTHON_UNUSED struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *__pyx_v_bbi_file) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("handle_block", 0);
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bbi/bbi_file.pyx":119
+ *     """
+ * 
+ *     def __init__( self, file=None, expected_sig=None, type_name=None ):             # <<<<<<<<<<<<<<
+ *         if file is not None:
+ *             self.open( file, expected_sig, type_name )
+ */
+
+/* Python wrapper */
+static int __pyx_pw_2bx_3bbi_8bbi_file_7BBIFile_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static int __pyx_pw_2bx_3bbi_8bbi_file_7BBIFile_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_file = 0;
+  PyObject *__pyx_v_expected_sig = 0;
+  PyObject *__pyx_v_type_name = 0;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__init__ (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_file,&__pyx_n_s_expected_sig,&__pyx_n_s_type_name,0};
+    PyObject* values[3] = {0,0,0};
+    values[0] = ((PyObject *)Py_None);
+    values[1] = ((PyObject *)Py_None);
+    values[2] = ((PyObject *)Py_None);
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_file);
+          if (value) { values[0] = value; kw_args--; }
+        }
+        case  1:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_expected_sig);
+          if (value) { values[1] = value; kw_args--; }
+        }
+        case  2:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_type_name);
+          if (value) { values[2] = value; kw_args--; }
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else {
+      switch (PyTuple_GET_SIZE(__pyx_args)) {
+        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+    }
+    __pyx_v_file = values[0];
+    __pyx_v_expected_sig = values[1];
+    __pyx_v_type_name = values[2];
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("__init__", 0, 0, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.bbi.bbi_file.BBIFile.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return -1;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_3bbi_8bbi_file_7BBIFile___init__(((struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *)__pyx_v_self), __pyx_v_file, __pyx_v_expected_sig, __pyx_v_type_name);
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_2bx_3bbi_8bbi_file_7BBIFile___init__(struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *__pyx_v_self, PyObject *__pyx_v_file, PyObject *__pyx_v_expected_sig, PyObject *__pyx_v_type_name) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  int __pyx_t_2;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  PyObject *__pyx_t_5 = NULL;
+  Py_ssize_t __pyx_t_6;
+  PyObject *__pyx_t_7 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__init__", 0);
+
+  /* "bx/bbi/bbi_file.pyx":120
+ * 
+ *     def __init__( self, file=None, expected_sig=None, type_name=None ):
+ *         if file is not None:             # <<<<<<<<<<<<<<
+ *             self.open( file, expected_sig, type_name )
+ * 
+ */
+  __pyx_t_1 = (__pyx_v_file != Py_None);
+  __pyx_t_2 = (__pyx_t_1 != 0);
+  if (__pyx_t_2) {
+
+    /* "bx/bbi/bbi_file.pyx":121
+ *     def __init__( self, file=None, expected_sig=None, type_name=None ):
+ *         if file is not None:
+ *             self.open( file, expected_sig, type_name )             # <<<<<<<<<<<<<<
+ * 
+ *     def open( self, file, expected_sig, type_name ):
+ */
+    __pyx_t_4 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_open); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 121; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    __pyx_t_5 = NULL;
+    __pyx_t_6 = 0;
+    if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_4))) {
+      __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_4);
+      if (likely(__pyx_t_5)) {
+        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
+        __Pyx_INCREF(__pyx_t_5);
+        __Pyx_INCREF(function);
+        __Pyx_DECREF_SET(__pyx_t_4, function);
+        __pyx_t_6 = 1;
+      }
+    }
+    __pyx_t_7 = PyTuple_New(3+__pyx_t_6); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 121; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_7);
+    if (__pyx_t_5) {
+      PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_5); __Pyx_GIVEREF(__pyx_t_5); __pyx_t_5 = NULL;
+    }
+    __Pyx_INCREF(__pyx_v_file);
+    PyTuple_SET_ITEM(__pyx_t_7, 0+__pyx_t_6, __pyx_v_file);
+    __Pyx_GIVEREF(__pyx_v_file);
+    __Pyx_INCREF(__pyx_v_expected_sig);
+    PyTuple_SET_ITEM(__pyx_t_7, 1+__pyx_t_6, __pyx_v_expected_sig);
+    __Pyx_GIVEREF(__pyx_v_expected_sig);
+    __Pyx_INCREF(__pyx_v_type_name);
+    PyTuple_SET_ITEM(__pyx_t_7, 2+__pyx_t_6, __pyx_v_type_name);
+    __Pyx_GIVEREF(__pyx_v_type_name);
+    __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_7, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 121; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  /* "bx/bbi/bbi_file.pyx":119
+ *     """
+ * 
+ *     def __init__( self, file=None, expected_sig=None, type_name=None ):             # <<<<<<<<<<<<<<
+ *         if file is not None:
+ *             self.open( file, expected_sig, type_name )
+ */
+
+  /* function exit code */
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_XDECREF(__pyx_t_5);
+  __Pyx_XDECREF(__pyx_t_7);
+  __Pyx_AddTraceback("bx.bbi.bbi_file.BBIFile.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = -1;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bbi/bbi_file.pyx":123
+ *             self.open( file, expected_sig, type_name )
+ * 
+ *     def open( self, file, expected_sig, type_name ):             # <<<<<<<<<<<<<<
+ *         """
+ *         Initialize from an existing bbi file, signature (magic) must be passed
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_3bbi_8bbi_file_7BBIFile_3open(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_2bx_3bbi_8bbi_file_7BBIFile_2open[] = "\n        Initialize from an existing bbi file, signature (magic) must be passed\n        in since this is generic. \n        ";
+static PyObject *__pyx_pw_2bx_3bbi_8bbi_file_7BBIFile_3open(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_file = 0;
+  PyObject *__pyx_v_expected_sig = 0;
+  CYTHON_UNUSED PyObject *__pyx_v_type_name = 0;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("open (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_file,&__pyx_n_s_expected_sig,&__pyx_n_s_type_name,0};
+    PyObject* values[3] = {0,0,0};
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_file)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_expected_sig)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("open", 1, 3, 3, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+        case  2:
+        if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_type_name)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("open", 1, 3, 3, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "open") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else if (PyTuple_GET_SIZE(__pyx_args) != 3) {
+      goto __pyx_L5_argtuple_error;
+    } else {
+      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+      values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+    }
+    __pyx_v_file = values[0];
+    __pyx_v_expected_sig = values[1];
+    __pyx_v_type_name = values[2];
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("open", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.bbi.bbi_file.BBIFile.open", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_3bbi_8bbi_file_7BBIFile_2open(((struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *)__pyx_v_self), __pyx_v_file, __pyx_v_expected_sig, __pyx_v_type_name);
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_2bx_3bbi_8bbi_file_7BBIFile_2open(struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *__pyx_v_self, PyObject *__pyx_v_file, PyObject *__pyx_v_expected_sig, CYTHON_UNUSED PyObject *__pyx_v_type_name) {
+  PyObject *__pyx_v_reader = NULL;
+  CYTHON_UNUSED long __pyx_v_i;
+  struct __pyx_obj_2bx_3bbi_8bbi_file_ZoomLevel *__pyx_v_level = NULL;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  Py_ssize_t __pyx_t_5;
+  PyObject *__pyx_t_6 = NULL;
+  __pyx_t_2bx_3bbi_5types_bits32 __pyx_t_7;
+  __pyx_t_2bx_3bbi_5types_boolean __pyx_t_8;
+  __pyx_t_2bx_3bbi_5types_bits16 __pyx_t_9;
+  __pyx_t_2bx_3bbi_5types_bits64 __pyx_t_10;
+  int __pyx_t_11;
+  PyObject *__pyx_t_12 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("open", 0);
+
+  /* "bx/bbi/bbi_file.pyx":128
+ *         in since this is generic.
+ *         """
+ *         assert expected_sig is not None             # <<<<<<<<<<<<<<
+ *         self.file = file
+ *         # Open the file in a BinaryFileReader, handles magic and byteswapping
+ */
+  #ifndef CYTHON_WITHOUT_ASSERTIONS
+  if (unlikely(!Py_OptimizeFlag)) {
+    __pyx_t_1 = (__pyx_v_expected_sig != Py_None);
+    if (unlikely(!(__pyx_t_1 != 0))) {
+      PyErr_SetNone(PyExc_AssertionError);
+      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 128; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+  }
+  #endif
+
+  /* "bx/bbi/bbi_file.pyx":129
+ *         """
+ *         assert expected_sig is not None
+ *         self.file = file             # <<<<<<<<<<<<<<
+ *         # Open the file in a BinaryFileReader, handles magic and byteswapping
+ *         self.reader = reader = BinaryFileReader( file, expected_sig )
+ */
+  __Pyx_INCREF(__pyx_v_file);
+  __Pyx_GIVEREF(__pyx_v_file);
+  __Pyx_GOTREF(__pyx_v_self->file);
+  __Pyx_DECREF(__pyx_v_self->file);
+  __pyx_v_self->file = __pyx_v_file;
+
+  /* "bx/bbi/bbi_file.pyx":131
+ *         self.file = file
+ *         # Open the file in a BinaryFileReader, handles magic and byteswapping
+ *         self.reader = reader = BinaryFileReader( file, expected_sig )             # <<<<<<<<<<<<<<
+ *         self.magic = expected_sig
+ *         self.is_byteswapped = self.reader.byteswap_needed
+ */
+  __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_BinaryFileReader); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 131; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_4 = NULL;
+  __pyx_t_5 = 0;
+  if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_3))) {
+    __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_3);
+    if (likely(__pyx_t_4)) {
+      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+      __Pyx_INCREF(__pyx_t_4);
+      __Pyx_INCREF(function);
+      __Pyx_DECREF_SET(__pyx_t_3, function);
+      __pyx_t_5 = 1;
+    }
+  }
+  __pyx_t_6 = PyTuple_New(2+__pyx_t_5); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 131; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_6);
+  if (__pyx_t_4) {
+    PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_4); __Pyx_GIVEREF(__pyx_t_4); __pyx_t_4 = NULL;
+  }
+  __Pyx_INCREF(__pyx_v_file);
+  PyTuple_SET_ITEM(__pyx_t_6, 0+__pyx_t_5, __pyx_v_file);
+  __Pyx_GIVEREF(__pyx_v_file);
+  __Pyx_INCREF(__pyx_v_expected_sig);
+  PyTuple_SET_ITEM(__pyx_t_6, 1+__pyx_t_5, __pyx_v_expected_sig);
+  __Pyx_GIVEREF(__pyx_v_expected_sig);
+  __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_6, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 131; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __Pyx_INCREF(__pyx_t_2);
+  __Pyx_GIVEREF(__pyx_t_2);
+  __Pyx_GOTREF(__pyx_v_self->reader);
+  __Pyx_DECREF(__pyx_v_self->reader);
+  __pyx_v_self->reader = __pyx_t_2;
+  __Pyx_INCREF(__pyx_t_2);
+  __pyx_v_reader = __pyx_t_2;
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+  /* "bx/bbi/bbi_file.pyx":132
+ *         # Open the file in a BinaryFileReader, handles magic and byteswapping
+ *         self.reader = reader = BinaryFileReader( file, expected_sig )
+ *         self.magic = expected_sig             # <<<<<<<<<<<<<<
+ *         self.is_byteswapped = self.reader.byteswap_needed
+ *         # Read header stuff
+ */
+  __pyx_t_7 = __Pyx_PyInt_As_unsigned_int(__pyx_v_expected_sig); if (unlikely((__pyx_t_7 == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_v_self->magic = __pyx_t_7;
+
+  /* "bx/bbi/bbi_file.pyx":133
+ *         self.reader = reader = BinaryFileReader( file, expected_sig )
+ *         self.magic = expected_sig
+ *         self.is_byteswapped = self.reader.byteswap_needed             # <<<<<<<<<<<<<<
+ *         # Read header stuff
+ *         self.version = reader.read_uint16()
+ */
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self->reader, __pyx_n_s_byteswap_needed); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 133; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_8 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_8 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 133; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_v_self->is_byteswapped = __pyx_t_8;
+
+  /* "bx/bbi/bbi_file.pyx":135
+ *         self.is_byteswapped = self.reader.byteswap_needed
+ *         # Read header stuff
+ *         self.version = reader.read_uint16()             # <<<<<<<<<<<<<<
+ *         self.zoom_levels = reader.read_uint16()
+ *         self.chrom_tree_offset = reader.read_uint64()
+ */
+  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_reader, __pyx_n_s_read_uint16); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 135; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_6 = NULL;
+  if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_3))) {
+    __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_3);
+    if (likely(__pyx_t_6)) {
+      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+      __Pyx_INCREF(__pyx_t_6);
+      __Pyx_INCREF(function);
+      __Pyx_DECREF_SET(__pyx_t_3, function);
+    }
+  }
+  if (__pyx_t_6) {
+    __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_6); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 135; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+  } else {
+    __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 135; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __pyx_t_9 = __Pyx_PyInt_As_unsigned_short(__pyx_t_2); if (unlikely((__pyx_t_9 == (unsigned short)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 135; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_v_self->version = __pyx_t_9;
+
+  /* "bx/bbi/bbi_file.pyx":136
+ *         # Read header stuff
+ *         self.version = reader.read_uint16()
+ *         self.zoom_levels = reader.read_uint16()             # <<<<<<<<<<<<<<
+ *         self.chrom_tree_offset = reader.read_uint64()
+ *         self.unzoomed_data_offset = reader.read_uint64()
+ */
+  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_reader, __pyx_n_s_read_uint16); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_6 = NULL;
+  if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_3))) {
+    __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_3);
+    if (likely(__pyx_t_6)) {
+      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+      __Pyx_INCREF(__pyx_t_6);
+      __Pyx_INCREF(function);
+      __Pyx_DECREF_SET(__pyx_t_3, function);
+    }
+  }
+  if (__pyx_t_6) {
+    __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_6); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+  } else {
+    __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __pyx_t_9 = __Pyx_PyInt_As_unsigned_short(__pyx_t_2); if (unlikely((__pyx_t_9 == (unsigned short)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_v_self->zoom_levels = __pyx_t_9;
+
+  /* "bx/bbi/bbi_file.pyx":137
+ *         self.version = reader.read_uint16()
+ *         self.zoom_levels = reader.read_uint16()
+ *         self.chrom_tree_offset = reader.read_uint64()             # <<<<<<<<<<<<<<
+ *         self.unzoomed_data_offset = reader.read_uint64()
+ *         self.unzoomed_index_offset = reader.read_uint64()
+ */
+  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_reader, __pyx_n_s_read_uint64); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 137; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_6 = NULL;
+  if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_3))) {
+    __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_3);
+    if (likely(__pyx_t_6)) {
+      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+      __Pyx_INCREF(__pyx_t_6);
+      __Pyx_INCREF(function);
+      __Pyx_DECREF_SET(__pyx_t_3, function);
+    }
+  }
+  if (__pyx_t_6) {
+    __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_6); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 137; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+  } else {
+    __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 137; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __pyx_t_10 = __Pyx_PyInt_As_unsigned_PY_LONG_LONG(__pyx_t_2); if (unlikely((__pyx_t_10 == (unsigned PY_LONG_LONG)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 137; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_v_self->chrom_tree_offset = __pyx_t_10;
+
+  /* "bx/bbi/bbi_file.pyx":138
+ *         self.zoom_levels = reader.read_uint16()
+ *         self.chrom_tree_offset = reader.read_uint64()
+ *         self.unzoomed_data_offset = reader.read_uint64()             # <<<<<<<<<<<<<<
+ *         self.unzoomed_index_offset = reader.read_uint64()
+ *         self.field_count = reader.read_uint16()
+ */
+  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_reader, __pyx_n_s_read_uint64); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 138; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_6 = NULL;
+  if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_3))) {
+    __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_3);
+    if (likely(__pyx_t_6)) {
+      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+      __Pyx_INCREF(__pyx_t_6);
+      __Pyx_INCREF(function);
+      __Pyx_DECREF_SET(__pyx_t_3, function);
+    }
+  }
+  if (__pyx_t_6) {
+    __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_6); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 138; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+  } else {
+    __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 138; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __pyx_t_10 = __Pyx_PyInt_As_unsigned_PY_LONG_LONG(__pyx_t_2); if (unlikely((__pyx_t_10 == (unsigned PY_LONG_LONG)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 138; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_v_self->unzoomed_data_offset = __pyx_t_10;
+
+  /* "bx/bbi/bbi_file.pyx":139
+ *         self.chrom_tree_offset = reader.read_uint64()
+ *         self.unzoomed_data_offset = reader.read_uint64()
+ *         self.unzoomed_index_offset = reader.read_uint64()             # <<<<<<<<<<<<<<
+ *         self.field_count = reader.read_uint16()
+ *         self.defined_field_count = reader.read_uint16()
+ */
+  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_reader, __pyx_n_s_read_uint64); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 139; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_6 = NULL;
+  if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_3))) {
+    __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_3);
+    if (likely(__pyx_t_6)) {
+      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+      __Pyx_INCREF(__pyx_t_6);
+      __Pyx_INCREF(function);
+      __Pyx_DECREF_SET(__pyx_t_3, function);
+    }
+  }
+  if (__pyx_t_6) {
+    __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_6); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 139; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+  } else {
+    __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 139; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __pyx_t_10 = __Pyx_PyInt_As_unsigned_PY_LONG_LONG(__pyx_t_2); if (unlikely((__pyx_t_10 == (unsigned PY_LONG_LONG)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 139; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_v_self->unzoomed_index_offset = __pyx_t_10;
+
+  /* "bx/bbi/bbi_file.pyx":140
+ *         self.unzoomed_data_offset = reader.read_uint64()
+ *         self.unzoomed_index_offset = reader.read_uint64()
+ *         self.field_count = reader.read_uint16()             # <<<<<<<<<<<<<<
+ *         self.defined_field_count = reader.read_uint16()
+ *         self.as_offset = reader.read_uint64()
+ */
+  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_reader, __pyx_n_s_read_uint16); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 140; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_6 = NULL;
+  if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_3))) {
+    __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_3);
+    if (likely(__pyx_t_6)) {
+      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+      __Pyx_INCREF(__pyx_t_6);
+      __Pyx_INCREF(function);
+      __Pyx_DECREF_SET(__pyx_t_3, function);
+    }
+  }
+  if (__pyx_t_6) {
+    __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_6); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 140; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+  } else {
+    __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 140; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __pyx_t_9 = __Pyx_PyInt_As_unsigned_short(__pyx_t_2); if (unlikely((__pyx_t_9 == (unsigned short)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 140; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_v_self->field_count = __pyx_t_9;
+
+  /* "bx/bbi/bbi_file.pyx":141
+ *         self.unzoomed_index_offset = reader.read_uint64()
+ *         self.field_count = reader.read_uint16()
+ *         self.defined_field_count = reader.read_uint16()             # <<<<<<<<<<<<<<
+ *         self.as_offset = reader.read_uint64()
+ *         self.total_summary_offset = reader.read_uint64()
+ */
+  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_reader, __pyx_n_s_read_uint16); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_6 = NULL;
+  if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_3))) {
+    __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_3);
+    if (likely(__pyx_t_6)) {
+      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+      __Pyx_INCREF(__pyx_t_6);
+      __Pyx_INCREF(function);
+      __Pyx_DECREF_SET(__pyx_t_3, function);
+    }
+  }
+  if (__pyx_t_6) {
+    __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_6); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+  } else {
+    __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __pyx_t_9 = __Pyx_PyInt_As_unsigned_short(__pyx_t_2); if (unlikely((__pyx_t_9 == (unsigned short)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_v_self->defined_field_count = __pyx_t_9;
+
+  /* "bx/bbi/bbi_file.pyx":142
+ *         self.field_count = reader.read_uint16()
+ *         self.defined_field_count = reader.read_uint16()
+ *         self.as_offset = reader.read_uint64()             # <<<<<<<<<<<<<<
+ *         self.total_summary_offset = reader.read_uint64()
+ *         self.uncompress_buf_size = reader.read_uint32()
+ */
+  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_reader, __pyx_n_s_read_uint64); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_6 = NULL;
+  if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_3))) {
+    __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_3);
+    if (likely(__pyx_t_6)) {
+      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+      __Pyx_INCREF(__pyx_t_6);
+      __Pyx_INCREF(function);
+      __Pyx_DECREF_SET(__pyx_t_3, function);
+    }
+  }
+  if (__pyx_t_6) {
+    __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_6); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+  } else {
+    __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __pyx_t_10 = __Pyx_PyInt_As_unsigned_PY_LONG_LONG(__pyx_t_2); if (unlikely((__pyx_t_10 == (unsigned PY_LONG_LONG)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_v_self->as_offset = __pyx_t_10;
+
+  /* "bx/bbi/bbi_file.pyx":143
+ *         self.defined_field_count = reader.read_uint16()
+ *         self.as_offset = reader.read_uint64()
+ *         self.total_summary_offset = reader.read_uint64()             # <<<<<<<<<<<<<<
+ *         self.uncompress_buf_size = reader.read_uint32()
+ *         # Skip reserved
+ */
+  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_reader, __pyx_n_s_read_uint64); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_6 = NULL;
+  if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_3))) {
+    __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_3);
+    if (likely(__pyx_t_6)) {
+      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+      __Pyx_INCREF(__pyx_t_6);
+      __Pyx_INCREF(function);
+      __Pyx_DECREF_SET(__pyx_t_3, function);
+    }
+  }
+  if (__pyx_t_6) {
+    __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_6); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+  } else {
+    __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __pyx_t_10 = __Pyx_PyInt_As_unsigned_PY_LONG_LONG(__pyx_t_2); if (unlikely((__pyx_t_10 == (unsigned PY_LONG_LONG)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_v_self->total_summary_offset = __pyx_t_10;
+
+  /* "bx/bbi/bbi_file.pyx":144
+ *         self.as_offset = reader.read_uint64()
+ *         self.total_summary_offset = reader.read_uint64()
+ *         self.uncompress_buf_size = reader.read_uint32()             # <<<<<<<<<<<<<<
+ *         # Skip reserved
+ *         reader.seek( 64 )
+ */
+  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_reader, __pyx_n_s_read_uint32); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 144; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_6 = NULL;
+  if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_3))) {
+    __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_3);
+    if (likely(__pyx_t_6)) {
+      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+      __Pyx_INCREF(__pyx_t_6);
+      __Pyx_INCREF(function);
+      __Pyx_DECREF_SET(__pyx_t_3, function);
+    }
+  }
+  if (__pyx_t_6) {
+    __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_6); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 144; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+  } else {
+    __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 144; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __pyx_t_7 = __Pyx_PyInt_As_unsigned_int(__pyx_t_2); if (unlikely((__pyx_t_7 == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 144; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_v_self->uncompress_buf_size = __pyx_t_7;
+
+  /* "bx/bbi/bbi_file.pyx":146
+ *         self.uncompress_buf_size = reader.read_uint32()
+ *         # Skip reserved
+ *         reader.seek( 64 )             # <<<<<<<<<<<<<<
+ *         # Read zoom headers
+ *         self.level_list = []
+ */
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_reader, __pyx_n_s_seek); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 146; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_tuple_, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 146; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+  /* "bx/bbi/bbi_file.pyx":148
+ *         reader.seek( 64 )
+ *         # Read zoom headers
+ *         self.level_list = []             # <<<<<<<<<<<<<<
+ *         for i from 0 <= i < self.zoom_levels:
+ *             level = ZoomLevel()
+ */
+  __pyx_t_3 = PyList_New(0); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 148; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_GIVEREF(__pyx_t_3);
+  __Pyx_GOTREF(__pyx_v_self->level_list);
+  __Pyx_DECREF(__pyx_v_self->level_list);
+  __pyx_v_self->level_list = __pyx_t_3;
+  __pyx_t_3 = 0;
+
+  /* "bx/bbi/bbi_file.pyx":149
+ *         # Read zoom headers
+ *         self.level_list = []
+ *         for i from 0 <= i < self.zoom_levels:             # <<<<<<<<<<<<<<
+ *             level = ZoomLevel()
+ *             level.bbi_file = self
+ */
+  __pyx_t_9 = __pyx_v_self->zoom_levels;
+  for (__pyx_v_i = 0; __pyx_v_i < __pyx_t_9; __pyx_v_i++) {
+
+    /* "bx/bbi/bbi_file.pyx":150
+ *         self.level_list = []
+ *         for i from 0 <= i < self.zoom_levels:
+ *             level = ZoomLevel()             # <<<<<<<<<<<<<<
+ *             level.bbi_file = self
+ *             level.reduction_level = reader.read_uint32()
+ */
+    __pyx_t_3 = __Pyx_PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_2bx_3bbi_8bbi_file_ZoomLevel)), __pyx_empty_tuple, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 150; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_XDECREF_SET(__pyx_v_level, ((struct __pyx_obj_2bx_3bbi_8bbi_file_ZoomLevel *)__pyx_t_3));
+    __pyx_t_3 = 0;
+
+    /* "bx/bbi/bbi_file.pyx":151
+ *         for i from 0 <= i < self.zoom_levels:
+ *             level = ZoomLevel()
+ *             level.bbi_file = self             # <<<<<<<<<<<<<<
+ *             level.reduction_level = reader.read_uint32()
+ *             level.reserved = reader.read_uint32()
+ */
+    __Pyx_INCREF(((PyObject *)__pyx_v_self));
+    __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
+    __Pyx_GOTREF(__pyx_v_level->bbi_file);
+    __Pyx_DECREF(((PyObject *)__pyx_v_level->bbi_file));
+    __pyx_v_level->bbi_file = __pyx_v_self;
+
+    /* "bx/bbi/bbi_file.pyx":152
+ *             level = ZoomLevel()
+ *             level.bbi_file = self
+ *             level.reduction_level = reader.read_uint32()             # <<<<<<<<<<<<<<
+ *             level.reserved = reader.read_uint32()
+ *             level.data_offset = reader.read_uint64()
+ */
+    __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_reader, __pyx_n_s_read_uint32); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 152; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_t_6 = NULL;
+    if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_2))) {
+      __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_2);
+      if (likely(__pyx_t_6)) {
+        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+        __Pyx_INCREF(__pyx_t_6);
+        __Pyx_INCREF(function);
+        __Pyx_DECREF_SET(__pyx_t_2, function);
+      }
+    }
+    if (__pyx_t_6) {
+      __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_6); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 152; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+    } else {
+      __pyx_t_3 = __Pyx_PyObject_CallNoArg(__pyx_t_2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 152; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    __pyx_t_7 = __Pyx_PyInt_As_unsigned_int(__pyx_t_3); if (unlikely((__pyx_t_7 == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 152; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __pyx_v_level->reduction_level = __pyx_t_7;
+
+    /* "bx/bbi/bbi_file.pyx":153
+ *             level.bbi_file = self
+ *             level.reduction_level = reader.read_uint32()
+ *             level.reserved = reader.read_uint32()             # <<<<<<<<<<<<<<
+ *             level.data_offset = reader.read_uint64()
+ *             level.index_offset = reader.read_uint64()
+ */
+    __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_reader, __pyx_n_s_read_uint32); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 153; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_t_6 = NULL;
+    if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_2))) {
+      __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_2);
+      if (likely(__pyx_t_6)) {
+        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+        __Pyx_INCREF(__pyx_t_6);
+        __Pyx_INCREF(function);
+        __Pyx_DECREF_SET(__pyx_t_2, function);
+      }
+    }
+    if (__pyx_t_6) {
+      __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_6); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 153; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+    } else {
+      __pyx_t_3 = __Pyx_PyObject_CallNoArg(__pyx_t_2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 153; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    __pyx_t_7 = __Pyx_PyInt_As_unsigned_int(__pyx_t_3); if (unlikely((__pyx_t_7 == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 153; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __pyx_v_level->reserved = __pyx_t_7;
+
+    /* "bx/bbi/bbi_file.pyx":154
+ *             level.reduction_level = reader.read_uint32()
+ *             level.reserved = reader.read_uint32()
+ *             level.data_offset = reader.read_uint64()             # <<<<<<<<<<<<<<
+ *             level.index_offset = reader.read_uint64()
+ *             self.level_list.append( level )
+ */
+    __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_reader, __pyx_n_s_read_uint64); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 154; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_t_6 = NULL;
+    if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_2))) {
+      __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_2);
+      if (likely(__pyx_t_6)) {
+        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+        __Pyx_INCREF(__pyx_t_6);
+        __Pyx_INCREF(function);
+        __Pyx_DECREF_SET(__pyx_t_2, function);
+      }
+    }
+    if (__pyx_t_6) {
+      __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_6); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 154; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+    } else {
+      __pyx_t_3 = __Pyx_PyObject_CallNoArg(__pyx_t_2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 154; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    __pyx_t_10 = __Pyx_PyInt_As_unsigned_PY_LONG_LONG(__pyx_t_3); if (unlikely((__pyx_t_10 == (unsigned PY_LONG_LONG)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 154; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __pyx_v_level->data_offset = __pyx_t_10;
+
+    /* "bx/bbi/bbi_file.pyx":155
+ *             level.reserved = reader.read_uint32()
+ *             level.data_offset = reader.read_uint64()
+ *             level.index_offset = reader.read_uint64()             # <<<<<<<<<<<<<<
+ *             self.level_list.append( level )
+ *         # Initialize and attach embedded BPTFile containing chromosome names and ids
+ */
+    __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_reader, __pyx_n_s_read_uint64); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 155; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_t_6 = NULL;
+    if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_2))) {
+      __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_2);
+      if (likely(__pyx_t_6)) {
+        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+        __Pyx_INCREF(__pyx_t_6);
+        __Pyx_INCREF(function);
+        __Pyx_DECREF_SET(__pyx_t_2, function);
+      }
+    }
+    if (__pyx_t_6) {
+      __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_6); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 155; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+    } else {
+      __pyx_t_3 = __Pyx_PyObject_CallNoArg(__pyx_t_2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 155; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    __pyx_t_10 = __Pyx_PyInt_As_unsigned_PY_LONG_LONG(__pyx_t_3); if (unlikely((__pyx_t_10 == (unsigned PY_LONG_LONG)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 155; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __pyx_v_level->index_offset = __pyx_t_10;
+
+    /* "bx/bbi/bbi_file.pyx":156
+ *             level.data_offset = reader.read_uint64()
+ *             level.index_offset = reader.read_uint64()
+ *             self.level_list.append( level )             # <<<<<<<<<<<<<<
+ *         # Initialize and attach embedded BPTFile containing chromosome names and ids
+ *         reader.seek( self.chrom_tree_offset )
+ */
+    __pyx_t_11 = __Pyx_PyObject_Append(__pyx_v_self->level_list, ((PyObject *)__pyx_v_level)); if (unlikely(__pyx_t_11 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+
+  /* "bx/bbi/bbi_file.pyx":158
+ *             self.level_list.append( level )
+ *         # Initialize and attach embedded BPTFile containing chromosome names and ids
+ *         reader.seek( self.chrom_tree_offset )             # <<<<<<<<<<<<<<
+ *         self.chrom_bpt = BPTFile( file=self.file )
+ * 
+ */
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_reader, __pyx_n_s_seek); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_6 = __Pyx_PyInt_From_unsigned_PY_LONG_LONG(__pyx_v_self->chrom_tree_offset); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_6);
+  __pyx_t_4 = NULL;
+  if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_2))) {
+    __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_2);
+    if (likely(__pyx_t_4)) {
+      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+      __Pyx_INCREF(__pyx_t_4);
+      __Pyx_INCREF(function);
+      __Pyx_DECREF_SET(__pyx_t_2, function);
+    }
+  }
+  if (!__pyx_t_4) {
+    __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_6); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+    __Pyx_GOTREF(__pyx_t_3);
+  } else {
+    __pyx_t_12 = PyTuple_New(1+1); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_12);
+    PyTuple_SET_ITEM(__pyx_t_12, 0, __pyx_t_4); __Pyx_GIVEREF(__pyx_t_4); __pyx_t_4 = NULL;
+    PyTuple_SET_ITEM(__pyx_t_12, 0+1, __pyx_t_6);
+    __Pyx_GIVEREF(__pyx_t_6);
+    __pyx_t_6 = 0;
+    __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_12, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
+  }
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+  /* "bx/bbi/bbi_file.pyx":159
+ *         # Initialize and attach embedded BPTFile containing chromosome names and ids
+ *         reader.seek( self.chrom_tree_offset )
+ *         self.chrom_bpt = BPTFile( file=self.file )             # <<<<<<<<<<<<<<
+ * 
+ *     cdef visit_blocks_in_region( self, bits32 chrom_id, bits32 start, bits32 end, BlockHandler handler ):
+ */
+  __pyx_t_3 = PyDict_New(); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 159; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_file, __pyx_v_self->file) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 159; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = __Pyx_PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_2bx_3bbi_8bpt_file_BPTFile)), __pyx_empty_tuple, __pyx_t_3); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 159; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __Pyx_GIVEREF(__pyx_t_2);
+  __Pyx_GOTREF(__pyx_v_self->chrom_bpt);
+  __Pyx_DECREF(((PyObject *)__pyx_v_self->chrom_bpt));
+  __pyx_v_self->chrom_bpt = ((struct __pyx_obj_2bx_3bbi_8bpt_file_BPTFile *)__pyx_t_2);
+  __pyx_t_2 = 0;
+
+  /* "bx/bbi/bbi_file.pyx":123
+ *             self.open( file, expected_sig, type_name )
+ * 
+ *     def open( self, file, expected_sig, type_name ):             # <<<<<<<<<<<<<<
+ *         """
+ *         Initialize from an existing bbi file, signature (magic) must be passed
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_XDECREF(__pyx_t_6);
+  __Pyx_XDECREF(__pyx_t_12);
+  __Pyx_AddTraceback("bx.bbi.bbi_file.BBIFile.open", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_reader);
+  __Pyx_XDECREF((PyObject *)__pyx_v_level);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bbi/bbi_file.pyx":161
+ *         self.chrom_bpt = BPTFile( file=self.file )
+ * 
+ *     cdef visit_blocks_in_region( self, bits32 chrom_id, bits32 start, bits32 end, BlockHandler handler ):             # <<<<<<<<<<<<<<
+ *         """
+ *         Visit each block from the full data that overlaps a specific region
+ */
+
+static PyObject *__pyx_f_2bx_3bbi_8bbi_file_7BBIFile_visit_blocks_in_region(struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *__pyx_v_self, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_chrom_id, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_start, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_end, struct __pyx_obj_2bx_3bbi_8bbi_file_BlockHandler *__pyx_v_handler) {
+  struct __pyx_obj_2bx_3bbi_12cirtree_file_CIRTreeFile *__pyx_v_ctf = 0;
+  PyObject *__pyx_v_reader = NULL;
+  PyObject *__pyx_v_block_list = NULL;
+  PyObject *__pyx_v_offset = NULL;
+  PyObject *__pyx_v_size = NULL;
+  PyObject *__pyx_v_block_data = NULL;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  PyObject *__pyx_t_5 = NULL;
+  PyObject *__pyx_t_6 = NULL;
+  Py_ssize_t __pyx_t_7;
+  PyObject *__pyx_t_8 = NULL;
+  PyObject *(*__pyx_t_9)(PyObject *);
+  PyObject *(*__pyx_t_10)(PyObject *);
+  int __pyx_t_11;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("visit_blocks_in_region", 0);
+
+  /* "bx/bbi/bbi_file.pyx":166
+ *         """
+ *         cdef CIRTreeFile ctf
+ *         reader = self.reader             # <<<<<<<<<<<<<<
+ *         reader.seek( self.unzoomed_index_offset )
+ *         ctf = CIRTreeFile( reader.file )
+ */
+  __pyx_t_1 = __pyx_v_self->reader;
+  __Pyx_INCREF(__pyx_t_1);
+  __pyx_v_reader = __pyx_t_1;
+  __pyx_t_1 = 0;
+
+  /* "bx/bbi/bbi_file.pyx":167
+ *         cdef CIRTreeFile ctf
+ *         reader = self.reader
+ *         reader.seek( self.unzoomed_index_offset )             # <<<<<<<<<<<<<<
+ *         ctf = CIRTreeFile( reader.file )
+ *         block_list = ctf.find_overlapping_blocks( chrom_id, start, end )
+ */
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_reader, __pyx_n_s_seek); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 167; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = __Pyx_PyInt_From_unsigned_PY_LONG_LONG(__pyx_v_self->unzoomed_index_offset); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 167; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_4 = NULL;
+  if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_2))) {
+    __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_2);
+    if (likely(__pyx_t_4)) {
+      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+      __Pyx_INCREF(__pyx_t_4);
+      __Pyx_INCREF(function);
+      __Pyx_DECREF_SET(__pyx_t_2, function);
+    }
+  }
+  if (!__pyx_t_4) {
+    __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 167; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __Pyx_GOTREF(__pyx_t_1);
+  } else {
+    __pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 167; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_5);
+    PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_4); __Pyx_GIVEREF(__pyx_t_4); __pyx_t_4 = NULL;
+    PyTuple_SET_ITEM(__pyx_t_5, 0+1, __pyx_t_3);
+    __Pyx_GIVEREF(__pyx_t_3);
+    __pyx_t_3 = 0;
+    __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_5, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 167; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+  }
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "bx/bbi/bbi_file.pyx":168
+ *         reader = self.reader
+ *         reader.seek( self.unzoomed_index_offset )
+ *         ctf = CIRTreeFile( reader.file )             # <<<<<<<<<<<<<<
+ *         block_list = ctf.find_overlapping_blocks( chrom_id, start, end )
+ *         for offset, size in block_list:
+ */
+  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_reader, __pyx_n_s_file); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 168; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 168; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
+  __Pyx_GIVEREF(__pyx_t_1);
+  __pyx_t_1 = 0;
+  __pyx_t_1 = __Pyx_PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_2bx_3bbi_12cirtree_file_CIRTreeFile)), __pyx_t_2, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 168; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_v_ctf = ((struct __pyx_obj_2bx_3bbi_12cirtree_file_CIRTreeFile *)__pyx_t_1);
+  __pyx_t_1 = 0;
+
+  /* "bx/bbi/bbi_file.pyx":169
+ *         reader.seek( self.unzoomed_index_offset )
+ *         ctf = CIRTreeFile( reader.file )
+ *         block_list = ctf.find_overlapping_blocks( chrom_id, start, end )             # <<<<<<<<<<<<<<
+ *         for offset, size in block_list:
+ *             # Seek to and read all data for the block
+ */
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_ctf), __pyx_n_s_find_overlapping_blocks); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_5 = __Pyx_PyInt_From_unsigned_int(__pyx_v_chrom_id); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __pyx_t_3 = __Pyx_PyInt_From_unsigned_int(__pyx_v_start); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_4 = __Pyx_PyInt_From_unsigned_int(__pyx_v_end); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __pyx_t_6 = NULL;
+  __pyx_t_7 = 0;
+  if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_2))) {
+    __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_2);
+    if (likely(__pyx_t_6)) {
+      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+      __Pyx_INCREF(__pyx_t_6);
+      __Pyx_INCREF(function);
+      __Pyx_DECREF_SET(__pyx_t_2, function);
+      __pyx_t_7 = 1;
+    }
+  }
+  __pyx_t_8 = PyTuple_New(3+__pyx_t_7); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_8);
+  if (__pyx_t_6) {
+    PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_6); __Pyx_GIVEREF(__pyx_t_6); __pyx_t_6 = NULL;
+  }
+  PyTuple_SET_ITEM(__pyx_t_8, 0+__pyx_t_7, __pyx_t_5);
+  __Pyx_GIVEREF(__pyx_t_5);
+  PyTuple_SET_ITEM(__pyx_t_8, 1+__pyx_t_7, __pyx_t_3);
+  __Pyx_GIVEREF(__pyx_t_3);
+  PyTuple_SET_ITEM(__pyx_t_8, 2+__pyx_t_7, __pyx_t_4);
+  __Pyx_GIVEREF(__pyx_t_4);
+  __pyx_t_5 = 0;
+  __pyx_t_3 = 0;
+  __pyx_t_4 = 0;
+  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_8, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_v_block_list = __pyx_t_1;
+  __pyx_t_1 = 0;
+
+  /* "bx/bbi/bbi_file.pyx":170
+ *         ctf = CIRTreeFile( reader.file )
+ *         block_list = ctf.find_overlapping_blocks( chrom_id, start, end )
+ *         for offset, size in block_list:             # <<<<<<<<<<<<<<
+ *             # Seek to and read all data for the block
+ *             reader.seek( offset )
+ */
+  if (likely(PyList_CheckExact(__pyx_v_block_list)) || PyTuple_CheckExact(__pyx_v_block_list)) {
+    __pyx_t_1 = __pyx_v_block_list; __Pyx_INCREF(__pyx_t_1); __pyx_t_7 = 0;
+    __pyx_t_9 = NULL;
+  } else {
+    __pyx_t_7 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_block_list); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 170; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __pyx_t_9 = Py_TYPE(__pyx_t_1)->tp_iternext; if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 170; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  for (;;) {
+    if (likely(!__pyx_t_9)) {
+      if (likely(PyList_CheckExact(__pyx_t_1))) {
+        if (__pyx_t_7 >= PyList_GET_SIZE(__pyx_t_1)) break;
+        #if CYTHON_COMPILING_IN_CPYTHON
+        __pyx_t_2 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_7); __Pyx_INCREF(__pyx_t_2); __pyx_t_7++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 170; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #else
+        __pyx_t_2 = PySequence_ITEM(__pyx_t_1, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 170; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #endif
+      } else {
+        if (__pyx_t_7 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
+        #if CYTHON_COMPILING_IN_CPYTHON
+        __pyx_t_2 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_7); __Pyx_INCREF(__pyx_t_2); __pyx_t_7++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 170; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #else
+        __pyx_t_2 = PySequence_ITEM(__pyx_t_1, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 170; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #endif
+      }
+    } else {
+      __pyx_t_2 = __pyx_t_9(__pyx_t_1);
+      if (unlikely(!__pyx_t_2)) {
+        PyObject* exc_type = PyErr_Occurred();
+        if (exc_type) {
+          if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+          else {__pyx_filename = __pyx_f[0]; __pyx_lineno = 170; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        }
+        break;
+      }
+      __Pyx_GOTREF(__pyx_t_2);
+    }
+    if ((likely(PyTuple_CheckExact(__pyx_t_2))) || (PyList_CheckExact(__pyx_t_2))) {
+      PyObject* sequence = __pyx_t_2;
+      #if CYTHON_COMPILING_IN_CPYTHON
+      Py_ssize_t size = Py_SIZE(sequence);
+      #else
+      Py_ssize_t size = PySequence_Size(sequence);
+      #endif
+      if (unlikely(size != 2)) {
+        if (size > 2) __Pyx_RaiseTooManyValuesError(2);
+        else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
+        {__pyx_filename = __pyx_f[0]; __pyx_lineno = 170; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      }
+      #if CYTHON_COMPILING_IN_CPYTHON
+      if (likely(PyTuple_CheckExact(sequence))) {
+        __pyx_t_8 = PyTuple_GET_ITEM(sequence, 0); 
+        __pyx_t_4 = PyTuple_GET_ITEM(sequence, 1); 
+      } else {
+        __pyx_t_8 = PyList_GET_ITEM(sequence, 0); 
+        __pyx_t_4 = PyList_GET_ITEM(sequence, 1); 
+      }
+      __Pyx_INCREF(__pyx_t_8);
+      __Pyx_INCREF(__pyx_t_4);
+      #else
+      __pyx_t_8 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 170; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_8);
+      __pyx_t_4 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 170; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      #endif
+      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    } else {
+      Py_ssize_t index = -1;
+      __pyx_t_3 = PyObject_GetIter(__pyx_t_2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 170; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+      __pyx_t_10 = Py_TYPE(__pyx_t_3)->tp_iternext;
+      index = 0; __pyx_t_8 = __pyx_t_10(__pyx_t_3); if (unlikely(!__pyx_t_8)) goto __pyx_L5_unpacking_failed;
+      __Pyx_GOTREF(__pyx_t_8);
+      index = 1; __pyx_t_4 = __pyx_t_10(__pyx_t_3); if (unlikely(!__pyx_t_4)) goto __pyx_L5_unpacking_failed;
+      __Pyx_GOTREF(__pyx_t_4);
+      if (__Pyx_IternextUnpackEndCheck(__pyx_t_10(__pyx_t_3), 2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 170; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_10 = NULL;
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      goto __pyx_L6_unpacking_done;
+      __pyx_L5_unpacking_failed:;
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_t_10 = NULL;
+      if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
+      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 170; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_L6_unpacking_done:;
+    }
+    __Pyx_XDECREF_SET(__pyx_v_offset, __pyx_t_8);
+    __pyx_t_8 = 0;
+    __Pyx_XDECREF_SET(__pyx_v_size, __pyx_t_4);
+    __pyx_t_4 = 0;
+
+    /* "bx/bbi/bbi_file.pyx":172
+ *         for offset, size in block_list:
+ *             # Seek to and read all data for the block
+ *             reader.seek( offset )             # <<<<<<<<<<<<<<
+ *             block_data = reader.read( size )
+ *             # Might need to uncompress
+ */
+    __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_reader, __pyx_n_s_seek); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 172; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    __pyx_t_8 = NULL;
+    if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_4))) {
+      __pyx_t_8 = PyMethod_GET_SELF(__pyx_t_4);
+      if (likely(__pyx_t_8)) {
+        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
+        __Pyx_INCREF(__pyx_t_8);
+        __Pyx_INCREF(function);
+        __Pyx_DECREF_SET(__pyx_t_4, function);
+      }
+    }
+    if (!__pyx_t_8) {
+      __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_v_offset); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 172; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_2);
+    } else {
+      __pyx_t_3 = PyTuple_New(1+1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 172; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_8); __Pyx_GIVEREF(__pyx_t_8); __pyx_t_8 = NULL;
+      __Pyx_INCREF(__pyx_v_offset);
+      PyTuple_SET_ITEM(__pyx_t_3, 0+1, __pyx_v_offset);
+      __Pyx_GIVEREF(__pyx_v_offset);
+      __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_3, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 172; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_2);
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    }
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+    /* "bx/bbi/bbi_file.pyx":173
+ *             # Seek to and read all data for the block
+ *             reader.seek( offset )
+ *             block_data = reader.read( size )             # <<<<<<<<<<<<<<
+ *             # Might need to uncompress
+ *             if self.uncompress_buf_size > 0:
+ */
+    __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_reader, __pyx_n_s_read); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 173; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    __pyx_t_3 = NULL;
+    if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_4))) {
+      __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_4);
+      if (likely(__pyx_t_3)) {
+        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
+        __Pyx_INCREF(__pyx_t_3);
+        __Pyx_INCREF(function);
+        __Pyx_DECREF_SET(__pyx_t_4, function);
+      }
+    }
+    if (!__pyx_t_3) {
+      __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_v_size); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 173; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_2);
+    } else {
+      __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 173; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_8);
+      PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_3); __Pyx_GIVEREF(__pyx_t_3); __pyx_t_3 = NULL;
+      __Pyx_INCREF(__pyx_v_size);
+      PyTuple_SET_ITEM(__pyx_t_8, 0+1, __pyx_v_size);
+      __Pyx_GIVEREF(__pyx_v_size);
+      __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_8, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 173; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_2);
+      __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+    }
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    __Pyx_XDECREF_SET(__pyx_v_block_data, __pyx_t_2);
+    __pyx_t_2 = 0;
+
+    /* "bx/bbi/bbi_file.pyx":175
+ *             block_data = reader.read( size )
+ *             # Might need to uncompress
+ *             if self.uncompress_buf_size > 0:             # <<<<<<<<<<<<<<
+ *                 block_data = zlib.decompress( block_data )
+ *             handler.handle_block( block_data, self )
+ */
+    __pyx_t_11 = ((__pyx_v_self->uncompress_buf_size > 0) != 0);
+    if (__pyx_t_11) {
+
+      /* "bx/bbi/bbi_file.pyx":176
+ *             # Might need to uncompress
+ *             if self.uncompress_buf_size > 0:
+ *                 block_data = zlib.decompress( block_data )             # <<<<<<<<<<<<<<
+ *             handler.handle_block( block_data, self )
+ * 
+ */
+      __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_zlib); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_decompress); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_8);
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      __pyx_t_4 = NULL;
+      if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_8))) {
+        __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_8);
+        if (likely(__pyx_t_4)) {
+          PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_8);
+          __Pyx_INCREF(__pyx_t_4);
+          __Pyx_INCREF(function);
+          __Pyx_DECREF_SET(__pyx_t_8, function);
+        }
+      }
+      if (!__pyx_t_4) {
+        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_8, __pyx_v_block_data); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_2);
+      } else {
+        __pyx_t_3 = PyTuple_New(1+1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_3);
+        PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_4); __Pyx_GIVEREF(__pyx_t_4); __pyx_t_4 = NULL;
+        __Pyx_INCREF(__pyx_v_block_data);
+        PyTuple_SET_ITEM(__pyx_t_3, 0+1, __pyx_v_block_data);
+        __Pyx_GIVEREF(__pyx_v_block_data);
+        __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_8, __pyx_t_3, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_2);
+        __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      }
+      __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+      __Pyx_DECREF_SET(__pyx_v_block_data, __pyx_t_2);
+      __pyx_t_2 = 0;
+      goto __pyx_L7;
+    }
+    __pyx_L7:;
+
+    /* "bx/bbi/bbi_file.pyx":177
+ *             if self.uncompress_buf_size > 0:
+ *                 block_data = zlib.decompress( block_data )
+ *             handler.handle_block( block_data, self )             # <<<<<<<<<<<<<<
+ * 
+ *     cpdef summarize( self, char * chrom, bits32 start, bits32 end, int summary_size ):
+ */
+    if (!(likely(PyString_CheckExact(__pyx_v_block_data))||((__pyx_v_block_data) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "str", Py_TYPE(__pyx_v_block_data)->tp_name), 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 177; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = ((struct __pyx_vtabstruct_2bx_3bbi_8bbi_file_BlockHandler *)__pyx_v_handler->__pyx_vtab)->handle_block(__pyx_v_handler, ((PyObject*)__pyx_v_block_data), __pyx_v_self); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 177; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+    /* "bx/bbi/bbi_file.pyx":170
+ *         ctf = CIRTreeFile( reader.file )
+ *         block_list = ctf.find_overlapping_blocks( chrom_id, start, end )
+ *         for offset, size in block_list:             # <<<<<<<<<<<<<<
+ *             # Seek to and read all data for the block
+ *             reader.seek( offset )
+ */
+  }
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "bx/bbi/bbi_file.pyx":161
+ *         self.chrom_bpt = BPTFile( file=self.file )
+ * 
+ *     cdef visit_blocks_in_region( self, bits32 chrom_id, bits32 start, bits32 end, BlockHandler handler ):             # <<<<<<<<<<<<<<
+ *         """
+ *         Visit each block from the full data that overlaps a specific region
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_XDECREF(__pyx_t_5);
+  __Pyx_XDECREF(__pyx_t_6);
+  __Pyx_XDECREF(__pyx_t_8);
+  __Pyx_AddTraceback("bx.bbi.bbi_file.BBIFile.visit_blocks_in_region", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XDECREF((PyObject *)__pyx_v_ctf);
+  __Pyx_XDECREF(__pyx_v_reader);
+  __Pyx_XDECREF(__pyx_v_block_list);
+  __Pyx_XDECREF(__pyx_v_offset);
+  __Pyx_XDECREF(__pyx_v_size);
+  __Pyx_XDECREF(__pyx_v_block_data);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bbi/bbi_file.pyx":179
+ *             handler.handle_block( block_data, self )
+ * 
+ *     cpdef summarize( self, char * chrom, bits32 start, bits32 end, int summary_size ):             # <<<<<<<<<<<<<<
+ *         """
+ *         Gets `summary_size` data points over the regions `chrom`:`start`-`end`.
+ */
+
+static PyObject *__pyx_pw_2bx_3bbi_8bbi_file_7BBIFile_5summarize(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyObject *__pyx_f_2bx_3bbi_8bbi_file_7BBIFile_summarize(struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *__pyx_v_self, char *__pyx_v_chrom, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_start, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_end, int __pyx_v_summary_size, int __pyx_skip_dispatch) {
+  PyObject *__pyx_v_chrom_id = NULL;
+  CYTHON_UNUSED PyObject *__pyx_v_chrom_size = NULL;
+  __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_base_size;
+  int __pyx_v_full_reduction;
+  int __pyx_v_zoom;
+  struct __pyx_obj_2bx_3bbi_8bbi_file_ZoomLevel *__pyx_v_zoom_level = 0;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  PyObject *__pyx_t_5 = NULL;
+  PyObject *__pyx_t_6 = NULL;
+  PyObject *__pyx_t_7 = NULL;
+  PyObject *__pyx_t_8 = NULL;
+  Py_ssize_t __pyx_t_9;
+  PyObject *__pyx_t_10 = NULL;
+  int __pyx_t_11;
+  PyObject *(*__pyx_t_12)(PyObject *);
+  int __pyx_t_13;
+  __pyx_t_2bx_3bbi_5types_bits32 __pyx_t_14;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("summarize", 0);
+  /* Check if called by wrapper */
+  if (unlikely(__pyx_skip_dispatch)) ;
+  /* Check if overridden in Python */
+  else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
+    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_summarize); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 179; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_2bx_3bbi_8bbi_file_7BBIFile_5summarize)) {
+      __Pyx_XDECREF(__pyx_r);
+      __pyx_t_3 = __Pyx_PyBytes_FromString(__pyx_v_chrom); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 179; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_4 = __Pyx_PyInt_From_unsigned_int(__pyx_v_start); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 179; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __pyx_t_5 = __Pyx_PyInt_From_unsigned_int(__pyx_v_end); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 179; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_5);
+      __pyx_t_6 = __Pyx_PyInt_From_int(__pyx_v_summary_size); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 179; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_6);
+      __Pyx_INCREF(__pyx_t_1);
+      __pyx_t_7 = __pyx_t_1; __pyx_t_8 = NULL;
+      __pyx_t_9 = 0;
+      if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_7))) {
+        __pyx_t_8 = PyMethod_GET_SELF(__pyx_t_7);
+        if (likely(__pyx_t_8)) {
+          PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_7);
+          __Pyx_INCREF(__pyx_t_8);
+          __Pyx_INCREF(function);
+          __Pyx_DECREF_SET(__pyx_t_7, function);
+          __pyx_t_9 = 1;
+        }
+      }
+      __pyx_t_10 = PyTuple_New(4+__pyx_t_9); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 179; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_10);
+      if (__pyx_t_8) {
+        PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_8); __Pyx_GIVEREF(__pyx_t_8); __pyx_t_8 = NULL;
+      }
+      PyTuple_SET_ITEM(__pyx_t_10, 0+__pyx_t_9, __pyx_t_3);
+      __Pyx_GIVEREF(__pyx_t_3);
+      PyTuple_SET_ITEM(__pyx_t_10, 1+__pyx_t_9, __pyx_t_4);
+      __Pyx_GIVEREF(__pyx_t_4);
+      PyTuple_SET_ITEM(__pyx_t_10, 2+__pyx_t_9, __pyx_t_5);
+      __Pyx_GIVEREF(__pyx_t_5);
+      PyTuple_SET_ITEM(__pyx_t_10, 3+__pyx_t_9, __pyx_t_6);
+      __Pyx_GIVEREF(__pyx_t_6);
+      __pyx_t_3 = 0;
+      __pyx_t_4 = 0;
+      __pyx_t_5 = 0;
+      __pyx_t_6 = 0;
+      __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_7, __pyx_t_10, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 179; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_2);
+      __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+      __pyx_r = __pyx_t_2;
+      __pyx_t_2 = 0;
+      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+      goto __pyx_L0;
+    }
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  }
+
+  /* "bx/bbi/bbi_file.pyx":183
+ *         Gets `summary_size` data points over the regions `chrom`:`start`-`end`.
+ *         """
+ *         if start >= end:             # <<<<<<<<<<<<<<
+ *             return None
+ *         chrom_id, chrom_size = self._get_chrom_id_and_size( chrom )
+ */
+  __pyx_t_11 = ((__pyx_v_start >= __pyx_v_end) != 0);
+  if (__pyx_t_11) {
+
+    /* "bx/bbi/bbi_file.pyx":184
+ *         """
+ *         if start >= end:
+ *             return None             # <<<<<<<<<<<<<<
+ *         chrom_id, chrom_size = self._get_chrom_id_and_size( chrom )
+ *         if chrom_id is None:
+ */
+    __Pyx_XDECREF(__pyx_r);
+    __Pyx_INCREF(Py_None);
+    __pyx_r = Py_None;
+    goto __pyx_L0;
+  }
+
+  /* "bx/bbi/bbi_file.pyx":185
+ *         if start >= end:
+ *             return None
+ *         chrom_id, chrom_size = self._get_chrom_id_and_size( chrom )             # <<<<<<<<<<<<<<
+ *         if chrom_id is None:
+ *             return None
+ */
+  __pyx_t_1 = ((struct __pyx_vtabstruct_2bx_3bbi_8bbi_file_BBIFile *)__pyx_v_self->__pyx_vtab)->_get_chrom_id_and_size(__pyx_v_self, __pyx_v_chrom); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 185; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if ((likely(PyTuple_CheckExact(__pyx_t_1))) || (PyList_CheckExact(__pyx_t_1))) {
+    PyObject* sequence = __pyx_t_1;
+    #if CYTHON_COMPILING_IN_CPYTHON
+    Py_ssize_t size = Py_SIZE(sequence);
+    #else
+    Py_ssize_t size = PySequence_Size(sequence);
+    #endif
+    if (unlikely(size != 2)) {
+      if (size > 2) __Pyx_RaiseTooManyValuesError(2);
+      else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
+      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 185; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+    #if CYTHON_COMPILING_IN_CPYTHON
+    if (likely(PyTuple_CheckExact(sequence))) {
+      __pyx_t_2 = PyTuple_GET_ITEM(sequence, 0); 
+      __pyx_t_7 = PyTuple_GET_ITEM(sequence, 1); 
+    } else {
+      __pyx_t_2 = PyList_GET_ITEM(sequence, 0); 
+      __pyx_t_7 = PyList_GET_ITEM(sequence, 1); 
+    }
+    __Pyx_INCREF(__pyx_t_2);
+    __Pyx_INCREF(__pyx_t_7);
+    #else
+    __pyx_t_2 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 185; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_t_7 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 185; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_7);
+    #endif
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  } else {
+    Py_ssize_t index = -1;
+    __pyx_t_10 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 185; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_10);
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    __pyx_t_12 = Py_TYPE(__pyx_t_10)->tp_iternext;
+    index = 0; __pyx_t_2 = __pyx_t_12(__pyx_t_10); if (unlikely(!__pyx_t_2)) goto __pyx_L4_unpacking_failed;
+    __Pyx_GOTREF(__pyx_t_2);
+    index = 1; __pyx_t_7 = __pyx_t_12(__pyx_t_10); if (unlikely(!__pyx_t_7)) goto __pyx_L4_unpacking_failed;
+    __Pyx_GOTREF(__pyx_t_7);
+    if (__Pyx_IternextUnpackEndCheck(__pyx_t_12(__pyx_t_10), 2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 185; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_12 = NULL;
+    __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+    goto __pyx_L5_unpacking_done;
+    __pyx_L4_unpacking_failed:;
+    __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+    __pyx_t_12 = NULL;
+    if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 185; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_L5_unpacking_done:;
+  }
+  __pyx_v_chrom_id = __pyx_t_2;
+  __pyx_t_2 = 0;
+  __pyx_v_chrom_size = __pyx_t_7;
+  __pyx_t_7 = 0;
+
+  /* "bx/bbi/bbi_file.pyx":186
+ *             return None
+ *         chrom_id, chrom_size = self._get_chrom_id_and_size( chrom )
+ *         if chrom_id is None:             # <<<<<<<<<<<<<<
+ *             return None
+ *         # Return value will be a structured array (rather than an array
+ */
+  __pyx_t_11 = (__pyx_v_chrom_id == Py_None);
+  __pyx_t_13 = (__pyx_t_11 != 0);
+  if (__pyx_t_13) {
+
+    /* "bx/bbi/bbi_file.pyx":187
+ *         chrom_id, chrom_size = self._get_chrom_id_and_size( chrom )
+ *         if chrom_id is None:
+ *             return None             # <<<<<<<<<<<<<<
+ *         # Return value will be a structured array (rather than an array
+ *         # of summary element structures
+ */
+    __Pyx_XDECREF(__pyx_r);
+    __Pyx_INCREF(Py_None);
+    __pyx_r = Py_None;
+    goto __pyx_L0;
+  }
+
+  /* "bx/bbi/bbi_file.pyx":192
+ * 
+ *         # Find appropriate zoom level
+ *         cdef bits32 base_size = end - start             # <<<<<<<<<<<<<<
+ *         cdef int full_reduction = base_size / summary_size
+ *         cdef int zoom = full_reduction / 2
+ */
+  __pyx_v_base_size = (__pyx_v_end - __pyx_v_start);
+
+  /* "bx/bbi/bbi_file.pyx":193
+ *         # Find appropriate zoom level
+ *         cdef bits32 base_size = end - start
+ *         cdef int full_reduction = base_size / summary_size             # <<<<<<<<<<<<<<
+ *         cdef int zoom = full_reduction / 2
+ *         if zoom < 0:
+ */
+  if (unlikely(__pyx_v_summary_size == 0)) {
+    #ifdef WITH_THREAD
+    PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+    #endif
+    PyErr_SetString(PyExc_ZeroDivisionError, "integer division or modulo by zero");
+    #ifdef WITH_THREAD
+    PyGILState_Release(__pyx_gilstate_save);
+    #endif
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 193; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  __pyx_v_full_reduction = (__pyx_v_base_size / __pyx_v_summary_size);
+
+  /* "bx/bbi/bbi_file.pyx":194
+ *         cdef bits32 base_size = end - start
+ *         cdef int full_reduction = base_size / summary_size
+ *         cdef int zoom = full_reduction / 2             # <<<<<<<<<<<<<<
+ *         if zoom < 0:
+ *             zoom = 0
+ */
+  __pyx_v_zoom = __Pyx_div_long(__pyx_v_full_reduction, 2);
+
+  /* "bx/bbi/bbi_file.pyx":195
+ *         cdef int full_reduction = base_size / summary_size
+ *         cdef int zoom = full_reduction / 2
+ *         if zoom < 0:             # <<<<<<<<<<<<<<
+ *             zoom = 0
+ *         cdef ZoomLevel zoom_level = self._best_zoom_level( zoom )
+ */
+  __pyx_t_13 = ((__pyx_v_zoom < 0) != 0);
+  if (__pyx_t_13) {
+
+    /* "bx/bbi/bbi_file.pyx":196
+ *         cdef int zoom = full_reduction / 2
+ *         if zoom < 0:
+ *             zoom = 0             # <<<<<<<<<<<<<<
+ *         cdef ZoomLevel zoom_level = self._best_zoom_level( zoom )
+ *         if zoom_level is not None:
+ */
+    __pyx_v_zoom = 0;
+    goto __pyx_L7;
+  }
+  __pyx_L7:;
+
+  /* "bx/bbi/bbi_file.pyx":197
+ *         if zoom < 0:
+ *             zoom = 0
+ *         cdef ZoomLevel zoom_level = self._best_zoom_level( zoom )             # <<<<<<<<<<<<<<
+ *         if zoom_level is not None:
+ *             return zoom_level._summarize( chrom_id, start, end, summary_size )
+ */
+  __pyx_t_1 = ((struct __pyx_vtabstruct_2bx_3bbi_8bbi_file_BBIFile *)__pyx_v_self->__pyx_vtab)->_best_zoom_level(__pyx_v_self, __pyx_v_zoom); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 197; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_2bx_3bbi_8bbi_file_ZoomLevel))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 197; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_v_zoom_level = ((struct __pyx_obj_2bx_3bbi_8bbi_file_ZoomLevel *)__pyx_t_1);
+  __pyx_t_1 = 0;
+
+  /* "bx/bbi/bbi_file.pyx":198
+ *             zoom = 0
+ *         cdef ZoomLevel zoom_level = self._best_zoom_level( zoom )
+ *         if zoom_level is not None:             # <<<<<<<<<<<<<<
+ *             return zoom_level._summarize( chrom_id, start, end, summary_size )
+ *         else:
+ */
+  __pyx_t_13 = (((PyObject *)__pyx_v_zoom_level) != Py_None);
+  __pyx_t_11 = (__pyx_t_13 != 0);
+  if (__pyx_t_11) {
+
+    /* "bx/bbi/bbi_file.pyx":199
+ *         cdef ZoomLevel zoom_level = self._best_zoom_level( zoom )
+ *         if zoom_level is not None:
+ *             return zoom_level._summarize( chrom_id, start, end, summary_size )             # <<<<<<<<<<<<<<
+ *         else:
+ *             return self._summarize_from_full( chrom_id, start, end, summary_size )
+ */
+    __Pyx_XDECREF(__pyx_r);
+    __pyx_t_14 = __Pyx_PyInt_As_unsigned_int(__pyx_v_chrom_id); if (unlikely((__pyx_t_14 == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 199; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = ((struct __pyx_vtabstruct_2bx_3bbi_8bbi_file_ZoomLevel *)__pyx_v_zoom_level->__pyx_vtab)->_summarize(__pyx_v_zoom_level, __pyx_t_14, __pyx_v_start, __pyx_v_end, __pyx_v_summary_size); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 199; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __pyx_r = __pyx_t_1;
+    __pyx_t_1 = 0;
+    goto __pyx_L0;
+  }
+  /*else*/ {
+
+    /* "bx/bbi/bbi_file.pyx":201
+ *             return zoom_level._summarize( chrom_id, start, end, summary_size )
+ *         else:
+ *             return self._summarize_from_full( chrom_id, start, end, summary_size )             # <<<<<<<<<<<<<<
+ * 
+ *     cpdef summarize_from_full( self, char * chrom, bits32 start, bits32 end, int summary_size ):
+ */
+    __Pyx_XDECREF(__pyx_r);
+    __pyx_t_14 = __Pyx_PyInt_As_unsigned_int(__pyx_v_chrom_id); if (unlikely((__pyx_t_14 == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 201; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = ((struct __pyx_vtabstruct_2bx_3bbi_8bbi_file_BBIFile *)__pyx_v_self->__pyx_vtab)->_summarize_from_full(__pyx_v_self, __pyx_t_14, __pyx_v_start, __pyx_v_end, __pyx_v_summary_size); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 201; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __pyx_r = __pyx_t_1;
+    __pyx_t_1 = 0;
+    goto __pyx_L0;
+  }
+
+  /* "bx/bbi/bbi_file.pyx":179
+ *             handler.handle_block( block_data, self )
+ * 
+ *     cpdef summarize( self, char * chrom, bits32 start, bits32 end, int summary_size ):             # <<<<<<<<<<<<<<
+ *         """
+ *         Gets `summary_size` data points over the regions `chrom`:`start`-`end`.
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_XDECREF(__pyx_t_5);
+  __Pyx_XDECREF(__pyx_t_6);
+  __Pyx_XDECREF(__pyx_t_7);
+  __Pyx_XDECREF(__pyx_t_8);
+  __Pyx_XDECREF(__pyx_t_10);
+  __Pyx_AddTraceback("bx.bbi.bbi_file.BBIFile.summarize", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_chrom_id);
+  __Pyx_XDECREF(__pyx_v_chrom_size);
+  __Pyx_XDECREF((PyObject *)__pyx_v_zoom_level);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_3bbi_8bbi_file_7BBIFile_5summarize(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_2bx_3bbi_8bbi_file_7BBIFile_4summarize[] = "\n        Gets `summary_size` data points over the regions `chrom`:`start`-`end`.\n        ";
+static PyObject *__pyx_pw_2bx_3bbi_8bbi_file_7BBIFile_5summarize(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  char *__pyx_v_chrom;
+  __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_start;
+  __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_end;
+  int __pyx_v_summary_size;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("summarize (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_chrom,&__pyx_n_s_start,&__pyx_n_s_end,&__pyx_n_s_summary_size,0};
+    PyObject* values[4] = {0,0,0,0};
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_chrom)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_start)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("summarize", 1, 4, 4, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 179; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+        case  2:
+        if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_end)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("summarize", 1, 4, 4, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 179; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+        case  3:
+        if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_summary_size)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("summarize", 1, 4, 4, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 179; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "summarize") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 179; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else if (PyTuple_GET_SIZE(__pyx_args) != 4) {
+      goto __pyx_L5_argtuple_error;
+    } else {
+      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+      values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+      values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+    }
+    __pyx_v_chrom = __Pyx_PyObject_AsString(values[0]); if (unlikely((!__pyx_v_chrom) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 179; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_start = __Pyx_PyInt_As_unsigned_int(values[1]); if (unlikely((__pyx_v_start == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 179; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_end = __Pyx_PyInt_As_unsigned_int(values[2]); if (unlikely((__pyx_v_end == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 179; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_summary_size = __Pyx_PyInt_As_int(values[3]); if (unlikely((__pyx_v_summary_size == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 179; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("summarize", 1, 4, 4, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 179; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.bbi.bbi_file.BBIFile.summarize", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_3bbi_8bbi_file_7BBIFile_4summarize(((struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *)__pyx_v_self), __pyx_v_chrom, __pyx_v_start, __pyx_v_end, __pyx_v_summary_size);
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_2bx_3bbi_8bbi_file_7BBIFile_4summarize(struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *__pyx_v_self, char *__pyx_v_chrom, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_start, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_end, int __pyx_v_summary_size) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("summarize", 0);
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = __pyx_f_2bx_3bbi_8bbi_file_7BBIFile_summarize(__pyx_v_self, __pyx_v_chrom, __pyx_v_start, __pyx_v_end, __pyx_v_summary_size, 1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 179; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("bx.bbi.bbi_file.BBIFile.summarize", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bbi/bbi_file.pyx":203
+ *             return self._summarize_from_full( chrom_id, start, end, summary_size )
+ * 
+ *     cpdef summarize_from_full( self, char * chrom, bits32 start, bits32 end, int summary_size ):             # <<<<<<<<<<<<<<
+ *         """
+ *         Gets `summary_size` data points over the regions `chrom`:`start`-`end`,
+ */
+
+static PyObject *__pyx_pw_2bx_3bbi_8bbi_file_7BBIFile_7summarize_from_full(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyObject *__pyx_f_2bx_3bbi_8bbi_file_7BBIFile_summarize_from_full(struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *__pyx_v_self, char *__pyx_v_chrom, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_start, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_end, int __pyx_v_summary_size, int __pyx_skip_dispatch) {
+  PyObject *__pyx_v_chrom_id = NULL;
+  CYTHON_UNUSED PyObject *__pyx_v_chrom_size = NULL;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  PyObject *__pyx_t_5 = NULL;
+  PyObject *__pyx_t_6 = NULL;
+  PyObject *__pyx_t_7 = NULL;
+  PyObject *__pyx_t_8 = NULL;
+  Py_ssize_t __pyx_t_9;
+  PyObject *__pyx_t_10 = NULL;
+  int __pyx_t_11;
+  PyObject *(*__pyx_t_12)(PyObject *);
+  int __pyx_t_13;
+  __pyx_t_2bx_3bbi_5types_bits32 __pyx_t_14;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("summarize_from_full", 0);
+  /* Check if called by wrapper */
+  if (unlikely(__pyx_skip_dispatch)) ;
+  /* Check if overridden in Python */
+  else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
+    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_summarize_from_full); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 203; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_2bx_3bbi_8bbi_file_7BBIFile_7summarize_from_full)) {
+      __Pyx_XDECREF(__pyx_r);
+      __pyx_t_3 = __Pyx_PyBytes_FromString(__pyx_v_chrom); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 203; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_4 = __Pyx_PyInt_From_unsigned_int(__pyx_v_start); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 203; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __pyx_t_5 = __Pyx_PyInt_From_unsigned_int(__pyx_v_end); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 203; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_5);
+      __pyx_t_6 = __Pyx_PyInt_From_int(__pyx_v_summary_size); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 203; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_6);
+      __Pyx_INCREF(__pyx_t_1);
+      __pyx_t_7 = __pyx_t_1; __pyx_t_8 = NULL;
+      __pyx_t_9 = 0;
+      if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_7))) {
+        __pyx_t_8 = PyMethod_GET_SELF(__pyx_t_7);
+        if (likely(__pyx_t_8)) {
+          PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_7);
+          __Pyx_INCREF(__pyx_t_8);
+          __Pyx_INCREF(function);
+          __Pyx_DECREF_SET(__pyx_t_7, function);
+          __pyx_t_9 = 1;
+        }
+      }
+      __pyx_t_10 = PyTuple_New(4+__pyx_t_9); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 203; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_10);
+      if (__pyx_t_8) {
+        PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_8); __Pyx_GIVEREF(__pyx_t_8); __pyx_t_8 = NULL;
+      }
+      PyTuple_SET_ITEM(__pyx_t_10, 0+__pyx_t_9, __pyx_t_3);
+      __Pyx_GIVEREF(__pyx_t_3);
+      PyTuple_SET_ITEM(__pyx_t_10, 1+__pyx_t_9, __pyx_t_4);
+      __Pyx_GIVEREF(__pyx_t_4);
+      PyTuple_SET_ITEM(__pyx_t_10, 2+__pyx_t_9, __pyx_t_5);
+      __Pyx_GIVEREF(__pyx_t_5);
+      PyTuple_SET_ITEM(__pyx_t_10, 3+__pyx_t_9, __pyx_t_6);
+      __Pyx_GIVEREF(__pyx_t_6);
+      __pyx_t_3 = 0;
+      __pyx_t_4 = 0;
+      __pyx_t_5 = 0;
+      __pyx_t_6 = 0;
+      __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_7, __pyx_t_10, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 203; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_2);
+      __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+      __pyx_r = __pyx_t_2;
+      __pyx_t_2 = 0;
+      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+      goto __pyx_L0;
+    }
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  }
+
+  /* "bx/bbi/bbi_file.pyx":208
+ *         always using the raw data points
+ *         """
+ *         if start >= end:             # <<<<<<<<<<<<<<
+ *             return None
+ *         chrom_id, chrom_size = self._get_chrom_id_and_size( chrom )
+ */
+  __pyx_t_11 = ((__pyx_v_start >= __pyx_v_end) != 0);
+  if (__pyx_t_11) {
+
+    /* "bx/bbi/bbi_file.pyx":209
+ *         """
+ *         if start >= end:
+ *             return None             # <<<<<<<<<<<<<<
+ *         chrom_id, chrom_size = self._get_chrom_id_and_size( chrom )
+ *         if chrom_id is None:
+ */
+    __Pyx_XDECREF(__pyx_r);
+    __Pyx_INCREF(Py_None);
+    __pyx_r = Py_None;
+    goto __pyx_L0;
+  }
+
+  /* "bx/bbi/bbi_file.pyx":210
+ *         if start >= end:
+ *             return None
+ *         chrom_id, chrom_size = self._get_chrom_id_and_size( chrom )             # <<<<<<<<<<<<<<
+ *         if chrom_id is None:
+ *             return None
+ */
+  __pyx_t_1 = ((struct __pyx_vtabstruct_2bx_3bbi_8bbi_file_BBIFile *)__pyx_v_self->__pyx_vtab)->_get_chrom_id_and_size(__pyx_v_self, __pyx_v_chrom); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 210; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if ((likely(PyTuple_CheckExact(__pyx_t_1))) || (PyList_CheckExact(__pyx_t_1))) {
+    PyObject* sequence = __pyx_t_1;
+    #if CYTHON_COMPILING_IN_CPYTHON
+    Py_ssize_t size = Py_SIZE(sequence);
+    #else
+    Py_ssize_t size = PySequence_Size(sequence);
+    #endif
+    if (unlikely(size != 2)) {
+      if (size > 2) __Pyx_RaiseTooManyValuesError(2);
+      else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
+      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 210; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+    #if CYTHON_COMPILING_IN_CPYTHON
+    if (likely(PyTuple_CheckExact(sequence))) {
+      __pyx_t_2 = PyTuple_GET_ITEM(sequence, 0); 
+      __pyx_t_7 = PyTuple_GET_ITEM(sequence, 1); 
+    } else {
+      __pyx_t_2 = PyList_GET_ITEM(sequence, 0); 
+      __pyx_t_7 = PyList_GET_ITEM(sequence, 1); 
+    }
+    __Pyx_INCREF(__pyx_t_2);
+    __Pyx_INCREF(__pyx_t_7);
+    #else
+    __pyx_t_2 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 210; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_t_7 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 210; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_7);
+    #endif
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  } else {
+    Py_ssize_t index = -1;
+    __pyx_t_10 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 210; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_10);
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    __pyx_t_12 = Py_TYPE(__pyx_t_10)->tp_iternext;
+    index = 0; __pyx_t_2 = __pyx_t_12(__pyx_t_10); if (unlikely(!__pyx_t_2)) goto __pyx_L4_unpacking_failed;
+    __Pyx_GOTREF(__pyx_t_2);
+    index = 1; __pyx_t_7 = __pyx_t_12(__pyx_t_10); if (unlikely(!__pyx_t_7)) goto __pyx_L4_unpacking_failed;
+    __Pyx_GOTREF(__pyx_t_7);
+    if (__Pyx_IternextUnpackEndCheck(__pyx_t_12(__pyx_t_10), 2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 210; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_12 = NULL;
+    __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+    goto __pyx_L5_unpacking_done;
+    __pyx_L4_unpacking_failed:;
+    __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+    __pyx_t_12 = NULL;
+    if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 210; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_L5_unpacking_done:;
+  }
+  __pyx_v_chrom_id = __pyx_t_2;
+  __pyx_t_2 = 0;
+  __pyx_v_chrom_size = __pyx_t_7;
+  __pyx_t_7 = 0;
+
+  /* "bx/bbi/bbi_file.pyx":211
+ *             return None
+ *         chrom_id, chrom_size = self._get_chrom_id_and_size( chrom )
+ *         if chrom_id is None:             # <<<<<<<<<<<<<<
+ *             return None
+ *         # Return value will be a structured array (rather than an array
+ */
+  __pyx_t_11 = (__pyx_v_chrom_id == Py_None);
+  __pyx_t_13 = (__pyx_t_11 != 0);
+  if (__pyx_t_13) {
+
+    /* "bx/bbi/bbi_file.pyx":212
+ *         chrom_id, chrom_size = self._get_chrom_id_and_size( chrom )
+ *         if chrom_id is None:
+ *             return None             # <<<<<<<<<<<<<<
+ *         # Return value will be a structured array (rather than an array
+ *         # of summary element structures
+ */
+    __Pyx_XDECREF(__pyx_r);
+    __Pyx_INCREF(Py_None);
+    __pyx_r = Py_None;
+    goto __pyx_L0;
+  }
+
+  /* "bx/bbi/bbi_file.pyx":215
+ *         # Return value will be a structured array (rather than an array
+ *         # of summary element structures
+ *         return self._summarize_from_full( chrom_id, start, end, summary_size )             # <<<<<<<<<<<<<<
+ * 
+ *     cpdef query( self, char * chrom, bits32 start, bits32 end, int summary_size ):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_14 = __Pyx_PyInt_As_unsigned_int(__pyx_v_chrom_id); if (unlikely((__pyx_t_14 == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 215; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = ((struct __pyx_vtabstruct_2bx_3bbi_8bbi_file_BBIFile *)__pyx_v_self->__pyx_vtab)->_summarize_from_full(__pyx_v_self, __pyx_t_14, __pyx_v_start, __pyx_v_end, __pyx_v_summary_size); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 215; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  /* "bx/bbi/bbi_file.pyx":203
+ *             return self._summarize_from_full( chrom_id, start, end, summary_size )
+ * 
+ *     cpdef summarize_from_full( self, char * chrom, bits32 start, bits32 end, int summary_size ):             # <<<<<<<<<<<<<<
+ *         """
+ *         Gets `summary_size` data points over the regions `chrom`:`start`-`end`,
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_XDECREF(__pyx_t_5);
+  __Pyx_XDECREF(__pyx_t_6);
+  __Pyx_XDECREF(__pyx_t_7);
+  __Pyx_XDECREF(__pyx_t_8);
+  __Pyx_XDECREF(__pyx_t_10);
+  __Pyx_AddTraceback("bx.bbi.bbi_file.BBIFile.summarize_from_full", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_chrom_id);
+  __Pyx_XDECREF(__pyx_v_chrom_size);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_3bbi_8bbi_file_7BBIFile_7summarize_from_full(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_2bx_3bbi_8bbi_file_7BBIFile_6summarize_from_full[] = "\n        Gets `summary_size` data points over the regions `chrom`:`start`-`end`, \n        always using the raw data points\n        ";
+static PyObject *__pyx_pw_2bx_3bbi_8bbi_file_7BBIFile_7summarize_from_full(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  char *__pyx_v_chrom;
+  __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_start;
+  __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_end;
+  int __pyx_v_summary_size;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("summarize_from_full (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_chrom,&__pyx_n_s_start,&__pyx_n_s_end,&__pyx_n_s_summary_size,0};
+    PyObject* values[4] = {0,0,0,0};
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_chrom)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_start)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("summarize_from_full", 1, 4, 4, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 203; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+        case  2:
+        if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_end)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("summarize_from_full", 1, 4, 4, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 203; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+        case  3:
+        if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_summary_size)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("summarize_from_full", 1, 4, 4, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 203; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "summarize_from_full") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 203; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else if (PyTuple_GET_SIZE(__pyx_args) != 4) {
+      goto __pyx_L5_argtuple_error;
+    } else {
+      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+      values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+      values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+    }
+    __pyx_v_chrom = __Pyx_PyObject_AsString(values[0]); if (unlikely((!__pyx_v_chrom) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 203; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_start = __Pyx_PyInt_As_unsigned_int(values[1]); if (unlikely((__pyx_v_start == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 203; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_end = __Pyx_PyInt_As_unsigned_int(values[2]); if (unlikely((__pyx_v_end == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 203; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_summary_size = __Pyx_PyInt_As_int(values[3]); if (unlikely((__pyx_v_summary_size == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 203; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("summarize_from_full", 1, 4, 4, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 203; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.bbi.bbi_file.BBIFile.summarize_from_full", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_3bbi_8bbi_file_7BBIFile_6summarize_from_full(((struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *)__pyx_v_self), __pyx_v_chrom, __pyx_v_start, __pyx_v_end, __pyx_v_summary_size);
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_2bx_3bbi_8bbi_file_7BBIFile_6summarize_from_full(struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *__pyx_v_self, char *__pyx_v_chrom, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_start, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_end, int __pyx_v_summary_size) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("summarize_from_full", 0);
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = __pyx_f_2bx_3bbi_8bbi_file_7BBIFile_summarize_from_full(__pyx_v_self, __pyx_v_chrom, __pyx_v_start, __pyx_v_end, __pyx_v_summary_size, 1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 203; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("bx.bbi.bbi_file.BBIFile.summarize_from_full", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bbi/bbi_file.pyx":217
+ *         return self._summarize_from_full( chrom_id, start, end, summary_size )
+ * 
+ *     cpdef query( self, char * chrom, bits32 start, bits32 end, int summary_size ):             # <<<<<<<<<<<<<<
+ *         """
+ *         Provides a different view of summary for region, a list of dictionaries
+ */
+
+static PyObject *__pyx_pw_2bx_3bbi_8bbi_file_7BBIFile_9query(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyObject *__pyx_f_2bx_3bbi_8bbi_file_7BBIFile_query(struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *__pyx_v_self, char *__pyx_v_chrom, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_start, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_end, int __pyx_v_summary_size, int __pyx_skip_dispatch) {
+  PyObject *__pyx_v_results = NULL;
+  PyObject *__pyx_v_rval = NULL;
+  int __pyx_v_i;
+  PyObject *__pyx_v_sum_data = NULL;
+  PyObject *__pyx_v_valid_count = NULL;
+  PyObject *__pyx_v_mean = NULL;
+  PyObject *__pyx_v_coverage = NULL;
+  PyObject *__pyx_v_variance = NULL;
+  PyObject *__pyx_v_std_dev = NULL;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  PyObject *__pyx_t_5 = NULL;
+  PyObject *__pyx_t_6 = NULL;
+  PyObject *__pyx_t_7 = NULL;
+  PyObject *__pyx_t_8 = NULL;
+  Py_ssize_t __pyx_t_9;
+  PyObject *__pyx_t_10 = NULL;
+  int __pyx_t_11;
+  int __pyx_t_12;
+  int __pyx_t_13;
+  int __pyx_t_14;
+  __pyx_t_2bx_3bbi_5types_bits32 __pyx_t_15;
+  long __pyx_t_16;
+  int __pyx_t_17;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("query", 0);
+  /* Check if called by wrapper */
+  if (unlikely(__pyx_skip_dispatch)) ;
+  /* Check if overridden in Python */
+  else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
+    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_query); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 217; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_2bx_3bbi_8bbi_file_7BBIFile_9query)) {
+      __Pyx_XDECREF(__pyx_r);
+      __pyx_t_3 = __Pyx_PyBytes_FromString(__pyx_v_chrom); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 217; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_4 = __Pyx_PyInt_From_unsigned_int(__pyx_v_start); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 217; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __pyx_t_5 = __Pyx_PyInt_From_unsigned_int(__pyx_v_end); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 217; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_5);
+      __pyx_t_6 = __Pyx_PyInt_From_int(__pyx_v_summary_size); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 217; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_6);
+      __Pyx_INCREF(__pyx_t_1);
+      __pyx_t_7 = __pyx_t_1; __pyx_t_8 = NULL;
+      __pyx_t_9 = 0;
+      if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_7))) {
+        __pyx_t_8 = PyMethod_GET_SELF(__pyx_t_7);
+        if (likely(__pyx_t_8)) {
+          PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_7);
+          __Pyx_INCREF(__pyx_t_8);
+          __Pyx_INCREF(function);
+          __Pyx_DECREF_SET(__pyx_t_7, function);
+          __pyx_t_9 = 1;
+        }
+      }
+      __pyx_t_10 = PyTuple_New(4+__pyx_t_9); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 217; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_10);
+      if (__pyx_t_8) {
+        PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_8); __Pyx_GIVEREF(__pyx_t_8); __pyx_t_8 = NULL;
+      }
+      PyTuple_SET_ITEM(__pyx_t_10, 0+__pyx_t_9, __pyx_t_3);
+      __Pyx_GIVEREF(__pyx_t_3);
+      PyTuple_SET_ITEM(__pyx_t_10, 1+__pyx_t_9, __pyx_t_4);
+      __Pyx_GIVEREF(__pyx_t_4);
+      PyTuple_SET_ITEM(__pyx_t_10, 2+__pyx_t_9, __pyx_t_5);
+      __Pyx_GIVEREF(__pyx_t_5);
+      PyTuple_SET_ITEM(__pyx_t_10, 3+__pyx_t_9, __pyx_t_6);
+      __Pyx_GIVEREF(__pyx_t_6);
+      __pyx_t_3 = 0;
+      __pyx_t_4 = 0;
+      __pyx_t_5 = 0;
+      __pyx_t_6 = 0;
+      __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_7, __pyx_t_10, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 217; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_2);
+      __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+      __pyx_r = __pyx_t_2;
+      __pyx_t_2 = 0;
+      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+      goto __pyx_L0;
+    }
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  }
+
+  /* "bx/bbi/bbi_file.pyx":223
+ *         """
+ * 
+ *         if end > 2147483647 or start < 0:             # <<<<<<<<<<<<<<
+ *             raise ValueError
+ *         results = self.summarize(chrom, start, end, summary_size)
+ */
+  __pyx_t_12 = ((__pyx_v_end > 2147483647) != 0);
+  if (!__pyx_t_12) {
+  } else {
+    __pyx_t_11 = __pyx_t_12;
+    goto __pyx_L4_bool_binop_done;
+  }
+  __pyx_t_12 = ((__pyx_v_start < 0) != 0);
+  __pyx_t_11 = __pyx_t_12;
+  __pyx_L4_bool_binop_done:;
+  if (__pyx_t_11) {
+
+    /* "bx/bbi/bbi_file.pyx":224
+ * 
+ *         if end > 2147483647 or start < 0:
+ *             raise ValueError             # <<<<<<<<<<<<<<
+ *         results = self.summarize(chrom, start, end, summary_size)
+ *         if not results:
+ */
+    __Pyx_Raise(__pyx_builtin_ValueError, 0, 0, 0);
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 224; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+
+  /* "bx/bbi/bbi_file.pyx":225
+ *         if end > 2147483647 or start < 0:
+ *             raise ValueError
+ *         results = self.summarize(chrom, start, end, summary_size)             # <<<<<<<<<<<<<<
+ *         if not results:
+ *             return None
+ */
+  __pyx_t_1 = ((struct __pyx_vtabstruct_2bx_3bbi_8bbi_file_BBIFile *)__pyx_v_self->__pyx_vtab)->summarize(__pyx_v_self, __pyx_v_chrom, __pyx_v_start, __pyx_v_end, __pyx_v_summary_size, 0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 225; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_v_results = __pyx_t_1;
+  __pyx_t_1 = 0;
+
+  /* "bx/bbi/bbi_file.pyx":226
+ *             raise ValueError
+ *         results = self.summarize(chrom, start, end, summary_size)
+ *         if not results:             # <<<<<<<<<<<<<<
+ *             return None
+ * 
+ */
+  __pyx_t_11 = __Pyx_PyObject_IsTrue(__pyx_v_results); if (unlikely(__pyx_t_11 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 226; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_12 = ((!__pyx_t_11) != 0);
+  if (__pyx_t_12) {
+
+    /* "bx/bbi/bbi_file.pyx":227
+ *         results = self.summarize(chrom, start, end, summary_size)
+ *         if not results:
+ *             return None             # <<<<<<<<<<<<<<
+ * 
+ *         rval = []
+ */
+    __Pyx_XDECREF(__pyx_r);
+    __Pyx_INCREF(Py_None);
+    __pyx_r = Py_None;
+    goto __pyx_L0;
+  }
+
+  /* "bx/bbi/bbi_file.pyx":229
+ *             return None
+ * 
+ *         rval = []             # <<<<<<<<<<<<<<
+ *         for i in range(summary_size):
+ *             sum_data = results.sum_data[i]
+ */
+  __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 229; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_v_rval = ((PyObject*)__pyx_t_1);
+  __pyx_t_1 = 0;
+
+  /* "bx/bbi/bbi_file.pyx":230
+ * 
+ *         rval = []
+ *         for i in range(summary_size):             # <<<<<<<<<<<<<<
+ *             sum_data = results.sum_data[i]
+ *             valid_count = results.valid_count[i]
+ */
+  __pyx_t_13 = __pyx_v_summary_size;
+  for (__pyx_t_14 = 0; __pyx_t_14 < __pyx_t_13; __pyx_t_14+=1) {
+    __pyx_v_i = __pyx_t_14;
+
+    /* "bx/bbi/bbi_file.pyx":231
+ *         rval = []
+ *         for i in range(summary_size):
+ *             sum_data = results.sum_data[i]             # <<<<<<<<<<<<<<
+ *             valid_count = results.valid_count[i]
+ *             mean = sum_data / valid_count
+ */
+    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_results, __pyx_n_s_sum_data); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 231; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_1, __pyx_v_i, int, 1, __Pyx_PyInt_From_int, 0, 1, 1); if (unlikely(__pyx_t_2 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 231; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+    __Pyx_GOTREF(__pyx_t_2);
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    __Pyx_XDECREF_SET(__pyx_v_sum_data, __pyx_t_2);
+    __pyx_t_2 = 0;
+
+    /* "bx/bbi/bbi_file.pyx":232
+ *         for i in range(summary_size):
+ *             sum_data = results.sum_data[i]
+ *             valid_count = results.valid_count[i]             # <<<<<<<<<<<<<<
+ *             mean = sum_data / valid_count
+ *             coverage = <double> summary_size / (end - start) * valid_count
+ */
+    __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_results, __pyx_n_s_valid_count); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 232; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_t_1 = __Pyx_GetItemInt(__pyx_t_2, __pyx_v_i, int, 1, __Pyx_PyInt_From_int, 0, 1, 1); if (unlikely(__pyx_t_1 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 232; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+    __Pyx_GOTREF(__pyx_t_1);
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    __Pyx_XDECREF_SET(__pyx_v_valid_count, __pyx_t_1);
+    __pyx_t_1 = 0;
+
+    /* "bx/bbi/bbi_file.pyx":233
+ *             sum_data = results.sum_data[i]
+ *             valid_count = results.valid_count[i]
+ *             mean = sum_data / valid_count             # <<<<<<<<<<<<<<
+ *             coverage = <double> summary_size / (end - start) * valid_count
+ * 
+ */
+    __pyx_t_1 = __Pyx_PyNumber_Divide(__pyx_v_sum_data, __pyx_v_valid_count); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 233; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __Pyx_XDECREF_SET(__pyx_v_mean, __pyx_t_1);
+    __pyx_t_1 = 0;
+
+    /* "bx/bbi/bbi_file.pyx":234
+ *             valid_count = results.valid_count[i]
+ *             mean = sum_data / valid_count
+ *             coverage = <double> summary_size / (end - start) * valid_count             # <<<<<<<<<<<<<<
+ * 
+ *             # print results.sum_squares[i], sum_data, valid_count
+ */
+    __pyx_t_15 = (__pyx_v_end - __pyx_v_start);
+    if (unlikely(__pyx_t_15 == 0)) {
+      #ifdef WITH_THREAD
+      PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+      #endif
+      PyErr_SetString(PyExc_ZeroDivisionError, "float division");
+      #ifdef WITH_THREAD
+      PyGILState_Release(__pyx_gilstate_save);
+      #endif
+      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 234; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+    __pyx_t_1 = PyFloat_FromDouble((((double)__pyx_v_summary_size) / __pyx_t_15)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 234; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __pyx_t_2 = PyNumber_Multiply(__pyx_t_1, __pyx_v_valid_count); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 234; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    __Pyx_XDECREF_SET(__pyx_v_coverage, __pyx_t_2);
+    __pyx_t_2 = 0;
+
+    /* "bx/bbi/bbi_file.pyx":237
+ * 
+ *             # print results.sum_squares[i], sum_data, valid_count
+ *             variance = results.sum_squares[i] - sum_data * sum_data / valid_count             # <<<<<<<<<<<<<<
+ *             if valid_count > 1:
+ *                 variance /= valid_count - 1
+ */
+    __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_results, __pyx_n_s_sum_squares); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 237; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_t_1 = __Pyx_GetItemInt(__pyx_t_2, __pyx_v_i, int, 1, __Pyx_PyInt_From_int, 0, 1, 1); if (unlikely(__pyx_t_1 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 237; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+    __Pyx_GOTREF(__pyx_t_1);
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    __pyx_t_2 = PyNumber_Multiply(__pyx_v_sum_data, __pyx_v_sum_data); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 237; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_t_7 = __Pyx_PyNumber_Divide(__pyx_t_2, __pyx_v_valid_count); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 237; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_7);
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    __pyx_t_2 = PyNumber_Subtract(__pyx_t_1, __pyx_t_7); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 237; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+    __Pyx_XDECREF_SET(__pyx_v_variance, __pyx_t_2);
+    __pyx_t_2 = 0;
+
+    /* "bx/bbi/bbi_file.pyx":238
+ *             # print results.sum_squares[i], sum_data, valid_count
+ *             variance = results.sum_squares[i] - sum_data * sum_data / valid_count
+ *             if valid_count > 1:             # <<<<<<<<<<<<<<
+ *                 variance /= valid_count - 1
+ *             std_dev = math.sqrt(max(variance, 0))
+ */
+    __pyx_t_2 = PyObject_RichCompare(__pyx_v_valid_count, __pyx_int_1, Py_GT); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 238; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_12 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_12 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 238; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    if (__pyx_t_12) {
+
+      /* "bx/bbi/bbi_file.pyx":239
+ *             variance = results.sum_squares[i] - sum_data * sum_data / valid_count
+ *             if valid_count > 1:
+ *                 variance /= valid_count - 1             # <<<<<<<<<<<<<<
+ *             std_dev = math.sqrt(max(variance, 0))
+ * 
+ */
+      __pyx_t_2 = PyNumber_Subtract(__pyx_v_valid_count, __pyx_int_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 239; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_2);
+      __pyx_t_7 = __Pyx_PyNumber_InPlaceDivide(__pyx_v_variance, __pyx_t_2); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 239; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_7);
+      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+      __Pyx_DECREF_SET(__pyx_v_variance, __pyx_t_7);
+      __pyx_t_7 = 0;
+      goto __pyx_L9;
+    }
+    __pyx_L9:;
+
+    /* "bx/bbi/bbi_file.pyx":240
+ *             if valid_count > 1:
+ *                 variance /= valid_count - 1
+ *             std_dev = math.sqrt(max(variance, 0))             # <<<<<<<<<<<<<<
+ * 
+ *             rval.append( { "mean": mean, "max": results.max_val[i], "min": results.min_val[i], \
+ */
+    __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_math); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 240; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_sqrt); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 240; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    __pyx_t_16 = 0;
+    __Pyx_INCREF(__pyx_v_variance);
+    __pyx_t_2 = __pyx_v_variance;
+    __pyx_t_6 = __Pyx_PyInt_From_long(__pyx_t_16); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 240; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_6);
+    __pyx_t_5 = PyObject_RichCompare(__pyx_t_6, __pyx_t_2, Py_GT); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 240; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+    __pyx_t_12 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely(__pyx_t_12 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 240; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+    if (__pyx_t_12) {
+      __pyx_t_5 = __Pyx_PyInt_From_long(__pyx_t_16); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 240; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_5);
+      __pyx_t_10 = __pyx_t_5;
+      __pyx_t_5 = 0;
+    } else {
+      __Pyx_INCREF(__pyx_t_2);
+      __pyx_t_10 = __pyx_t_2;
+    }
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    __pyx_t_2 = NULL;
+    if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_1))) {
+      __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_1);
+      if (likely(__pyx_t_2)) {
+        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_1);
+        __Pyx_INCREF(__pyx_t_2);
+        __Pyx_INCREF(function);
+        __Pyx_DECREF_SET(__pyx_t_1, function);
+      }
+    }
+    if (!__pyx_t_2) {
+      __pyx_t_7 = __Pyx_PyObject_CallOneArg(__pyx_t_1, __pyx_t_10); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 240; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+      __Pyx_GOTREF(__pyx_t_7);
+    } else {
+      __pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 240; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_5);
+      PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_2); __Pyx_GIVEREF(__pyx_t_2); __pyx_t_2 = NULL;
+      __Pyx_INCREF(__pyx_t_10);
+      PyTuple_SET_ITEM(__pyx_t_5, 0+1, __pyx_t_10);
+      __Pyx_GIVEREF(__pyx_t_10);
+      __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+      __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_5, NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 240; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_7);
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+    }
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    __Pyx_XDECREF_SET(__pyx_v_std_dev, __pyx_t_7);
+    __pyx_t_7 = 0;
+
+    /* "bx/bbi/bbi_file.pyx":242
+ *             std_dev = math.sqrt(max(variance, 0))
+ * 
+ *             rval.append( { "mean": mean, "max": results.max_val[i], "min": results.min_val[i], \             # <<<<<<<<<<<<<<
+ *                         "coverage": coverage, "std_dev": std_dev } )
+ * 
+ */
+    __pyx_t_7 = PyDict_New(); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 242; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_7);
+    if (PyDict_SetItem(__pyx_t_7, __pyx_n_s_mean, __pyx_v_mean) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 242; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_results, __pyx_n_s_max_val); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 242; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __pyx_t_5 = __Pyx_GetItemInt(__pyx_t_1, __pyx_v_i, int, 1, __Pyx_PyInt_From_int, 0, 1, 1); if (unlikely(__pyx_t_5 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 242; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+    __Pyx_GOTREF(__pyx_t_5);
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    if (PyDict_SetItem(__pyx_t_7, __pyx_n_s_max, __pyx_t_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 242; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+    __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_results, __pyx_n_s_min_val); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 242; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_5);
+    __pyx_t_1 = __Pyx_GetItemInt(__pyx_t_5, __pyx_v_i, int, 1, __Pyx_PyInt_From_int, 0, 1, 1); if (unlikely(__pyx_t_1 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 242; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+    __Pyx_GOTREF(__pyx_t_1);
+    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+    if (PyDict_SetItem(__pyx_t_7, __pyx_n_s_min, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 242; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+    /* "bx/bbi/bbi_file.pyx":243
+ * 
+ *             rval.append( { "mean": mean, "max": results.max_val[i], "min": results.min_val[i], \
+ *                         "coverage": coverage, "std_dev": std_dev } )             # <<<<<<<<<<<<<<
+ * 
+ *         return rval
+ */
+    if (PyDict_SetItem(__pyx_t_7, __pyx_n_s_coverage, __pyx_v_coverage) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 242; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (PyDict_SetItem(__pyx_t_7, __pyx_n_s_std_dev, __pyx_v_std_dev) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 242; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+    /* "bx/bbi/bbi_file.pyx":242
+ *             std_dev = math.sqrt(max(variance, 0))
+ * 
+ *             rval.append( { "mean": mean, "max": results.max_val[i], "min": results.min_val[i], \             # <<<<<<<<<<<<<<
+ *                         "coverage": coverage, "std_dev": std_dev } )
+ * 
+ */
+    __pyx_t_17 = __Pyx_PyList_Append(__pyx_v_rval, __pyx_t_7); if (unlikely(__pyx_t_17 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 242; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+  }
+
+  /* "bx/bbi/bbi_file.pyx":245
+ *                         "coverage": coverage, "std_dev": std_dev } )
+ * 
+ *         return rval             # <<<<<<<<<<<<<<
+ * 
+ *     cdef _get_chrom_id_and_size( self, char * chrom ):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __Pyx_INCREF(__pyx_v_rval);
+  __pyx_r = __pyx_v_rval;
+  goto __pyx_L0;
+
+  /* "bx/bbi/bbi_file.pyx":217
+ *         return self._summarize_from_full( chrom_id, start, end, summary_size )
+ * 
+ *     cpdef query( self, char * chrom, bits32 start, bits32 end, int summary_size ):             # <<<<<<<<<<<<<<
+ *         """
+ *         Provides a different view of summary for region, a list of dictionaries
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_XDECREF(__pyx_t_5);
+  __Pyx_XDECREF(__pyx_t_6);
+  __Pyx_XDECREF(__pyx_t_7);
+  __Pyx_XDECREF(__pyx_t_8);
+  __Pyx_XDECREF(__pyx_t_10);
+  __Pyx_AddTraceback("bx.bbi.bbi_file.BBIFile.query", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_results);
+  __Pyx_XDECREF(__pyx_v_rval);
+  __Pyx_XDECREF(__pyx_v_sum_data);
+  __Pyx_XDECREF(__pyx_v_valid_count);
+  __Pyx_XDECREF(__pyx_v_mean);
+  __Pyx_XDECREF(__pyx_v_coverage);
+  __Pyx_XDECREF(__pyx_v_variance);
+  __Pyx_XDECREF(__pyx_v_std_dev);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_3bbi_8bbi_file_7BBIFile_9query(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_2bx_3bbi_8bbi_file_7BBIFile_8query[] = "\n        Provides a different view of summary for region, a list of dictionaries\n        with keys: mean, max, min, coverage, std_dev\n        ";
+static PyObject *__pyx_pw_2bx_3bbi_8bbi_file_7BBIFile_9query(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  char *__pyx_v_chrom;
+  __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_start;
+  __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_end;
+  int __pyx_v_summary_size;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("query (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_chrom,&__pyx_n_s_start,&__pyx_n_s_end,&__pyx_n_s_summary_size,0};
+    PyObject* values[4] = {0,0,0,0};
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_chrom)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_start)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("query", 1, 4, 4, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 217; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+        case  2:
+        if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_end)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("query", 1, 4, 4, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 217; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+        case  3:
+        if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_summary_size)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("query", 1, 4, 4, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 217; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "query") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 217; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else if (PyTuple_GET_SIZE(__pyx_args) != 4) {
+      goto __pyx_L5_argtuple_error;
+    } else {
+      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+      values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+      values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+    }
+    __pyx_v_chrom = __Pyx_PyObject_AsString(values[0]); if (unlikely((!__pyx_v_chrom) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 217; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_start = __Pyx_PyInt_As_unsigned_int(values[1]); if (unlikely((__pyx_v_start == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 217; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_end = __Pyx_PyInt_As_unsigned_int(values[2]); if (unlikely((__pyx_v_end == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 217; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_summary_size = __Pyx_PyInt_As_int(values[3]); if (unlikely((__pyx_v_summary_size == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 217; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("query", 1, 4, 4, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 217; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.bbi.bbi_file.BBIFile.query", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_3bbi_8bbi_file_7BBIFile_8query(((struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *)__pyx_v_self), __pyx_v_chrom, __pyx_v_start, __pyx_v_end, __pyx_v_summary_size);
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_2bx_3bbi_8bbi_file_7BBIFile_8query(struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *__pyx_v_self, char *__pyx_v_chrom, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_start, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_end, int __pyx_v_summary_size) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("query", 0);
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = __pyx_f_2bx_3bbi_8bbi_file_7BBIFile_query(__pyx_v_self, __pyx_v_chrom, __pyx_v_start, __pyx_v_end, __pyx_v_summary_size, 1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 217; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("bx.bbi.bbi_file.BBIFile.query", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bbi/bbi_file.pyx":247
+ *         return rval
+ * 
+ *     cdef _get_chrom_id_and_size( self, char * chrom ):             # <<<<<<<<<<<<<<
+ *         """
+ *         Lookup id and size from the chromosome named `chrom`
+ */
+
+static PyObject *__pyx_f_2bx_3bbi_8bbi_file_7BBIFile__get_chrom_id_and_size(struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *__pyx_v_self, char *__pyx_v_chrom) {
+  PyObject *__pyx_v_bytes = NULL;
+  PyObject *__pyx_v_chrom_id = NULL;
+  PyObject *__pyx_v_chrom_size = NULL;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  PyObject *__pyx_t_5 = NULL;
+  int __pyx_t_6;
+  int __pyx_t_7;
+  Py_ssize_t __pyx_t_8;
+  PyObject *(*__pyx_t_9)(PyObject *);
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("_get_chrom_id_and_size", 0);
+
+  /* "bx/bbi/bbi_file.pyx":251
+ *         Lookup id and size from the chromosome named `chrom`
+ *         """
+ *         bytes = self.chrom_bpt.find( chrom )             # <<<<<<<<<<<<<<
+ *         if bytes is not None:
+ *             # The value is two 32 bit uints, use the BPT's reader for checking byteswapping
+ */
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self->chrom_bpt), __pyx_n_s_find); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 251; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = __Pyx_PyBytes_FromString(__pyx_v_chrom); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 251; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_4 = NULL;
+  if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_2))) {
+    __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_2);
+    if (likely(__pyx_t_4)) {
+      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+      __Pyx_INCREF(__pyx_t_4);
+      __Pyx_INCREF(function);
+      __Pyx_DECREF_SET(__pyx_t_2, function);
+    }
+  }
+  if (!__pyx_t_4) {
+    __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 251; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __Pyx_GOTREF(__pyx_t_1);
+  } else {
+    __pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 251; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_5);
+    PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_4); __Pyx_GIVEREF(__pyx_t_4); __pyx_t_4 = NULL;
+    PyTuple_SET_ITEM(__pyx_t_5, 0+1, __pyx_t_3);
+    __Pyx_GIVEREF(__pyx_t_3);
+    __pyx_t_3 = 0;
+    __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_5, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 251; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+  }
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_v_bytes = __pyx_t_1;
+  __pyx_t_1 = 0;
+
+  /* "bx/bbi/bbi_file.pyx":252
+ *         """
+ *         bytes = self.chrom_bpt.find( chrom )
+ *         if bytes is not None:             # <<<<<<<<<<<<<<
+ *             # The value is two 32 bit uints, use the BPT's reader for checking byteswapping
+ *             assert len( bytes ) == 8
+ */
+  __pyx_t_6 = (__pyx_v_bytes != Py_None);
+  __pyx_t_7 = (__pyx_t_6 != 0);
+  if (__pyx_t_7) {
+
+    /* "bx/bbi/bbi_file.pyx":254
+ *         if bytes is not None:
+ *             # The value is two 32 bit uints, use the BPT's reader for checking byteswapping
+ *             assert len( bytes ) == 8             # <<<<<<<<<<<<<<
+ *             chrom_id, chrom_size = self.chrom_bpt.reader.unpack( "II", bytes )
+ *             return chrom_id, chrom_size
+ */
+    #ifndef CYTHON_WITHOUT_ASSERTIONS
+    if (unlikely(!Py_OptimizeFlag)) {
+      __pyx_t_8 = PyObject_Length(__pyx_v_bytes); if (unlikely(__pyx_t_8 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 254; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      if (unlikely(!((__pyx_t_8 == 8) != 0))) {
+        PyErr_SetNone(PyExc_AssertionError);
+        {__pyx_filename = __pyx_f[0]; __pyx_lineno = 254; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      }
+    }
+    #endif
+
+    /* "bx/bbi/bbi_file.pyx":255
+ *             # The value is two 32 bit uints, use the BPT's reader for checking byteswapping
+ *             assert len( bytes ) == 8
+ *             chrom_id, chrom_size = self.chrom_bpt.reader.unpack( "II", bytes )             # <<<<<<<<<<<<<<
+ *             return chrom_id, chrom_size
+ *         else:
+ */
+    __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self->chrom_bpt->reader, __pyx_n_s_unpack); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 255; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_t_5 = NULL;
+    __pyx_t_8 = 0;
+    if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_2))) {
+      __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_2);
+      if (likely(__pyx_t_5)) {
+        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+        __Pyx_INCREF(__pyx_t_5);
+        __Pyx_INCREF(function);
+        __Pyx_DECREF_SET(__pyx_t_2, function);
+        __pyx_t_8 = 1;
+      }
+    }
+    __pyx_t_3 = PyTuple_New(2+__pyx_t_8); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 255; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    if (__pyx_t_5) {
+      PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_5); __Pyx_GIVEREF(__pyx_t_5); __pyx_t_5 = NULL;
+    }
+    __Pyx_INCREF(__pyx_n_s_II);
+    PyTuple_SET_ITEM(__pyx_t_3, 0+__pyx_t_8, __pyx_n_s_II);
+    __Pyx_GIVEREF(__pyx_n_s_II);
+    __Pyx_INCREF(__pyx_v_bytes);
+    PyTuple_SET_ITEM(__pyx_t_3, 1+__pyx_t_8, __pyx_v_bytes);
+    __Pyx_GIVEREF(__pyx_v_bytes);
+    __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_3, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 255; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    if ((likely(PyTuple_CheckExact(__pyx_t_1))) || (PyList_CheckExact(__pyx_t_1))) {
+      PyObject* sequence = __pyx_t_1;
+      #if CYTHON_COMPILING_IN_CPYTHON
+      Py_ssize_t size = Py_SIZE(sequence);
+      #else
+      Py_ssize_t size = PySequence_Size(sequence);
+      #endif
+      if (unlikely(size != 2)) {
+        if (size > 2) __Pyx_RaiseTooManyValuesError(2);
+        else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
+        {__pyx_filename = __pyx_f[0]; __pyx_lineno = 255; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      }
+      #if CYTHON_COMPILING_IN_CPYTHON
+      if (likely(PyTuple_CheckExact(sequence))) {
+        __pyx_t_2 = PyTuple_GET_ITEM(sequence, 0); 
+        __pyx_t_3 = PyTuple_GET_ITEM(sequence, 1); 
+      } else {
+        __pyx_t_2 = PyList_GET_ITEM(sequence, 0); 
+        __pyx_t_3 = PyList_GET_ITEM(sequence, 1); 
+      }
+      __Pyx_INCREF(__pyx_t_2);
+      __Pyx_INCREF(__pyx_t_3);
+      #else
+      __pyx_t_2 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 255; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_2);
+      __pyx_t_3 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 255; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      #endif
+      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    } else {
+      Py_ssize_t index = -1;
+      __pyx_t_5 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 255; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_5);
+      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+      __pyx_t_9 = Py_TYPE(__pyx_t_5)->tp_iternext;
+      index = 0; __pyx_t_2 = __pyx_t_9(__pyx_t_5); if (unlikely(!__pyx_t_2)) goto __pyx_L4_unpacking_failed;
+      __Pyx_GOTREF(__pyx_t_2);
+      index = 1; __pyx_t_3 = __pyx_t_9(__pyx_t_5); if (unlikely(!__pyx_t_3)) goto __pyx_L4_unpacking_failed;
+      __Pyx_GOTREF(__pyx_t_3);
+      if (__Pyx_IternextUnpackEndCheck(__pyx_t_9(__pyx_t_5), 2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 255; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_9 = NULL;
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      goto __pyx_L5_unpacking_done;
+      __pyx_L4_unpacking_failed:;
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      __pyx_t_9 = NULL;
+      if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
+      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 255; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_L5_unpacking_done:;
+    }
+    __pyx_v_chrom_id = __pyx_t_2;
+    __pyx_t_2 = 0;
+    __pyx_v_chrom_size = __pyx_t_3;
+    __pyx_t_3 = 0;
+
+    /* "bx/bbi/bbi_file.pyx":256
+ *             assert len( bytes ) == 8
+ *             chrom_id, chrom_size = self.chrom_bpt.reader.unpack( "II", bytes )
+ *             return chrom_id, chrom_size             # <<<<<<<<<<<<<<
+ *         else:
+ *             return None, None
+ */
+    __Pyx_XDECREF(__pyx_r);
+    __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 256; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __Pyx_INCREF(__pyx_v_chrom_id);
+    PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_chrom_id);
+    __Pyx_GIVEREF(__pyx_v_chrom_id);
+    __Pyx_INCREF(__pyx_v_chrom_size);
+    PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_v_chrom_size);
+    __Pyx_GIVEREF(__pyx_v_chrom_size);
+    __pyx_r = __pyx_t_1;
+    __pyx_t_1 = 0;
+    goto __pyx_L0;
+  }
+  /*else*/ {
+
+    /* "bx/bbi/bbi_file.pyx":258
+ *             return chrom_id, chrom_size
+ *         else:
+ *             return None, None             # <<<<<<<<<<<<<<
+ * 
+ *     cdef _summarize_from_full( self, bits32 chrom_id, bits32 start, bits32 end, int summary_size ):
+ */
+    __Pyx_XDECREF(__pyx_r);
+    __Pyx_INCREF(__pyx_tuple__2);
+    __pyx_r = __pyx_tuple__2;
+    goto __pyx_L0;
+  }
+
+  /* "bx/bbi/bbi_file.pyx":247
+ *         return rval
+ * 
+ *     cdef _get_chrom_id_and_size( self, char * chrom ):             # <<<<<<<<<<<<<<
+ *         """
+ *         Lookup id and size from the chromosome named `chrom`
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_XDECREF(__pyx_t_5);
+  __Pyx_AddTraceback("bx.bbi.bbi_file.BBIFile._get_chrom_id_and_size", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_bytes);
+  __Pyx_XDECREF(__pyx_v_chrom_id);
+  __Pyx_XDECREF(__pyx_v_chrom_size);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bbi/bbi_file.pyx":260
+ *             return None, None
+ * 
+ *     cdef _summarize_from_full( self, bits32 chrom_id, bits32 start, bits32 end, int summary_size ):             # <<<<<<<<<<<<<<
+ *         """
+ *         Create summary from full data. This is data specific so must be overridden.
+ */
+
+static PyObject *__pyx_f_2bx_3bbi_8bbi_file_7BBIFile__summarize_from_full(CYTHON_UNUSED struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *__pyx_v_self, CYTHON_UNUSED __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_chrom_id, CYTHON_UNUSED __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_start, CYTHON_UNUSED __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_end, CYTHON_UNUSED int __pyx_v_summary_size) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_summarize_from_full", 0);
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bbi/bbi_file.pyx":266
+ *         pass
+ * 
+ *     cdef _best_zoom_level( self, int desired_reduction ):             # <<<<<<<<<<<<<<
+ *         if desired_reduction <= 1:
+ *             return None
+ */
+
+static PyObject *__pyx_f_2bx_3bbi_8bbi_file_7BBIFile__best_zoom_level(struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *__pyx_v_self, int __pyx_v_desired_reduction) {
+  struct __pyx_obj_2bx_3bbi_8bbi_file_ZoomLevel *__pyx_v_level = 0;
+  struct __pyx_obj_2bx_3bbi_8bbi_file_ZoomLevel *__pyx_v_closest_level = 0;
+  int __pyx_v_diff;
+  int __pyx_v_closest_diff;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
+  Py_ssize_t __pyx_t_3;
+  PyObject *(*__pyx_t_4)(PyObject *);
+  PyObject *__pyx_t_5 = NULL;
+  int __pyx_t_6;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("_best_zoom_level", 0);
+
+  /* "bx/bbi/bbi_file.pyx":267
+ * 
+ *     cdef _best_zoom_level( self, int desired_reduction ):
+ *         if desired_reduction <= 1:             # <<<<<<<<<<<<<<
+ *             return None
+ * 
+ */
+  __pyx_t_1 = ((__pyx_v_desired_reduction <= 1) != 0);
+  if (__pyx_t_1) {
+
+    /* "bx/bbi/bbi_file.pyx":268
+ *     cdef _best_zoom_level( self, int desired_reduction ):
+ *         if desired_reduction <= 1:
+ *             return None             # <<<<<<<<<<<<<<
+ * 
+ *         cdef ZoomLevel level, closest_level
+ */
+    __Pyx_XDECREF(__pyx_r);
+    __Pyx_INCREF(Py_None);
+    __pyx_r = Py_None;
+    goto __pyx_L0;
+  }
+
+  /* "bx/bbi/bbi_file.pyx":271
+ * 
+ *         cdef ZoomLevel level, closest_level
+ *         cdef int diff, closest_diff = limits.INT_MAX             # <<<<<<<<<<<<<<
+ * 
+ *         closest_level = None
+ */
+  __pyx_v_closest_diff = INT_MAX;
+
+  /* "bx/bbi/bbi_file.pyx":273
+ *         cdef int diff, closest_diff = limits.INT_MAX
+ * 
+ *         closest_level = None             # <<<<<<<<<<<<<<
+ *         for level in self.level_list:
+ *             diff = desired_reduction - level.reduction_level
+ */
+  __Pyx_INCREF(Py_None);
+  __pyx_v_closest_level = ((struct __pyx_obj_2bx_3bbi_8bbi_file_ZoomLevel *)Py_None);
+
+  /* "bx/bbi/bbi_file.pyx":274
+ * 
+ *         closest_level = None
+ *         for level in self.level_list:             # <<<<<<<<<<<<<<
+ *             diff = desired_reduction - level.reduction_level
+ *             if diff >= 0 and diff < closest_diff:
+ */
+  if (likely(PyList_CheckExact(__pyx_v_self->level_list)) || PyTuple_CheckExact(__pyx_v_self->level_list)) {
+    __pyx_t_2 = __pyx_v_self->level_list; __Pyx_INCREF(__pyx_t_2); __pyx_t_3 = 0;
+    __pyx_t_4 = NULL;
+  } else {
+    __pyx_t_3 = -1; __pyx_t_2 = PyObject_GetIter(__pyx_v_self->level_list); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 274; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_t_4 = Py_TYPE(__pyx_t_2)->tp_iternext; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 274; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  for (;;) {
+    if (likely(!__pyx_t_4)) {
+      if (likely(PyList_CheckExact(__pyx_t_2))) {
+        if (__pyx_t_3 >= PyList_GET_SIZE(__pyx_t_2)) break;
+        #if CYTHON_COMPILING_IN_CPYTHON
+        __pyx_t_5 = PyList_GET_ITEM(__pyx_t_2, __pyx_t_3); __Pyx_INCREF(__pyx_t_5); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 274; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #else
+        __pyx_t_5 = PySequence_ITEM(__pyx_t_2, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 274; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #endif
+      } else {
+        if (__pyx_t_3 >= PyTuple_GET_SIZE(__pyx_t_2)) break;
+        #if CYTHON_COMPILING_IN_CPYTHON
+        __pyx_t_5 = PyTuple_GET_ITEM(__pyx_t_2, __pyx_t_3); __Pyx_INCREF(__pyx_t_5); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 274; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #else
+        __pyx_t_5 = PySequence_ITEM(__pyx_t_2, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 274; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #endif
+      }
+    } else {
+      __pyx_t_5 = __pyx_t_4(__pyx_t_2);
+      if (unlikely(!__pyx_t_5)) {
+        PyObject* exc_type = PyErr_Occurred();
+        if (exc_type) {
+          if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+          else {__pyx_filename = __pyx_f[0]; __pyx_lineno = 274; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        }
+        break;
+      }
+      __Pyx_GOTREF(__pyx_t_5);
+    }
+    if (!(likely(((__pyx_t_5) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_5, __pyx_ptype_2bx_3bbi_8bbi_file_ZoomLevel))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 274; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_XDECREF_SET(__pyx_v_level, ((struct __pyx_obj_2bx_3bbi_8bbi_file_ZoomLevel *)__pyx_t_5));
+    __pyx_t_5 = 0;
+
+    /* "bx/bbi/bbi_file.pyx":275
+ *         closest_level = None
+ *         for level in self.level_list:
+ *             diff = desired_reduction - level.reduction_level             # <<<<<<<<<<<<<<
+ *             if diff >= 0 and diff < closest_diff:
+ *                 closest_diff = diff
+ */
+    __pyx_v_diff = (__pyx_v_desired_reduction - __pyx_v_level->reduction_level);
+
+    /* "bx/bbi/bbi_file.pyx":276
+ *         for level in self.level_list:
+ *             diff = desired_reduction - level.reduction_level
+ *             if diff >= 0 and diff < closest_diff:             # <<<<<<<<<<<<<<
+ *                 closest_diff = diff
+ *                 closest_level = level
+ */
+    __pyx_t_6 = ((__pyx_v_diff >= 0) != 0);
+    if (__pyx_t_6) {
+    } else {
+      __pyx_t_1 = __pyx_t_6;
+      goto __pyx_L7_bool_binop_done;
+    }
+    __pyx_t_6 = ((__pyx_v_diff < __pyx_v_closest_diff) != 0);
+    __pyx_t_1 = __pyx_t_6;
+    __pyx_L7_bool_binop_done:;
+    if (__pyx_t_1) {
+
+      /* "bx/bbi/bbi_file.pyx":277
+ *             diff = desired_reduction - level.reduction_level
+ *             if diff >= 0 and diff < closest_diff:
+ *                 closest_diff = diff             # <<<<<<<<<<<<<<
+ *                 closest_level = level
+ *         return closest_level
+ */
+      __pyx_v_closest_diff = __pyx_v_diff;
+
+      /* "bx/bbi/bbi_file.pyx":278
+ *             if diff >= 0 and diff < closest_diff:
+ *                 closest_diff = diff
+ *                 closest_level = level             # <<<<<<<<<<<<<<
+ *         return closest_level
+ * 
+ */
+      __Pyx_INCREF(((PyObject *)__pyx_v_level));
+      __Pyx_DECREF_SET(__pyx_v_closest_level, __pyx_v_level);
+      goto __pyx_L6;
+    }
+    __pyx_L6:;
+
+    /* "bx/bbi/bbi_file.pyx":274
+ * 
+ *         closest_level = None
+ *         for level in self.level_list:             # <<<<<<<<<<<<<<
+ *             diff = desired_reduction - level.reduction_level
+ *             if diff >= 0 and diff < closest_diff:
+ */
+  }
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+  /* "bx/bbi/bbi_file.pyx":279
+ *                 closest_diff = diff
+ *                 closest_level = level
+ *         return closest_level             # <<<<<<<<<<<<<<
+ * 
+ * cdef class ZoomLevel:
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __Pyx_INCREF(((PyObject *)__pyx_v_closest_level));
+  __pyx_r = ((PyObject *)__pyx_v_closest_level);
+  goto __pyx_L0;
+
+  /* "bx/bbi/bbi_file.pyx":266
+ *         pass
+ * 
+ *     cdef _best_zoom_level( self, int desired_reduction ):             # <<<<<<<<<<<<<<
+ *         if desired_reduction <= 1:
+ *             return None
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_5);
+  __Pyx_AddTraceback("bx.bbi.bbi_file.BBIFile._best_zoom_level", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XDECREF((PyObject *)__pyx_v_level);
+  __Pyx_XDECREF((PyObject *)__pyx_v_closest_level);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bbi/bbi_file.pxd":56
+ *     cdef object reader
+ *     # The magic number or type signature (whether the file is bigWig or bigBed or...)
+ *     cdef public bits32 magic             # <<<<<<<<<<<<<<
+ *     # Is the file byteswapped relative to our native byte order?
+ *     cdef boolean is_byteswapped
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_3bbi_8bbi_file_7BBIFile_5magic_1__get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_2bx_3bbi_8bbi_file_7BBIFile_5magic_1__get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_3bbi_8bbi_file_7BBIFile_5magic___get__(((struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *)__pyx_v_self));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_2bx_3bbi_8bbi_file_7BBIFile_5magic___get__(struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__get__", 0);
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = __Pyx_PyInt_From_unsigned_int(__pyx_v_self->magic); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 56; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("bx.bbi.bbi_file.BBIFile.magic.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_2bx_3bbi_8bbi_file_7BBIFile_5magic_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value); /*proto*/
+static int __pyx_pw_2bx_3bbi_8bbi_file_7BBIFile_5magic_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__set__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_3bbi_8bbi_file_7BBIFile_5magic_2__set__(((struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *)__pyx_v_self), ((PyObject *)__pyx_v_value));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_2bx_3bbi_8bbi_file_7BBIFile_5magic_2__set__(struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __pyx_t_2bx_3bbi_5types_bits32 __pyx_t_1;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__set__", 0);
+  __pyx_t_1 = __Pyx_PyInt_As_unsigned_int(__pyx_v_value); if (unlikely((__pyx_t_1 == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 56; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_v_self->magic = __pyx_t_1;
+
+  /* function exit code */
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_AddTraceback("bx.bbi.bbi_file.BBIFile.magic.__set__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = -1;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bbi/bbi_file.pxd":62
+ *     cdef BPTFile chrom_bpt
+ *     # Version number
+ *     cdef public bits16 version             # <<<<<<<<<<<<<<
+ *     # Number of zoom levels
+ *     cdef public bits16 zoom_levels
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_3bbi_8bbi_file_7BBIFile_7version_1__get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_2bx_3bbi_8bbi_file_7BBIFile_7version_1__get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_3bbi_8bbi_file_7BBIFile_7version___get__(((struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *)__pyx_v_self));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_2bx_3bbi_8bbi_file_7BBIFile_7version___get__(struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__get__", 0);
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = __Pyx_PyInt_From_unsigned_short(__pyx_v_self->version); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 62; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("bx.bbi.bbi_file.BBIFile.version.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_2bx_3bbi_8bbi_file_7BBIFile_7version_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value); /*proto*/
+static int __pyx_pw_2bx_3bbi_8bbi_file_7BBIFile_7version_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__set__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_3bbi_8bbi_file_7BBIFile_7version_2__set__(((struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *)__pyx_v_self), ((PyObject *)__pyx_v_value));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_2bx_3bbi_8bbi_file_7BBIFile_7version_2__set__(struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __pyx_t_2bx_3bbi_5types_bits16 __pyx_t_1;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__set__", 0);
+  __pyx_t_1 = __Pyx_PyInt_As_unsigned_short(__pyx_v_value); if (unlikely((__pyx_t_1 == (unsigned short)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 62; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_v_self->version = __pyx_t_1;
+
+  /* function exit code */
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_AddTraceback("bx.bbi.bbi_file.BBIFile.version.__set__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = -1;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bbi/bbi_file.pxd":64
+ *     cdef public bits16 version
+ *     # Number of zoom levels
+ *     cdef public bits16 zoom_levels             # <<<<<<<<<<<<<<
+ *     # Offset to chromosome index
+ *     cdef bits64 chrom_tree_offset
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_3bbi_8bbi_file_7BBIFile_11zoom_levels_1__get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_2bx_3bbi_8bbi_file_7BBIFile_11zoom_levels_1__get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_3bbi_8bbi_file_7BBIFile_11zoom_levels___get__(((struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *)__pyx_v_self));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_2bx_3bbi_8bbi_file_7BBIFile_11zoom_levels___get__(struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__get__", 0);
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = __Pyx_PyInt_From_unsigned_short(__pyx_v_self->zoom_levels); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 64; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("bx.bbi.bbi_file.BBIFile.zoom_levels.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_2bx_3bbi_8bbi_file_7BBIFile_11zoom_levels_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value); /*proto*/
+static int __pyx_pw_2bx_3bbi_8bbi_file_7BBIFile_11zoom_levels_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__set__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_3bbi_8bbi_file_7BBIFile_11zoom_levels_2__set__(((struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *)__pyx_v_self), ((PyObject *)__pyx_v_value));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_2bx_3bbi_8bbi_file_7BBIFile_11zoom_levels_2__set__(struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __pyx_t_2bx_3bbi_5types_bits16 __pyx_t_1;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__set__", 0);
+  __pyx_t_1 = __Pyx_PyInt_As_unsigned_short(__pyx_v_value); if (unlikely((__pyx_t_1 == (unsigned short)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 64; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_v_self->zoom_levels = __pyx_t_1;
+
+  /* function exit code */
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_AddTraceback("bx.bbi.bbi_file.BBIFile.zoom_levels.__set__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = -1;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bbi/bbi_file.pxd":81
+ *     cdef bits32 uncompress_buf_size
+ *     # Zoom levels list
+ *     cdef public object level_list             # <<<<<<<<<<<<<<
+ * 
+ *     cdef visit_blocks_in_region( self, bits32 chrom_id, bits32 start, bits32 end, BlockHandler handler )
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_3bbi_8bbi_file_7BBIFile_10level_list_1__get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_2bx_3bbi_8bbi_file_7BBIFile_10level_list_1__get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_3bbi_8bbi_file_7BBIFile_10level_list___get__(((struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *)__pyx_v_self));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_2bx_3bbi_8bbi_file_7BBIFile_10level_list___get__(struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__get__", 0);
+  __Pyx_XDECREF(__pyx_r);
+  __Pyx_INCREF(__pyx_v_self->level_list);
+  __pyx_r = __pyx_v_self->level_list;
+  goto __pyx_L0;
+
+  /* function exit code */
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_2bx_3bbi_8bbi_file_7BBIFile_10level_list_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value); /*proto*/
+static int __pyx_pw_2bx_3bbi_8bbi_file_7BBIFile_10level_list_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__set__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_3bbi_8bbi_file_7BBIFile_10level_list_2__set__(((struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *)__pyx_v_self), ((PyObject *)__pyx_v_value));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_2bx_3bbi_8bbi_file_7BBIFile_10level_list_2__set__(struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__set__", 0);
+  __Pyx_INCREF(__pyx_v_value);
+  __Pyx_GIVEREF(__pyx_v_value);
+  __Pyx_GOTREF(__pyx_v_self->level_list);
+  __Pyx_DECREF(__pyx_v_self->level_list);
+  __pyx_v_self->level_list = __pyx_v_value;
+
+  /* function exit code */
+  __pyx_r = 0;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_2bx_3bbi_8bbi_file_7BBIFile_10level_list_5__del__(PyObject *__pyx_v_self); /*proto*/
+static int __pyx_pw_2bx_3bbi_8bbi_file_7BBIFile_10level_list_5__del__(PyObject *__pyx_v_self) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__del__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_3bbi_8bbi_file_7BBIFile_10level_list_4__del__(((struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *)__pyx_v_self));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_2bx_3bbi_8bbi_file_7BBIFile_10level_list_4__del__(struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *__pyx_v_self) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__del__", 0);
+  __Pyx_INCREF(Py_None);
+  __Pyx_GIVEREF(Py_None);
+  __Pyx_GOTREF(__pyx_v_self->level_list);
+  __Pyx_DECREF(__pyx_v_self->level_list);
+  __pyx_v_self->level_list = Py_None;
+
+  /* function exit code */
+  __pyx_r = 0;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bbi/bbi_file.pyx":289
+ *     cdef int item_count
+ * 
+ *     def _summary_blocks_in_region( self, bits32 chrom_id, bits32 start, bits32 end ):             # <<<<<<<<<<<<<<
+ *         """
+ *         Return a list of all SummaryBlocks that overlap the region
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_3bbi_8bbi_file_9ZoomLevel_1_summary_blocks_in_region(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_2bx_3bbi_8bbi_file_9ZoomLevel__summary_blocks_in_region[] = "\n        Return a list of all SummaryBlocks that overlap the region \n        `chrom_id`:`start`-`end`\n        ";
+static PyObject *__pyx_pw_2bx_3bbi_8bbi_file_9ZoomLevel_1_summary_blocks_in_region(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_chrom_id;
+  __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_start;
+  __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_end;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_summary_blocks_in_region (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_chrom_id,&__pyx_n_s_start,&__pyx_n_s_end,0};
+    PyObject* values[3] = {0,0,0};
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_chrom_id)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_start)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("_summary_blocks_in_region", 1, 3, 3, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 289; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+        case  2:
+        if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_end)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("_summary_blocks_in_region", 1, 3, 3, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 289; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_summary_blocks_in_region") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 289; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else if (PyTuple_GET_SIZE(__pyx_args) != 3) {
+      goto __pyx_L5_argtuple_error;
+    } else {
+      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+      values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+    }
+    __pyx_v_chrom_id = __Pyx_PyInt_As_unsigned_int(values[0]); if (unlikely((__pyx_v_chrom_id == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 289; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_start = __Pyx_PyInt_As_unsigned_int(values[1]); if (unlikely((__pyx_v_start == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 289; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_end = __Pyx_PyInt_As_unsigned_int(values[2]); if (unlikely((__pyx_v_end == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 289; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("_summary_blocks_in_region", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 289; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.bbi.bbi_file.ZoomLevel._summary_blocks_in_region", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_3bbi_8bbi_file_9ZoomLevel__summary_blocks_in_region(((struct __pyx_obj_2bx_3bbi_8bbi_file_ZoomLevel *)__pyx_v_self), __pyx_v_chrom_id, __pyx_v_start, __pyx_v_end);
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_2bx_3bbi_8bbi_file_9ZoomLevel__summary_blocks_in_region(struct __pyx_obj_2bx_3bbi_8bbi_file_ZoomLevel *__pyx_v_self, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_chrom_id, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_start, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_end) {
+  struct __pyx_obj_2bx_3bbi_12cirtree_file_CIRTreeFile *__pyx_v_ctf = 0;
+  PyObject *__pyx_v_rval = NULL;
+  PyObject *__pyx_v_reader = NULL;
+  PyObject *__pyx_v_block_list = NULL;
+  PyObject *__pyx_v_sum_dtype = NULL;
+  PyObject *__pyx_v_offset = NULL;
+  PyObject *__pyx_v_size = NULL;
+  PyObject *__pyx_v_block_data = NULL;
+  PyObject *__pyx_v_block_size = NULL;
+  PyObject *__pyx_v_item_count = NULL;
+  PyObject *__pyx_v_arr = NULL;
+  PyObject *__pyx_v_d = NULL;
+  PyObject *__pyx_v_x = NULL;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  PyObject *__pyx_t_5 = NULL;
+  PyObject *__pyx_t_6 = NULL;
+  Py_ssize_t __pyx_t_7;
+  PyObject *__pyx_t_8 = NULL;
+  PyObject *__pyx_t_9 = NULL;
+  PyObject *__pyx_t_10 = NULL;
+  PyObject *(*__pyx_t_11)(PyObject *);
+  PyObject *(*__pyx_t_12)(PyObject *);
+  int __pyx_t_13;
+  Py_ssize_t __pyx_t_14;
+  PyObject *(*__pyx_t_15)(PyObject *);
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("_summary_blocks_in_region", 0);
+
+  /* "bx/bbi/bbi_file.pyx":296
+ *         cdef CIRTreeFile ctf
+ *         cdef SummaryBlock summary
+ *         rval = deque()             # <<<<<<<<<<<<<<
+ *         reader = self.bbi_file.reader
+ *         reader.seek( self.index_offset )
+ */
+  __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_deque); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 296; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = NULL;
+  if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_2))) {
+    __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2);
+    if (likely(__pyx_t_3)) {
+      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+      __Pyx_INCREF(__pyx_t_3);
+      __Pyx_INCREF(function);
+      __Pyx_DECREF_SET(__pyx_t_2, function);
+    }
+  }
+  if (__pyx_t_3) {
+    __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 296; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  } else {
+    __pyx_t_1 = __Pyx_PyObject_CallNoArg(__pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 296; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_v_rval = __pyx_t_1;
+  __pyx_t_1 = 0;
+
+  /* "bx/bbi/bbi_file.pyx":297
+ *         cdef SummaryBlock summary
+ *         rval = deque()
+ *         reader = self.bbi_file.reader             # <<<<<<<<<<<<<<
+ *         reader.seek( self.index_offset )
+ *         ctf = CIRTreeFile( reader.file )
+ */
+  __pyx_t_1 = __pyx_v_self->bbi_file->reader;
+  __Pyx_INCREF(__pyx_t_1);
+  __pyx_v_reader = __pyx_t_1;
+  __pyx_t_1 = 0;
+
+  /* "bx/bbi/bbi_file.pyx":298
+ *         rval = deque()
+ *         reader = self.bbi_file.reader
+ *         reader.seek( self.index_offset )             # <<<<<<<<<<<<<<
+ *         ctf = CIRTreeFile( reader.file )
+ *         block_list = ctf.find_overlapping_blocks( chrom_id, start, end )
+ */
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_reader, __pyx_n_s_seek); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 298; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = __Pyx_PyInt_From_unsigned_PY_LONG_LONG(__pyx_v_self->index_offset); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 298; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_4 = NULL;
+  if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_2))) {
+    __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_2);
+    if (likely(__pyx_t_4)) {
+      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+      __Pyx_INCREF(__pyx_t_4);
+      __Pyx_INCREF(function);
+      __Pyx_DECREF_SET(__pyx_t_2, function);
+    }
+  }
+  if (!__pyx_t_4) {
+    __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 298; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __Pyx_GOTREF(__pyx_t_1);
+  } else {
+    __pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 298; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_5);
+    PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_4); __Pyx_GIVEREF(__pyx_t_4); __pyx_t_4 = NULL;
+    PyTuple_SET_ITEM(__pyx_t_5, 0+1, __pyx_t_3);
+    __Pyx_GIVEREF(__pyx_t_3);
+    __pyx_t_3 = 0;
+    __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_5, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 298; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+  }
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "bx/bbi/bbi_file.pyx":299
+ *         reader = self.bbi_file.reader
+ *         reader.seek( self.index_offset )
+ *         ctf = CIRTreeFile( reader.file )             # <<<<<<<<<<<<<<
+ *         block_list = ctf.find_overlapping_blocks( chrom_id, start, end )
+ * 
+ */
+  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_reader, __pyx_n_s_file); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 299; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 299; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
+  __Pyx_GIVEREF(__pyx_t_1);
+  __pyx_t_1 = 0;
+  __pyx_t_1 = __Pyx_PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_2bx_3bbi_12cirtree_file_CIRTreeFile)), __pyx_t_2, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 299; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_v_ctf = ((struct __pyx_obj_2bx_3bbi_12cirtree_file_CIRTreeFile *)__pyx_t_1);
+  __pyx_t_1 = 0;
+
+  /* "bx/bbi/bbi_file.pyx":300
+ *         reader.seek( self.index_offset )
+ *         ctf = CIRTreeFile( reader.file )
+ *         block_list = ctf.find_overlapping_blocks( chrom_id, start, end )             # <<<<<<<<<<<<<<
+ * 
+ *         sum_dtype = np.dtype([('chrom_id', np.uint32),
+ */
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_ctf), __pyx_n_s_find_overlapping_blocks); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 300; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_5 = __Pyx_PyInt_From_unsigned_int(__pyx_v_chrom_id); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 300; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __pyx_t_3 = __Pyx_PyInt_From_unsigned_int(__pyx_v_start); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 300; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_4 = __Pyx_PyInt_From_unsigned_int(__pyx_v_end); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 300; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __pyx_t_6 = NULL;
+  __pyx_t_7 = 0;
+  if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_2))) {
+    __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_2);
+    if (likely(__pyx_t_6)) {
+      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+      __Pyx_INCREF(__pyx_t_6);
+      __Pyx_INCREF(function);
+      __Pyx_DECREF_SET(__pyx_t_2, function);
+      __pyx_t_7 = 1;
+    }
+  }
+  __pyx_t_8 = PyTuple_New(3+__pyx_t_7); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 300; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_8);
+  if (__pyx_t_6) {
+    PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_6); __Pyx_GIVEREF(__pyx_t_6); __pyx_t_6 = NULL;
+  }
+  PyTuple_SET_ITEM(__pyx_t_8, 0+__pyx_t_7, __pyx_t_5);
+  __Pyx_GIVEREF(__pyx_t_5);
+  PyTuple_SET_ITEM(__pyx_t_8, 1+__pyx_t_7, __pyx_t_3);
+  __Pyx_GIVEREF(__pyx_t_3);
+  PyTuple_SET_ITEM(__pyx_t_8, 2+__pyx_t_7, __pyx_t_4);
+  __Pyx_GIVEREF(__pyx_t_4);
+  __pyx_t_5 = 0;
+  __pyx_t_3 = 0;
+  __pyx_t_4 = 0;
+  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_8, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 300; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_v_block_list = __pyx_t_1;
+  __pyx_t_1 = 0;
+
+  /* "bx/bbi/bbi_file.pyx":302
+ *         block_list = ctf.find_overlapping_blocks( chrom_id, start, end )
+ * 
+ *         sum_dtype = np.dtype([('chrom_id', np.uint32),             # <<<<<<<<<<<<<<
+ *                               ('start', np.uint32),
+ *                               ('end', np.uint32),
+ */
+  __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 302; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_uint32); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 302; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 302; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_INCREF(__pyx_n_s_chrom_id);
+  PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_n_s_chrom_id);
+  __Pyx_GIVEREF(__pyx_n_s_chrom_id);
+  PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_t_2);
+  __Pyx_GIVEREF(__pyx_t_2);
+  __pyx_t_2 = 0;
+
+  /* "bx/bbi/bbi_file.pyx":303
+ * 
+ *         sum_dtype = np.dtype([('chrom_id', np.uint32),
+ *                               ('start', np.uint32),             # <<<<<<<<<<<<<<
+ *                               ('end', np.uint32),
+ *                               ('valid_count', np.uint32),
+ */
+  __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 303; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_uint32); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 303; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_8);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 303; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_INCREF(__pyx_n_s_start);
+  PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_n_s_start);
+  __Pyx_GIVEREF(__pyx_n_s_start);
+  PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_8);
+  __Pyx_GIVEREF(__pyx_t_8);
+  __pyx_t_8 = 0;
+
+  /* "bx/bbi/bbi_file.pyx":304
+ *         sum_dtype = np.dtype([('chrom_id', np.uint32),
+ *                               ('start', np.uint32),
+ *                               ('end', np.uint32),             # <<<<<<<<<<<<<<
+ *                               ('valid_count', np.uint32),
+ *                               ('min_val', np.float32),
+ */
+  __pyx_t_8 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 304; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_8);
+  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_8, __pyx_n_s_uint32); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 304; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+  __pyx_t_8 = PyTuple_New(2); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 304; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_8);
+  __Pyx_INCREF(__pyx_n_s_end);
+  PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_n_s_end);
+  __Pyx_GIVEREF(__pyx_n_s_end);
+  PyTuple_SET_ITEM(__pyx_t_8, 1, __pyx_t_4);
+  __Pyx_GIVEREF(__pyx_t_4);
+  __pyx_t_4 = 0;
+
+  /* "bx/bbi/bbi_file.pyx":305
+ *                               ('start', np.uint32),
+ *                               ('end', np.uint32),
+ *                               ('valid_count', np.uint32),             # <<<<<<<<<<<<<<
+ *                               ('min_val', np.float32),
+ *                               ('max_val', np.float32),
+ */
+  __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 305; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_uint32); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 305; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 305; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __Pyx_INCREF(__pyx_n_s_valid_count);
+  PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_n_s_valid_count);
+  __Pyx_GIVEREF(__pyx_n_s_valid_count);
+  PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_3);
+  __Pyx_GIVEREF(__pyx_t_3);
+  __pyx_t_3 = 0;
+
+  /* "bx/bbi/bbi_file.pyx":306
+ *                               ('end', np.uint32),
+ *                               ('valid_count', np.uint32),
+ *                               ('min_val', np.float32),             # <<<<<<<<<<<<<<
+ *                               ('max_val', np.float32),
+ *                               ('sum_data', np.float32),
+ */
+  __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 306; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_float32); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 306; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 306; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_INCREF(__pyx_n_s_min_val);
+  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_n_s_min_val);
+  __Pyx_GIVEREF(__pyx_n_s_min_val);
+  PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_5);
+  __Pyx_GIVEREF(__pyx_t_5);
+  __pyx_t_5 = 0;
+
+  /* "bx/bbi/bbi_file.pyx":307
+ *                               ('valid_count', np.uint32),
+ *                               ('min_val', np.float32),
+ *                               ('max_val', np.float32),             # <<<<<<<<<<<<<<
+ *                               ('sum_data', np.float32),
+ *                               ('sum_squares', np.float32)])
+ */
+  __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 307; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_float32); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 307; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_6);
+  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+  __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 307; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __Pyx_INCREF(__pyx_n_s_max_val);
+  PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_n_s_max_val);
+  __Pyx_GIVEREF(__pyx_n_s_max_val);
+  PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_t_6);
+  __Pyx_GIVEREF(__pyx_t_6);
+  __pyx_t_6 = 0;
+
+  /* "bx/bbi/bbi_file.pyx":308
+ *                               ('min_val', np.float32),
+ *                               ('max_val', np.float32),
+ *                               ('sum_data', np.float32),             # <<<<<<<<<<<<<<
+ *                               ('sum_squares', np.float32)])
+ * 
+ */
+  __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 308; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_6);
+  __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_float32); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 308; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_9);
+  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+  __pyx_t_6 = PyTuple_New(2); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 308; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_6);
+  __Pyx_INCREF(__pyx_n_s_sum_data);
+  PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_n_s_sum_data);
+  __Pyx_GIVEREF(__pyx_n_s_sum_data);
+  PyTuple_SET_ITEM(__pyx_t_6, 1, __pyx_t_9);
+  __Pyx_GIVEREF(__pyx_t_9);
+  __pyx_t_9 = 0;
+
+  /* "bx/bbi/bbi_file.pyx":309
+ *                               ('max_val', np.float32),
+ *                               ('sum_data', np.float32),
+ *                               ('sum_squares', np.float32)])             # <<<<<<<<<<<<<<
+ * 
+ *         for offset, size in block_list:
+ */
+  __pyx_t_9 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 309; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_9);
+  __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_t_9, __pyx_n_s_float32); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 309; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_10);
+  __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+  __pyx_t_9 = PyTuple_New(2); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 309; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_9);
+  __Pyx_INCREF(__pyx_n_s_sum_squares);
+  PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_n_s_sum_squares);
+  __Pyx_GIVEREF(__pyx_n_s_sum_squares);
+  PyTuple_SET_ITEM(__pyx_t_9, 1, __pyx_t_10);
+  __Pyx_GIVEREF(__pyx_t_10);
+  __pyx_t_10 = 0;
+
+  /* "bx/bbi/bbi_file.pyx":302
+ *         block_list = ctf.find_overlapping_blocks( chrom_id, start, end )
+ * 
+ *         sum_dtype = np.dtype([('chrom_id', np.uint32),             # <<<<<<<<<<<<<<
+ *                               ('start', np.uint32),
+ *                               ('end', np.uint32),
+ */
+  __pyx_t_10 = PyList_New(8); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 302; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_10);
+  PyList_SET_ITEM(__pyx_t_10, 0, __pyx_t_1);
+  __Pyx_GIVEREF(__pyx_t_1);
+  PyList_SET_ITEM(__pyx_t_10, 1, __pyx_t_2);
+  __Pyx_GIVEREF(__pyx_t_2);
+  PyList_SET_ITEM(__pyx_t_10, 2, __pyx_t_8);
+  __Pyx_GIVEREF(__pyx_t_8);
+  PyList_SET_ITEM(__pyx_t_10, 3, __pyx_t_4);
+  __Pyx_GIVEREF(__pyx_t_4);
+  PyList_SET_ITEM(__pyx_t_10, 4, __pyx_t_3);
+  __Pyx_GIVEREF(__pyx_t_3);
+  PyList_SET_ITEM(__pyx_t_10, 5, __pyx_t_5);
+  __Pyx_GIVEREF(__pyx_t_5);
+  PyList_SET_ITEM(__pyx_t_10, 6, __pyx_t_6);
+  __Pyx_GIVEREF(__pyx_t_6);
+  PyList_SET_ITEM(__pyx_t_10, 7, __pyx_t_9);
+  __Pyx_GIVEREF(__pyx_t_9);
+  __pyx_t_1 = 0;
+  __pyx_t_2 = 0;
+  __pyx_t_8 = 0;
+  __pyx_t_4 = 0;
+  __pyx_t_3 = 0;
+  __pyx_t_5 = 0;
+  __pyx_t_6 = 0;
+  __pyx_t_9 = 0;
+  __pyx_t_9 = PyTuple_New(1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 302; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_9);
+  PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_10);
+  __Pyx_GIVEREF(__pyx_t_10);
+  __pyx_t_10 = 0;
+  __pyx_t_10 = __Pyx_PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_5numpy_dtype)), __pyx_t_9, NULL); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 302; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_10);
+  __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+  __pyx_v_sum_dtype = __pyx_t_10;
+  __pyx_t_10 = 0;
+
+  /* "bx/bbi/bbi_file.pyx":311
+ *                               ('sum_squares', np.float32)])
+ * 
+ *         for offset, size in block_list:             # <<<<<<<<<<<<<<
+ *             # Seek to and read all data for the block
+ *             reader.seek( offset )
+ */
+  if (likely(PyList_CheckExact(__pyx_v_block_list)) || PyTuple_CheckExact(__pyx_v_block_list)) {
+    __pyx_t_10 = __pyx_v_block_list; __Pyx_INCREF(__pyx_t_10); __pyx_t_7 = 0;
+    __pyx_t_11 = NULL;
+  } else {
+    __pyx_t_7 = -1; __pyx_t_10 = PyObject_GetIter(__pyx_v_block_list); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 311; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_10);
+    __pyx_t_11 = Py_TYPE(__pyx_t_10)->tp_iternext; if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 311; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  for (;;) {
+    if (likely(!__pyx_t_11)) {
+      if (likely(PyList_CheckExact(__pyx_t_10))) {
+        if (__pyx_t_7 >= PyList_GET_SIZE(__pyx_t_10)) break;
+        #if CYTHON_COMPILING_IN_CPYTHON
+        __pyx_t_9 = PyList_GET_ITEM(__pyx_t_10, __pyx_t_7); __Pyx_INCREF(__pyx_t_9); __pyx_t_7++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 311; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #else
+        __pyx_t_9 = PySequence_ITEM(__pyx_t_10, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 311; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #endif
+      } else {
+        if (__pyx_t_7 >= PyTuple_GET_SIZE(__pyx_t_10)) break;
+        #if CYTHON_COMPILING_IN_CPYTHON
+        __pyx_t_9 = PyTuple_GET_ITEM(__pyx_t_10, __pyx_t_7); __Pyx_INCREF(__pyx_t_9); __pyx_t_7++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 311; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #else
+        __pyx_t_9 = PySequence_ITEM(__pyx_t_10, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 311; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #endif
+      }
+    } else {
+      __pyx_t_9 = __pyx_t_11(__pyx_t_10);
+      if (unlikely(!__pyx_t_9)) {
+        PyObject* exc_type = PyErr_Occurred();
+        if (exc_type) {
+          if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+          else {__pyx_filename = __pyx_f[0]; __pyx_lineno = 311; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        }
+        break;
+      }
+      __Pyx_GOTREF(__pyx_t_9);
+    }
+    if ((likely(PyTuple_CheckExact(__pyx_t_9))) || (PyList_CheckExact(__pyx_t_9))) {
+      PyObject* sequence = __pyx_t_9;
+      #if CYTHON_COMPILING_IN_CPYTHON
+      Py_ssize_t size = Py_SIZE(sequence);
+      #else
+      Py_ssize_t size = PySequence_Size(sequence);
+      #endif
+      if (unlikely(size != 2)) {
+        if (size > 2) __Pyx_RaiseTooManyValuesError(2);
+        else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
+        {__pyx_filename = __pyx_f[0]; __pyx_lineno = 311; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      }
+      #if CYTHON_COMPILING_IN_CPYTHON
+      if (likely(PyTuple_CheckExact(sequence))) {
+        __pyx_t_6 = PyTuple_GET_ITEM(sequence, 0); 
+        __pyx_t_5 = PyTuple_GET_ITEM(sequence, 1); 
+      } else {
+        __pyx_t_6 = PyList_GET_ITEM(sequence, 0); 
+        __pyx_t_5 = PyList_GET_ITEM(sequence, 1); 
+      }
+      __Pyx_INCREF(__pyx_t_6);
+      __Pyx_INCREF(__pyx_t_5);
+      #else
+      __pyx_t_6 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 311; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_6);
+      __pyx_t_5 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 311; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_5);
+      #endif
+      __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+    } else {
+      Py_ssize_t index = -1;
+      __pyx_t_3 = PyObject_GetIter(__pyx_t_9); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 311; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+      __pyx_t_12 = Py_TYPE(__pyx_t_3)->tp_iternext;
+      index = 0; __pyx_t_6 = __pyx_t_12(__pyx_t_3); if (unlikely(!__pyx_t_6)) goto __pyx_L5_unpacking_failed;
+      __Pyx_GOTREF(__pyx_t_6);
+      index = 1; __pyx_t_5 = __pyx_t_12(__pyx_t_3); if (unlikely(!__pyx_t_5)) goto __pyx_L5_unpacking_failed;
+      __Pyx_GOTREF(__pyx_t_5);
+      if (__Pyx_IternextUnpackEndCheck(__pyx_t_12(__pyx_t_3), 2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 311; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_12 = NULL;
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      goto __pyx_L6_unpacking_done;
+      __pyx_L5_unpacking_failed:;
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_t_12 = NULL;
+      if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
+      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 311; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_L6_unpacking_done:;
+    }
+    __Pyx_XDECREF_SET(__pyx_v_offset, __pyx_t_6);
+    __pyx_t_6 = 0;
+    __Pyx_XDECREF_SET(__pyx_v_size, __pyx_t_5);
+    __pyx_t_5 = 0;
+
+    /* "bx/bbi/bbi_file.pyx":313
+ *         for offset, size in block_list:
+ *             # Seek to and read all data for the block
+ *             reader.seek( offset )             # <<<<<<<<<<<<<<
+ *             block_data = reader.read( size )
+ *             # Might need to uncompress
+ */
+    __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_reader, __pyx_n_s_seek); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 313; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_5);
+    __pyx_t_6 = NULL;
+    if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_5))) {
+      __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_5);
+      if (likely(__pyx_t_6)) {
+        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
+        __Pyx_INCREF(__pyx_t_6);
+        __Pyx_INCREF(function);
+        __Pyx_DECREF_SET(__pyx_t_5, function);
+      }
+    }
+    if (!__pyx_t_6) {
+      __pyx_t_9 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_v_offset); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 313; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_9);
+    } else {
+      __pyx_t_3 = PyTuple_New(1+1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 313; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_6); __Pyx_GIVEREF(__pyx_t_6); __pyx_t_6 = NULL;
+      __Pyx_INCREF(__pyx_v_offset);
+      PyTuple_SET_ITEM(__pyx_t_3, 0+1, __pyx_v_offset);
+      __Pyx_GIVEREF(__pyx_v_offset);
+      __pyx_t_9 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_3, NULL); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 313; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_9);
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    }
+    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+    __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+
+    /* "bx/bbi/bbi_file.pyx":314
+ *             # Seek to and read all data for the block
+ *             reader.seek( offset )
+ *             block_data = reader.read( size )             # <<<<<<<<<<<<<<
+ *             # Might need to uncompress
+ *             if self.bbi_file.uncompress_buf_size > 0:
+ */
+    __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_reader, __pyx_n_s_read); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 314; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_5);
+    __pyx_t_3 = NULL;
+    if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_5))) {
+      __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_5);
+      if (likely(__pyx_t_3)) {
+        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
+        __Pyx_INCREF(__pyx_t_3);
+        __Pyx_INCREF(function);
+        __Pyx_DECREF_SET(__pyx_t_5, function);
+      }
+    }
+    if (!__pyx_t_3) {
+      __pyx_t_9 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_v_size); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 314; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_9);
+    } else {
+      __pyx_t_6 = PyTuple_New(1+1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 314; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_6);
+      PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_3); __Pyx_GIVEREF(__pyx_t_3); __pyx_t_3 = NULL;
+      __Pyx_INCREF(__pyx_v_size);
+      PyTuple_SET_ITEM(__pyx_t_6, 0+1, __pyx_v_size);
+      __Pyx_GIVEREF(__pyx_v_size);
+      __pyx_t_9 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_6, NULL); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 314; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_9);
+      __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+    }
+    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+    __Pyx_XDECREF_SET(__pyx_v_block_data, __pyx_t_9);
+    __pyx_t_9 = 0;
+
+    /* "bx/bbi/bbi_file.pyx":316
+ *             block_data = reader.read( size )
+ *             # Might need to uncompress
+ *             if self.bbi_file.uncompress_buf_size > 0:             # <<<<<<<<<<<<<<
+ *                 ## block_data = zlib.decompress( block_data, buf_size = self.bbi_file.uncompress_buf_size )
+ *                 block_data = zlib.decompress( block_data )
+ */
+    __pyx_t_13 = ((__pyx_v_self->bbi_file->uncompress_buf_size > 0) != 0);
+    if (__pyx_t_13) {
+
+      /* "bx/bbi/bbi_file.pyx":318
+ *             if self.bbi_file.uncompress_buf_size > 0:
+ *                 ## block_data = zlib.decompress( block_data, buf_size = self.bbi_file.uncompress_buf_size )
+ *                 block_data = zlib.decompress( block_data )             # <<<<<<<<<<<<<<
+ *             block_size = len( block_data )
+ *             # The block should be a bunch of summaries.
+ */
+      __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_zlib); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 318; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_5);
+      __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_decompress); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 318; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_6);
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      __pyx_t_5 = NULL;
+      if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_6))) {
+        __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_6);
+        if (likely(__pyx_t_5)) {
+          PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6);
+          __Pyx_INCREF(__pyx_t_5);
+          __Pyx_INCREF(function);
+          __Pyx_DECREF_SET(__pyx_t_6, function);
+        }
+      }
+      if (!__pyx_t_5) {
+        __pyx_t_9 = __Pyx_PyObject_CallOneArg(__pyx_t_6, __pyx_v_block_data); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 318; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_9);
+      } else {
+        __pyx_t_3 = PyTuple_New(1+1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 318; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_3);
+        PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_5); __Pyx_GIVEREF(__pyx_t_5); __pyx_t_5 = NULL;
+        __Pyx_INCREF(__pyx_v_block_data);
+        PyTuple_SET_ITEM(__pyx_t_3, 0+1, __pyx_v_block_data);
+        __Pyx_GIVEREF(__pyx_v_block_data);
+        __pyx_t_9 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_t_3, NULL); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 318; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_9);
+        __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      }
+      __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+      __Pyx_DECREF_SET(__pyx_v_block_data, __pyx_t_9);
+      __pyx_t_9 = 0;
+      goto __pyx_L7;
+    }
+    __pyx_L7:;
+
+    /* "bx/bbi/bbi_file.pyx":319
+ *                 ## block_data = zlib.decompress( block_data, buf_size = self.bbi_file.uncompress_buf_size )
+ *                 block_data = zlib.decompress( block_data )
+ *             block_size = len( block_data )             # <<<<<<<<<<<<<<
+ *             # The block should be a bunch of summaries.
+ *             assert block_size % summary_on_disk_size == 0
+ */
+    __pyx_t_14 = PyObject_Length(__pyx_v_block_data); if (unlikely(__pyx_t_14 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 319; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_9 = PyInt_FromSsize_t(__pyx_t_14); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 319; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_9);
+    __Pyx_XDECREF_SET(__pyx_v_block_size, __pyx_t_9);
+    __pyx_t_9 = 0;
+
+    /* "bx/bbi/bbi_file.pyx":321
+ *             block_size = len( block_data )
+ *             # The block should be a bunch of summaries.
+ *             assert block_size % summary_on_disk_size == 0             # <<<<<<<<<<<<<<
+ *             item_count = block_size / summary_on_disk_size
+ * 
+ */
+    #ifndef CYTHON_WITHOUT_ASSERTIONS
+    if (unlikely(!Py_OptimizeFlag)) {
+      __pyx_t_9 = PyNumber_Remainder(__pyx_v_block_size, __pyx_int_32); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 321; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_9);
+      __pyx_t_6 = PyObject_RichCompare(__pyx_t_9, __pyx_int_0, Py_EQ); __Pyx_XGOTREF(__pyx_t_6); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 321; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+      __pyx_t_13 = __Pyx_PyObject_IsTrue(__pyx_t_6); if (unlikely(__pyx_t_13 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 321; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+      if (unlikely(!__pyx_t_13)) {
+        PyErr_SetNone(PyExc_AssertionError);
+        {__pyx_filename = __pyx_f[0]; __pyx_lineno = 321; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      }
+    }
+    #endif
+
+    /* "bx/bbi/bbi_file.pyx":322
+ *             # The block should be a bunch of summaries.
+ *             assert block_size % summary_on_disk_size == 0
+ *             item_count = block_size / summary_on_disk_size             # <<<<<<<<<<<<<<
+ * 
+ *             arr = np.fromstring(block_data, sum_dtype, item_count)
+ */
+    __pyx_t_6 = __Pyx_PyNumber_Divide(__pyx_v_block_size, __pyx_int_32); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 322; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_6);
+    __Pyx_XDECREF_SET(__pyx_v_item_count, __pyx_t_6);
+    __pyx_t_6 = 0;
+
+    /* "bx/bbi/bbi_file.pyx":324
+ *             item_count = block_size / summary_on_disk_size
+ * 
+ *             arr = np.fromstring(block_data, sum_dtype, item_count)             # <<<<<<<<<<<<<<
+ *             # covert to dict to match old implementation:
+ *             d = [dict(zip(arr.dtype.names, x)) for x in arr]
+ */
+    __pyx_t_9 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 324; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_9);
+    __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_9, __pyx_n_s_fromstring); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 324; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+    __pyx_t_9 = NULL;
+    __pyx_t_14 = 0;
+    if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_3))) {
+      __pyx_t_9 = PyMethod_GET_SELF(__pyx_t_3);
+      if (likely(__pyx_t_9)) {
+        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+        __Pyx_INCREF(__pyx_t_9);
+        __Pyx_INCREF(function);
+        __Pyx_DECREF_SET(__pyx_t_3, function);
+        __pyx_t_14 = 1;
+      }
+    }
+    __pyx_t_5 = PyTuple_New(3+__pyx_t_14); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 324; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_5);
+    if (__pyx_t_9) {
+      PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_9); __Pyx_GIVEREF(__pyx_t_9); __pyx_t_9 = NULL;
+    }
+    __Pyx_INCREF(__pyx_v_block_data);
+    PyTuple_SET_ITEM(__pyx_t_5, 0+__pyx_t_14, __pyx_v_block_data);
+    __Pyx_GIVEREF(__pyx_v_block_data);
+    __Pyx_INCREF(__pyx_v_sum_dtype);
+    PyTuple_SET_ITEM(__pyx_t_5, 1+__pyx_t_14, __pyx_v_sum_dtype);
+    __Pyx_GIVEREF(__pyx_v_sum_dtype);
+    __Pyx_INCREF(__pyx_v_item_count);
+    PyTuple_SET_ITEM(__pyx_t_5, 2+__pyx_t_14, __pyx_v_item_count);
+    __Pyx_GIVEREF(__pyx_v_item_count);
+    __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_5, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 324; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_6);
+    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __Pyx_XDECREF_SET(__pyx_v_arr, __pyx_t_6);
+    __pyx_t_6 = 0;
+
+    /* "bx/bbi/bbi_file.pyx":326
+ *             arr = np.fromstring(block_data, sum_dtype, item_count)
+ *             # covert to dict to match old implementation:
+ *             d = [dict(zip(arr.dtype.names, x)) for x in arr]             # <<<<<<<<<<<<<<
+ *             rval.extend(d)
+ * 
+ */
+    __pyx_t_6 = PyList_New(0); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 326; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_6);
+    if (likely(PyList_CheckExact(__pyx_v_arr)) || PyTuple_CheckExact(__pyx_v_arr)) {
+      __pyx_t_3 = __pyx_v_arr; __Pyx_INCREF(__pyx_t_3); __pyx_t_14 = 0;
+      __pyx_t_15 = NULL;
+    } else {
+      __pyx_t_14 = -1; __pyx_t_3 = PyObject_GetIter(__pyx_v_arr); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 326; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_15 = Py_TYPE(__pyx_t_3)->tp_iternext; if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 326; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+    for (;;) {
+      if (likely(!__pyx_t_15)) {
+        if (likely(PyList_CheckExact(__pyx_t_3))) {
+          if (__pyx_t_14 >= PyList_GET_SIZE(__pyx_t_3)) break;
+          #if CYTHON_COMPILING_IN_CPYTHON
+          __pyx_t_5 = PyList_GET_ITEM(__pyx_t_3, __pyx_t_14); __Pyx_INCREF(__pyx_t_5); __pyx_t_14++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 326; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          #else
+          __pyx_t_5 = PySequence_ITEM(__pyx_t_3, __pyx_t_14); __pyx_t_14++; if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 326; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          #endif
+        } else {
+          if (__pyx_t_14 >= PyTuple_GET_SIZE(__pyx_t_3)) break;
+          #if CYTHON_COMPILING_IN_CPYTHON
+          __pyx_t_5 = PyTuple_GET_ITEM(__pyx_t_3, __pyx_t_14); __Pyx_INCREF(__pyx_t_5); __pyx_t_14++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 326; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          #else
+          __pyx_t_5 = PySequence_ITEM(__pyx_t_3, __pyx_t_14); __pyx_t_14++; if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 326; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          #endif
+        }
+      } else {
+        __pyx_t_5 = __pyx_t_15(__pyx_t_3);
+        if (unlikely(!__pyx_t_5)) {
+          PyObject* exc_type = PyErr_Occurred();
+          if (exc_type) {
+            if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+            else {__pyx_filename = __pyx_f[0]; __pyx_lineno = 326; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          }
+          break;
+        }
+        __Pyx_GOTREF(__pyx_t_5);
+      }
+      __Pyx_XDECREF_SET(__pyx_v_x, __pyx_t_5);
+      __pyx_t_5 = 0;
+      __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_arr, __pyx_n_s_dtype); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 326; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_5);
+      __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_names); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 326; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_9);
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 326; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_5);
+      PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_9);
+      __Pyx_GIVEREF(__pyx_t_9);
+      __Pyx_INCREF(__pyx_v_x);
+      PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_v_x);
+      __Pyx_GIVEREF(__pyx_v_x);
+      __pyx_t_9 = 0;
+      __pyx_t_9 = __Pyx_PyObject_Call(__pyx_builtin_zip, __pyx_t_5, NULL); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 326; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_9);
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 326; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_5);
+      PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_9);
+      __Pyx_GIVEREF(__pyx_t_9);
+      __pyx_t_9 = 0;
+      __pyx_t_9 = __Pyx_PyObject_Call(((PyObject *)((PyObject*)(&PyDict_Type))), __pyx_t_5, NULL); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 326; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_9);
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      if (unlikely(__Pyx_ListComp_Append(__pyx_t_6, (PyObject*)__pyx_t_9))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 326; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+    }
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __Pyx_XDECREF_SET(__pyx_v_d, ((PyObject*)__pyx_t_6));
+    __pyx_t_6 = 0;
+
+    /* "bx/bbi/bbi_file.pyx":327
+ *             # covert to dict to match old implementation:
+ *             d = [dict(zip(arr.dtype.names, x)) for x in arr]
+ *             rval.extend(d)             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_rval, __pyx_n_s_extend); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 327; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __pyx_t_9 = NULL;
+    if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_3))) {
+      __pyx_t_9 = PyMethod_GET_SELF(__pyx_t_3);
+      if (likely(__pyx_t_9)) {
+        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+        __Pyx_INCREF(__pyx_t_9);
+        __Pyx_INCREF(function);
+        __Pyx_DECREF_SET(__pyx_t_3, function);
+      }
+    }
+    if (!__pyx_t_9) {
+      __pyx_t_6 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_v_d); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 327; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_6);
+    } else {
+      __pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 327; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_5);
+      PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_9); __Pyx_GIVEREF(__pyx_t_9); __pyx_t_9 = NULL;
+      __Pyx_INCREF(__pyx_v_d);
+      PyTuple_SET_ITEM(__pyx_t_5, 0+1, __pyx_v_d);
+      __Pyx_GIVEREF(__pyx_v_d);
+      __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_5, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 327; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_6);
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+    }
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+
+    /* "bx/bbi/bbi_file.pyx":311
+ *                               ('sum_squares', np.float32)])
+ * 
+ *         for offset, size in block_list:             # <<<<<<<<<<<<<<
+ *             # Seek to and read all data for the block
+ *             reader.seek( offset )
+ */
+  }
+  __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+
+  /* "bx/bbi/bbi_file.pyx":355
+ * 
+ *             """
+ *         return rval             # <<<<<<<<<<<<<<
+ * 
+ *     cdef _get_summary_slice( self, bits32 base_start, bits32 base_end, summaries ):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __Pyx_INCREF(__pyx_v_rval);
+  __pyx_r = __pyx_v_rval;
+  goto __pyx_L0;
+
+  /* "bx/bbi/bbi_file.pyx":289
+ *     cdef int item_count
+ * 
+ *     def _summary_blocks_in_region( self, bits32 chrom_id, bits32 start, bits32 end ):             # <<<<<<<<<<<<<<
+ *         """
+ *         Return a list of all SummaryBlocks that overlap the region
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_XDECREF(__pyx_t_5);
+  __Pyx_XDECREF(__pyx_t_6);
+  __Pyx_XDECREF(__pyx_t_8);
+  __Pyx_XDECREF(__pyx_t_9);
+  __Pyx_XDECREF(__pyx_t_10);
+  __Pyx_AddTraceback("bx.bbi.bbi_file.ZoomLevel._summary_blocks_in_region", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XDECREF((PyObject *)__pyx_v_ctf);
+  __Pyx_XDECREF(__pyx_v_rval);
+  __Pyx_XDECREF(__pyx_v_reader);
+  __Pyx_XDECREF(__pyx_v_block_list);
+  __Pyx_XDECREF(__pyx_v_sum_dtype);
+  __Pyx_XDECREF(__pyx_v_offset);
+  __Pyx_XDECREF(__pyx_v_size);
+  __Pyx_XDECREF(__pyx_v_block_data);
+  __Pyx_XDECREF(__pyx_v_block_size);
+  __Pyx_XDECREF(__pyx_v_item_count);
+  __Pyx_XDECREF(__pyx_v_arr);
+  __Pyx_XDECREF(__pyx_v_d);
+  __Pyx_XDECREF(__pyx_v_x);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bbi/bbi_file.pyx":357
+ *         return rval
+ * 
+ *     cdef _get_summary_slice( self, bits32 base_start, bits32 base_end, summaries ):             # <<<<<<<<<<<<<<
+ *         cdef float valid_count = 0.0
+ *         cdef float sum_data = 0.0
+ */
+
+static PyObject *__pyx_f_2bx_3bbi_8bbi_file_9ZoomLevel__get_summary_slice(CYTHON_UNUSED struct __pyx_obj_2bx_3bbi_8bbi_file_ZoomLevel *__pyx_v_self, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_base_start, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_base_end, PyObject *__pyx_v_summaries) {
+  float __pyx_v_valid_count;
+  float __pyx_v_sum_data;
+  float __pyx_v_sum_squares;
+  float __pyx_v_min_val;
+  float __pyx_v_max_val;
+  float __pyx_v_overlap_factor;
+  int __pyx_v_overlap;
+  PyObject *__pyx_v_summary = NULL;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  float __pyx_t_3;
+  int __pyx_t_4;
+  Py_ssize_t __pyx_t_5;
+  PyObject *(*__pyx_t_6)(PyObject *);
+  PyObject *__pyx_t_7 = NULL;
+  PyObject *__pyx_t_8 = NULL;
+  int __pyx_t_9;
+  int __pyx_t_10;
+  PyObject *__pyx_t_11 = NULL;
+  PyObject *__pyx_t_12 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("_get_summary_slice", 0);
+
+  /* "bx/bbi/bbi_file.pyx":358
+ * 
+ *     cdef _get_summary_slice( self, bits32 base_start, bits32 base_end, summaries ):
+ *         cdef float valid_count = 0.0             # <<<<<<<<<<<<<<
+ *         cdef float sum_data = 0.0
+ *         cdef float sum_squares = 0.0
+ */
+  __pyx_v_valid_count = 0.0;
+
+  /* "bx/bbi/bbi_file.pyx":359
+ *     cdef _get_summary_slice( self, bits32 base_start, bits32 base_end, summaries ):
+ *         cdef float valid_count = 0.0
+ *         cdef float sum_data = 0.0             # <<<<<<<<<<<<<<
+ *         cdef float sum_squares = 0.0
+ *         cdef float min_val = numpy.nan
+ */
+  __pyx_v_sum_data = 0.0;
+
+  /* "bx/bbi/bbi_file.pyx":360
+ *         cdef float valid_count = 0.0
+ *         cdef float sum_data = 0.0
+ *         cdef float sum_squares = 0.0             # <<<<<<<<<<<<<<
+ *         cdef float min_val = numpy.nan
+ *         cdef float max_val = numpy.nan
+ */
+  __pyx_v_sum_squares = 0.0;
+
+  /* "bx/bbi/bbi_file.pyx":361
+ *         cdef float sum_data = 0.0
+ *         cdef float sum_squares = 0.0
+ *         cdef float min_val = numpy.nan             # <<<<<<<<<<<<<<
+ *         cdef float max_val = numpy.nan
+ *         cdef float overlap_factor
+ */
+  __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 361; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_nan); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 361; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_3 = __pyx_PyFloat_AsFloat(__pyx_t_2); if (unlikely((__pyx_t_3 == (float)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 361; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_v_min_val = __pyx_t_3;
+
+  /* "bx/bbi/bbi_file.pyx":362
+ *         cdef float sum_squares = 0.0
+ *         cdef float min_val = numpy.nan
+ *         cdef float max_val = numpy.nan             # <<<<<<<<<<<<<<
+ *         cdef float overlap_factor
+ *         cdef int overlap
+ */
+  __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 362; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_nan); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 362; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_3 = __pyx_PyFloat_AsFloat(__pyx_t_1); if (unlikely((__pyx_t_3 == (float)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 362; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_v_max_val = __pyx_t_3;
+
+  /* "bx/bbi/bbi_file.pyx":366
+ *         cdef int overlap
+ * 
+ *         if summaries:             # <<<<<<<<<<<<<<
+ * 
+ *             # TODO: if we keep this a an array from summary_blocks in region,
+ */
+  __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_v_summaries); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 366; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (__pyx_t_4) {
+
+    /* "bx/bbi/bbi_file.pyx":370
+ *             # TODO: if we keep this a an array from summary_blocks in region,
+ *             # this will be much faster.
+ *             min_val = summaries[0]['min_val']             # <<<<<<<<<<<<<<
+ *             max_val = summaries[0]['max_val']
+ * 
+ */
+    __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_summaries, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_1 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 370; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+    __Pyx_GOTREF(__pyx_t_1);
+    __pyx_t_2 = PyObject_GetItem(__pyx_t_1, __pyx_n_s_min_val); if (unlikely(__pyx_t_2 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 370; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+    __Pyx_GOTREF(__pyx_t_2);
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    __pyx_t_3 = __pyx_PyFloat_AsFloat(__pyx_t_2); if (unlikely((__pyx_t_3 == (float)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 370; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    __pyx_v_min_val = __pyx_t_3;
+
+    /* "bx/bbi/bbi_file.pyx":371
+ *             # this will be much faster.
+ *             min_val = summaries[0]['min_val']
+ *             max_val = summaries[0]['max_val']             # <<<<<<<<<<<<<<
+ * 
+ *             for summary in summaries:
+ */
+    __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_summaries, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_2 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 371; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_t_1 = PyObject_GetItem(__pyx_t_2, __pyx_n_s_max_val); if (unlikely(__pyx_t_1 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 371; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+    __Pyx_GOTREF(__pyx_t_1);
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    __pyx_t_3 = __pyx_PyFloat_AsFloat(__pyx_t_1); if (unlikely((__pyx_t_3 == (float)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 371; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    __pyx_v_max_val = __pyx_t_3;
+
+    /* "bx/bbi/bbi_file.pyx":373
+ *             max_val = summaries[0]['max_val']
+ * 
+ *             for summary in summaries:             # <<<<<<<<<<<<<<
+ *                 if summary['start'] >= base_end:
+ *                     break
+ */
+    if (likely(PyList_CheckExact(__pyx_v_summaries)) || PyTuple_CheckExact(__pyx_v_summaries)) {
+      __pyx_t_1 = __pyx_v_summaries; __Pyx_INCREF(__pyx_t_1); __pyx_t_5 = 0;
+      __pyx_t_6 = NULL;
+    } else {
+      __pyx_t_5 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_summaries); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 373; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_1);
+      __pyx_t_6 = Py_TYPE(__pyx_t_1)->tp_iternext; if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 373; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+    for (;;) {
+      if (likely(!__pyx_t_6)) {
+        if (likely(PyList_CheckExact(__pyx_t_1))) {
+          if (__pyx_t_5 >= PyList_GET_SIZE(__pyx_t_1)) break;
+          #if CYTHON_COMPILING_IN_CPYTHON
+          __pyx_t_2 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_5); __Pyx_INCREF(__pyx_t_2); __pyx_t_5++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 373; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          #else
+          __pyx_t_2 = PySequence_ITEM(__pyx_t_1, __pyx_t_5); __pyx_t_5++; if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 373; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          #endif
+        } else {
+          if (__pyx_t_5 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
+          #if CYTHON_COMPILING_IN_CPYTHON
+          __pyx_t_2 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_5); __Pyx_INCREF(__pyx_t_2); __pyx_t_5++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 373; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          #else
+          __pyx_t_2 = PySequence_ITEM(__pyx_t_1, __pyx_t_5); __pyx_t_5++; if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 373; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          #endif
+        }
+      } else {
+        __pyx_t_2 = __pyx_t_6(__pyx_t_1);
+        if (unlikely(!__pyx_t_2)) {
+          PyObject* exc_type = PyErr_Occurred();
+          if (exc_type) {
+            if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+            else {__pyx_filename = __pyx_f[0]; __pyx_lineno = 373; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          }
+          break;
+        }
+        __Pyx_GOTREF(__pyx_t_2);
+      }
+      __Pyx_XDECREF_SET(__pyx_v_summary, __pyx_t_2);
+      __pyx_t_2 = 0;
+
+      /* "bx/bbi/bbi_file.pyx":374
+ * 
+ *             for summary in summaries:
+ *                 if summary['start'] >= base_end:             # <<<<<<<<<<<<<<
+ *                     break
+ * 
+ */
+      __pyx_t_2 = PyObject_GetItem(__pyx_v_summary, __pyx_n_s_start); if (unlikely(__pyx_t_2 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 374; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+      __Pyx_GOTREF(__pyx_t_2);
+      __pyx_t_7 = __Pyx_PyInt_From_unsigned_int(__pyx_v_base_end); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 374; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_7);
+      __pyx_t_8 = PyObject_RichCompare(__pyx_t_2, __pyx_t_7, Py_GE); __Pyx_XGOTREF(__pyx_t_8); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 374; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+      __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_8); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 374; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+      if (__pyx_t_4) {
+
+        /* "bx/bbi/bbi_file.pyx":375
+ *             for summary in summaries:
+ *                 if summary['start'] >= base_end:
+ *                     break             # <<<<<<<<<<<<<<
+ * 
+ *                 overlap = range_intersection( base_start, base_end, summary['start'], summary['end'] )
+ */
+        goto __pyx_L5_break;
+      }
+
+      /* "bx/bbi/bbi_file.pyx":377
+ *                     break
+ * 
+ *                 overlap = range_intersection( base_start, base_end, summary['start'], summary['end'] )             # <<<<<<<<<<<<<<
+ *                 if overlap > 0:
+ *                     overlap_factor = <double> overlap / (summary['end'] - summary['start'])
+ */
+      __pyx_t_8 = PyObject_GetItem(__pyx_v_summary, __pyx_n_s_start); if (unlikely(__pyx_t_8 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 377; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+      __Pyx_GOTREF(__pyx_t_8);
+      __pyx_t_9 = __Pyx_PyInt_As_int(__pyx_t_8); if (unlikely((__pyx_t_9 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 377; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+      __pyx_t_8 = PyObject_GetItem(__pyx_v_summary, __pyx_n_s_end); if (unlikely(__pyx_t_8 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 377; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+      __Pyx_GOTREF(__pyx_t_8);
+      __pyx_t_10 = __Pyx_PyInt_As_int(__pyx_t_8); if (unlikely((__pyx_t_10 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 377; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+      __pyx_v_overlap = __pyx_f_2bx_3bbi_8bbi_file_range_intersection(__pyx_v_base_start, __pyx_v_base_end, __pyx_t_9, __pyx_t_10);
+
+      /* "bx/bbi/bbi_file.pyx":378
+ * 
+ *                 overlap = range_intersection( base_start, base_end, summary['start'], summary['end'] )
+ *                 if overlap > 0:             # <<<<<<<<<<<<<<
+ *                     overlap_factor = <double> overlap / (summary['end'] - summary['start'])
+ * 
+ */
+      __pyx_t_4 = ((__pyx_v_overlap > 0) != 0);
+      if (__pyx_t_4) {
+
+        /* "bx/bbi/bbi_file.pyx":379
+ *                 overlap = range_intersection( base_start, base_end, summary['start'], summary['end'] )
+ *                 if overlap > 0:
+ *                     overlap_factor = <double> overlap / (summary['end'] - summary['start'])             # <<<<<<<<<<<<<<
+ * 
+ *                     valid_count += summary['valid_count'] * overlap_factor
+ */
+        __pyx_t_8 = PyFloat_FromDouble(((double)__pyx_v_overlap)); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 379; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_8);
+        __pyx_t_7 = PyObject_GetItem(__pyx_v_summary, __pyx_n_s_end); if (unlikely(__pyx_t_7 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 379; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+        __Pyx_GOTREF(__pyx_t_7);
+        __pyx_t_2 = PyObject_GetItem(__pyx_v_summary, __pyx_n_s_start); if (unlikely(__pyx_t_2 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 379; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+        __Pyx_GOTREF(__pyx_t_2);
+        __pyx_t_11 = PyNumber_Subtract(__pyx_t_7, __pyx_t_2); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 379; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_11);
+        __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+        __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+        __pyx_t_2 = __Pyx_PyNumber_Divide(__pyx_t_8, __pyx_t_11); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 379; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_2);
+        __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+        __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+        __pyx_t_3 = __pyx_PyFloat_AsFloat(__pyx_t_2); if (unlikely((__pyx_t_3 == (float)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 379; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+        __pyx_v_overlap_factor = __pyx_t_3;
+
+        /* "bx/bbi/bbi_file.pyx":381
+ *                     overlap_factor = <double> overlap / (summary['end'] - summary['start'])
+ * 
+ *                     valid_count += summary['valid_count'] * overlap_factor             # <<<<<<<<<<<<<<
+ *                     sum_data += summary['sum_data'] * overlap_factor
+ *                     sum_squares += summary['sum_squares'] * overlap_factor
+ */
+        __pyx_t_2 = PyFloat_FromDouble(__pyx_v_valid_count); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 381; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_2);
+        __pyx_t_11 = PyObject_GetItem(__pyx_v_summary, __pyx_n_s_valid_count); if (unlikely(__pyx_t_11 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 381; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+        __Pyx_GOTREF(__pyx_t_11);
+        __pyx_t_8 = PyFloat_FromDouble(__pyx_v_overlap_factor); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 381; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_8);
+        __pyx_t_7 = PyNumber_Multiply(__pyx_t_11, __pyx_t_8); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 381; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_7);
+        __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+        __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+        __pyx_t_8 = PyNumber_InPlaceAdd(__pyx_t_2, __pyx_t_7); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 381; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_8);
+        __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+        __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+        __pyx_t_3 = __pyx_PyFloat_AsFloat(__pyx_t_8); if (unlikely((__pyx_t_3 == (float)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 381; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+        __pyx_v_valid_count = __pyx_t_3;
+
+        /* "bx/bbi/bbi_file.pyx":382
+ * 
+ *                     valid_count += summary['valid_count'] * overlap_factor
+ *                     sum_data += summary['sum_data'] * overlap_factor             # <<<<<<<<<<<<<<
+ *                     sum_squares += summary['sum_squares'] * overlap_factor
+ * 
+ */
+        __pyx_t_8 = PyFloat_FromDouble(__pyx_v_sum_data); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 382; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_8);
+        __pyx_t_7 = PyObject_GetItem(__pyx_v_summary, __pyx_n_s_sum_data); if (unlikely(__pyx_t_7 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 382; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+        __Pyx_GOTREF(__pyx_t_7);
+        __pyx_t_2 = PyFloat_FromDouble(__pyx_v_overlap_factor); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 382; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_2);
+        __pyx_t_11 = PyNumber_Multiply(__pyx_t_7, __pyx_t_2); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 382; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_11);
+        __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+        __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+        __pyx_t_2 = PyNumber_InPlaceAdd(__pyx_t_8, __pyx_t_11); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 382; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_2);
+        __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+        __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+        __pyx_t_3 = __pyx_PyFloat_AsFloat(__pyx_t_2); if (unlikely((__pyx_t_3 == (float)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 382; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+        __pyx_v_sum_data = __pyx_t_3;
+
+        /* "bx/bbi/bbi_file.pyx":383
+ *                     valid_count += summary['valid_count'] * overlap_factor
+ *                     sum_data += summary['sum_data'] * overlap_factor
+ *                     sum_squares += summary['sum_squares'] * overlap_factor             # <<<<<<<<<<<<<<
+ * 
+ *                     if max_val < summary['max_val']:
+ */
+        __pyx_t_2 = PyFloat_FromDouble(__pyx_v_sum_squares); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 383; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_2);
+        __pyx_t_11 = PyObject_GetItem(__pyx_v_summary, __pyx_n_s_sum_squares); if (unlikely(__pyx_t_11 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 383; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+        __Pyx_GOTREF(__pyx_t_11);
+        __pyx_t_8 = PyFloat_FromDouble(__pyx_v_overlap_factor); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 383; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_8);
+        __pyx_t_7 = PyNumber_Multiply(__pyx_t_11, __pyx_t_8); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 383; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_7);
+        __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+        __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+        __pyx_t_8 = PyNumber_InPlaceAdd(__pyx_t_2, __pyx_t_7); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 383; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_8);
+        __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+        __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+        __pyx_t_3 = __pyx_PyFloat_AsFloat(__pyx_t_8); if (unlikely((__pyx_t_3 == (float)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 383; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+        __pyx_v_sum_squares = __pyx_t_3;
+
+        /* "bx/bbi/bbi_file.pyx":385
+ *                     sum_squares += summary['sum_squares'] * overlap_factor
+ * 
+ *                     if max_val < summary['max_val']:             # <<<<<<<<<<<<<<
+ *                         max_val = summary['max_val']
+ *                     if min_val > summary['min_val']:
+ */
+        __pyx_t_8 = PyFloat_FromDouble(__pyx_v_max_val); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 385; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_8);
+        __pyx_t_7 = PyObject_GetItem(__pyx_v_summary, __pyx_n_s_max_val); if (unlikely(__pyx_t_7 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 385; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+        __Pyx_GOTREF(__pyx_t_7);
+        __pyx_t_2 = PyObject_RichCompare(__pyx_t_8, __pyx_t_7, Py_LT); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 385; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+        __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+        __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 385; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+        if (__pyx_t_4) {
+
+          /* "bx/bbi/bbi_file.pyx":386
+ * 
+ *                     if max_val < summary['max_val']:
+ *                         max_val = summary['max_val']             # <<<<<<<<<<<<<<
+ *                     if min_val > summary['min_val']:
+ *                         min_val = summary['min_val']
+ */
+          __pyx_t_2 = PyObject_GetItem(__pyx_v_summary, __pyx_n_s_max_val); if (unlikely(__pyx_t_2 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 386; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+          __Pyx_GOTREF(__pyx_t_2);
+          __pyx_t_3 = __pyx_PyFloat_AsFloat(__pyx_t_2); if (unlikely((__pyx_t_3 == (float)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 386; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+          __pyx_v_max_val = __pyx_t_3;
+          goto __pyx_L8;
+        }
+        __pyx_L8:;
+
+        /* "bx/bbi/bbi_file.pyx":387
+ *                     if max_val < summary['max_val']:
+ *                         max_val = summary['max_val']
+ *                     if min_val > summary['min_val']:             # <<<<<<<<<<<<<<
+ *                         min_val = summary['min_val']
+ * 
+ */
+        __pyx_t_2 = PyFloat_FromDouble(__pyx_v_min_val); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 387; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_2);
+        __pyx_t_7 = PyObject_GetItem(__pyx_v_summary, __pyx_n_s_min_val); if (unlikely(__pyx_t_7 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 387; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+        __Pyx_GOTREF(__pyx_t_7);
+        __pyx_t_8 = PyObject_RichCompare(__pyx_t_2, __pyx_t_7, Py_GT); __Pyx_XGOTREF(__pyx_t_8); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 387; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+        __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+        __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_8); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 387; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+        if (__pyx_t_4) {
+
+          /* "bx/bbi/bbi_file.pyx":388
+ *                         max_val = summary['max_val']
+ *                     if min_val > summary['min_val']:
+ *                         min_val = summary['min_val']             # <<<<<<<<<<<<<<
+ * 
+ *         return valid_count, sum_data, sum_squares, min_val, max_val
+ */
+          __pyx_t_8 = PyObject_GetItem(__pyx_v_summary, __pyx_n_s_min_val); if (unlikely(__pyx_t_8 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 388; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+          __Pyx_GOTREF(__pyx_t_8);
+          __pyx_t_3 = __pyx_PyFloat_AsFloat(__pyx_t_8); if (unlikely((__pyx_t_3 == (float)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 388; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+          __pyx_v_min_val = __pyx_t_3;
+          goto __pyx_L9;
+        }
+        __pyx_L9:;
+        goto __pyx_L7;
+      }
+      __pyx_L7:;
+
+      /* "bx/bbi/bbi_file.pyx":373
+ *             max_val = summaries[0]['max_val']
+ * 
+ *             for summary in summaries:             # <<<<<<<<<<<<<<
+ *                 if summary['start'] >= base_end:
+ *                     break
+ */
+    }
+    __pyx_L5_break:;
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  /* "bx/bbi/bbi_file.pyx":390
+ *                         min_val = summary['min_val']
+ * 
+ *         return valid_count, sum_data, sum_squares, min_val, max_val             # <<<<<<<<<<<<<<
+ * 
+ *     cdef _summarize( self, bits32 chrom_id, bits32 start, bits32 end, int summary_size ):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = PyFloat_FromDouble(__pyx_v_valid_count); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 390; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_8 = PyFloat_FromDouble(__pyx_v_sum_data); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 390; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_8);
+  __pyx_t_7 = PyFloat_FromDouble(__pyx_v_sum_squares); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 390; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_7);
+  __pyx_t_2 = PyFloat_FromDouble(__pyx_v_min_val); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 390; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_11 = PyFloat_FromDouble(__pyx_v_max_val); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 390; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_11);
+  __pyx_t_12 = PyTuple_New(5); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 390; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_12);
+  PyTuple_SET_ITEM(__pyx_t_12, 0, __pyx_t_1);
+  __Pyx_GIVEREF(__pyx_t_1);
+  PyTuple_SET_ITEM(__pyx_t_12, 1, __pyx_t_8);
+  __Pyx_GIVEREF(__pyx_t_8);
+  PyTuple_SET_ITEM(__pyx_t_12, 2, __pyx_t_7);
+  __Pyx_GIVEREF(__pyx_t_7);
+  PyTuple_SET_ITEM(__pyx_t_12, 3, __pyx_t_2);
+  __Pyx_GIVEREF(__pyx_t_2);
+  PyTuple_SET_ITEM(__pyx_t_12, 4, __pyx_t_11);
+  __Pyx_GIVEREF(__pyx_t_11);
+  __pyx_t_1 = 0;
+  __pyx_t_8 = 0;
+  __pyx_t_7 = 0;
+  __pyx_t_2 = 0;
+  __pyx_t_11 = 0;
+  __pyx_r = __pyx_t_12;
+  __pyx_t_12 = 0;
+  goto __pyx_L0;
+
+  /* "bx/bbi/bbi_file.pyx":357
+ *         return rval
+ * 
+ *     cdef _get_summary_slice( self, bits32 base_start, bits32 base_end, summaries ):             # <<<<<<<<<<<<<<
+ *         cdef float valid_count = 0.0
+ *         cdef float sum_data = 0.0
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_7);
+  __Pyx_XDECREF(__pyx_t_8);
+  __Pyx_XDECREF(__pyx_t_11);
+  __Pyx_XDECREF(__pyx_t_12);
+  __Pyx_AddTraceback("bx.bbi.bbi_file.ZoomLevel._get_summary_slice", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_summary);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bbi/bbi_file.pyx":392
+ *         return valid_count, sum_data, sum_squares, min_val, max_val
+ * 
+ *     cdef _summarize( self, bits32 chrom_id, bits32 start, bits32 end, int summary_size ):             # <<<<<<<<<<<<<<
+ *         return SummarizedData( start, end, summary_size )
+ */
+
+static PyObject *__pyx_f_2bx_3bbi_8bbi_file_9ZoomLevel__summarize(CYTHON_UNUSED struct __pyx_obj_2bx_3bbi_8bbi_file_ZoomLevel *__pyx_v_self, CYTHON_UNUSED __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_chrom_id, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_start, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_end, int __pyx_v_summary_size) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("_summarize", 0);
+
+  /* "bx/bbi/bbi_file.pyx":393
+ * 
+ *     cdef _summarize( self, bits32 chrom_id, bits32 start, bits32 end, int summary_size ):
+ *         return SummarizedData( start, end, summary_size )             # <<<<<<<<<<<<<<
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = __Pyx_PyInt_From_unsigned_int(__pyx_v_start); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 393; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = __Pyx_PyInt_From_unsigned_int(__pyx_v_end); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 393; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_summary_size); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 393; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_4 = PyTuple_New(3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 393; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_1);
+  __Pyx_GIVEREF(__pyx_t_1);
+  PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_2);
+  __Pyx_GIVEREF(__pyx_t_2);
+  PyTuple_SET_ITEM(__pyx_t_4, 2, __pyx_t_3);
+  __Pyx_GIVEREF(__pyx_t_3);
+  __pyx_t_1 = 0;
+  __pyx_t_2 = 0;
+  __pyx_t_3 = 0;
+  __pyx_t_3 = __Pyx_PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_2bx_3bbi_8bbi_file_SummarizedData)), __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 393; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  __pyx_r = __pyx_t_3;
+  __pyx_t_3 = 0;
+  goto __pyx_L0;
+
+  /* "bx/bbi/bbi_file.pyx":392
+ *         return valid_count, sum_data, sum_squares, min_val, max_val
+ * 
+ *     cdef _summarize( self, bits32 chrom_id, bits32 start, bits32 end, int summary_size ):             # <<<<<<<<<<<<<<
+ *         return SummarizedData( start, end, summary_size )
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_AddTraceback("bx.bbi.bbi_file.ZoomLevel._summarize", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bbi/bbi_file.pyx":283
+ * cdef class ZoomLevel:
+ *     cdef BBIFile bbi_file
+ *     cdef public bits32 reduction_level             # <<<<<<<<<<<<<<
+ *     cdef bits32 reserved
+ *     cdef public bits64 data_offset
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_3bbi_8bbi_file_9ZoomLevel_15reduction_level_1__get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_2bx_3bbi_8bbi_file_9ZoomLevel_15reduction_level_1__get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_3bbi_8bbi_file_9ZoomLevel_15reduction_level___get__(((struct __pyx_obj_2bx_3bbi_8bbi_file_ZoomLevel *)__pyx_v_self));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_2bx_3bbi_8bbi_file_9ZoomLevel_15reduction_level___get__(struct __pyx_obj_2bx_3bbi_8bbi_file_ZoomLevel *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__get__", 0);
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = __Pyx_PyInt_From_unsigned_int(__pyx_v_self->reduction_level); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 283; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("bx.bbi.bbi_file.ZoomLevel.reduction_level.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_2bx_3bbi_8bbi_file_9ZoomLevel_15reduction_level_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value); /*proto*/
+static int __pyx_pw_2bx_3bbi_8bbi_file_9ZoomLevel_15reduction_level_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__set__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_3bbi_8bbi_file_9ZoomLevel_15reduction_level_2__set__(((struct __pyx_obj_2bx_3bbi_8bbi_file_ZoomLevel *)__pyx_v_self), ((PyObject *)__pyx_v_value));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_2bx_3bbi_8bbi_file_9ZoomLevel_15reduction_level_2__set__(struct __pyx_obj_2bx_3bbi_8bbi_file_ZoomLevel *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __pyx_t_2bx_3bbi_5types_bits32 __pyx_t_1;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__set__", 0);
+  __pyx_t_1 = __Pyx_PyInt_As_unsigned_int(__pyx_v_value); if (unlikely((__pyx_t_1 == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 283; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_v_self->reduction_level = __pyx_t_1;
+
+  /* function exit code */
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_AddTraceback("bx.bbi.bbi_file.ZoomLevel.reduction_level.__set__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = -1;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bbi/bbi_file.pyx":285
+ *     cdef public bits32 reduction_level
+ *     cdef bits32 reserved
+ *     cdef public bits64 data_offset             # <<<<<<<<<<<<<<
+ *     cdef public bits64 index_offset
+ *     cdef int item_count
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_3bbi_8bbi_file_9ZoomLevel_11data_offset_1__get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_2bx_3bbi_8bbi_file_9ZoomLevel_11data_offset_1__get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_3bbi_8bbi_file_9ZoomLevel_11data_offset___get__(((struct __pyx_obj_2bx_3bbi_8bbi_file_ZoomLevel *)__pyx_v_self));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_2bx_3bbi_8bbi_file_9ZoomLevel_11data_offset___get__(struct __pyx_obj_2bx_3bbi_8bbi_file_ZoomLevel *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__get__", 0);
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = __Pyx_PyInt_From_unsigned_PY_LONG_LONG(__pyx_v_self->data_offset); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 285; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("bx.bbi.bbi_file.ZoomLevel.data_offset.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_2bx_3bbi_8bbi_file_9ZoomLevel_11data_offset_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value); /*proto*/
+static int __pyx_pw_2bx_3bbi_8bbi_file_9ZoomLevel_11data_offset_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__set__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_3bbi_8bbi_file_9ZoomLevel_11data_offset_2__set__(((struct __pyx_obj_2bx_3bbi_8bbi_file_ZoomLevel *)__pyx_v_self), ((PyObject *)__pyx_v_value));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_2bx_3bbi_8bbi_file_9ZoomLevel_11data_offset_2__set__(struct __pyx_obj_2bx_3bbi_8bbi_file_ZoomLevel *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __pyx_t_2bx_3bbi_5types_bits64 __pyx_t_1;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__set__", 0);
+  __pyx_t_1 = __Pyx_PyInt_As_unsigned_PY_LONG_LONG(__pyx_v_value); if (unlikely((__pyx_t_1 == (unsigned PY_LONG_LONG)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 285; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_v_self->data_offset = __pyx_t_1;
+
+  /* function exit code */
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_AddTraceback("bx.bbi.bbi_file.ZoomLevel.data_offset.__set__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = -1;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bbi/bbi_file.pyx":286
+ *     cdef bits32 reserved
+ *     cdef public bits64 data_offset
+ *     cdef public bits64 index_offset             # <<<<<<<<<<<<<<
+ *     cdef int item_count
+ * 
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_3bbi_8bbi_file_9ZoomLevel_12index_offset_1__get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_2bx_3bbi_8bbi_file_9ZoomLevel_12index_offset_1__get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_3bbi_8bbi_file_9ZoomLevel_12index_offset___get__(((struct __pyx_obj_2bx_3bbi_8bbi_file_ZoomLevel *)__pyx_v_self));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_2bx_3bbi_8bbi_file_9ZoomLevel_12index_offset___get__(struct __pyx_obj_2bx_3bbi_8bbi_file_ZoomLevel *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__get__", 0);
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = __Pyx_PyInt_From_unsigned_PY_LONG_LONG(__pyx_v_self->index_offset); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 286; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("bx.bbi.bbi_file.ZoomLevel.index_offset.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_2bx_3bbi_8bbi_file_9ZoomLevel_12index_offset_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value); /*proto*/
+static int __pyx_pw_2bx_3bbi_8bbi_file_9ZoomLevel_12index_offset_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__set__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_3bbi_8bbi_file_9ZoomLevel_12index_offset_2__set__(((struct __pyx_obj_2bx_3bbi_8bbi_file_ZoomLevel *)__pyx_v_self), ((PyObject *)__pyx_v_value));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_2bx_3bbi_8bbi_file_9ZoomLevel_12index_offset_2__set__(struct __pyx_obj_2bx_3bbi_8bbi_file_ZoomLevel *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __pyx_t_2bx_3bbi_5types_bits64 __pyx_t_1;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__set__", 0);
+  __pyx_t_1 = __Pyx_PyInt_As_unsigned_PY_LONG_LONG(__pyx_v_value); if (unlikely((__pyx_t_1 == (unsigned PY_LONG_LONG)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 286; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_v_self->index_offset = __pyx_t_1;
+
+  /* function exit code */
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_AddTraceback("bx.bbi.bbi_file.ZoomLevel.index_offset.__set__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = -1;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":197
+ *         # experimental exception made for __getbuffer__ and __releasebuffer__
+ *         # -- the details of this may change.
+ *         def __getbuffer__(ndarray self, Py_buffer* info, int flags):             # <<<<<<<<<<<<<<
+ *             # This implementation of getbuffer is geared towards Cython
+ *             # requirements, and does not yet fullfill the PEP.
+ */
+
+/* Python wrapper */
+static CYTHON_UNUSED int __pyx_pw_5numpy_7ndarray_1__getbuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /*proto*/
+static CYTHON_UNUSED int __pyx_pw_5numpy_7ndarray_1__getbuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__getbuffer__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_5numpy_7ndarray___getbuffer__(((PyArrayObject *)__pyx_v_self), ((Py_buffer *)__pyx_v_info), ((int)__pyx_v_flags));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) {
+  int __pyx_v_copy_shape;
+  int __pyx_v_i;
+  int __pyx_v_ndim;
+  int __pyx_v_endian_detector;
+  int __pyx_v_little_endian;
+  int __pyx_v_t;
+  char *__pyx_v_f;
+  PyArray_Descr *__pyx_v_descr = 0;
+  int __pyx_v_offset;
+  int __pyx_v_hasfields;
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  int __pyx_t_2;
+  PyObject *__pyx_t_3 = NULL;
+  int __pyx_t_4;
+  int __pyx_t_5;
+  PyObject *__pyx_t_6 = NULL;
+  char *__pyx_t_7;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__getbuffer__", 0);
+  if (__pyx_v_info != NULL) {
+    __pyx_v_info->obj = Py_None; __Pyx_INCREF(Py_None);
+    __Pyx_GIVEREF(__pyx_v_info->obj);
+  }
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":203
+ *             # of flags
+ * 
+ *             if info == NULL: return             # <<<<<<<<<<<<<<
+ * 
+ *             cdef int copy_shape, i, ndim
+ */
+  __pyx_t_1 = ((__pyx_v_info == NULL) != 0);
+  if (__pyx_t_1) {
+    __pyx_r = 0;
+    goto __pyx_L0;
+  }
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":206
+ * 
+ *             cdef int copy_shape, i, ndim
+ *             cdef int endian_detector = 1             # <<<<<<<<<<<<<<
+ *             cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)
+ * 
+ */
+  __pyx_v_endian_detector = 1;
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":207
+ *             cdef int copy_shape, i, ndim
+ *             cdef int endian_detector = 1
+ *             cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)             # <<<<<<<<<<<<<<
+ * 
+ *             ndim = PyArray_NDIM(self)
+ */
+  __pyx_v_little_endian = ((((char *)(&__pyx_v_endian_detector))[0]) != 0);
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":209
+ *             cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)
+ * 
+ *             ndim = PyArray_NDIM(self)             # <<<<<<<<<<<<<<
+ * 
+ *             if sizeof(npy_intp) != sizeof(Py_ssize_t):
+ */
+  __pyx_v_ndim = PyArray_NDIM(__pyx_v_self);
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":211
+ *             ndim = PyArray_NDIM(self)
+ * 
+ *             if sizeof(npy_intp) != sizeof(Py_ssize_t):             # <<<<<<<<<<<<<<
+ *                 copy_shape = 1
+ *             else:
+ */
+  __pyx_t_1 = (((sizeof(npy_intp)) != (sizeof(Py_ssize_t))) != 0);
+  if (__pyx_t_1) {
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":212
+ * 
+ *             if sizeof(npy_intp) != sizeof(Py_ssize_t):
+ *                 copy_shape = 1             # <<<<<<<<<<<<<<
+ *             else:
+ *                 copy_shape = 0
+ */
+    __pyx_v_copy_shape = 1;
+    goto __pyx_L4;
+  }
+  /*else*/ {
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":214
+ *                 copy_shape = 1
+ *             else:
+ *                 copy_shape = 0             # <<<<<<<<<<<<<<
+ * 
+ *             if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)
+ */
+    __pyx_v_copy_shape = 0;
+  }
+  __pyx_L4:;
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":216
+ *                 copy_shape = 0
+ * 
+ *             if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)             # <<<<<<<<<<<<<<
+ *                 and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)):
+ *                 raise ValueError(u"ndarray is not C contiguous")
+ */
+  __pyx_t_2 = (((__pyx_v_flags & PyBUF_C_CONTIGUOUS) == PyBUF_C_CONTIGUOUS) != 0);
+  if (__pyx_t_2) {
+  } else {
+    __pyx_t_1 = __pyx_t_2;
+    goto __pyx_L6_bool_binop_done;
+  }
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":217
+ * 
+ *             if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)
+ *                 and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)):             # <<<<<<<<<<<<<<
+ *                 raise ValueError(u"ndarray is not C contiguous")
+ * 
+ */
+  __pyx_t_2 = ((!(PyArray_CHKFLAGS(__pyx_v_self, NPY_C_CONTIGUOUS) != 0)) != 0);
+  __pyx_t_1 = __pyx_t_2;
+  __pyx_L6_bool_binop_done:;
+  if (__pyx_t_1) {
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":218
+ *             if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)
+ *                 and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)):
+ *                 raise ValueError(u"ndarray is not C contiguous")             # <<<<<<<<<<<<<<
+ * 
+ *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
+ */
+    __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__3, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 218; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    {__pyx_filename = __pyx_f[2]; __pyx_lineno = 218; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":220
+ *                 raise ValueError(u"ndarray is not C contiguous")
+ * 
+ *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)             # <<<<<<<<<<<<<<
+ *                 and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)):
+ *                 raise ValueError(u"ndarray is not Fortran contiguous")
+ */
+  __pyx_t_2 = (((__pyx_v_flags & PyBUF_F_CONTIGUOUS) == PyBUF_F_CONTIGUOUS) != 0);
+  if (__pyx_t_2) {
+  } else {
+    __pyx_t_1 = __pyx_t_2;
+    goto __pyx_L9_bool_binop_done;
+  }
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":221
+ * 
+ *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
+ *                 and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)):             # <<<<<<<<<<<<<<
+ *                 raise ValueError(u"ndarray is not Fortran contiguous")
+ * 
+ */
+  __pyx_t_2 = ((!(PyArray_CHKFLAGS(__pyx_v_self, NPY_F_CONTIGUOUS) != 0)) != 0);
+  __pyx_t_1 = __pyx_t_2;
+  __pyx_L9_bool_binop_done:;
+  if (__pyx_t_1) {
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":222
+ *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
+ *                 and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)):
+ *                 raise ValueError(u"ndarray is not Fortran contiguous")             # <<<<<<<<<<<<<<
+ * 
+ *             info.buf = PyArray_DATA(self)
+ */
+    __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 222; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    {__pyx_filename = __pyx_f[2]; __pyx_lineno = 222; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":224
+ *                 raise ValueError(u"ndarray is not Fortran contiguous")
+ * 
+ *             info.buf = PyArray_DATA(self)             # <<<<<<<<<<<<<<
+ *             info.ndim = ndim
+ *             if copy_shape:
+ */
+  __pyx_v_info->buf = PyArray_DATA(__pyx_v_self);
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":225
+ * 
+ *             info.buf = PyArray_DATA(self)
+ *             info.ndim = ndim             # <<<<<<<<<<<<<<
+ *             if copy_shape:
+ *                 # Allocate new buffer for strides and shape info.
+ */
+  __pyx_v_info->ndim = __pyx_v_ndim;
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":226
+ *             info.buf = PyArray_DATA(self)
+ *             info.ndim = ndim
+ *             if copy_shape:             # <<<<<<<<<<<<<<
+ *                 # Allocate new buffer for strides and shape info.
+ *                 # This is allocated as one block, strides first.
+ */
+  __pyx_t_1 = (__pyx_v_copy_shape != 0);
+  if (__pyx_t_1) {
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":229
+ *                 # Allocate new buffer for strides and shape info.
+ *                 # This is allocated as one block, strides first.
+ *                 info.strides = <Py_ssize_t*>stdlib.malloc(sizeof(Py_ssize_t) * <size_t>ndim * 2)             # <<<<<<<<<<<<<<
+ *                 info.shape = info.strides + ndim
+ *                 for i in range(ndim):
+ */
+    __pyx_v_info->strides = ((Py_ssize_t *)malloc((((sizeof(Py_ssize_t)) * ((size_t)__pyx_v_ndim)) * 2)));
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":230
+ *                 # This is allocated as one block, strides first.
+ *                 info.strides = <Py_ssize_t*>stdlib.malloc(sizeof(Py_ssize_t) * <size_t>ndim * 2)
+ *                 info.shape = info.strides + ndim             # <<<<<<<<<<<<<<
+ *                 for i in range(ndim):
+ *                     info.strides[i] = PyArray_STRIDES(self)[i]
+ */
+    __pyx_v_info->shape = (__pyx_v_info->strides + __pyx_v_ndim);
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":231
+ *                 info.strides = <Py_ssize_t*>stdlib.malloc(sizeof(Py_ssize_t) * <size_t>ndim * 2)
+ *                 info.shape = info.strides + ndim
+ *                 for i in range(ndim):             # <<<<<<<<<<<<<<
+ *                     info.strides[i] = PyArray_STRIDES(self)[i]
+ *                     info.shape[i] = PyArray_DIMS(self)[i]
+ */
+    __pyx_t_4 = __pyx_v_ndim;
+    for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_4; __pyx_t_5+=1) {
+      __pyx_v_i = __pyx_t_5;
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":232
+ *                 info.shape = info.strides + ndim
+ *                 for i in range(ndim):
+ *                     info.strides[i] = PyArray_STRIDES(self)[i]             # <<<<<<<<<<<<<<
+ *                     info.shape[i] = PyArray_DIMS(self)[i]
+ *             else:
+ */
+      (__pyx_v_info->strides[__pyx_v_i]) = (PyArray_STRIDES(__pyx_v_self)[__pyx_v_i]);
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":233
+ *                 for i in range(ndim):
+ *                     info.strides[i] = PyArray_STRIDES(self)[i]
+ *                     info.shape[i] = PyArray_DIMS(self)[i]             # <<<<<<<<<<<<<<
+ *             else:
+ *                 info.strides = <Py_ssize_t*>PyArray_STRIDES(self)
+ */
+      (__pyx_v_info->shape[__pyx_v_i]) = (PyArray_DIMS(__pyx_v_self)[__pyx_v_i]);
+    }
+    goto __pyx_L11;
+  }
+  /*else*/ {
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":235
+ *                     info.shape[i] = PyArray_DIMS(self)[i]
+ *             else:
+ *                 info.strides = <Py_ssize_t*>PyArray_STRIDES(self)             # <<<<<<<<<<<<<<
+ *                 info.shape = <Py_ssize_t*>PyArray_DIMS(self)
+ *             info.suboffsets = NULL
+ */
+    __pyx_v_info->strides = ((Py_ssize_t *)PyArray_STRIDES(__pyx_v_self));
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":236
+ *             else:
+ *                 info.strides = <Py_ssize_t*>PyArray_STRIDES(self)
+ *                 info.shape = <Py_ssize_t*>PyArray_DIMS(self)             # <<<<<<<<<<<<<<
+ *             info.suboffsets = NULL
+ *             info.itemsize = PyArray_ITEMSIZE(self)
+ */
+    __pyx_v_info->shape = ((Py_ssize_t *)PyArray_DIMS(__pyx_v_self));
+  }
+  __pyx_L11:;
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":237
+ *                 info.strides = <Py_ssize_t*>PyArray_STRIDES(self)
+ *                 info.shape = <Py_ssize_t*>PyArray_DIMS(self)
+ *             info.suboffsets = NULL             # <<<<<<<<<<<<<<
+ *             info.itemsize = PyArray_ITEMSIZE(self)
+ *             info.readonly = not PyArray_ISWRITEABLE(self)
+ */
+  __pyx_v_info->suboffsets = NULL;
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":238
+ *                 info.shape = <Py_ssize_t*>PyArray_DIMS(self)
+ *             info.suboffsets = NULL
+ *             info.itemsize = PyArray_ITEMSIZE(self)             # <<<<<<<<<<<<<<
+ *             info.readonly = not PyArray_ISWRITEABLE(self)
+ * 
+ */
+  __pyx_v_info->itemsize = PyArray_ITEMSIZE(__pyx_v_self);
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":239
+ *             info.suboffsets = NULL
+ *             info.itemsize = PyArray_ITEMSIZE(self)
+ *             info.readonly = not PyArray_ISWRITEABLE(self)             # <<<<<<<<<<<<<<
+ * 
+ *             cdef int t
+ */
+  __pyx_v_info->readonly = (!(PyArray_ISWRITEABLE(__pyx_v_self) != 0));
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":242
+ * 
+ *             cdef int t
+ *             cdef char* f = NULL             # <<<<<<<<<<<<<<
+ *             cdef dtype descr = self.descr
+ *             cdef list stack
+ */
+  __pyx_v_f = NULL;
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":243
+ *             cdef int t
+ *             cdef char* f = NULL
+ *             cdef dtype descr = self.descr             # <<<<<<<<<<<<<<
+ *             cdef list stack
+ *             cdef int offset
+ */
+  __pyx_t_3 = ((PyObject *)__pyx_v_self->descr);
+  __Pyx_INCREF(__pyx_t_3);
+  __pyx_v_descr = ((PyArray_Descr *)__pyx_t_3);
+  __pyx_t_3 = 0;
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":247
+ *             cdef int offset
+ * 
+ *             cdef bint hasfields = PyDataType_HASFIELDS(descr)             # <<<<<<<<<<<<<<
+ * 
+ *             if not hasfields and not copy_shape:
+ */
+  __pyx_v_hasfields = PyDataType_HASFIELDS(__pyx_v_descr);
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":249
+ *             cdef bint hasfields = PyDataType_HASFIELDS(descr)
+ * 
+ *             if not hasfields and not copy_shape:             # <<<<<<<<<<<<<<
+ *                 # do not call releasebuffer
+ *                 info.obj = None
+ */
+  __pyx_t_2 = ((!(__pyx_v_hasfields != 0)) != 0);
+  if (__pyx_t_2) {
+  } else {
+    __pyx_t_1 = __pyx_t_2;
+    goto __pyx_L15_bool_binop_done;
+  }
+  __pyx_t_2 = ((!(__pyx_v_copy_shape != 0)) != 0);
+  __pyx_t_1 = __pyx_t_2;
+  __pyx_L15_bool_binop_done:;
+  if (__pyx_t_1) {
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":251
+ *             if not hasfields and not copy_shape:
+ *                 # do not call releasebuffer
+ *                 info.obj = None             # <<<<<<<<<<<<<<
+ *             else:
+ *                 # need to call releasebuffer
+ */
+    __Pyx_INCREF(Py_None);
+    __Pyx_GIVEREF(Py_None);
+    __Pyx_GOTREF(__pyx_v_info->obj);
+    __Pyx_DECREF(__pyx_v_info->obj);
+    __pyx_v_info->obj = Py_None;
+    goto __pyx_L14;
+  }
+  /*else*/ {
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":254
+ *             else:
+ *                 # need to call releasebuffer
+ *                 info.obj = self             # <<<<<<<<<<<<<<
+ * 
+ *             if not hasfields:
+ */
+    __Pyx_INCREF(((PyObject *)__pyx_v_self));
+    __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
+    __Pyx_GOTREF(__pyx_v_info->obj);
+    __Pyx_DECREF(__pyx_v_info->obj);
+    __pyx_v_info->obj = ((PyObject *)__pyx_v_self);
+  }
+  __pyx_L14:;
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":256
+ *                 info.obj = self
+ * 
+ *             if not hasfields:             # <<<<<<<<<<<<<<
+ *                 t = descr.type_num
+ *                 if ((descr.byteorder == c'>' and little_endian) or
+ */
+  __pyx_t_1 = ((!(__pyx_v_hasfields != 0)) != 0);
+  if (__pyx_t_1) {
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":257
+ * 
+ *             if not hasfields:
+ *                 t = descr.type_num             # <<<<<<<<<<<<<<
+ *                 if ((descr.byteorder == c'>' and little_endian) or
+ *                     (descr.byteorder == c'<' and not little_endian)):
+ */
+    __pyx_t_4 = __pyx_v_descr->type_num;
+    __pyx_v_t = __pyx_t_4;
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":258
+ *             if not hasfields:
+ *                 t = descr.type_num
+ *                 if ((descr.byteorder == c'>' and little_endian) or             # <<<<<<<<<<<<<<
+ *                     (descr.byteorder == c'<' and not little_endian)):
+ *                     raise ValueError(u"Non-native byte order not supported")
+ */
+    __pyx_t_2 = ((__pyx_v_descr->byteorder == '>') != 0);
+    if (!__pyx_t_2) {
+      goto __pyx_L20_next_or;
+    } else {
+    }
+    __pyx_t_2 = (__pyx_v_little_endian != 0);
+    if (!__pyx_t_2) {
+    } else {
+      __pyx_t_1 = __pyx_t_2;
+      goto __pyx_L19_bool_binop_done;
+    }
+    __pyx_L20_next_or:;
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":259
+ *                 t = descr.type_num
+ *                 if ((descr.byteorder == c'>' and little_endian) or
+ *                     (descr.byteorder == c'<' and not little_endian)):             # <<<<<<<<<<<<<<
+ *                     raise ValueError(u"Non-native byte order not supported")
+ *                 if   t == NPY_BYTE:        f = "b"
+ */
+    __pyx_t_2 = ((__pyx_v_descr->byteorder == '<') != 0);
+    if (__pyx_t_2) {
+    } else {
+      __pyx_t_1 = __pyx_t_2;
+      goto __pyx_L19_bool_binop_done;
+    }
+    __pyx_t_2 = ((!(__pyx_v_little_endian != 0)) != 0);
+    __pyx_t_1 = __pyx_t_2;
+    __pyx_L19_bool_binop_done:;
+    if (__pyx_t_1) {
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":260
+ *                 if ((descr.byteorder == c'>' and little_endian) or
+ *                     (descr.byteorder == c'<' and not little_endian)):
+ *                     raise ValueError(u"Non-native byte order not supported")             # <<<<<<<<<<<<<<
+ *                 if   t == NPY_BYTE:        f = "b"
+ *                 elif t == NPY_UBYTE:       f = "B"
+ */
+      __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__5, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 260; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      {__pyx_filename = __pyx_f[2]; __pyx_lineno = 260; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":277
+ *                 elif t == NPY_CDOUBLE:     f = "Zd"
+ *                 elif t == NPY_CLONGDOUBLE: f = "Zg"
+ *                 elif t == NPY_OBJECT:      f = "O"             # <<<<<<<<<<<<<<
+ *                 else:
+ *                     raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
+ */
+    switch (__pyx_v_t) {
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":261
+ *                     (descr.byteorder == c'<' and not little_endian)):
+ *                     raise ValueError(u"Non-native byte order not supported")
+ *                 if   t == NPY_BYTE:        f = "b"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_UBYTE:       f = "B"
+ *                 elif t == NPY_SHORT:       f = "h"
+ */
+      case NPY_BYTE:
+      __pyx_v_f = __pyx_k_b;
+      break;
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":262
+ *                     raise ValueError(u"Non-native byte order not supported")
+ *                 if   t == NPY_BYTE:        f = "b"
+ *                 elif t == NPY_UBYTE:       f = "B"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_SHORT:       f = "h"
+ *                 elif t == NPY_USHORT:      f = "H"
+ */
+      case NPY_UBYTE:
+      __pyx_v_f = __pyx_k_B;
+      break;
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":263
+ *                 if   t == NPY_BYTE:        f = "b"
+ *                 elif t == NPY_UBYTE:       f = "B"
+ *                 elif t == NPY_SHORT:       f = "h"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_USHORT:      f = "H"
+ *                 elif t == NPY_INT:         f = "i"
+ */
+      case NPY_SHORT:
+      __pyx_v_f = __pyx_k_h;
+      break;
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":264
+ *                 elif t == NPY_UBYTE:       f = "B"
+ *                 elif t == NPY_SHORT:       f = "h"
+ *                 elif t == NPY_USHORT:      f = "H"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_INT:         f = "i"
+ *                 elif t == NPY_UINT:        f = "I"
+ */
+      case NPY_USHORT:
+      __pyx_v_f = __pyx_k_H;
+      break;
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":265
+ *                 elif t == NPY_SHORT:       f = "h"
+ *                 elif t == NPY_USHORT:      f = "H"
+ *                 elif t == NPY_INT:         f = "i"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_UINT:        f = "I"
+ *                 elif t == NPY_LONG:        f = "l"
+ */
+      case NPY_INT:
+      __pyx_v_f = __pyx_k_i;
+      break;
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":266
+ *                 elif t == NPY_USHORT:      f = "H"
+ *                 elif t == NPY_INT:         f = "i"
+ *                 elif t == NPY_UINT:        f = "I"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_LONG:        f = "l"
+ *                 elif t == NPY_ULONG:       f = "L"
+ */
+      case NPY_UINT:
+      __pyx_v_f = __pyx_k_I;
+      break;
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":267
+ *                 elif t == NPY_INT:         f = "i"
+ *                 elif t == NPY_UINT:        f = "I"
+ *                 elif t == NPY_LONG:        f = "l"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_ULONG:       f = "L"
+ *                 elif t == NPY_LONGLONG:    f = "q"
+ */
+      case NPY_LONG:
+      __pyx_v_f = __pyx_k_l;
+      break;
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":268
+ *                 elif t == NPY_UINT:        f = "I"
+ *                 elif t == NPY_LONG:        f = "l"
+ *                 elif t == NPY_ULONG:       f = "L"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_LONGLONG:    f = "q"
+ *                 elif t == NPY_ULONGLONG:   f = "Q"
+ */
+      case NPY_ULONG:
+      __pyx_v_f = __pyx_k_L;
+      break;
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":269
+ *                 elif t == NPY_LONG:        f = "l"
+ *                 elif t == NPY_ULONG:       f = "L"
+ *                 elif t == NPY_LONGLONG:    f = "q"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_ULONGLONG:   f = "Q"
+ *                 elif t == NPY_FLOAT:       f = "f"
+ */
+      case NPY_LONGLONG:
+      __pyx_v_f = __pyx_k_q;
+      break;
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":270
+ *                 elif t == NPY_ULONG:       f = "L"
+ *                 elif t == NPY_LONGLONG:    f = "q"
+ *                 elif t == NPY_ULONGLONG:   f = "Q"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_FLOAT:       f = "f"
+ *                 elif t == NPY_DOUBLE:      f = "d"
+ */
+      case NPY_ULONGLONG:
+      __pyx_v_f = __pyx_k_Q;
+      break;
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":271
+ *                 elif t == NPY_LONGLONG:    f = "q"
+ *                 elif t == NPY_ULONGLONG:   f = "Q"
+ *                 elif t == NPY_FLOAT:       f = "f"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_DOUBLE:      f = "d"
+ *                 elif t == NPY_LONGDOUBLE:  f = "g"
+ */
+      case NPY_FLOAT:
+      __pyx_v_f = __pyx_k_f;
+      break;
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":272
+ *                 elif t == NPY_ULONGLONG:   f = "Q"
+ *                 elif t == NPY_FLOAT:       f = "f"
+ *                 elif t == NPY_DOUBLE:      f = "d"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_LONGDOUBLE:  f = "g"
+ *                 elif t == NPY_CFLOAT:      f = "Zf"
+ */
+      case NPY_DOUBLE:
+      __pyx_v_f = __pyx_k_d;
+      break;
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":273
+ *                 elif t == NPY_FLOAT:       f = "f"
+ *                 elif t == NPY_DOUBLE:      f = "d"
+ *                 elif t == NPY_LONGDOUBLE:  f = "g"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_CFLOAT:      f = "Zf"
+ *                 elif t == NPY_CDOUBLE:     f = "Zd"
+ */
+      case NPY_LONGDOUBLE:
+      __pyx_v_f = __pyx_k_g;
+      break;
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":274
+ *                 elif t == NPY_DOUBLE:      f = "d"
+ *                 elif t == NPY_LONGDOUBLE:  f = "g"
+ *                 elif t == NPY_CFLOAT:      f = "Zf"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_CDOUBLE:     f = "Zd"
+ *                 elif t == NPY_CLONGDOUBLE: f = "Zg"
+ */
+      case NPY_CFLOAT:
+      __pyx_v_f = __pyx_k_Zf;
+      break;
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":275
+ *                 elif t == NPY_LONGDOUBLE:  f = "g"
+ *                 elif t == NPY_CFLOAT:      f = "Zf"
+ *                 elif t == NPY_CDOUBLE:     f = "Zd"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_CLONGDOUBLE: f = "Zg"
+ *                 elif t == NPY_OBJECT:      f = "O"
+ */
+      case NPY_CDOUBLE:
+      __pyx_v_f = __pyx_k_Zd;
+      break;
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":276
+ *                 elif t == NPY_CFLOAT:      f = "Zf"
+ *                 elif t == NPY_CDOUBLE:     f = "Zd"
+ *                 elif t == NPY_CLONGDOUBLE: f = "Zg"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_OBJECT:      f = "O"
+ *                 else:
+ */
+      case NPY_CLONGDOUBLE:
+      __pyx_v_f = __pyx_k_Zg;
+      break;
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":277
+ *                 elif t == NPY_CDOUBLE:     f = "Zd"
+ *                 elif t == NPY_CLONGDOUBLE: f = "Zg"
+ *                 elif t == NPY_OBJECT:      f = "O"             # <<<<<<<<<<<<<<
+ *                 else:
+ *                     raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
+ */
+      case NPY_OBJECT:
+      __pyx_v_f = __pyx_k_O;
+      break;
+      default:
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":279
+ *                 elif t == NPY_OBJECT:      f = "O"
+ *                 else:
+ *                     raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)             # <<<<<<<<<<<<<<
+ *                 info.format = f
+ *                 return
+ */
+      __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_t); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 279; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_6 = PyUnicode_Format(__pyx_kp_u_unknown_dtype_code_in_numpy_pxd, __pyx_t_3); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 279; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_6);
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 279; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_6);
+      __Pyx_GIVEREF(__pyx_t_6);
+      __pyx_t_6 = 0;
+      __pyx_t_6 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_3, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 279; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_6);
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __Pyx_Raise(__pyx_t_6, 0, 0, 0);
+      __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+      {__pyx_filename = __pyx_f[2]; __pyx_lineno = 279; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      break;
+    }
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":280
+ *                 else:
+ *                     raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
+ *                 info.format = f             # <<<<<<<<<<<<<<
+ *                 return
+ *             else:
+ */
+    __pyx_v_info->format = __pyx_v_f;
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":281
+ *                     raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
+ *                 info.format = f
+ *                 return             # <<<<<<<<<<<<<<
+ *             else:
+ *                 info.format = <char*>stdlib.malloc(_buffer_format_string_len)
+ */
+    __pyx_r = 0;
+    goto __pyx_L0;
+  }
+  /*else*/ {
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":283
+ *                 return
+ *             else:
+ *                 info.format = <char*>stdlib.malloc(_buffer_format_string_len)             # <<<<<<<<<<<<<<
+ *                 info.format[0] = c'^' # Native data types, manual alignment
+ *                 offset = 0
+ */
+    __pyx_v_info->format = ((char *)malloc(255));
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":284
+ *             else:
+ *                 info.format = <char*>stdlib.malloc(_buffer_format_string_len)
+ *                 info.format[0] = c'^' # Native data types, manual alignment             # <<<<<<<<<<<<<<
+ *                 offset = 0
+ *                 f = _util_dtypestring(descr, info.format + 1,
+ */
+    (__pyx_v_info->format[0]) = '^';
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":285
+ *                 info.format = <char*>stdlib.malloc(_buffer_format_string_len)
+ *                 info.format[0] = c'^' # Native data types, manual alignment
+ *                 offset = 0             # <<<<<<<<<<<<<<
+ *                 f = _util_dtypestring(descr, info.format + 1,
+ *                                       info.format + _buffer_format_string_len,
+ */
+    __pyx_v_offset = 0;
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":286
+ *                 info.format[0] = c'^' # Native data types, manual alignment
+ *                 offset = 0
+ *                 f = _util_dtypestring(descr, info.format + 1,             # <<<<<<<<<<<<<<
+ *                                       info.format + _buffer_format_string_len,
+ *                                       &offset)
+ */
+    __pyx_t_7 = __pyx_f_5numpy__util_dtypestring(__pyx_v_descr, (__pyx_v_info->format + 1), (__pyx_v_info->format + 255), (&__pyx_v_offset)); if (unlikely(__pyx_t_7 == NULL)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 286; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_v_f = __pyx_t_7;
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":289
+ *                                       info.format + _buffer_format_string_len,
+ *                                       &offset)
+ *                 f[0] = c'\0' # Terminate format string             # <<<<<<<<<<<<<<
+ * 
+ *         def __releasebuffer__(ndarray self, Py_buffer* info):
+ */
+    (__pyx_v_f[0]) = '\x00';
+  }
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":197
+ *         # experimental exception made for __getbuffer__ and __releasebuffer__
+ *         # -- the details of this may change.
+ *         def __getbuffer__(ndarray self, Py_buffer* info, int flags):             # <<<<<<<<<<<<<<
+ *             # This implementation of getbuffer is geared towards Cython
+ *             # requirements, and does not yet fullfill the PEP.
+ */
+
+  /* function exit code */
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_6);
+  __Pyx_AddTraceback("numpy.ndarray.__getbuffer__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = -1;
+  if (__pyx_v_info != NULL && __pyx_v_info->obj != NULL) {
+    __Pyx_GOTREF(__pyx_v_info->obj);
+    __Pyx_DECREF(__pyx_v_info->obj); __pyx_v_info->obj = NULL;
+  }
+  goto __pyx_L2;
+  __pyx_L0:;
+  if (__pyx_v_info != NULL && __pyx_v_info->obj == Py_None) {
+    __Pyx_GOTREF(Py_None);
+    __Pyx_DECREF(Py_None); __pyx_v_info->obj = NULL;
+  }
+  __pyx_L2:;
+  __Pyx_XDECREF((PyObject *)__pyx_v_descr);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":291
+ *                 f[0] = c'\0' # Terminate format string
+ * 
+ *         def __releasebuffer__(ndarray self, Py_buffer* info):             # <<<<<<<<<<<<<<
+ *             if PyArray_HASFIELDS(self):
+ *                 stdlib.free(info.format)
+ */
+
+/* Python wrapper */
+static CYTHON_UNUSED void __pyx_pw_5numpy_7ndarray_3__releasebuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info); /*proto*/
+static CYTHON_UNUSED void __pyx_pw_5numpy_7ndarray_3__releasebuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info) {
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__releasebuffer__ (wrapper)", 0);
+  __pyx_pf_5numpy_7ndarray_2__releasebuffer__(((PyArrayObject *)__pyx_v_self), ((Py_buffer *)__pyx_v_info));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+}
+
+static void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info) {
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("__releasebuffer__", 0);
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":292
+ * 
+ *         def __releasebuffer__(ndarray self, Py_buffer* info):
+ *             if PyArray_HASFIELDS(self):             # <<<<<<<<<<<<<<
+ *                 stdlib.free(info.format)
+ *             if sizeof(npy_intp) != sizeof(Py_ssize_t):
+ */
+  __pyx_t_1 = (PyArray_HASFIELDS(__pyx_v_self) != 0);
+  if (__pyx_t_1) {
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":293
+ *         def __releasebuffer__(ndarray self, Py_buffer* info):
+ *             if PyArray_HASFIELDS(self):
+ *                 stdlib.free(info.format)             # <<<<<<<<<<<<<<
+ *             if sizeof(npy_intp) != sizeof(Py_ssize_t):
+ *                 stdlib.free(info.strides)
+ */
+    free(__pyx_v_info->format);
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":294
+ *             if PyArray_HASFIELDS(self):
+ *                 stdlib.free(info.format)
+ *             if sizeof(npy_intp) != sizeof(Py_ssize_t):             # <<<<<<<<<<<<<<
+ *                 stdlib.free(info.strides)
+ *                 # info.shape was stored after info.strides in the same block
+ */
+  __pyx_t_1 = (((sizeof(npy_intp)) != (sizeof(Py_ssize_t))) != 0);
+  if (__pyx_t_1) {
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":295
+ *                 stdlib.free(info.format)
+ *             if sizeof(npy_intp) != sizeof(Py_ssize_t):
+ *                 stdlib.free(info.strides)             # <<<<<<<<<<<<<<
+ *                 # info.shape was stored after info.strides in the same block
+ * 
+ */
+    free(__pyx_v_info->strides);
+    goto __pyx_L4;
+  }
+  __pyx_L4:;
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":291
+ *                 f[0] = c'\0' # Terminate format string
+ * 
+ *         def __releasebuffer__(ndarray self, Py_buffer* info):             # <<<<<<<<<<<<<<
+ *             if PyArray_HASFIELDS(self):
+ *                 stdlib.free(info.format)
+ */
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+}
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":771
+ * ctypedef npy_cdouble     complex_t
+ * 
+ * cdef inline object PyArray_MultiIterNew1(a):             # <<<<<<<<<<<<<<
+ *     return PyArray_MultiIterNew(1, <void*>a)
+ * 
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew1(PyObject *__pyx_v_a) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("PyArray_MultiIterNew1", 0);
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":772
+ * 
+ * cdef inline object PyArray_MultiIterNew1(a):
+ *     return PyArray_MultiIterNew(1, <void*>a)             # <<<<<<<<<<<<<<
+ * 
+ * cdef inline object PyArray_MultiIterNew2(a, b):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = PyArray_MultiIterNew(1, ((void *)__pyx_v_a)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 772; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":771
+ * ctypedef npy_cdouble     complex_t
+ * 
+ * cdef inline object PyArray_MultiIterNew1(a):             # <<<<<<<<<<<<<<
+ *     return PyArray_MultiIterNew(1, <void*>a)
+ * 
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("numpy.PyArray_MultiIterNew1", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":774
+ *     return PyArray_MultiIterNew(1, <void*>a)
+ * 
+ * cdef inline object PyArray_MultiIterNew2(a, b):             # <<<<<<<<<<<<<<
+ *     return PyArray_MultiIterNew(2, <void*>a, <void*>b)
+ * 
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew2(PyObject *__pyx_v_a, PyObject *__pyx_v_b) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("PyArray_MultiIterNew2", 0);
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":775
+ * 
+ * cdef inline object PyArray_MultiIterNew2(a, b):
+ *     return PyArray_MultiIterNew(2, <void*>a, <void*>b)             # <<<<<<<<<<<<<<
+ * 
+ * cdef inline object PyArray_MultiIterNew3(a, b, c):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = PyArray_MultiIterNew(2, ((void *)__pyx_v_a), ((void *)__pyx_v_b)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 775; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":774
+ *     return PyArray_MultiIterNew(1, <void*>a)
+ * 
+ * cdef inline object PyArray_MultiIterNew2(a, b):             # <<<<<<<<<<<<<<
+ *     return PyArray_MultiIterNew(2, <void*>a, <void*>b)
+ * 
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("numpy.PyArray_MultiIterNew2", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":777
+ *     return PyArray_MultiIterNew(2, <void*>a, <void*>b)
+ * 
+ * cdef inline object PyArray_MultiIterNew3(a, b, c):             # <<<<<<<<<<<<<<
+ *     return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)
+ * 
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew3(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("PyArray_MultiIterNew3", 0);
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":778
+ * 
+ * cdef inline object PyArray_MultiIterNew3(a, b, c):
+ *     return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)             # <<<<<<<<<<<<<<
+ * 
+ * cdef inline object PyArray_MultiIterNew4(a, b, c, d):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = PyArray_MultiIterNew(3, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 778; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":777
+ *     return PyArray_MultiIterNew(2, <void*>a, <void*>b)
+ * 
+ * cdef inline object PyArray_MultiIterNew3(a, b, c):             # <<<<<<<<<<<<<<
+ *     return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)
+ * 
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("numpy.PyArray_MultiIterNew3", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":780
+ *     return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)
+ * 
+ * cdef inline object PyArray_MultiIterNew4(a, b, c, d):             # <<<<<<<<<<<<<<
+ *     return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)
+ * 
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew4(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c, PyObject *__pyx_v_d) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("PyArray_MultiIterNew4", 0);
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":781
+ * 
+ * cdef inline object PyArray_MultiIterNew4(a, b, c, d):
+ *     return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)             # <<<<<<<<<<<<<<
+ * 
+ * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = PyArray_MultiIterNew(4, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c), ((void *)__pyx_v_d)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 781; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":780
+ *     return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)
+ * 
+ * cdef inline object PyArray_MultiIterNew4(a, b, c, d):             # <<<<<<<<<<<<<<
+ *     return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)
+ * 
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("numpy.PyArray_MultiIterNew4", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":783
+ *     return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)
+ * 
+ * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e):             # <<<<<<<<<<<<<<
+ *     return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)
+ * 
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew5(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c, PyObject *__pyx_v_d, PyObject *__pyx_v_e) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("PyArray_MultiIterNew5", 0);
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":784
+ * 
+ * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e):
+ *     return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)             # <<<<<<<<<<<<<<
+ * 
+ * cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL:
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = PyArray_MultiIterNew(5, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c), ((void *)__pyx_v_d), ((void *)__pyx_v_e)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 784; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":783
+ *     return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)
+ * 
+ * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e):             # <<<<<<<<<<<<<<
+ *     return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)
+ * 
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("numpy.PyArray_MultiIterNew5", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":786
+ *     return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)
+ * 
+ * cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL:             # <<<<<<<<<<<<<<
+ *     # Recursive utility function used in __getbuffer__ to get format
+ *     # string. The new location in the format string is returned.
+ */
+
+static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx_v_descr, char *__pyx_v_f, char *__pyx_v_end, int *__pyx_v_offset) {
+  PyArray_Descr *__pyx_v_child = 0;
+  int __pyx_v_endian_detector;
+  int __pyx_v_little_endian;
+  PyObject *__pyx_v_fields = 0;
+  PyObject *__pyx_v_childname = NULL;
+  PyObject *__pyx_v_new_offset = NULL;
+  PyObject *__pyx_v_t = NULL;
+  char *__pyx_r;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  Py_ssize_t __pyx_t_2;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  int __pyx_t_5;
+  int __pyx_t_6;
+  int __pyx_t_7;
+  long __pyx_t_8;
+  char *__pyx_t_9;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("_util_dtypestring", 0);
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":793
+ *     cdef int delta_offset
+ *     cdef tuple i
+ *     cdef int endian_detector = 1             # <<<<<<<<<<<<<<
+ *     cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)
+ *     cdef tuple fields
+ */
+  __pyx_v_endian_detector = 1;
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":794
+ *     cdef tuple i
+ *     cdef int endian_detector = 1
+ *     cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)             # <<<<<<<<<<<<<<
+ *     cdef tuple fields
+ * 
+ */
+  __pyx_v_little_endian = ((((char *)(&__pyx_v_endian_detector))[0]) != 0);
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":797
+ *     cdef tuple fields
+ * 
+ *     for childname in descr.names:             # <<<<<<<<<<<<<<
+ *         fields = descr.fields[childname]
+ *         child, new_offset = fields
+ */
+  if (unlikely(__pyx_v_descr->names == Py_None)) {
+    PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable");
+    {__pyx_filename = __pyx_f[2]; __pyx_lineno = 797; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  __pyx_t_1 = __pyx_v_descr->names; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0;
+  for (;;) {
+    if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
+    #if CYTHON_COMPILING_IN_CPYTHON
+    __pyx_t_3 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_3); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 797; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    #else
+    __pyx_t_3 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 797; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    #endif
+    __Pyx_XDECREF_SET(__pyx_v_childname, __pyx_t_3);
+    __pyx_t_3 = 0;
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":798
+ * 
+ *     for childname in descr.names:
+ *         fields = descr.fields[childname]             # <<<<<<<<<<<<<<
+ *         child, new_offset = fields
+ * 
+ */
+    if (unlikely(__pyx_v_descr->fields == Py_None)) {
+      PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable");
+      {__pyx_filename = __pyx_f[2]; __pyx_lineno = 798; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+    __pyx_t_3 = __Pyx_PyDict_GetItem(__pyx_v_descr->fields, __pyx_v_childname); if (unlikely(__pyx_t_3 == NULL)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 798; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+    __Pyx_GOTREF(__pyx_t_3);
+    if (!(likely(PyTuple_CheckExact(__pyx_t_3))||((__pyx_t_3) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "tuple", Py_TYPE(__pyx_t_3)->tp_name), 0))) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 798; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_XDECREF_SET(__pyx_v_fields, ((PyObject*)__pyx_t_3));
+    __pyx_t_3 = 0;
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":799
+ *     for childname in descr.names:
+ *         fields = descr.fields[childname]
+ *         child, new_offset = fields             # <<<<<<<<<<<<<<
+ * 
+ *         if (end - f) - <int>(new_offset - offset[0]) < 15:
+ */
+    if (likely(__pyx_v_fields != Py_None)) {
+      PyObject* sequence = __pyx_v_fields;
+      #if CYTHON_COMPILING_IN_CPYTHON
+      Py_ssize_t size = Py_SIZE(sequence);
+      #else
+      Py_ssize_t size = PySequence_Size(sequence);
+      #endif
+      if (unlikely(size != 2)) {
+        if (size > 2) __Pyx_RaiseTooManyValuesError(2);
+        else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
+        {__pyx_filename = __pyx_f[2]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      }
+      #if CYTHON_COMPILING_IN_CPYTHON
+      __pyx_t_3 = PyTuple_GET_ITEM(sequence, 0); 
+      __pyx_t_4 = PyTuple_GET_ITEM(sequence, 1); 
+      __Pyx_INCREF(__pyx_t_3);
+      __Pyx_INCREF(__pyx_t_4);
+      #else
+      __pyx_t_3 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_4 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      #endif
+    } else {
+      __Pyx_RaiseNoneNotIterableError(); {__pyx_filename = __pyx_f[2]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+    if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_ptype_5numpy_dtype))))) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_XDECREF_SET(__pyx_v_child, ((PyArray_Descr *)__pyx_t_3));
+    __pyx_t_3 = 0;
+    __Pyx_XDECREF_SET(__pyx_v_new_offset, __pyx_t_4);
+    __pyx_t_4 = 0;
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":801
+ *         child, new_offset = fields
+ * 
+ *         if (end - f) - <int>(new_offset - offset[0]) < 15:             # <<<<<<<<<<<<<<
+ *             raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd")
+ * 
+ */
+    __pyx_t_4 = __Pyx_PyInt_From_int((__pyx_v_offset[0])); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 801; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    __pyx_t_3 = PyNumber_Subtract(__pyx_v_new_offset, __pyx_t_4); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 801; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    __pyx_t_5 = __Pyx_PyInt_As_int(__pyx_t_3); if (unlikely((__pyx_t_5 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 801; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __pyx_t_6 = ((((__pyx_v_end - __pyx_v_f) - ((int)__pyx_t_5)) < 15) != 0);
+    if (__pyx_t_6) {
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":802
+ * 
+ *         if (end - f) - <int>(new_offset - offset[0]) < 15:
+ *             raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd")             # <<<<<<<<<<<<<<
+ * 
+ *         if ((child.byteorder == c'>' and little_endian) or
+ */
+      __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_RuntimeError, __pyx_tuple__6, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 802; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      {__pyx_filename = __pyx_f[2]; __pyx_lineno = 802; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":804
+ *             raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd")
+ * 
+ *         if ((child.byteorder == c'>' and little_endian) or             # <<<<<<<<<<<<<<
+ *             (child.byteorder == c'<' and not little_endian)):
+ *             raise ValueError(u"Non-native byte order not supported")
+ */
+    __pyx_t_7 = ((__pyx_v_child->byteorder == '>') != 0);
+    if (!__pyx_t_7) {
+      goto __pyx_L8_next_or;
+    } else {
+    }
+    __pyx_t_7 = (__pyx_v_little_endian != 0);
+    if (!__pyx_t_7) {
+    } else {
+      __pyx_t_6 = __pyx_t_7;
+      goto __pyx_L7_bool_binop_done;
+    }
+    __pyx_L8_next_or:;
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":805
+ * 
+ *         if ((child.byteorder == c'>' and little_endian) or
+ *             (child.byteorder == c'<' and not little_endian)):             # <<<<<<<<<<<<<<
+ *             raise ValueError(u"Non-native byte order not supported")
+ *             # One could encode it in the format string and have Cython
+ */
+    __pyx_t_7 = ((__pyx_v_child->byteorder == '<') != 0);
+    if (__pyx_t_7) {
+    } else {
+      __pyx_t_6 = __pyx_t_7;
+      goto __pyx_L7_bool_binop_done;
+    }
+    __pyx_t_7 = ((!(__pyx_v_little_endian != 0)) != 0);
+    __pyx_t_6 = __pyx_t_7;
+    __pyx_L7_bool_binop_done:;
+    if (__pyx_t_6) {
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":806
+ *         if ((child.byteorder == c'>' and little_endian) or
+ *             (child.byteorder == c'<' and not little_endian)):
+ *             raise ValueError(u"Non-native byte order not supported")             # <<<<<<<<<<<<<<
+ *             # One could encode it in the format string and have Cython
+ *             # complain instead, BUT: < and > in format strings also imply
+ */
+      __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__7, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 806; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      {__pyx_filename = __pyx_f[2]; __pyx_lineno = 806; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":816
+ * 
+ *         # Output padding bytes
+ *         while offset[0] < new_offset:             # <<<<<<<<<<<<<<
+ *             f[0] = 120 # "x"; pad byte
+ *             f += 1
+ */
+    while (1) {
+      __pyx_t_3 = __Pyx_PyInt_From_int((__pyx_v_offset[0])); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 816; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_4 = PyObject_RichCompare(__pyx_t_3, __pyx_v_new_offset, Py_LT); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 816; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 816; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      if (!__pyx_t_6) break;
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":817
+ *         # Output padding bytes
+ *         while offset[0] < new_offset:
+ *             f[0] = 120 # "x"; pad byte             # <<<<<<<<<<<<<<
+ *             f += 1
+ *             offset[0] += 1
+ */
+      (__pyx_v_f[0]) = 120;
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":818
+ *         while offset[0] < new_offset:
+ *             f[0] = 120 # "x"; pad byte
+ *             f += 1             # <<<<<<<<<<<<<<
+ *             offset[0] += 1
+ * 
+ */
+      __pyx_v_f = (__pyx_v_f + 1);
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":819
+ *             f[0] = 120 # "x"; pad byte
+ *             f += 1
+ *             offset[0] += 1             # <<<<<<<<<<<<<<
+ * 
+ *         offset[0] += child.itemsize
+ */
+      __pyx_t_8 = 0;
+      (__pyx_v_offset[__pyx_t_8]) = ((__pyx_v_offset[__pyx_t_8]) + 1);
+    }
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":821
+ *             offset[0] += 1
+ * 
+ *         offset[0] += child.itemsize             # <<<<<<<<<<<<<<
+ * 
+ *         if not PyDataType_HASFIELDS(child):
+ */
+    __pyx_t_8 = 0;
+    (__pyx_v_offset[__pyx_t_8]) = ((__pyx_v_offset[__pyx_t_8]) + __pyx_v_child->elsize);
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":823
+ *         offset[0] += child.itemsize
+ * 
+ *         if not PyDataType_HASFIELDS(child):             # <<<<<<<<<<<<<<
+ *             t = child.type_num
+ *             if end - f < 5:
+ */
+    __pyx_t_6 = ((!(PyDataType_HASFIELDS(__pyx_v_child) != 0)) != 0);
+    if (__pyx_t_6) {
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":824
+ * 
+ *         if not PyDataType_HASFIELDS(child):
+ *             t = child.type_num             # <<<<<<<<<<<<<<
+ *             if end - f < 5:
+ *                 raise RuntimeError(u"Format string allocated too short.")
+ */
+      __pyx_t_4 = __Pyx_PyInt_From_int(__pyx_v_child->type_num); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 824; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __Pyx_XDECREF_SET(__pyx_v_t, __pyx_t_4);
+      __pyx_t_4 = 0;
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":825
+ *         if not PyDataType_HASFIELDS(child):
+ *             t = child.type_num
+ *             if end - f < 5:             # <<<<<<<<<<<<<<
+ *                 raise RuntimeError(u"Format string allocated too short.")
+ * 
+ */
+      __pyx_t_6 = (((__pyx_v_end - __pyx_v_f) < 5) != 0);
+      if (__pyx_t_6) {
+
+        /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":826
+ *             t = child.type_num
+ *             if end - f < 5:
+ *                 raise RuntimeError(u"Format string allocated too short.")             # <<<<<<<<<<<<<<
+ * 
+ *             # Until ticket #99 is fixed, use integers to avoid warnings
+ */
+        __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_RuntimeError, __pyx_tuple__8, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 826; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_4);
+        __Pyx_Raise(__pyx_t_4, 0, 0, 0);
+        __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+        {__pyx_filename = __pyx_f[2]; __pyx_lineno = 826; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      }
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":829
+ * 
+ *             # Until ticket #99 is fixed, use integers to avoid warnings
+ *             if   t == NPY_BYTE:        f[0] =  98 #"b"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_UBYTE:       f[0] =  66 #"B"
+ *             elif t == NPY_SHORT:       f[0] = 104 #"h"
+ */
+      __pyx_t_4 = PyInt_FromLong(NPY_BYTE); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 829; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 829; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 829; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 98;
+        goto __pyx_L15;
+      }
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":830
+ *             # Until ticket #99 is fixed, use integers to avoid warnings
+ *             if   t == NPY_BYTE:        f[0] =  98 #"b"
+ *             elif t == NPY_UBYTE:       f[0] =  66 #"B"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_SHORT:       f[0] = 104 #"h"
+ *             elif t == NPY_USHORT:      f[0] =  72 #"H"
+ */
+      __pyx_t_3 = PyInt_FromLong(NPY_UBYTE); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 830; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 830; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 830; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 66;
+        goto __pyx_L15;
+      }
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":831
+ *             if   t == NPY_BYTE:        f[0] =  98 #"b"
+ *             elif t == NPY_UBYTE:       f[0] =  66 #"B"
+ *             elif t == NPY_SHORT:       f[0] = 104 #"h"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_USHORT:      f[0] =  72 #"H"
+ *             elif t == NPY_INT:         f[0] = 105 #"i"
+ */
+      __pyx_t_4 = PyInt_FromLong(NPY_SHORT); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 831; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 831; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 831; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 104;
+        goto __pyx_L15;
+      }
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":832
+ *             elif t == NPY_UBYTE:       f[0] =  66 #"B"
+ *             elif t == NPY_SHORT:       f[0] = 104 #"h"
+ *             elif t == NPY_USHORT:      f[0] =  72 #"H"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_INT:         f[0] = 105 #"i"
+ *             elif t == NPY_UINT:        f[0] =  73 #"I"
+ */
+      __pyx_t_3 = PyInt_FromLong(NPY_USHORT); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 832; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 832; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 832; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 72;
+        goto __pyx_L15;
+      }
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":833
+ *             elif t == NPY_SHORT:       f[0] = 104 #"h"
+ *             elif t == NPY_USHORT:      f[0] =  72 #"H"
+ *             elif t == NPY_INT:         f[0] = 105 #"i"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_UINT:        f[0] =  73 #"I"
+ *             elif t == NPY_LONG:        f[0] = 108 #"l"
+ */
+      __pyx_t_4 = PyInt_FromLong(NPY_INT); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 833; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 833; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 833; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 105;
+        goto __pyx_L15;
+      }
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":834
+ *             elif t == NPY_USHORT:      f[0] =  72 #"H"
+ *             elif t == NPY_INT:         f[0] = 105 #"i"
+ *             elif t == NPY_UINT:        f[0] =  73 #"I"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_LONG:        f[0] = 108 #"l"
+ *             elif t == NPY_ULONG:       f[0] = 76  #"L"
+ */
+      __pyx_t_3 = PyInt_FromLong(NPY_UINT); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 834; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 834; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 834; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 73;
+        goto __pyx_L15;
+      }
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":835
+ *             elif t == NPY_INT:         f[0] = 105 #"i"
+ *             elif t == NPY_UINT:        f[0] =  73 #"I"
+ *             elif t == NPY_LONG:        f[0] = 108 #"l"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_ULONG:       f[0] = 76  #"L"
+ *             elif t == NPY_LONGLONG:    f[0] = 113 #"q"
+ */
+      __pyx_t_4 = PyInt_FromLong(NPY_LONG); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 835; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 835; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 835; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 108;
+        goto __pyx_L15;
+      }
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":836
+ *             elif t == NPY_UINT:        f[0] =  73 #"I"
+ *             elif t == NPY_LONG:        f[0] = 108 #"l"
+ *             elif t == NPY_ULONG:       f[0] = 76  #"L"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_LONGLONG:    f[0] = 113 #"q"
+ *             elif t == NPY_ULONGLONG:   f[0] = 81  #"Q"
+ */
+      __pyx_t_3 = PyInt_FromLong(NPY_ULONG); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 836; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 836; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 836; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 76;
+        goto __pyx_L15;
+      }
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":837
+ *             elif t == NPY_LONG:        f[0] = 108 #"l"
+ *             elif t == NPY_ULONG:       f[0] = 76  #"L"
+ *             elif t == NPY_LONGLONG:    f[0] = 113 #"q"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_ULONGLONG:   f[0] = 81  #"Q"
+ *             elif t == NPY_FLOAT:       f[0] = 102 #"f"
+ */
+      __pyx_t_4 = PyInt_FromLong(NPY_LONGLONG); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 837; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 837; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 837; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 113;
+        goto __pyx_L15;
+      }
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":838
+ *             elif t == NPY_ULONG:       f[0] = 76  #"L"
+ *             elif t == NPY_LONGLONG:    f[0] = 113 #"q"
+ *             elif t == NPY_ULONGLONG:   f[0] = 81  #"Q"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_FLOAT:       f[0] = 102 #"f"
+ *             elif t == NPY_DOUBLE:      f[0] = 100 #"d"
+ */
+      __pyx_t_3 = PyInt_FromLong(NPY_ULONGLONG); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 838; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 838; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 838; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 81;
+        goto __pyx_L15;
+      }
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":839
+ *             elif t == NPY_LONGLONG:    f[0] = 113 #"q"
+ *             elif t == NPY_ULONGLONG:   f[0] = 81  #"Q"
+ *             elif t == NPY_FLOAT:       f[0] = 102 #"f"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_DOUBLE:      f[0] = 100 #"d"
+ *             elif t == NPY_LONGDOUBLE:  f[0] = 103 #"g"
+ */
+      __pyx_t_4 = PyInt_FromLong(NPY_FLOAT); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 839; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 839; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 839; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 102;
+        goto __pyx_L15;
+      }
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":840
+ *             elif t == NPY_ULONGLONG:   f[0] = 81  #"Q"
+ *             elif t == NPY_FLOAT:       f[0] = 102 #"f"
+ *             elif t == NPY_DOUBLE:      f[0] = 100 #"d"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_LONGDOUBLE:  f[0] = 103 #"g"
+ *             elif t == NPY_CFLOAT:      f[0] = 90; f[1] = 102; f += 1 # Zf
+ */
+      __pyx_t_3 = PyInt_FromLong(NPY_DOUBLE); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 840; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 840; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 840; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 100;
+        goto __pyx_L15;
+      }
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":841
+ *             elif t == NPY_FLOAT:       f[0] = 102 #"f"
+ *             elif t == NPY_DOUBLE:      f[0] = 100 #"d"
+ *             elif t == NPY_LONGDOUBLE:  f[0] = 103 #"g"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_CFLOAT:      f[0] = 90; f[1] = 102; f += 1 # Zf
+ *             elif t == NPY_CDOUBLE:     f[0] = 90; f[1] = 100; f += 1 # Zd
+ */
+      __pyx_t_4 = PyInt_FromLong(NPY_LONGDOUBLE); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 841; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 841; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 841; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 103;
+        goto __pyx_L15;
+      }
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":842
+ *             elif t == NPY_DOUBLE:      f[0] = 100 #"d"
+ *             elif t == NPY_LONGDOUBLE:  f[0] = 103 #"g"
+ *             elif t == NPY_CFLOAT:      f[0] = 90; f[1] = 102; f += 1 # Zf             # <<<<<<<<<<<<<<
+ *             elif t == NPY_CDOUBLE:     f[0] = 90; f[1] = 100; f += 1 # Zd
+ *             elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg
+ */
+      __pyx_t_3 = PyInt_FromLong(NPY_CFLOAT); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 842; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 842; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 842; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 90;
+        (__pyx_v_f[1]) = 102;
+        __pyx_v_f = (__pyx_v_f + 1);
+        goto __pyx_L15;
+      }
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":843
+ *             elif t == NPY_LONGDOUBLE:  f[0] = 103 #"g"
+ *             elif t == NPY_CFLOAT:      f[0] = 90; f[1] = 102; f += 1 # Zf
+ *             elif t == NPY_CDOUBLE:     f[0] = 90; f[1] = 100; f += 1 # Zd             # <<<<<<<<<<<<<<
+ *             elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg
+ *             elif t == NPY_OBJECT:      f[0] = 79 #"O"
+ */
+      __pyx_t_4 = PyInt_FromLong(NPY_CDOUBLE); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 843; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 843; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 843; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 90;
+        (__pyx_v_f[1]) = 100;
+        __pyx_v_f = (__pyx_v_f + 1);
+        goto __pyx_L15;
+      }
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":844
+ *             elif t == NPY_CFLOAT:      f[0] = 90; f[1] = 102; f += 1 # Zf
+ *             elif t == NPY_CDOUBLE:     f[0] = 90; f[1] = 100; f += 1 # Zd
+ *             elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg             # <<<<<<<<<<<<<<
+ *             elif t == NPY_OBJECT:      f[0] = 79 #"O"
+ *             else:
+ */
+      __pyx_t_3 = PyInt_FromLong(NPY_CLONGDOUBLE); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 844; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 844; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 844; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 90;
+        (__pyx_v_f[1]) = 103;
+        __pyx_v_f = (__pyx_v_f + 1);
+        goto __pyx_L15;
+      }
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":845
+ *             elif t == NPY_CDOUBLE:     f[0] = 90; f[1] = 100; f += 1 # Zd
+ *             elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg
+ *             elif t == NPY_OBJECT:      f[0] = 79 #"O"             # <<<<<<<<<<<<<<
+ *             else:
+ *                 raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
+ */
+      __pyx_t_4 = PyInt_FromLong(NPY_OBJECT); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 845; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 845; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 845; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 79;
+        goto __pyx_L15;
+      }
+      /*else*/ {
+
+        /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":847
+ *             elif t == NPY_OBJECT:      f[0] = 79 #"O"
+ *             else:
+ *                 raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)             # <<<<<<<<<<<<<<
+ *             f += 1
+ *         else:
+ */
+        __pyx_t_3 = PyUnicode_Format(__pyx_kp_u_unknown_dtype_code_in_numpy_pxd, __pyx_v_t); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 847; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_3);
+        __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 847; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_4);
+        PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
+        __Pyx_GIVEREF(__pyx_t_3);
+        __pyx_t_3 = 0;
+        __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 847; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_3);
+        __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+        __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+        __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+        {__pyx_filename = __pyx_f[2]; __pyx_lineno = 847; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      }
+      __pyx_L15:;
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":848
+ *             else:
+ *                 raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
+ *             f += 1             # <<<<<<<<<<<<<<
+ *         else:
+ *             # Cython ignores struct boundary information ("T{...}"),
+ */
+      __pyx_v_f = (__pyx_v_f + 1);
+      goto __pyx_L13;
+    }
+    /*else*/ {
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":852
+ *             # Cython ignores struct boundary information ("T{...}"),
+ *             # so don't output it
+ *             f = _util_dtypestring(child, f, end, offset)             # <<<<<<<<<<<<<<
+ *     return f
+ * 
+ */
+      __pyx_t_9 = __pyx_f_5numpy__util_dtypestring(__pyx_v_child, __pyx_v_f, __pyx_v_end, __pyx_v_offset); if (unlikely(__pyx_t_9 == NULL)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 852; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_v_f = __pyx_t_9;
+    }
+    __pyx_L13:;
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":797
+ *     cdef tuple fields
+ * 
+ *     for childname in descr.names:             # <<<<<<<<<<<<<<
+ *         fields = descr.fields[childname]
+ *         child, new_offset = fields
+ */
+  }
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":853
+ *             # so don't output it
+ *             f = _util_dtypestring(child, f, end, offset)
+ *     return f             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+  __pyx_r = __pyx_v_f;
+  goto __pyx_L0;
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":786
+ *     return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)
+ * 
+ * cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL:             # <<<<<<<<<<<<<<
+ *     # Recursive utility function used in __getbuffer__ to get format
+ *     # string. The new location in the format string is returned.
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_AddTraceback("numpy._util_dtypestring", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XDECREF((PyObject *)__pyx_v_child);
+  __Pyx_XDECREF(__pyx_v_fields);
+  __Pyx_XDECREF(__pyx_v_childname);
+  __Pyx_XDECREF(__pyx_v_new_offset);
+  __Pyx_XDECREF(__pyx_v_t);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":969
+ * 
+ * 
+ * cdef inline void set_array_base(ndarray arr, object base):             # <<<<<<<<<<<<<<
+ *      cdef PyObject* baseptr
+ *      if base is None:
+ */
+
+static CYTHON_INLINE void __pyx_f_5numpy_set_array_base(PyArrayObject *__pyx_v_arr, PyObject *__pyx_v_base) {
+  PyObject *__pyx_v_baseptr;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  int __pyx_t_2;
+  __Pyx_RefNannySetupContext("set_array_base", 0);
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":971
+ * cdef inline void set_array_base(ndarray arr, object base):
+ *      cdef PyObject* baseptr
+ *      if base is None:             # <<<<<<<<<<<<<<
+ *          baseptr = NULL
+ *      else:
+ */
+  __pyx_t_1 = (__pyx_v_base == Py_None);
+  __pyx_t_2 = (__pyx_t_1 != 0);
+  if (__pyx_t_2) {
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":972
+ *      cdef PyObject* baseptr
+ *      if base is None:
+ *          baseptr = NULL             # <<<<<<<<<<<<<<
+ *      else:
+ *          Py_INCREF(base) # important to do this before decref below!
+ */
+    __pyx_v_baseptr = NULL;
+    goto __pyx_L3;
+  }
+  /*else*/ {
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":974
+ *          baseptr = NULL
+ *      else:
+ *          Py_INCREF(base) # important to do this before decref below!             # <<<<<<<<<<<<<<
+ *          baseptr = <PyObject*>base
+ *      Py_XDECREF(arr.base)
+ */
+    Py_INCREF(__pyx_v_base);
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":975
+ *      else:
+ *          Py_INCREF(base) # important to do this before decref below!
+ *          baseptr = <PyObject*>base             # <<<<<<<<<<<<<<
+ *      Py_XDECREF(arr.base)
+ *      arr.base = baseptr
+ */
+    __pyx_v_baseptr = ((PyObject *)__pyx_v_base);
+  }
+  __pyx_L3:;
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":976
+ *          Py_INCREF(base) # important to do this before decref below!
+ *          baseptr = <PyObject*>base
+ *      Py_XDECREF(arr.base)             # <<<<<<<<<<<<<<
+ *      arr.base = baseptr
+ * 
+ */
+  Py_XDECREF(__pyx_v_arr->base);
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":977
+ *          baseptr = <PyObject*>base
+ *      Py_XDECREF(arr.base)
+ *      arr.base = baseptr             # <<<<<<<<<<<<<<
+ * 
+ * cdef inline object get_array_base(ndarray arr):
+ */
+  __pyx_v_arr->base = __pyx_v_baseptr;
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":969
+ * 
+ * 
+ * cdef inline void set_array_base(ndarray arr, object base):             # <<<<<<<<<<<<<<
+ *      cdef PyObject* baseptr
+ *      if base is None:
+ */
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+}
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":979
+ *      arr.base = baseptr
+ * 
+ * cdef inline object get_array_base(ndarray arr):             # <<<<<<<<<<<<<<
+ *     if arr.base is NULL:
+ *         return None
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_5numpy_get_array_base(PyArrayObject *__pyx_v_arr) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("get_array_base", 0);
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":980
+ * 
+ * cdef inline object get_array_base(ndarray arr):
+ *     if arr.base is NULL:             # <<<<<<<<<<<<<<
+ *         return None
+ *     else:
+ */
+  __pyx_t_1 = ((__pyx_v_arr->base == NULL) != 0);
+  if (__pyx_t_1) {
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":981
+ * cdef inline object get_array_base(ndarray arr):
+ *     if arr.base is NULL:
+ *         return None             # <<<<<<<<<<<<<<
+ *     else:
+ *         return <object>arr.base
+ */
+    __Pyx_XDECREF(__pyx_r);
+    __Pyx_INCREF(Py_None);
+    __pyx_r = Py_None;
+    goto __pyx_L0;
+  }
+  /*else*/ {
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":983
+ *         return None
+ *     else:
+ *         return <object>arr.base             # <<<<<<<<<<<<<<
+ */
+    __Pyx_XDECREF(__pyx_r);
+    __Pyx_INCREF(((PyObject *)__pyx_v_arr->base));
+    __pyx_r = ((PyObject *)__pyx_v_arr->base);
+    goto __pyx_L0;
+  }
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":979
+ *      arr.base = baseptr
+ * 
+ * cdef inline object get_array_base(ndarray arr):             # <<<<<<<<<<<<<<
+ *     if arr.base is NULL:
+ *         return None
+ */
+
+  /* function exit code */
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_tp_new_2bx_3bbi_8bbi_file_SummaryBlock(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) {
+  PyObject *o;
+  if (likely((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)) {
+    o = (*t->tp_alloc)(t, 0);
+  } else {
+    o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0);
+  }
+  if (unlikely(!o)) return 0;
+  return o;
+}
+
+static void __pyx_tp_dealloc_2bx_3bbi_8bbi_file_SummaryBlock(PyObject *o) {
+  #if PY_VERSION_HEX >= 0x030400a1
+  if (unlikely(Py_TYPE(o)->tp_finalize) && (!PyType_IS_GC(Py_TYPE(o)) || !_PyGC_FINALIZED(o))) {
+    if (PyObject_CallFinalizerFromDealloc(o)) return;
+  }
+  #endif
+  (*Py_TYPE(o)->tp_free)(o);
+}
+
+static PyObject *__pyx_getprop_2bx_3bbi_8bbi_file_12SummaryBlock_chrom_id(PyObject *o, CYTHON_UNUSED void *x) {
+  return __pyx_pw_2bx_3bbi_8bbi_file_12SummaryBlock_8chrom_id_1__get__(o);
+}
+
+static int __pyx_setprop_2bx_3bbi_8bbi_file_12SummaryBlock_chrom_id(PyObject *o, PyObject *v, CYTHON_UNUSED void *x) {
+  if (v) {
+    return __pyx_pw_2bx_3bbi_8bbi_file_12SummaryBlock_8chrom_id_3__set__(o, v);
+  }
+  else {
+    PyErr_SetString(PyExc_NotImplementedError, "__del__");
+    return -1;
+  }
+}
+
+static PyObject *__pyx_getprop_2bx_3bbi_8bbi_file_12SummaryBlock_start(PyObject *o, CYTHON_UNUSED void *x) {
+  return __pyx_pw_2bx_3bbi_8bbi_file_12SummaryBlock_5start_1__get__(o);
+}
+
+static int __pyx_setprop_2bx_3bbi_8bbi_file_12SummaryBlock_start(PyObject *o, PyObject *v, CYTHON_UNUSED void *x) {
+  if (v) {
+    return __pyx_pw_2bx_3bbi_8bbi_file_12SummaryBlock_5start_3__set__(o, v);
+  }
+  else {
+    PyErr_SetString(PyExc_NotImplementedError, "__del__");
+    return -1;
+  }
+}
+
+static PyObject *__pyx_getprop_2bx_3bbi_8bbi_file_12SummaryBlock_end(PyObject *o, CYTHON_UNUSED void *x) {
+  return __pyx_pw_2bx_3bbi_8bbi_file_12SummaryBlock_3end_1__get__(o);
+}
+
+static int __pyx_setprop_2bx_3bbi_8bbi_file_12SummaryBlock_end(PyObject *o, PyObject *v, CYTHON_UNUSED void *x) {
+  if (v) {
+    return __pyx_pw_2bx_3bbi_8bbi_file_12SummaryBlock_3end_3__set__(o, v);
+  }
+  else {
+    PyErr_SetString(PyExc_NotImplementedError, "__del__");
+    return -1;
+  }
+}
+
+static PyObject *__pyx_getprop_2bx_3bbi_8bbi_file_12SummaryBlock_valid_count(PyObject *o, CYTHON_UNUSED void *x) {
+  return __pyx_pw_2bx_3bbi_8bbi_file_12SummaryBlock_11valid_count_1__get__(o);
+}
+
+static int __pyx_setprop_2bx_3bbi_8bbi_file_12SummaryBlock_valid_count(PyObject *o, PyObject *v, CYTHON_UNUSED void *x) {
+  if (v) {
+    return __pyx_pw_2bx_3bbi_8bbi_file_12SummaryBlock_11valid_count_3__set__(o, v);
+  }
+  else {
+    PyErr_SetString(PyExc_NotImplementedError, "__del__");
+    return -1;
+  }
+}
+
+static PyObject *__pyx_getprop_2bx_3bbi_8bbi_file_12SummaryBlock_min_val(PyObject *o, CYTHON_UNUSED void *x) {
+  return __pyx_pw_2bx_3bbi_8bbi_file_12SummaryBlock_7min_val_1__get__(o);
+}
+
+static int __pyx_setprop_2bx_3bbi_8bbi_file_12SummaryBlock_min_val(PyObject *o, PyObject *v, CYTHON_UNUSED void *x) {
+  if (v) {
+    return __pyx_pw_2bx_3bbi_8bbi_file_12SummaryBlock_7min_val_3__set__(o, v);
+  }
+  else {
+    PyErr_SetString(PyExc_NotImplementedError, "__del__");
+    return -1;
+  }
+}
+
+static PyObject *__pyx_getprop_2bx_3bbi_8bbi_file_12SummaryBlock_max_val(PyObject *o, CYTHON_UNUSED void *x) {
+  return __pyx_pw_2bx_3bbi_8bbi_file_12SummaryBlock_7max_val_1__get__(o);
+}
+
+static int __pyx_setprop_2bx_3bbi_8bbi_file_12SummaryBlock_max_val(PyObject *o, PyObject *v, CYTHON_UNUSED void *x) {
+  if (v) {
+    return __pyx_pw_2bx_3bbi_8bbi_file_12SummaryBlock_7max_val_3__set__(o, v);
+  }
+  else {
+    PyErr_SetString(PyExc_NotImplementedError, "__del__");
+    return -1;
+  }
+}
+
+static PyObject *__pyx_getprop_2bx_3bbi_8bbi_file_12SummaryBlock_sum_data(PyObject *o, CYTHON_UNUSED void *x) {
+  return __pyx_pw_2bx_3bbi_8bbi_file_12SummaryBlock_8sum_data_1__get__(o);
+}
+
+static int __pyx_setprop_2bx_3bbi_8bbi_file_12SummaryBlock_sum_data(PyObject *o, PyObject *v, CYTHON_UNUSED void *x) {
+  if (v) {
+    return __pyx_pw_2bx_3bbi_8bbi_file_12SummaryBlock_8sum_data_3__set__(o, v);
+  }
+  else {
+    PyErr_SetString(PyExc_NotImplementedError, "__del__");
+    return -1;
+  }
+}
+
+static PyObject *__pyx_getprop_2bx_3bbi_8bbi_file_12SummaryBlock_sum_squares(PyObject *o, CYTHON_UNUSED void *x) {
+  return __pyx_pw_2bx_3bbi_8bbi_file_12SummaryBlock_11sum_squares_1__get__(o);
+}
+
+static int __pyx_setprop_2bx_3bbi_8bbi_file_12SummaryBlock_sum_squares(PyObject *o, PyObject *v, CYTHON_UNUSED void *x) {
+  if (v) {
+    return __pyx_pw_2bx_3bbi_8bbi_file_12SummaryBlock_11sum_squares_3__set__(o, v);
+  }
+  else {
+    PyErr_SetString(PyExc_NotImplementedError, "__del__");
+    return -1;
+  }
+}
+
+static struct PyGetSetDef __pyx_getsets_2bx_3bbi_8bbi_file_SummaryBlock[] = {
+  {(char *)"chrom_id", __pyx_getprop_2bx_3bbi_8bbi_file_12SummaryBlock_chrom_id, __pyx_setprop_2bx_3bbi_8bbi_file_12SummaryBlock_chrom_id, 0, 0},
+  {(char *)"start", __pyx_getprop_2bx_3bbi_8bbi_file_12SummaryBlock_start, __pyx_setprop_2bx_3bbi_8bbi_file_12SummaryBlock_start, 0, 0},
+  {(char *)"end", __pyx_getprop_2bx_3bbi_8bbi_file_12SummaryBlock_end, __pyx_setprop_2bx_3bbi_8bbi_file_12SummaryBlock_end, 0, 0},
+  {(char *)"valid_count", __pyx_getprop_2bx_3bbi_8bbi_file_12SummaryBlock_valid_count, __pyx_setprop_2bx_3bbi_8bbi_file_12SummaryBlock_valid_count, 0, 0},
+  {(char *)"min_val", __pyx_getprop_2bx_3bbi_8bbi_file_12SummaryBlock_min_val, __pyx_setprop_2bx_3bbi_8bbi_file_12SummaryBlock_min_val, 0, 0},
+  {(char *)"max_val", __pyx_getprop_2bx_3bbi_8bbi_file_12SummaryBlock_max_val, __pyx_setprop_2bx_3bbi_8bbi_file_12SummaryBlock_max_val, 0, 0},
+  {(char *)"sum_data", __pyx_getprop_2bx_3bbi_8bbi_file_12SummaryBlock_sum_data, __pyx_setprop_2bx_3bbi_8bbi_file_12SummaryBlock_sum_data, 0, 0},
+  {(char *)"sum_squares", __pyx_getprop_2bx_3bbi_8bbi_file_12SummaryBlock_sum_squares, __pyx_setprop_2bx_3bbi_8bbi_file_12SummaryBlock_sum_squares, 0, 0},
+  {0, 0, 0, 0, 0}
+};
+
+static PyTypeObject __pyx_type_2bx_3bbi_8bbi_file_SummaryBlock = {
+  PyVarObject_HEAD_INIT(0, 0)
+  "bx.bbi.bbi_file.SummaryBlock", /*tp_name*/
+  sizeof(struct __pyx_obj_2bx_3bbi_8bbi_file_SummaryBlock), /*tp_basicsize*/
+  0, /*tp_itemsize*/
+  __pyx_tp_dealloc_2bx_3bbi_8bbi_file_SummaryBlock, /*tp_dealloc*/
+  0, /*tp_print*/
+  0, /*tp_getattr*/
+  0, /*tp_setattr*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*tp_compare*/
+  #else
+  0, /*reserved*/
+  #endif
+  0, /*tp_repr*/
+  0, /*tp_as_number*/
+  0, /*tp_as_sequence*/
+  0, /*tp_as_mapping*/
+  0, /*tp_hash*/
+  0, /*tp_call*/
+  0, /*tp_str*/
+  0, /*tp_getattro*/
+  0, /*tp_setattro*/
+  0, /*tp_as_buffer*/
+  Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE, /*tp_flags*/
+  "\n    A block of summary data from disk\n    ", /*tp_doc*/
+  0, /*tp_traverse*/
+  0, /*tp_clear*/
+  0, /*tp_richcompare*/
+  0, /*tp_weaklistoffset*/
+  0, /*tp_iter*/
+  0, /*tp_iternext*/
+  0, /*tp_methods*/
+  0, /*tp_members*/
+  __pyx_getsets_2bx_3bbi_8bbi_file_SummaryBlock, /*tp_getset*/
+  0, /*tp_base*/
+  0, /*tp_dict*/
+  0, /*tp_descr_get*/
+  0, /*tp_descr_set*/
+  0, /*tp_dictoffset*/
+  0, /*tp_init*/
+  0, /*tp_alloc*/
+  __pyx_tp_new_2bx_3bbi_8bbi_file_SummaryBlock, /*tp_new*/
+  0, /*tp_free*/
+  0, /*tp_is_gc*/
+  0, /*tp_bases*/
+  0, /*tp_mro*/
+  0, /*tp_cache*/
+  0, /*tp_subclasses*/
+  0, /*tp_weaklist*/
+  0, /*tp_del*/
+  0, /*tp_version_tag*/
+  #if PY_VERSION_HEX >= 0x030400a1
+  0, /*tp_finalize*/
+  #endif
+};
+static struct __pyx_vtabstruct_2bx_3bbi_8bbi_file_SummarizedData __pyx_vtable_2bx_3bbi_8bbi_file_SummarizedData;
+
+static PyObject *__pyx_tp_new_2bx_3bbi_8bbi_file_SummarizedData(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) {
+  struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData *p;
+  PyObject *o;
+  if (likely((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)) {
+    o = (*t->tp_alloc)(t, 0);
+  } else {
+    o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0);
+  }
+  if (unlikely(!o)) return 0;
+  p = ((struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData *)o);
+  p->__pyx_vtab = __pyx_vtabptr_2bx_3bbi_8bbi_file_SummarizedData;
+  p->valid_count = ((PyArrayObject *)Py_None); Py_INCREF(Py_None);
+  p->min_val = ((PyArrayObject *)Py_None); Py_INCREF(Py_None);
+  p->max_val = ((PyArrayObject *)Py_None); Py_INCREF(Py_None);
+  p->sum_data = ((PyArrayObject *)Py_None); Py_INCREF(Py_None);
+  p->sum_squares = ((PyArrayObject *)Py_None); Py_INCREF(Py_None);
+  return o;
+}
+
+static void __pyx_tp_dealloc_2bx_3bbi_8bbi_file_SummarizedData(PyObject *o) {
+  struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData *p = (struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData *)o;
+  #if PY_VERSION_HEX >= 0x030400a1
+  if (unlikely(Py_TYPE(o)->tp_finalize) && !_PyGC_FINALIZED(o)) {
+    if (PyObject_CallFinalizerFromDealloc(o)) return;
+  }
+  #endif
+  PyObject_GC_UnTrack(o);
+  Py_CLEAR(p->valid_count);
+  Py_CLEAR(p->min_val);
+  Py_CLEAR(p->max_val);
+  Py_CLEAR(p->sum_data);
+  Py_CLEAR(p->sum_squares);
+  (*Py_TYPE(o)->tp_free)(o);
+}
+
+static int __pyx_tp_traverse_2bx_3bbi_8bbi_file_SummarizedData(PyObject *o, visitproc v, void *a) {
+  int e;
+  struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData *p = (struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData *)o;
+  if (p->valid_count) {
+    e = (*v)(((PyObject*)p->valid_count), a); if (e) return e;
+  }
+  if (p->min_val) {
+    e = (*v)(((PyObject*)p->min_val), a); if (e) return e;
+  }
+  if (p->max_val) {
+    e = (*v)(((PyObject*)p->max_val), a); if (e) return e;
+  }
+  if (p->sum_data) {
+    e = (*v)(((PyObject*)p->sum_data), a); if (e) return e;
+  }
+  if (p->sum_squares) {
+    e = (*v)(((PyObject*)p->sum_squares), a); if (e) return e;
+  }
+  return 0;
+}
+
+static int __pyx_tp_clear_2bx_3bbi_8bbi_file_SummarizedData(PyObject *o) {
+  PyObject* tmp;
+  struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData *p = (struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData *)o;
+  tmp = ((PyObject*)p->valid_count);
+  p->valid_count = ((PyArrayObject *)Py_None); Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  tmp = ((PyObject*)p->min_val);
+  p->min_val = ((PyArrayObject *)Py_None); Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  tmp = ((PyObject*)p->max_val);
+  p->max_val = ((PyArrayObject *)Py_None); Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  tmp = ((PyObject*)p->sum_data);
+  p->sum_data = ((PyArrayObject *)Py_None); Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  tmp = ((PyObject*)p->sum_squares);
+  p->sum_squares = ((PyArrayObject *)Py_None); Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  return 0;
+}
+
+static PyObject *__pyx_getprop_2bx_3bbi_8bbi_file_14SummarizedData_start(PyObject *o, CYTHON_UNUSED void *x) {
+  return __pyx_pw_2bx_3bbi_8bbi_file_14SummarizedData_5start_1__get__(o);
+}
+
+static int __pyx_setprop_2bx_3bbi_8bbi_file_14SummarizedData_start(PyObject *o, PyObject *v, CYTHON_UNUSED void *x) {
+  if (v) {
+    return __pyx_pw_2bx_3bbi_8bbi_file_14SummarizedData_5start_3__set__(o, v);
+  }
+  else {
+    PyErr_SetString(PyExc_NotImplementedError, "__del__");
+    return -1;
+  }
+}
+
+static PyObject *__pyx_getprop_2bx_3bbi_8bbi_file_14SummarizedData_end(PyObject *o, CYTHON_UNUSED void *x) {
+  return __pyx_pw_2bx_3bbi_8bbi_file_14SummarizedData_3end_1__get__(o);
+}
+
+static int __pyx_setprop_2bx_3bbi_8bbi_file_14SummarizedData_end(PyObject *o, PyObject *v, CYTHON_UNUSED void *x) {
+  if (v) {
+    return __pyx_pw_2bx_3bbi_8bbi_file_14SummarizedData_3end_3__set__(o, v);
+  }
+  else {
+    PyErr_SetString(PyExc_NotImplementedError, "__del__");
+    return -1;
+  }
+}
+
+static PyObject *__pyx_getprop_2bx_3bbi_8bbi_file_14SummarizedData_size(PyObject *o, CYTHON_UNUSED void *x) {
+  return __pyx_pw_2bx_3bbi_8bbi_file_14SummarizedData_4size_1__get__(o);
+}
+
+static int __pyx_setprop_2bx_3bbi_8bbi_file_14SummarizedData_size(PyObject *o, PyObject *v, CYTHON_UNUSED void *x) {
+  if (v) {
+    return __pyx_pw_2bx_3bbi_8bbi_file_14SummarizedData_4size_3__set__(o, v);
+  }
+  else {
+    PyErr_SetString(PyExc_NotImplementedError, "__del__");
+    return -1;
+  }
+}
+
+static PyObject *__pyx_getprop_2bx_3bbi_8bbi_file_14SummarizedData_valid_count(PyObject *o, CYTHON_UNUSED void *x) {
+  return __pyx_pw_2bx_3bbi_8bbi_file_14SummarizedData_11valid_count_1__get__(o);
+}
+
+static int __pyx_setprop_2bx_3bbi_8bbi_file_14SummarizedData_valid_count(PyObject *o, PyObject *v, CYTHON_UNUSED void *x) {
+  if (v) {
+    return __pyx_pw_2bx_3bbi_8bbi_file_14SummarizedData_11valid_count_3__set__(o, v);
+  }
+  else {
+    return __pyx_pw_2bx_3bbi_8bbi_file_14SummarizedData_11valid_count_5__del__(o);
+  }
+}
+
+static PyObject *__pyx_getprop_2bx_3bbi_8bbi_file_14SummarizedData_min_val(PyObject *o, CYTHON_UNUSED void *x) {
+  return __pyx_pw_2bx_3bbi_8bbi_file_14SummarizedData_7min_val_1__get__(o);
+}
+
+static int __pyx_setprop_2bx_3bbi_8bbi_file_14SummarizedData_min_val(PyObject *o, PyObject *v, CYTHON_UNUSED void *x) {
+  if (v) {
+    return __pyx_pw_2bx_3bbi_8bbi_file_14SummarizedData_7min_val_3__set__(o, v);
+  }
+  else {
+    return __pyx_pw_2bx_3bbi_8bbi_file_14SummarizedData_7min_val_5__del__(o);
+  }
+}
+
+static PyObject *__pyx_getprop_2bx_3bbi_8bbi_file_14SummarizedData_max_val(PyObject *o, CYTHON_UNUSED void *x) {
+  return __pyx_pw_2bx_3bbi_8bbi_file_14SummarizedData_7max_val_1__get__(o);
+}
+
+static int __pyx_setprop_2bx_3bbi_8bbi_file_14SummarizedData_max_val(PyObject *o, PyObject *v, CYTHON_UNUSED void *x) {
+  if (v) {
+    return __pyx_pw_2bx_3bbi_8bbi_file_14SummarizedData_7max_val_3__set__(o, v);
+  }
+  else {
+    return __pyx_pw_2bx_3bbi_8bbi_file_14SummarizedData_7max_val_5__del__(o);
+  }
+}
+
+static PyObject *__pyx_getprop_2bx_3bbi_8bbi_file_14SummarizedData_sum_data(PyObject *o, CYTHON_UNUSED void *x) {
+  return __pyx_pw_2bx_3bbi_8bbi_file_14SummarizedData_8sum_data_1__get__(o);
+}
+
+static int __pyx_setprop_2bx_3bbi_8bbi_file_14SummarizedData_sum_data(PyObject *o, PyObject *v, CYTHON_UNUSED void *x) {
+  if (v) {
+    return __pyx_pw_2bx_3bbi_8bbi_file_14SummarizedData_8sum_data_3__set__(o, v);
+  }
+  else {
+    return __pyx_pw_2bx_3bbi_8bbi_file_14SummarizedData_8sum_data_5__del__(o);
+  }
+}
+
+static PyObject *__pyx_getprop_2bx_3bbi_8bbi_file_14SummarizedData_sum_squares(PyObject *o, CYTHON_UNUSED void *x) {
+  return __pyx_pw_2bx_3bbi_8bbi_file_14SummarizedData_11sum_squares_1__get__(o);
+}
+
+static int __pyx_setprop_2bx_3bbi_8bbi_file_14SummarizedData_sum_squares(PyObject *o, PyObject *v, CYTHON_UNUSED void *x) {
+  if (v) {
+    return __pyx_pw_2bx_3bbi_8bbi_file_14SummarizedData_11sum_squares_3__set__(o, v);
+  }
+  else {
+    return __pyx_pw_2bx_3bbi_8bbi_file_14SummarizedData_11sum_squares_5__del__(o);
+  }
+}
+
+static PyMethodDef __pyx_methods_2bx_3bbi_8bbi_file_SummarizedData[] = {
+  {0, 0, 0, 0}
+};
+
+static struct PyGetSetDef __pyx_getsets_2bx_3bbi_8bbi_file_SummarizedData[] = {
+  {(char *)"start", __pyx_getprop_2bx_3bbi_8bbi_file_14SummarizedData_start, __pyx_setprop_2bx_3bbi_8bbi_file_14SummarizedData_start, 0, 0},
+  {(char *)"end", __pyx_getprop_2bx_3bbi_8bbi_file_14SummarizedData_end, __pyx_setprop_2bx_3bbi_8bbi_file_14SummarizedData_end, 0, 0},
+  {(char *)"size", __pyx_getprop_2bx_3bbi_8bbi_file_14SummarizedData_size, __pyx_setprop_2bx_3bbi_8bbi_file_14SummarizedData_size, 0, 0},
+  {(char *)"valid_count", __pyx_getprop_2bx_3bbi_8bbi_file_14SummarizedData_valid_count, __pyx_setprop_2bx_3bbi_8bbi_file_14SummarizedData_valid_count, 0, 0},
+  {(char *)"min_val", __pyx_getprop_2bx_3bbi_8bbi_file_14SummarizedData_min_val, __pyx_setprop_2bx_3bbi_8bbi_file_14SummarizedData_min_val, 0, 0},
+  {(char *)"max_val", __pyx_getprop_2bx_3bbi_8bbi_file_14SummarizedData_max_val, __pyx_setprop_2bx_3bbi_8bbi_file_14SummarizedData_max_val, 0, 0},
+  {(char *)"sum_data", __pyx_getprop_2bx_3bbi_8bbi_file_14SummarizedData_sum_data, __pyx_setprop_2bx_3bbi_8bbi_file_14SummarizedData_sum_data, 0, 0},
+  {(char *)"sum_squares", __pyx_getprop_2bx_3bbi_8bbi_file_14SummarizedData_sum_squares, __pyx_setprop_2bx_3bbi_8bbi_file_14SummarizedData_sum_squares, 0, 0},
+  {0, 0, 0, 0, 0}
+};
+
+static PyTypeObject __pyx_type_2bx_3bbi_8bbi_file_SummarizedData = {
+  PyVarObject_HEAD_INIT(0, 0)
+  "bx.bbi.bbi_file.SummarizedData", /*tp_name*/
+  sizeof(struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData), /*tp_basicsize*/
+  0, /*tp_itemsize*/
+  __pyx_tp_dealloc_2bx_3bbi_8bbi_file_SummarizedData, /*tp_dealloc*/
+  0, /*tp_print*/
+  0, /*tp_getattr*/
+  0, /*tp_setattr*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*tp_compare*/
+  #else
+  0, /*reserved*/
+  #endif
+  0, /*tp_repr*/
+  0, /*tp_as_number*/
+  0, /*tp_as_sequence*/
+  0, /*tp_as_mapping*/
+  0, /*tp_hash*/
+  0, /*tp_call*/
+  0, /*tp_str*/
+  0, /*tp_getattro*/
+  0, /*tp_setattro*/
+  0, /*tp_as_buffer*/
+  Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+  "\n    The result of using SummaryBlocks read from the file to produce a \n    aggregation over a particular range and resolution\n    ", /*tp_doc*/
+  __pyx_tp_traverse_2bx_3bbi_8bbi_file_SummarizedData, /*tp_traverse*/
+  __pyx_tp_clear_2bx_3bbi_8bbi_file_SummarizedData, /*tp_clear*/
+  0, /*tp_richcompare*/
+  0, /*tp_weaklistoffset*/
+  0, /*tp_iter*/
+  0, /*tp_iternext*/
+  __pyx_methods_2bx_3bbi_8bbi_file_SummarizedData, /*tp_methods*/
+  0, /*tp_members*/
+  __pyx_getsets_2bx_3bbi_8bbi_file_SummarizedData, /*tp_getset*/
+  0, /*tp_base*/
+  0, /*tp_dict*/
+  0, /*tp_descr_get*/
+  0, /*tp_descr_set*/
+  0, /*tp_dictoffset*/
+  __pyx_pw_2bx_3bbi_8bbi_file_14SummarizedData_1__init__, /*tp_init*/
+  0, /*tp_alloc*/
+  __pyx_tp_new_2bx_3bbi_8bbi_file_SummarizedData, /*tp_new*/
+  0, /*tp_free*/
+  0, /*tp_is_gc*/
+  0, /*tp_bases*/
+  0, /*tp_mro*/
+  0, /*tp_cache*/
+  0, /*tp_subclasses*/
+  0, /*tp_weaklist*/
+  0, /*tp_del*/
+  0, /*tp_version_tag*/
+  #if PY_VERSION_HEX >= 0x030400a1
+  0, /*tp_finalize*/
+  #endif
+};
+static struct __pyx_vtabstruct_2bx_3bbi_8bbi_file_BBIFile __pyx_vtable_2bx_3bbi_8bbi_file_BBIFile;
+
+static PyObject *__pyx_tp_new_2bx_3bbi_8bbi_file_BBIFile(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) {
+  struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *p;
+  PyObject *o;
+  if (likely((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)) {
+    o = (*t->tp_alloc)(t, 0);
+  } else {
+    o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0);
+  }
+  if (unlikely(!o)) return 0;
+  p = ((struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *)o);
+  p->__pyx_vtab = __pyx_vtabptr_2bx_3bbi_8bbi_file_BBIFile;
+  p->file = Py_None; Py_INCREF(Py_None);
+  p->reader = Py_None; Py_INCREF(Py_None);
+  p->chrom_bpt = ((struct __pyx_obj_2bx_3bbi_8bpt_file_BPTFile *)Py_None); Py_INCREF(Py_None);
+  p->level_list = Py_None; Py_INCREF(Py_None);
+  return o;
+}
+
+static void __pyx_tp_dealloc_2bx_3bbi_8bbi_file_BBIFile(PyObject *o) {
+  struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *p = (struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *)o;
+  #if PY_VERSION_HEX >= 0x030400a1
+  if (unlikely(Py_TYPE(o)->tp_finalize) && !_PyGC_FINALIZED(o)) {
+    if (PyObject_CallFinalizerFromDealloc(o)) return;
+  }
+  #endif
+  PyObject_GC_UnTrack(o);
+  Py_CLEAR(p->file);
+  Py_CLEAR(p->reader);
+  Py_CLEAR(p->chrom_bpt);
+  Py_CLEAR(p->level_list);
+  (*Py_TYPE(o)->tp_free)(o);
+}
+
+static int __pyx_tp_traverse_2bx_3bbi_8bbi_file_BBIFile(PyObject *o, visitproc v, void *a) {
+  int e;
+  struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *p = (struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *)o;
+  if (p->file) {
+    e = (*v)(p->file, a); if (e) return e;
+  }
+  if (p->reader) {
+    e = (*v)(p->reader, a); if (e) return e;
+  }
+  if (p->chrom_bpt) {
+    e = (*v)(((PyObject*)p->chrom_bpt), a); if (e) return e;
+  }
+  if (p->level_list) {
+    e = (*v)(p->level_list, a); if (e) return e;
+  }
+  return 0;
+}
+
+static int __pyx_tp_clear_2bx_3bbi_8bbi_file_BBIFile(PyObject *o) {
+  PyObject* tmp;
+  struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *p = (struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *)o;
+  tmp = ((PyObject*)p->file);
+  p->file = Py_None; Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  tmp = ((PyObject*)p->reader);
+  p->reader = Py_None; Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  tmp = ((PyObject*)p->chrom_bpt);
+  p->chrom_bpt = ((struct __pyx_obj_2bx_3bbi_8bpt_file_BPTFile *)Py_None); Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  tmp = ((PyObject*)p->level_list);
+  p->level_list = Py_None; Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  return 0;
+}
+
+static PyObject *__pyx_getprop_2bx_3bbi_8bbi_file_7BBIFile_magic(PyObject *o, CYTHON_UNUSED void *x) {
+  return __pyx_pw_2bx_3bbi_8bbi_file_7BBIFile_5magic_1__get__(o);
+}
+
+static int __pyx_setprop_2bx_3bbi_8bbi_file_7BBIFile_magic(PyObject *o, PyObject *v, CYTHON_UNUSED void *x) {
+  if (v) {
+    return __pyx_pw_2bx_3bbi_8bbi_file_7BBIFile_5magic_3__set__(o, v);
+  }
+  else {
+    PyErr_SetString(PyExc_NotImplementedError, "__del__");
+    return -1;
+  }
+}
+
+static PyObject *__pyx_getprop_2bx_3bbi_8bbi_file_7BBIFile_version(PyObject *o, CYTHON_UNUSED void *x) {
+  return __pyx_pw_2bx_3bbi_8bbi_file_7BBIFile_7version_1__get__(o);
+}
+
+static int __pyx_setprop_2bx_3bbi_8bbi_file_7BBIFile_version(PyObject *o, PyObject *v, CYTHON_UNUSED void *x) {
+  if (v) {
+    return __pyx_pw_2bx_3bbi_8bbi_file_7BBIFile_7version_3__set__(o, v);
+  }
+  else {
+    PyErr_SetString(PyExc_NotImplementedError, "__del__");
+    return -1;
+  }
+}
+
+static PyObject *__pyx_getprop_2bx_3bbi_8bbi_file_7BBIFile_zoom_levels(PyObject *o, CYTHON_UNUSED void *x) {
+  return __pyx_pw_2bx_3bbi_8bbi_file_7BBIFile_11zoom_levels_1__get__(o);
+}
+
+static int __pyx_setprop_2bx_3bbi_8bbi_file_7BBIFile_zoom_levels(PyObject *o, PyObject *v, CYTHON_UNUSED void *x) {
+  if (v) {
+    return __pyx_pw_2bx_3bbi_8bbi_file_7BBIFile_11zoom_levels_3__set__(o, v);
+  }
+  else {
+    PyErr_SetString(PyExc_NotImplementedError, "__del__");
+    return -1;
+  }
+}
+
+static PyObject *__pyx_getprop_2bx_3bbi_8bbi_file_7BBIFile_level_list(PyObject *o, CYTHON_UNUSED void *x) {
+  return __pyx_pw_2bx_3bbi_8bbi_file_7BBIFile_10level_list_1__get__(o);
+}
+
+static int __pyx_setprop_2bx_3bbi_8bbi_file_7BBIFile_level_list(PyObject *o, PyObject *v, CYTHON_UNUSED void *x) {
+  if (v) {
+    return __pyx_pw_2bx_3bbi_8bbi_file_7BBIFile_10level_list_3__set__(o, v);
+  }
+  else {
+    return __pyx_pw_2bx_3bbi_8bbi_file_7BBIFile_10level_list_5__del__(o);
+  }
+}
+
+static PyMethodDef __pyx_methods_2bx_3bbi_8bbi_file_BBIFile[] = {
+  {"open", (PyCFunction)__pyx_pw_2bx_3bbi_8bbi_file_7BBIFile_3open, METH_VARARGS|METH_KEYWORDS, __pyx_doc_2bx_3bbi_8bbi_file_7BBIFile_2open},
+  {"summarize", (PyCFunction)__pyx_pw_2bx_3bbi_8bbi_file_7BBIFile_5summarize, METH_VARARGS|METH_KEYWORDS, __pyx_doc_2bx_3bbi_8bbi_file_7BBIFile_4summarize},
+  {"summarize_from_full", (PyCFunction)__pyx_pw_2bx_3bbi_8bbi_file_7BBIFile_7summarize_from_full, METH_VARARGS|METH_KEYWORDS, __pyx_doc_2bx_3bbi_8bbi_file_7BBIFile_6summarize_from_full},
+  {"query", (PyCFunction)__pyx_pw_2bx_3bbi_8bbi_file_7BBIFile_9query, METH_VARARGS|METH_KEYWORDS, __pyx_doc_2bx_3bbi_8bbi_file_7BBIFile_8query},
+  {0, 0, 0, 0}
+};
+
+static struct PyGetSetDef __pyx_getsets_2bx_3bbi_8bbi_file_BBIFile[] = {
+  {(char *)"magic", __pyx_getprop_2bx_3bbi_8bbi_file_7BBIFile_magic, __pyx_setprop_2bx_3bbi_8bbi_file_7BBIFile_magic, 0, 0},
+  {(char *)"version", __pyx_getprop_2bx_3bbi_8bbi_file_7BBIFile_version, __pyx_setprop_2bx_3bbi_8bbi_file_7BBIFile_version, 0, 0},
+  {(char *)"zoom_levels", __pyx_getprop_2bx_3bbi_8bbi_file_7BBIFile_zoom_levels, __pyx_setprop_2bx_3bbi_8bbi_file_7BBIFile_zoom_levels, 0, 0},
+  {(char *)"level_list", __pyx_getprop_2bx_3bbi_8bbi_file_7BBIFile_level_list, __pyx_setprop_2bx_3bbi_8bbi_file_7BBIFile_level_list, 0, 0},
+  {0, 0, 0, 0, 0}
+};
+
+static PyTypeObject __pyx_type_2bx_3bbi_8bbi_file_BBIFile = {
+  PyVarObject_HEAD_INIT(0, 0)
+  "bx.bbi.bbi_file.BBIFile", /*tp_name*/
+  sizeof(struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile), /*tp_basicsize*/
+  0, /*tp_itemsize*/
+  __pyx_tp_dealloc_2bx_3bbi_8bbi_file_BBIFile, /*tp_dealloc*/
+  0, /*tp_print*/
+  0, /*tp_getattr*/
+  0, /*tp_setattr*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*tp_compare*/
+  #else
+  0, /*reserved*/
+  #endif
+  0, /*tp_repr*/
+  0, /*tp_as_number*/
+  0, /*tp_as_sequence*/
+  0, /*tp_as_mapping*/
+  0, /*tp_hash*/
+  0, /*tp_call*/
+  0, /*tp_str*/
+  0, /*tp_getattro*/
+  0, /*tp_setattro*/
+  0, /*tp_as_buffer*/
+  Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+  "\n    A \"big binary indexed\" file. Stores blocks of raw data and numeric \n    summaries of that data at different levels of aggregation (\"zoom levels\").\n    Generic enough to accommodate both wiggle and bed data. \n    ", /*tp_doc*/
+  __pyx_tp_traverse_2bx_3bbi_8bbi_file_BBIFile, /*tp_traverse*/
+  __pyx_tp_clear_2bx_3bbi_8bbi_file_BBIFile, /*tp_clear*/
+  0, /*tp_richcompare*/
+  0, /*tp_weaklistoffset*/
+  0, /*tp_iter*/
+  0, /*tp_iternext*/
+  __pyx_methods_2bx_3bbi_8bbi_file_BBIFile, /*tp_methods*/
+  0, /*tp_members*/
+  __pyx_getsets_2bx_3bbi_8bbi_file_BBIFile, /*tp_getset*/
+  0, /*tp_base*/
+  0, /*tp_dict*/
+  0, /*tp_descr_get*/
+  0, /*tp_descr_set*/
+  0, /*tp_dictoffset*/
+  __pyx_pw_2bx_3bbi_8bbi_file_7BBIFile_1__init__, /*tp_init*/
+  0, /*tp_alloc*/
+  __pyx_tp_new_2bx_3bbi_8bbi_file_BBIFile, /*tp_new*/
+  0, /*tp_free*/
+  0, /*tp_is_gc*/
+  0, /*tp_bases*/
+  0, /*tp_mro*/
+  0, /*tp_cache*/
+  0, /*tp_subclasses*/
+  0, /*tp_weaklist*/
+  0, /*tp_del*/
+  0, /*tp_version_tag*/
+  #if PY_VERSION_HEX >= 0x030400a1
+  0, /*tp_finalize*/
+  #endif
+};
+static struct __pyx_vtabstruct_2bx_3bbi_8bbi_file_BlockHandler __pyx_vtable_2bx_3bbi_8bbi_file_BlockHandler;
+
+static PyObject *__pyx_tp_new_2bx_3bbi_8bbi_file_BlockHandler(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) {
+  struct __pyx_obj_2bx_3bbi_8bbi_file_BlockHandler *p;
+  PyObject *o;
+  if (likely((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)) {
+    o = (*t->tp_alloc)(t, 0);
+  } else {
+    o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0);
+  }
+  if (unlikely(!o)) return 0;
+  p = ((struct __pyx_obj_2bx_3bbi_8bbi_file_BlockHandler *)o);
+  p->__pyx_vtab = __pyx_vtabptr_2bx_3bbi_8bbi_file_BlockHandler;
+  return o;
+}
+
+static void __pyx_tp_dealloc_2bx_3bbi_8bbi_file_BlockHandler(PyObject *o) {
+  #if PY_VERSION_HEX >= 0x030400a1
+  if (unlikely(Py_TYPE(o)->tp_finalize) && (!PyType_IS_GC(Py_TYPE(o)) || !_PyGC_FINALIZED(o))) {
+    if (PyObject_CallFinalizerFromDealloc(o)) return;
+  }
+  #endif
+  (*Py_TYPE(o)->tp_free)(o);
+}
+
+static PyTypeObject __pyx_type_2bx_3bbi_8bbi_file_BlockHandler = {
+  PyVarObject_HEAD_INIT(0, 0)
+  "bx.bbi.bbi_file.BlockHandler", /*tp_name*/
+  sizeof(struct __pyx_obj_2bx_3bbi_8bbi_file_BlockHandler), /*tp_basicsize*/
+  0, /*tp_itemsize*/
+  __pyx_tp_dealloc_2bx_3bbi_8bbi_file_BlockHandler, /*tp_dealloc*/
+  0, /*tp_print*/
+  0, /*tp_getattr*/
+  0, /*tp_setattr*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*tp_compare*/
+  #else
+  0, /*reserved*/
+  #endif
+  0, /*tp_repr*/
+  0, /*tp_as_number*/
+  0, /*tp_as_sequence*/
+  0, /*tp_as_mapping*/
+  0, /*tp_hash*/
+  0, /*tp_call*/
+  0, /*tp_str*/
+  0, /*tp_getattro*/
+  0, /*tp_setattro*/
+  0, /*tp_as_buffer*/
+  Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE, /*tp_flags*/
+  "\n    Callback for `BBIFile.visit_blocks_in_region`\n    ", /*tp_doc*/
+  0, /*tp_traverse*/
+  0, /*tp_clear*/
+  0, /*tp_richcompare*/
+  0, /*tp_weaklistoffset*/
+  0, /*tp_iter*/
+  0, /*tp_iternext*/
+  0, /*tp_methods*/
+  0, /*tp_members*/
+  0, /*tp_getset*/
+  0, /*tp_base*/
+  0, /*tp_dict*/
+  0, /*tp_descr_get*/
+  0, /*tp_descr_set*/
+  0, /*tp_dictoffset*/
+  0, /*tp_init*/
+  0, /*tp_alloc*/
+  __pyx_tp_new_2bx_3bbi_8bbi_file_BlockHandler, /*tp_new*/
+  0, /*tp_free*/
+  0, /*tp_is_gc*/
+  0, /*tp_bases*/
+  0, /*tp_mro*/
+  0, /*tp_cache*/
+  0, /*tp_subclasses*/
+  0, /*tp_weaklist*/
+  0, /*tp_del*/
+  0, /*tp_version_tag*/
+  #if PY_VERSION_HEX >= 0x030400a1
+  0, /*tp_finalize*/
+  #endif
+};
+static struct __pyx_vtabstruct_2bx_3bbi_8bbi_file_ZoomLevel __pyx_vtable_2bx_3bbi_8bbi_file_ZoomLevel;
+
+static PyObject *__pyx_tp_new_2bx_3bbi_8bbi_file_ZoomLevel(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) {
+  struct __pyx_obj_2bx_3bbi_8bbi_file_ZoomLevel *p;
+  PyObject *o;
+  if (likely((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)) {
+    o = (*t->tp_alloc)(t, 0);
+  } else {
+    o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0);
+  }
+  if (unlikely(!o)) return 0;
+  p = ((struct __pyx_obj_2bx_3bbi_8bbi_file_ZoomLevel *)o);
+  p->__pyx_vtab = __pyx_vtabptr_2bx_3bbi_8bbi_file_ZoomLevel;
+  p->bbi_file = ((struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *)Py_None); Py_INCREF(Py_None);
+  return o;
+}
+
+static void __pyx_tp_dealloc_2bx_3bbi_8bbi_file_ZoomLevel(PyObject *o) {
+  struct __pyx_obj_2bx_3bbi_8bbi_file_ZoomLevel *p = (struct __pyx_obj_2bx_3bbi_8bbi_file_ZoomLevel *)o;
+  #if PY_VERSION_HEX >= 0x030400a1
+  if (unlikely(Py_TYPE(o)->tp_finalize) && !_PyGC_FINALIZED(o)) {
+    if (PyObject_CallFinalizerFromDealloc(o)) return;
+  }
+  #endif
+  PyObject_GC_UnTrack(o);
+  Py_CLEAR(p->bbi_file);
+  (*Py_TYPE(o)->tp_free)(o);
+}
+
+static int __pyx_tp_traverse_2bx_3bbi_8bbi_file_ZoomLevel(PyObject *o, visitproc v, void *a) {
+  int e;
+  struct __pyx_obj_2bx_3bbi_8bbi_file_ZoomLevel *p = (struct __pyx_obj_2bx_3bbi_8bbi_file_ZoomLevel *)o;
+  if (p->bbi_file) {
+    e = (*v)(((PyObject*)p->bbi_file), a); if (e) return e;
+  }
+  return 0;
+}
+
+static int __pyx_tp_clear_2bx_3bbi_8bbi_file_ZoomLevel(PyObject *o) {
+  PyObject* tmp;
+  struct __pyx_obj_2bx_3bbi_8bbi_file_ZoomLevel *p = (struct __pyx_obj_2bx_3bbi_8bbi_file_ZoomLevel *)o;
+  tmp = ((PyObject*)p->bbi_file);
+  p->bbi_file = ((struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *)Py_None); Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  return 0;
+}
+
+static PyObject *__pyx_getprop_2bx_3bbi_8bbi_file_9ZoomLevel_reduction_level(PyObject *o, CYTHON_UNUSED void *x) {
+  return __pyx_pw_2bx_3bbi_8bbi_file_9ZoomLevel_15reduction_level_1__get__(o);
+}
+
+static int __pyx_setprop_2bx_3bbi_8bbi_file_9ZoomLevel_reduction_level(PyObject *o, PyObject *v, CYTHON_UNUSED void *x) {
+  if (v) {
+    return __pyx_pw_2bx_3bbi_8bbi_file_9ZoomLevel_15reduction_level_3__set__(o, v);
+  }
+  else {
+    PyErr_SetString(PyExc_NotImplementedError, "__del__");
+    return -1;
+  }
+}
+
+static PyObject *__pyx_getprop_2bx_3bbi_8bbi_file_9ZoomLevel_data_offset(PyObject *o, CYTHON_UNUSED void *x) {
+  return __pyx_pw_2bx_3bbi_8bbi_file_9ZoomLevel_11data_offset_1__get__(o);
+}
+
+static int __pyx_setprop_2bx_3bbi_8bbi_file_9ZoomLevel_data_offset(PyObject *o, PyObject *v, CYTHON_UNUSED void *x) {
+  if (v) {
+    return __pyx_pw_2bx_3bbi_8bbi_file_9ZoomLevel_11data_offset_3__set__(o, v);
+  }
+  else {
+    PyErr_SetString(PyExc_NotImplementedError, "__del__");
+    return -1;
+  }
+}
+
+static PyObject *__pyx_getprop_2bx_3bbi_8bbi_file_9ZoomLevel_index_offset(PyObject *o, CYTHON_UNUSED void *x) {
+  return __pyx_pw_2bx_3bbi_8bbi_file_9ZoomLevel_12index_offset_1__get__(o);
+}
+
+static int __pyx_setprop_2bx_3bbi_8bbi_file_9ZoomLevel_index_offset(PyObject *o, PyObject *v, CYTHON_UNUSED void *x) {
+  if (v) {
+    return __pyx_pw_2bx_3bbi_8bbi_file_9ZoomLevel_12index_offset_3__set__(o, v);
+  }
+  else {
+    PyErr_SetString(PyExc_NotImplementedError, "__del__");
+    return -1;
+  }
+}
+
+static PyMethodDef __pyx_methods_2bx_3bbi_8bbi_file_ZoomLevel[] = {
+  {"_summary_blocks_in_region", (PyCFunction)__pyx_pw_2bx_3bbi_8bbi_file_9ZoomLevel_1_summary_blocks_in_region, METH_VARARGS|METH_KEYWORDS, __pyx_doc_2bx_3bbi_8bbi_file_9ZoomLevel__summary_blocks_in_region},
+  {0, 0, 0, 0}
+};
+
+static struct PyGetSetDef __pyx_getsets_2bx_3bbi_8bbi_file_ZoomLevel[] = {
+  {(char *)"reduction_level", __pyx_getprop_2bx_3bbi_8bbi_file_9ZoomLevel_reduction_level, __pyx_setprop_2bx_3bbi_8bbi_file_9ZoomLevel_reduction_level, 0, 0},
+  {(char *)"data_offset", __pyx_getprop_2bx_3bbi_8bbi_file_9ZoomLevel_data_offset, __pyx_setprop_2bx_3bbi_8bbi_file_9ZoomLevel_data_offset, 0, 0},
+  {(char *)"index_offset", __pyx_getprop_2bx_3bbi_8bbi_file_9ZoomLevel_index_offset, __pyx_setprop_2bx_3bbi_8bbi_file_9ZoomLevel_index_offset, 0, 0},
+  {0, 0, 0, 0, 0}
+};
+
+static PyTypeObject __pyx_type_2bx_3bbi_8bbi_file_ZoomLevel = {
+  PyVarObject_HEAD_INIT(0, 0)
+  "bx.bbi.bbi_file.ZoomLevel", /*tp_name*/
+  sizeof(struct __pyx_obj_2bx_3bbi_8bbi_file_ZoomLevel), /*tp_basicsize*/
+  0, /*tp_itemsize*/
+  __pyx_tp_dealloc_2bx_3bbi_8bbi_file_ZoomLevel, /*tp_dealloc*/
+  0, /*tp_print*/
+  0, /*tp_getattr*/
+  0, /*tp_setattr*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*tp_compare*/
+  #else
+  0, /*reserved*/
+  #endif
+  0, /*tp_repr*/
+  0, /*tp_as_number*/
+  0, /*tp_as_sequence*/
+  0, /*tp_as_mapping*/
+  0, /*tp_hash*/
+  0, /*tp_call*/
+  0, /*tp_str*/
+  0, /*tp_getattro*/
+  0, /*tp_setattro*/
+  0, /*tp_as_buffer*/
+  Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+  0, /*tp_doc*/
+  __pyx_tp_traverse_2bx_3bbi_8bbi_file_ZoomLevel, /*tp_traverse*/
+  __pyx_tp_clear_2bx_3bbi_8bbi_file_ZoomLevel, /*tp_clear*/
+  0, /*tp_richcompare*/
+  0, /*tp_weaklistoffset*/
+  0, /*tp_iter*/
+  0, /*tp_iternext*/
+  __pyx_methods_2bx_3bbi_8bbi_file_ZoomLevel, /*tp_methods*/
+  0, /*tp_members*/
+  __pyx_getsets_2bx_3bbi_8bbi_file_ZoomLevel, /*tp_getset*/
+  0, /*tp_base*/
+  0, /*tp_dict*/
+  0, /*tp_descr_get*/
+  0, /*tp_descr_set*/
+  0, /*tp_dictoffset*/
+  0, /*tp_init*/
+  0, /*tp_alloc*/
+  __pyx_tp_new_2bx_3bbi_8bbi_file_ZoomLevel, /*tp_new*/
+  0, /*tp_free*/
+  0, /*tp_is_gc*/
+  0, /*tp_bases*/
+  0, /*tp_mro*/
+  0, /*tp_cache*/
+  0, /*tp_subclasses*/
+  0, /*tp_weaklist*/
+  0, /*tp_del*/
+  0, /*tp_version_tag*/
+  #if PY_VERSION_HEX >= 0x030400a1
+  0, /*tp_finalize*/
+  #endif
+};
+
+static PyMethodDef __pyx_methods[] = {
+  {0, 0, 0, 0}
+};
+
+#if PY_MAJOR_VERSION >= 3
+static struct PyModuleDef __pyx_moduledef = {
+  #if PY_VERSION_HEX < 0x03020000
+    { PyObject_HEAD_INIT(NULL) NULL, 0, NULL },
+  #else
+    PyModuleDef_HEAD_INIT,
+  #endif
+    "bbi_file",
+    __pyx_k_Core_implementation_for_reading, /* m_doc */
+    -1, /* m_size */
+    __pyx_methods /* m_methods */,
+    NULL, /* m_reload */
+    NULL, /* m_traverse */
+    NULL, /* m_clear */
+    NULL /* m_free */
+};
+#endif
+
+static __Pyx_StringTabEntry __pyx_string_tab[] = {
+  {&__pyx_n_s_BinaryFileReader, __pyx_k_BinaryFileReader, sizeof(__pyx_k_BinaryFileReader), 0, 0, 1, 1},
+  {&__pyx_kp_u_Format_string_allocated_too_shor, __pyx_k_Format_string_allocated_too_shor, sizeof(__pyx_k_Format_string_allocated_too_shor), 0, 1, 0, 0},
+  {&__pyx_kp_u_Format_string_allocated_too_shor_2, __pyx_k_Format_string_allocated_too_shor_2, sizeof(__pyx_k_Format_string_allocated_too_shor_2), 0, 1, 0, 0},
+  {&__pyx_n_s_II, __pyx_k_II, sizeof(__pyx_k_II), 0, 0, 1, 1},
+  {&__pyx_kp_u_Non_native_byte_order_not_suppor, __pyx_k_Non_native_byte_order_not_suppor, sizeof(__pyx_k_Non_native_byte_order_not_suppor), 0, 1, 0, 0},
+  {&__pyx_n_s_RuntimeError, __pyx_k_RuntimeError, sizeof(__pyx_k_RuntimeError), 0, 0, 1, 1},
+  {&__pyx_n_s_StringIO, __pyx_k_StringIO, sizeof(__pyx_k_StringIO), 0, 0, 1, 1},
+  {&__pyx_n_s_ValueError, __pyx_k_ValueError, sizeof(__pyx_k_ValueError), 0, 0, 1, 1},
+  {&__pyx_n_s_append, __pyx_k_append, sizeof(__pyx_k_append), 0, 0, 1, 1},
+  {&__pyx_n_s_bx_misc_binary_file, __pyx_k_bx_misc_binary_file, sizeof(__pyx_k_bx_misc_binary_file), 0, 0, 1, 1},
+  {&__pyx_n_s_byteswap_needed, __pyx_k_byteswap_needed, sizeof(__pyx_k_byteswap_needed), 0, 0, 1, 1},
+  {&__pyx_n_s_cStringIO, __pyx_k_cStringIO, sizeof(__pyx_k_cStringIO), 0, 0, 1, 1},
+  {&__pyx_n_s_chrom, __pyx_k_chrom, sizeof(__pyx_k_chrom), 0, 0, 1, 1},
+  {&__pyx_n_s_chrom_id, __pyx_k_chrom_id, sizeof(__pyx_k_chrom_id), 0, 0, 1, 1},
+  {&__pyx_n_s_collections, __pyx_k_collections, sizeof(__pyx_k_collections), 0, 0, 1, 1},
+  {&__pyx_n_s_coverage, __pyx_k_coverage, sizeof(__pyx_k_coverage), 0, 0, 1, 1},
+  {&__pyx_n_s_decompress, __pyx_k_decompress, sizeof(__pyx_k_decompress), 0, 0, 1, 1},
+  {&__pyx_n_s_deque, __pyx_k_deque, sizeof(__pyx_k_deque), 0, 0, 1, 1},
+  {&__pyx_n_s_dtype, __pyx_k_dtype, sizeof(__pyx_k_dtype), 0, 0, 1, 1},
+  {&__pyx_n_s_end, __pyx_k_end, sizeof(__pyx_k_end), 0, 0, 1, 1},
+  {&__pyx_n_s_expected_sig, __pyx_k_expected_sig, sizeof(__pyx_k_expected_sig), 0, 0, 1, 1},
+  {&__pyx_n_s_extend, __pyx_k_extend, sizeof(__pyx_k_extend), 0, 0, 1, 1},
+  {&__pyx_n_s_file, __pyx_k_file, sizeof(__pyx_k_file), 0, 0, 1, 1},
+  {&__pyx_n_s_find, __pyx_k_find, sizeof(__pyx_k_find), 0, 0, 1, 1},
+  {&__pyx_n_s_find_overlapping_blocks, __pyx_k_find_overlapping_blocks, sizeof(__pyx_k_find_overlapping_blocks), 0, 0, 1, 1},
+  {&__pyx_n_s_float32, __pyx_k_float32, sizeof(__pyx_k_float32), 0, 0, 1, 1},
+  {&__pyx_n_s_float64, __pyx_k_float64, sizeof(__pyx_k_float64), 0, 0, 1, 1},
+  {&__pyx_n_s_fromstring, __pyx_k_fromstring, sizeof(__pyx_k_fromstring), 0, 0, 1, 1},
+  {&__pyx_n_s_import, __pyx_k_import, sizeof(__pyx_k_import), 0, 0, 1, 1},
+  {&__pyx_n_s_main, __pyx_k_main, sizeof(__pyx_k_main), 0, 0, 1, 1},
+  {&__pyx_n_s_math, __pyx_k_math, sizeof(__pyx_k_math), 0, 0, 1, 1},
+  {&__pyx_n_s_max, __pyx_k_max, sizeof(__pyx_k_max), 0, 0, 1, 1},
+  {&__pyx_n_s_max_val, __pyx_k_max_val, sizeof(__pyx_k_max_val), 0, 0, 1, 1},
+  {&__pyx_n_s_mean, __pyx_k_mean, sizeof(__pyx_k_mean), 0, 0, 1, 1},
+  {&__pyx_n_s_min, __pyx_k_min, sizeof(__pyx_k_min), 0, 0, 1, 1},
+  {&__pyx_n_s_min_val, __pyx_k_min_val, sizeof(__pyx_k_min_val), 0, 0, 1, 1},
+  {&__pyx_n_s_names, __pyx_k_names, sizeof(__pyx_k_names), 0, 0, 1, 1},
+  {&__pyx_n_s_nan, __pyx_k_nan, sizeof(__pyx_k_nan), 0, 0, 1, 1},
+  {&__pyx_kp_u_ndarray_is_not_C_contiguous, __pyx_k_ndarray_is_not_C_contiguous, sizeof(__pyx_k_ndarray_is_not_C_contiguous), 0, 1, 0, 0},
+  {&__pyx_kp_u_ndarray_is_not_Fortran_contiguou, __pyx_k_ndarray_is_not_Fortran_contiguou, sizeof(__pyx_k_ndarray_is_not_Fortran_contiguou), 0, 1, 0, 0},
+  {&__pyx_n_s_np, __pyx_k_np, sizeof(__pyx_k_np), 0, 0, 1, 1},
+  {&__pyx_n_s_numpy, __pyx_k_numpy, sizeof(__pyx_k_numpy), 0, 0, 1, 1},
+  {&__pyx_n_s_open, __pyx_k_open, sizeof(__pyx_k_open), 0, 0, 1, 1},
+  {&__pyx_n_s_pyx_vtable, __pyx_k_pyx_vtable, sizeof(__pyx_k_pyx_vtable), 0, 0, 1, 1},
+  {&__pyx_n_s_query, __pyx_k_query, sizeof(__pyx_k_query), 0, 0, 1, 1},
+  {&__pyx_n_s_range, __pyx_k_range, sizeof(__pyx_k_range), 0, 0, 1, 1},
+  {&__pyx_n_s_read, __pyx_k_read, sizeof(__pyx_k_read), 0, 0, 1, 1},
+  {&__pyx_n_s_read_uint16, __pyx_k_read_uint16, sizeof(__pyx_k_read_uint16), 0, 0, 1, 1},
+  {&__pyx_n_s_read_uint32, __pyx_k_read_uint32, sizeof(__pyx_k_read_uint32), 0, 0, 1, 1},
+  {&__pyx_n_s_read_uint64, __pyx_k_read_uint64, sizeof(__pyx_k_read_uint64), 0, 0, 1, 1},
+  {&__pyx_n_s_seek, __pyx_k_seek, sizeof(__pyx_k_seek), 0, 0, 1, 1},
+  {&__pyx_n_s_size, __pyx_k_size, sizeof(__pyx_k_size), 0, 0, 1, 1},
+  {&__pyx_n_s_sqrt, __pyx_k_sqrt, sizeof(__pyx_k_sqrt), 0, 0, 1, 1},
+  {&__pyx_n_s_start, __pyx_k_start, sizeof(__pyx_k_start), 0, 0, 1, 1},
+  {&__pyx_n_s_std_dev, __pyx_k_std_dev, sizeof(__pyx_k_std_dev), 0, 0, 1, 1},
+  {&__pyx_n_s_sum_data, __pyx_k_sum_data, sizeof(__pyx_k_sum_data), 0, 0, 1, 1},
+  {&__pyx_n_s_sum_squares, __pyx_k_sum_squares, sizeof(__pyx_k_sum_squares), 0, 0, 1, 1},
+  {&__pyx_n_s_summarize, __pyx_k_summarize, sizeof(__pyx_k_summarize), 0, 0, 1, 1},
+  {&__pyx_n_s_summarize_from_full, __pyx_k_summarize_from_full, sizeof(__pyx_k_summarize_from_full), 0, 0, 1, 1},
+  {&__pyx_n_s_summary_size, __pyx_k_summary_size, sizeof(__pyx_k_summary_size), 0, 0, 1, 1},
+  {&__pyx_n_s_test, __pyx_k_test, sizeof(__pyx_k_test), 0, 0, 1, 1},
+  {&__pyx_n_s_type_name, __pyx_k_type_name, sizeof(__pyx_k_type_name), 0, 0, 1, 1},
+  {&__pyx_n_s_uint32, __pyx_k_uint32, sizeof(__pyx_k_uint32), 0, 0, 1, 1},
+  {&__pyx_kp_u_unknown_dtype_code_in_numpy_pxd, __pyx_k_unknown_dtype_code_in_numpy_pxd, sizeof(__pyx_k_unknown_dtype_code_in_numpy_pxd), 0, 1, 0, 0},
+  {&__pyx_n_s_unpack, __pyx_k_unpack, sizeof(__pyx_k_unpack), 0, 0, 1, 1},
+  {&__pyx_n_s_valid_count, __pyx_k_valid_count, sizeof(__pyx_k_valid_count), 0, 0, 1, 1},
+  {&__pyx_n_s_zeros, __pyx_k_zeros, sizeof(__pyx_k_zeros), 0, 0, 1, 1},
+  {&__pyx_n_s_zip, __pyx_k_zip, sizeof(__pyx_k_zip), 0, 0, 1, 1},
+  {&__pyx_n_s_zlib, __pyx_k_zlib, sizeof(__pyx_k_zlib), 0, 0, 1, 1},
+  {0, 0, 0, 0, 0, 0, 0}
+};
+static int __Pyx_InitCachedBuiltins(void) {
+  __pyx_builtin_ValueError = __Pyx_GetBuiltinName(__pyx_n_s_ValueError); if (!__pyx_builtin_ValueError) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 224; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_builtin_range = __Pyx_GetBuiltinName(__pyx_n_s_range); if (!__pyx_builtin_range) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 230; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_builtin_zip = __Pyx_GetBuiltinName(__pyx_n_s_zip); if (!__pyx_builtin_zip) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 326; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_builtin_RuntimeError = __Pyx_GetBuiltinName(__pyx_n_s_RuntimeError); if (!__pyx_builtin_RuntimeError) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 802; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  return 0;
+  __pyx_L1_error:;
+  return -1;
+}
+
+static int __Pyx_InitCachedConstants(void) {
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0);
+
+  /* "bx/bbi/bbi_file.pyx":146
+ *         self.uncompress_buf_size = reader.read_uint32()
+ *         # Skip reserved
+ *         reader.seek( 64 )             # <<<<<<<<<<<<<<
+ *         # Read zoom headers
+ *         self.level_list = []
+ */
+  __pyx_tuple_ = PyTuple_Pack(1, __pyx_int_64); if (unlikely(!__pyx_tuple_)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 146; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple_);
+  __Pyx_GIVEREF(__pyx_tuple_);
+
+  /* "bx/bbi/bbi_file.pyx":258
+ *             return chrom_id, chrom_size
+ *         else:
+ *             return None, None             # <<<<<<<<<<<<<<
+ * 
+ *     cdef _summarize_from_full( self, bits32 chrom_id, bits32 start, bits32 end, int summary_size ):
+ */
+  __pyx_tuple__2 = PyTuple_Pack(2, Py_None, Py_None); if (unlikely(!__pyx_tuple__2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 258; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__2);
+  __Pyx_GIVEREF(__pyx_tuple__2);
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":218
+ *             if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)
+ *                 and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)):
+ *                 raise ValueError(u"ndarray is not C contiguous")             # <<<<<<<<<<<<<<
+ * 
+ *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
+ */
+  __pyx_tuple__3 = PyTuple_Pack(1, __pyx_kp_u_ndarray_is_not_C_contiguous); if (unlikely(!__pyx_tuple__3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 218; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__3);
+  __Pyx_GIVEREF(__pyx_tuple__3);
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":222
+ *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
+ *                 and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)):
+ *                 raise ValueError(u"ndarray is not Fortran contiguous")             # <<<<<<<<<<<<<<
+ * 
+ *             info.buf = PyArray_DATA(self)
+ */
+  __pyx_tuple__4 = PyTuple_Pack(1, __pyx_kp_u_ndarray_is_not_Fortran_contiguou); if (unlikely(!__pyx_tuple__4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 222; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__4);
+  __Pyx_GIVEREF(__pyx_tuple__4);
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":260
+ *                 if ((descr.byteorder == c'>' and little_endian) or
+ *                     (descr.byteorder == c'<' and not little_endian)):
+ *                     raise ValueError(u"Non-native byte order not supported")             # <<<<<<<<<<<<<<
+ *                 if   t == NPY_BYTE:        f = "b"
+ *                 elif t == NPY_UBYTE:       f = "B"
+ */
+  __pyx_tuple__5 = PyTuple_Pack(1, __pyx_kp_u_Non_native_byte_order_not_suppor); if (unlikely(!__pyx_tuple__5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 260; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__5);
+  __Pyx_GIVEREF(__pyx_tuple__5);
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":802
+ * 
+ *         if (end - f) - <int>(new_offset - offset[0]) < 15:
+ *             raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd")             # <<<<<<<<<<<<<<
+ * 
+ *         if ((child.byteorder == c'>' and little_endian) or
+ */
+  __pyx_tuple__6 = PyTuple_Pack(1, __pyx_kp_u_Format_string_allocated_too_shor); if (unlikely(!__pyx_tuple__6)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 802; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__6);
+  __Pyx_GIVEREF(__pyx_tuple__6);
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":806
+ *         if ((child.byteorder == c'>' and little_endian) or
+ *             (child.byteorder == c'<' and not little_endian)):
+ *             raise ValueError(u"Non-native byte order not supported")             # <<<<<<<<<<<<<<
+ *             # One could encode it in the format string and have Cython
+ *             # complain instead, BUT: < and > in format strings also imply
+ */
+  __pyx_tuple__7 = PyTuple_Pack(1, __pyx_kp_u_Non_native_byte_order_not_suppor); if (unlikely(!__pyx_tuple__7)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 806; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__7);
+  __Pyx_GIVEREF(__pyx_tuple__7);
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":826
+ *             t = child.type_num
+ *             if end - f < 5:
+ *                 raise RuntimeError(u"Format string allocated too short.")             # <<<<<<<<<<<<<<
+ * 
+ *             # Until ticket #99 is fixed, use integers to avoid warnings
+ */
+  __pyx_tuple__8 = PyTuple_Pack(1, __pyx_kp_u_Format_string_allocated_too_shor_2); if (unlikely(!__pyx_tuple__8)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 826; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__8);
+  __Pyx_GIVEREF(__pyx_tuple__8);
+  __Pyx_RefNannyFinishContext();
+  return 0;
+  __pyx_L1_error:;
+  __Pyx_RefNannyFinishContext();
+  return -1;
+}
+
+static int __Pyx_InitGlobals(void) {
+  if (__Pyx_InitStrings(__pyx_string_tab) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  __pyx_int_0 = PyInt_FromLong(0); if (unlikely(!__pyx_int_0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_int_1 = PyInt_FromLong(1); if (unlikely(!__pyx_int_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_int_32 = PyInt_FromLong(32); if (unlikely(!__pyx_int_32)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_int_64 = PyInt_FromLong(64); if (unlikely(!__pyx_int_64)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  return 0;
+  __pyx_L1_error:;
+  return -1;
+}
+
+#if PY_MAJOR_VERSION < 3
+PyMODINIT_FUNC initbbi_file(void); /*proto*/
+PyMODINIT_FUNC initbbi_file(void)
+#else
+PyMODINIT_FUNC PyInit_bbi_file(void); /*proto*/
+PyMODINIT_FUNC PyInit_bbi_file(void)
+#endif
+{
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannyDeclarations
+  #if CYTHON_REFNANNY
+  __Pyx_RefNanny = __Pyx_RefNannyImportAPI("refnanny");
+  if (!__Pyx_RefNanny) {
+      PyErr_Clear();
+      __Pyx_RefNanny = __Pyx_RefNannyImportAPI("Cython.Runtime.refnanny");
+      if (!__Pyx_RefNanny)
+          Py_FatalError("failed to import 'refnanny' module");
+  }
+  #endif
+  __Pyx_RefNannySetupContext("PyMODINIT_FUNC PyInit_bbi_file(void)", 0);
+  if ( __Pyx_check_binary_version() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_bytes)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #ifdef __Pyx_CyFunction_USED
+  if (__Pyx_CyFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #endif
+  #ifdef __Pyx_FusedFunction_USED
+  if (__pyx_FusedFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #endif
+  #ifdef __Pyx_Generator_USED
+  if (__pyx_Generator_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #endif
+  /*--- Library function declarations ---*/
+  /*--- Threads initialization code ---*/
+  #if defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS
+  #ifdef WITH_THREAD /* Python build with threading support? */
+  PyEval_InitThreads();
+  #endif
+  #endif
+  /*--- Module creation code ---*/
+  #if PY_MAJOR_VERSION < 3
+  __pyx_m = Py_InitModule4("bbi_file", __pyx_methods, __pyx_k_Core_implementation_for_reading, 0, PYTHON_API_VERSION); Py_XINCREF(__pyx_m);
+  #else
+  __pyx_m = PyModule_Create(&__pyx_moduledef);
+  #endif
+  if (unlikely(!__pyx_m)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_d = PyModule_GetDict(__pyx_m); if (unlikely(!__pyx_d)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  Py_INCREF(__pyx_d);
+  __pyx_b = PyImport_AddModule(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_b)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #if CYTHON_COMPILING_IN_PYPY
+  Py_INCREF(__pyx_b);
+  #endif
+  if (PyObject_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  /*--- Initialize various global constants etc. ---*/
+  if (unlikely(__Pyx_InitGlobals() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #if PY_MAJOR_VERSION < 3 && (__PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT)
+  if (__Pyx_init_sys_getdefaultencoding_params() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #endif
+  if (__pyx_module_is_main_bx__bbi__bbi_file) {
+    if (PyObject_SetAttrString(__pyx_m, "__name__", __pyx_n_s_main) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  }
+  #if PY_MAJOR_VERSION >= 3
+  {
+    PyObject *modules = PyImport_GetModuleDict(); if (unlikely(!modules)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (!PyDict_GetItemString(modules, "bx.bbi.bbi_file")) {
+      if (unlikely(PyDict_SetItemString(modules, "bx.bbi.bbi_file", __pyx_m) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+  }
+  #endif
+  /*--- Builtin init code ---*/
+  if (unlikely(__Pyx_InitCachedBuiltins() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  /*--- Constants init code ---*/
+  if (unlikely(__Pyx_InitCachedConstants() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  /*--- Global init code ---*/
+  /*--- Variable export code ---*/
+  /*--- Function export code ---*/
+  /*--- Type init code ---*/
+  if (PyType_Ready(&__pyx_type_2bx_3bbi_8bbi_file_SummaryBlock) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 52; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_type_2bx_3bbi_8bbi_file_SummaryBlock.tp_print = 0;
+  if (PyObject_SetAttrString(__pyx_m, "SummaryBlock", (PyObject *)&__pyx_type_2bx_3bbi_8bbi_file_SummaryBlock) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 52; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_2bx_3bbi_8bbi_file_SummaryBlock = &__pyx_type_2bx_3bbi_8bbi_file_SummaryBlock;
+  __pyx_vtabptr_2bx_3bbi_8bbi_file_SummarizedData = &__pyx_vtable_2bx_3bbi_8bbi_file_SummarizedData;
+  __pyx_vtable_2bx_3bbi_8bbi_file_SummarizedData.accumulate_interval_value = (PyObject *(*)(struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData *, __pyx_t_2bx_3bbi_5types_bits32, __pyx_t_2bx_3bbi_5types_bits32, float))__pyx_f_2bx_3bbi_8bbi_file_14SummarizedData_accumulate_interval_value;
+  if (PyType_Ready(&__pyx_type_2bx_3bbi_8bbi_file_SummarizedData) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 58; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_type_2bx_3bbi_8bbi_file_SummarizedData.tp_print = 0;
+  if (__Pyx_SetVtable(__pyx_type_2bx_3bbi_8bbi_file_SummarizedData.tp_dict, __pyx_vtabptr_2bx_3bbi_8bbi_file_SummarizedData) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 58; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyObject_SetAttrString(__pyx_m, "SummarizedData", (PyObject *)&__pyx_type_2bx_3bbi_8bbi_file_SummarizedData) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 58; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_2bx_3bbi_8bbi_file_SummarizedData = &__pyx_type_2bx_3bbi_8bbi_file_SummarizedData;
+  __pyx_vtabptr_2bx_3bbi_8bbi_file_BBIFile = &__pyx_vtable_2bx_3bbi_8bbi_file_BBIFile;
+  __pyx_vtable_2bx_3bbi_8bbi_file_BBIFile.visit_blocks_in_region = (PyObject *(*)(struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *, __pyx_t_2bx_3bbi_5types_bits32, __pyx_t_2bx_3bbi_5types_bits32, __pyx_t_2bx_3bbi_5types_bits32, struct __pyx_obj_2bx_3bbi_8bbi_file_BlockHandler *))__pyx_f_2bx_3bbi_8bbi_file_7BBIFile_visit_blocks_in_region;
+  __pyx_vtable_2bx_3bbi_8bbi_file_BBIFile._get_chrom_id_and_size = (PyObject *(*)(struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *, char *))__pyx_f_2bx_3bbi_8bbi_file_7BBIFile__get_chrom_id_and_size;
+  __pyx_vtable_2bx_3bbi_8bbi_file_BBIFile._best_zoom_level = (PyObject *(*)(struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *, int))__pyx_f_2bx_3bbi_8bbi_file_7BBIFile__best_zoom_level;
+  __pyx_vtable_2bx_3bbi_8bbi_file_BBIFile.summarize = (PyObject *(*)(struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *, char *, __pyx_t_2bx_3bbi_5types_bits32, __pyx_t_2bx_3bbi_5types_bits32, int, int __pyx_skip_dispatch))__pyx_f_2bx_3bbi_8bbi_file_7BBIFile_summarize;
+  __pyx_vtable_2bx_3bbi_8bbi_file_BBIFile.summarize_from_full = (PyObject *(*)(struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *, char *, __pyx_t_2bx_3bbi_5types_bits32, __pyx_t_2bx_3bbi_5types_bits32, int, int __pyx_skip_dispatch))__pyx_f_2bx_3bbi_8bbi_file_7BBIFile_summarize_from_full;
+  __pyx_vtable_2bx_3bbi_8bbi_file_BBIFile.query = (PyObject *(*)(struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *, char *, __pyx_t_2bx_3bbi_5types_bits32, __pyx_t_2bx_3bbi_5types_bits32, int, int __pyx_skip_dispatch))__pyx_f_2bx_3bbi_8bbi_file_7BBIFile_query;
+  __pyx_vtable_2bx_3bbi_8bbi_file_BBIFile._summarize_from_full = (PyObject *(*)(struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *, __pyx_t_2bx_3bbi_5types_bits32, __pyx_t_2bx_3bbi_5types_bits32, __pyx_t_2bx_3bbi_5types_bits32, int))__pyx_f_2bx_3bbi_8bbi_file_7BBIFile__summarize_from_full;
+  if (PyType_Ready(&__pyx_type_2bx_3bbi_8bbi_file_BBIFile) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 112; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_type_2bx_3bbi_8bbi_file_BBIFile.tp_print = 0;
+  if (__Pyx_SetVtable(__pyx_type_2bx_3bbi_8bbi_file_BBIFile.tp_dict, __pyx_vtabptr_2bx_3bbi_8bbi_file_BBIFile) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 112; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyObject_SetAttrString(__pyx_m, "BBIFile", (PyObject *)&__pyx_type_2bx_3bbi_8bbi_file_BBIFile) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 112; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_2bx_3bbi_8bbi_file_BBIFile = &__pyx_type_2bx_3bbi_8bbi_file_BBIFile;
+  __pyx_vtabptr_2bx_3bbi_8bbi_file_BlockHandler = &__pyx_vtable_2bx_3bbi_8bbi_file_BlockHandler;
+  __pyx_vtable_2bx_3bbi_8bbi_file_BlockHandler.handle_block = (PyObject *(*)(struct __pyx_obj_2bx_3bbi_8bbi_file_BlockHandler *, PyObject *, struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *))__pyx_f_2bx_3bbi_8bbi_file_12BlockHandler_handle_block;
+  if (PyType_Ready(&__pyx_type_2bx_3bbi_8bbi_file_BlockHandler) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 105; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_type_2bx_3bbi_8bbi_file_BlockHandler.tp_print = 0;
+  if (__Pyx_SetVtable(__pyx_type_2bx_3bbi_8bbi_file_BlockHandler.tp_dict, __pyx_vtabptr_2bx_3bbi_8bbi_file_BlockHandler) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 105; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyObject_SetAttrString(__pyx_m, "BlockHandler", (PyObject *)&__pyx_type_2bx_3bbi_8bbi_file_BlockHandler) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 105; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_2bx_3bbi_8bbi_file_BlockHandler = &__pyx_type_2bx_3bbi_8bbi_file_BlockHandler;
+  __pyx_vtabptr_2bx_3bbi_8bbi_file_ZoomLevel = &__pyx_vtable_2bx_3bbi_8bbi_file_ZoomLevel;
+  __pyx_vtable_2bx_3bbi_8bbi_file_ZoomLevel._get_summary_slice = (PyObject *(*)(struct __pyx_obj_2bx_3bbi_8bbi_file_ZoomLevel *, __pyx_t_2bx_3bbi_5types_bits32, __pyx_t_2bx_3bbi_5types_bits32, PyObject *))__pyx_f_2bx_3bbi_8bbi_file_9ZoomLevel__get_summary_slice;
+  __pyx_vtable_2bx_3bbi_8bbi_file_ZoomLevel._summarize = (PyObject *(*)(struct __pyx_obj_2bx_3bbi_8bbi_file_ZoomLevel *, __pyx_t_2bx_3bbi_5types_bits32, __pyx_t_2bx_3bbi_5types_bits32, __pyx_t_2bx_3bbi_5types_bits32, int))__pyx_f_2bx_3bbi_8bbi_file_9ZoomLevel__summarize;
+  if (PyType_Ready(&__pyx_type_2bx_3bbi_8bbi_file_ZoomLevel) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 281; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_type_2bx_3bbi_8bbi_file_ZoomLevel.tp_print = 0;
+  if (__Pyx_SetVtable(__pyx_type_2bx_3bbi_8bbi_file_ZoomLevel.tp_dict, __pyx_vtabptr_2bx_3bbi_8bbi_file_ZoomLevel) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 281; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyObject_SetAttrString(__pyx_m, "ZoomLevel", (PyObject *)&__pyx_type_2bx_3bbi_8bbi_file_ZoomLevel) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 281; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_2bx_3bbi_8bbi_file_ZoomLevel = &__pyx_type_2bx_3bbi_8bbi_file_ZoomLevel;
+  /*--- Type import code ---*/
+  __pyx_ptype_2bx_3bbi_8bpt_file_BPTFile = __Pyx_ImportType("bx.bbi.bpt_file", "BPTFile", sizeof(struct __pyx_obj_2bx_3bbi_8bpt_file_BPTFile), 1); if (unlikely(!__pyx_ptype_2bx_3bbi_8bpt_file_BPTFile)) {__pyx_filename = __pyx_f[3]; __pyx_lineno = 5; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_2bx_3bbi_12cirtree_file_CIRTreeFile = __Pyx_ImportType("bx.bbi.cirtree_file", "CIRTreeFile", sizeof(struct __pyx_obj_2bx_3bbi_12cirtree_file_CIRTreeFile), 1); if (unlikely(!__pyx_ptype_2bx_3bbi_12cirtree_file_CIRTreeFile)) {__pyx_filename = __pyx_f[4]; __pyx_lineno = 3; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_7cpython_4type_type = __Pyx_ImportType(__Pyx_BUILTIN_MODULE_NAME, "type", 
+  #if CYTHON_COMPILING_IN_PYPY
+  sizeof(PyTypeObject),
+  #else
+  sizeof(PyHeapTypeObject),
+  #endif
+  0); if (unlikely(!__pyx_ptype_7cpython_4type_type)) {__pyx_filename = __pyx_f[5]; __pyx_lineno = 9; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_5numpy_dtype = __Pyx_ImportType("numpy", "dtype", sizeof(PyArray_Descr), 0); if (unlikely(!__pyx_ptype_5numpy_dtype)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 155; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_5numpy_flatiter = __Pyx_ImportType("numpy", "flatiter", sizeof(PyArrayIterObject), 0); if (unlikely(!__pyx_ptype_5numpy_flatiter)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 168; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_5numpy_broadcast = __Pyx_ImportType("numpy", "broadcast", sizeof(PyArrayMultiIterObject), 0); if (unlikely(!__pyx_ptype_5numpy_broadcast)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 172; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_5numpy_ndarray = __Pyx_ImportType("numpy", "ndarray", sizeof(PyArrayObject), 0); if (unlikely(!__pyx_ptype_5numpy_ndarray)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 181; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_5numpy_ufunc = __Pyx_ImportType("numpy", "ufunc", sizeof(PyUFuncObject), 0); if (unlikely(!__pyx_ptype_5numpy_ufunc)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 864; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  /*--- Variable import code ---*/
+  /*--- Function import code ---*/
+  /*--- Execution code ---*/
+
+  /* "bx/bbi/bbi_file.pyx":12
+ * cimport cython
+ * 
+ * from collections import deque             # <<<<<<<<<<<<<<
+ * from bpt_file cimport BPTFile
+ * from cirtree_file cimport CIRTreeFile
+ */
+  __pyx_t_1 = PyList_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 12; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_INCREF(__pyx_n_s_deque);
+  PyList_SET_ITEM(__pyx_t_1, 0, __pyx_n_s_deque);
+  __Pyx_GIVEREF(__pyx_n_s_deque);
+  __pyx_t_2 = __Pyx_Import(__pyx_n_s_collections, __pyx_t_1, -1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 12; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_1 = __Pyx_ImportFrom(__pyx_t_2, __pyx_n_s_deque); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 12; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_deque, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 12; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+  /* "bx/bbi/bbi_file.pyx":19
+ * from libc cimport limits
+ * 
+ * import numpy             # <<<<<<<<<<<<<<
+ * cimport numpy
+ * cimport numpy as np
+ */
+  __pyx_t_2 = __Pyx_Import(__pyx_n_s_numpy, 0, -1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 19; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_numpy, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 19; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+  /* "bx/bbi/bbi_file.pyx":22
+ * cimport numpy
+ * cimport numpy as np
+ * import numpy as np             # <<<<<<<<<<<<<<
+ * 
+ * from bx.misc.binary_file import BinaryFileReader
+ */
+  __pyx_t_2 = __Pyx_Import(__pyx_n_s_numpy, 0, -1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 22; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_np, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 22; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+  /* "bx/bbi/bbi_file.pyx":24
+ * import numpy as np
+ * 
+ * from bx.misc.binary_file import BinaryFileReader             # <<<<<<<<<<<<<<
+ * from cStringIO import StringIO
+ * import zlib, math
+ */
+  __pyx_t_2 = PyList_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 24; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_INCREF(__pyx_n_s_BinaryFileReader);
+  PyList_SET_ITEM(__pyx_t_2, 0, __pyx_n_s_BinaryFileReader);
+  __Pyx_GIVEREF(__pyx_n_s_BinaryFileReader);
+  __pyx_t_1 = __Pyx_Import(__pyx_n_s_bx_misc_binary_file, __pyx_t_2, -1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 24; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_1, __pyx_n_s_BinaryFileReader); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 24; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_BinaryFileReader, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 24; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "bx/bbi/bbi_file.pyx":25
+ * 
+ * from bx.misc.binary_file import BinaryFileReader
+ * from cStringIO import StringIO             # <<<<<<<<<<<<<<
+ * import zlib, math
+ * 
+ */
+  __pyx_t_1 = PyList_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 25; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_INCREF(__pyx_n_s_StringIO);
+  PyList_SET_ITEM(__pyx_t_1, 0, __pyx_n_s_StringIO);
+  __Pyx_GIVEREF(__pyx_n_s_StringIO);
+  __pyx_t_2 = __Pyx_Import(__pyx_n_s_cStringIO, __pyx_t_1, -1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 25; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_1 = __Pyx_ImportFrom(__pyx_t_2, __pyx_n_s_StringIO); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 25; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_StringIO, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 25; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+  /* "bx/bbi/bbi_file.pyx":26
+ * from bx.misc.binary_file import BinaryFileReader
+ * from cStringIO import StringIO
+ * import zlib, math             # <<<<<<<<<<<<<<
+ * 
+ * # Signatures for bbi related file types
+ */
+  __pyx_t_2 = __Pyx_Import(__pyx_n_s_zlib, 0, -1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 26; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_zlib, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 26; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_2 = __Pyx_Import(__pyx_n_s_math, 0, -1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 26; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_math, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 26; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+  /* "bx/bbi/bbi_file.pyx":30
+ * # Signatures for bbi related file types
+ * 
+ * cdef public int big_wig_sig = 0x888FFC26             # <<<<<<<<<<<<<<
+ * cdef public int big_bed_sig = 0x8789F2EB
+ * 
+ */
+  big_wig_sig = 0x888FFC26;
+
+  /* "bx/bbi/bbi_file.pyx":31
+ * 
+ * cdef public int big_wig_sig = 0x888FFC26
+ * cdef public int big_bed_sig = 0x8789F2EB             # <<<<<<<<<<<<<<
+ * 
+ * # Some record sizes for parsing
+ */
+  big_bed_sig = 0x8789F2EB;
+
+  /* "bx/bbi/bbi_file.pyx":1
+ * # cython: profile=False             # <<<<<<<<<<<<<<
+ * 
+ * """
+ */
+  __pyx_t_2 = PyDict_New(); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":979
+ *      arr.base = baseptr
+ * 
+ * cdef inline object get_array_base(ndarray arr):             # <<<<<<<<<<<<<<
+ *     if arr.base is NULL:
+ *         return None
+ */
+
+  /*--- Wrapped vars code ---*/
+
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  if (__pyx_m) {
+    if (__pyx_d) {
+      __Pyx_AddTraceback("init bx.bbi.bbi_file", __pyx_clineno, __pyx_lineno, __pyx_filename);
+    }
+    Py_DECREF(__pyx_m); __pyx_m = 0;
+  } else if (!PyErr_Occurred()) {
+    PyErr_SetString(PyExc_ImportError, "init bx.bbi.bbi_file");
+  }
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  #if PY_MAJOR_VERSION < 3
+  return;
+  #else
+  return __pyx_m;
+  #endif
+}
+
+/* --- Runtime support code --- */
+#if CYTHON_REFNANNY
+static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) {
+    PyObject *m = NULL, *p = NULL;
+    void *r = NULL;
+    m = PyImport_ImportModule((char *)modname);
+    if (!m) goto end;
+    p = PyObject_GetAttrString(m, (char *)"RefNannyAPI");
+    if (!p) goto end;
+    r = PyLong_AsVoidPtr(p);
+end:
+    Py_XDECREF(p);
+    Py_XDECREF(m);
+    return (__Pyx_RefNannyAPIStruct *)r;
+}
+#endif
+
+static PyObject *__Pyx_GetBuiltinName(PyObject *name) {
+    PyObject* result = __Pyx_PyObject_GetAttrStr(__pyx_b, name);
+    if (unlikely(!result)) {
+        PyErr_Format(PyExc_NameError,
+#if PY_MAJOR_VERSION >= 3
+            "name '%U' is not defined", name);
+#else
+            "name '%.200s' is not defined", PyString_AS_STRING(name));
+#endif
+    }
+    return result;
+}
+
+static void __Pyx_RaiseArgtupleInvalid(
+    const char* func_name,
+    int exact,
+    Py_ssize_t num_min,
+    Py_ssize_t num_max,
+    Py_ssize_t num_found)
+{
+    Py_ssize_t num_expected;
+    const char *more_or_less;
+    if (num_found < num_min) {
+        num_expected = num_min;
+        more_or_less = "at least";
+    } else {
+        num_expected = num_max;
+        more_or_less = "at most";
+    }
+    if (exact) {
+        more_or_less = "exactly";
+    }
+    PyErr_Format(PyExc_TypeError,
+                 "%.200s() takes %.8s %" CYTHON_FORMAT_SSIZE_T "d positional argument%.1s (%" CYTHON_FORMAT_SSIZE_T "d given)",
+                 func_name, more_or_less, num_expected,
+                 (num_expected == 1) ? "" : "s", num_found);
+}
+
+static void __Pyx_RaiseDoubleKeywordsError(
+    const char* func_name,
+    PyObject* kw_name)
+{
+    PyErr_Format(PyExc_TypeError,
+        #if PY_MAJOR_VERSION >= 3
+        "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
+        #else
+        "%s() got multiple values for keyword argument '%s'", func_name,
+        PyString_AsString(kw_name));
+        #endif
+}
+
+static int __Pyx_ParseOptionalKeywords(
+    PyObject *kwds,
+    PyObject **argnames[],
+    PyObject *kwds2,
+    PyObject *values[],
+    Py_ssize_t num_pos_args,
+    const char* function_name)
+{
+    PyObject *key = 0, *value = 0;
+    Py_ssize_t pos = 0;
+    PyObject*** name;
+    PyObject*** first_kw_arg = argnames + num_pos_args;
+    while (PyDict_Next(kwds, &pos, &key, &value)) {
+        name = first_kw_arg;
+        while (*name && (**name != key)) name++;
+        if (*name) {
+            values[name-argnames] = value;
+            continue;
+        }
+        name = first_kw_arg;
+        #if PY_MAJOR_VERSION < 3
+        if (likely(PyString_CheckExact(key)) || likely(PyString_Check(key))) {
+            while (*name) {
+                if ((CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**name) == PyString_GET_SIZE(key))
+                        && _PyString_Eq(**name, key)) {
+                    values[name-argnames] = value;
+                    break;
+                }
+                name++;
+            }
+            if (*name) continue;
+            else {
+                PyObject*** argname = argnames;
+                while (argname != first_kw_arg) {
+                    if ((**argname == key) || (
+                            (CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**argname) == PyString_GET_SIZE(key))
+                             && _PyString_Eq(**argname, key))) {
+                        goto arg_passed_twice;
+                    }
+                    argname++;
+                }
+            }
+        } else
+        #endif
+        if (likely(PyUnicode_Check(key))) {
+            while (*name) {
+                int cmp = (**name == key) ? 0 :
+                #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3
+                    (PyUnicode_GET_SIZE(**name) != PyUnicode_GET_SIZE(key)) ? 1 :
+                #endif
+                    PyUnicode_Compare(**name, key);
+                if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad;
+                if (cmp == 0) {
+                    values[name-argnames] = value;
+                    break;
+                }
+                name++;
+            }
+            if (*name) continue;
+            else {
+                PyObject*** argname = argnames;
+                while (argname != first_kw_arg) {
+                    int cmp = (**argname == key) ? 0 :
+                    #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3
+                        (PyUnicode_GET_SIZE(**argname) != PyUnicode_GET_SIZE(key)) ? 1 :
+                    #endif
+                        PyUnicode_Compare(**argname, key);
+                    if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad;
+                    if (cmp == 0) goto arg_passed_twice;
+                    argname++;
+                }
+            }
+        } else
+            goto invalid_keyword_type;
+        if (kwds2) {
+            if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
+        } else {
+            goto invalid_keyword;
+        }
+    }
+    return 0;
+arg_passed_twice:
+    __Pyx_RaiseDoubleKeywordsError(function_name, key);
+    goto bad;
+invalid_keyword_type:
+    PyErr_Format(PyExc_TypeError,
+        "%.200s() keywords must be strings", function_name);
+    goto bad;
+invalid_keyword:
+    PyErr_Format(PyExc_TypeError,
+    #if PY_MAJOR_VERSION < 3
+        "%.200s() got an unexpected keyword argument '%.200s'",
+        function_name, PyString_AsString(key));
+    #else
+        "%s() got an unexpected keyword argument '%U'",
+        function_name, key);
+    #endif
+bad:
+    return -1;
+}
+
+static CYTHON_INLINE PyObject *__Pyx_GetModuleGlobalName(PyObject *name) {
+    PyObject *result;
+#if CYTHON_COMPILING_IN_CPYTHON
+    result = PyDict_GetItem(__pyx_d, name);
+    if (likely(result)) {
+        Py_INCREF(result);
+    } else {
+#else
+    result = PyObject_GetItem(__pyx_d, name);
+    if (!result) {
+        PyErr_Clear();
+#endif
+        result = __Pyx_GetBuiltinName(name);
+    }
+    return result;
+}
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw) {
+    PyObject *result;
+    ternaryfunc call = func->ob_type->tp_call;
+    if (unlikely(!call))
+        return PyObject_Call(func, arg, kw);
+    if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object")))
+        return NULL;
+    result = (*call)(func, arg, kw);
+    Py_LeaveRecursiveCall();
+    if (unlikely(!result) && unlikely(!PyErr_Occurred())) {
+        PyErr_SetString(
+            PyExc_SystemError,
+            "NULL result without error in PyObject_Call");
+    }
+    return result;
+}
+#endif
+
+static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type) {
+    if (unlikely(!type)) {
+        PyErr_SetString(PyExc_SystemError, "Missing type object");
+        return 0;
+    }
+    if (likely(PyObject_TypeCheck(obj, type)))
+        return 1;
+    PyErr_Format(PyExc_TypeError, "Cannot convert %.200s to %.200s",
+                 Py_TYPE(obj)->tp_name, type->tp_name);
+    return 0;
+}
+
+static CYTHON_INLINE int __Pyx_IsLittleEndian(void) {
+  unsigned int n = 1;
+  return *(unsigned char*)(&n) != 0;
+}
+static void __Pyx_BufFmt_Init(__Pyx_BufFmt_Context* ctx,
+                              __Pyx_BufFmt_StackElem* stack,
+                              __Pyx_TypeInfo* type) {
+  stack[0].field = &ctx->root;
+  stack[0].parent_offset = 0;
+  ctx->root.type = type;
+  ctx->root.name = "buffer dtype";
+  ctx->root.offset = 0;
+  ctx->head = stack;
+  ctx->head->field = &ctx->root;
+  ctx->fmt_offset = 0;
+  ctx->head->parent_offset = 0;
+  ctx->new_packmode = '@';
+  ctx->enc_packmode = '@';
+  ctx->new_count = 1;
+  ctx->enc_count = 0;
+  ctx->enc_type = 0;
+  ctx->is_complex = 0;
+  ctx->is_valid_array = 0;
+  ctx->struct_alignment = 0;
+  while (type->typegroup == 'S') {
+    ++ctx->head;
+    ctx->head->field = type->fields;
+    ctx->head->parent_offset = 0;
+    type = type->fields->type;
+  }
+}
+static int __Pyx_BufFmt_ParseNumber(const char** ts) {
+    int count;
+    const char* t = *ts;
+    if (*t < '0' || *t > '9') {
+      return -1;
+    } else {
+        count = *t++ - '0';
+        while (*t >= '0' && *t < '9') {
+            count *= 10;
+            count += *t++ - '0';
+        }
+    }
+    *ts = t;
+    return count;
+}
+static int __Pyx_BufFmt_ExpectNumber(const char **ts) {
+    int number = __Pyx_BufFmt_ParseNumber(ts);
+    if (number == -1)
+        PyErr_Format(PyExc_ValueError,\
+                     "Does not understand character buffer dtype format string ('%c')", **ts);
+    return number;
+}
+static void __Pyx_BufFmt_RaiseUnexpectedChar(char ch) {
+  PyErr_Format(PyExc_ValueError,
+               "Unexpected format string character: '%c'", ch);
+}
+static const char* __Pyx_BufFmt_DescribeTypeChar(char ch, int is_complex) {
+  switch (ch) {
+    case 'c': return "'char'";
+    case 'b': return "'signed char'";
+    case 'B': return "'unsigned char'";
+    case 'h': return "'short'";
+    case 'H': return "'unsigned short'";
+    case 'i': return "'int'";
+    case 'I': return "'unsigned int'";
+    case 'l': return "'long'";
+    case 'L': return "'unsigned long'";
+    case 'q': return "'long long'";
+    case 'Q': return "'unsigned long long'";
+    case 'f': return (is_complex ? "'complex float'" : "'float'");
+    case 'd': return (is_complex ? "'complex double'" : "'double'");
+    case 'g': return (is_complex ? "'complex long double'" : "'long double'");
+    case 'T': return "a struct";
+    case 'O': return "Python object";
+    case 'P': return "a pointer";
+    case 's': case 'p': return "a string";
+    case 0: return "end";
+    default: return "unparseable format string";
+  }
+}
+static size_t __Pyx_BufFmt_TypeCharToStandardSize(char ch, int is_complex) {
+  switch (ch) {
+    case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1;
+    case 'h': case 'H': return 2;
+    case 'i': case 'I': case 'l': case 'L': return 4;
+    case 'q': case 'Q': return 8;
+    case 'f': return (is_complex ? 8 : 4);
+    case 'd': return (is_complex ? 16 : 8);
+    case 'g': {
+      PyErr_SetString(PyExc_ValueError, "Python does not define a standard format string size for long double ('g')..");
+      return 0;
+    }
+    case 'O': case 'P': return sizeof(void*);
+    default:
+      __Pyx_BufFmt_RaiseUnexpectedChar(ch);
+      return 0;
+    }
+}
+static size_t __Pyx_BufFmt_TypeCharToNativeSize(char ch, int is_complex) {
+  switch (ch) {
+    case 'c': case 'b': case 'B': case 's': case 'p': return 1;
+    case 'h': case 'H': return sizeof(short);
+    case 'i': case 'I': return sizeof(int);
+    case 'l': case 'L': return sizeof(long);
+    #ifdef HAVE_LONG_LONG
+    case 'q': case 'Q': return sizeof(PY_LONG_LONG);
+    #endif
+    case 'f': return sizeof(float) * (is_complex ? 2 : 1);
+    case 'd': return sizeof(double) * (is_complex ? 2 : 1);
+    case 'g': return sizeof(long double) * (is_complex ? 2 : 1);
+    case 'O': case 'P': return sizeof(void*);
+    default: {
+      __Pyx_BufFmt_RaiseUnexpectedChar(ch);
+      return 0;
+    }
+  }
+}
+typedef struct { char c; short x; } __Pyx_st_short;
+typedef struct { char c; int x; } __Pyx_st_int;
+typedef struct { char c; long x; } __Pyx_st_long;
+typedef struct { char c; float x; } __Pyx_st_float;
+typedef struct { char c; double x; } __Pyx_st_double;
+typedef struct { char c; long double x; } __Pyx_st_longdouble;
+typedef struct { char c; void *x; } __Pyx_st_void_p;
+#ifdef HAVE_LONG_LONG
+typedef struct { char c; PY_LONG_LONG x; } __Pyx_st_longlong;
+#endif
+static size_t __Pyx_BufFmt_TypeCharToAlignment(char ch, CYTHON_UNUSED int is_complex) {
+  switch (ch) {
+    case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1;
+    case 'h': case 'H': return sizeof(__Pyx_st_short) - sizeof(short);
+    case 'i': case 'I': return sizeof(__Pyx_st_int) - sizeof(int);
+    case 'l': case 'L': return sizeof(__Pyx_st_long) - sizeof(long);
+#ifdef HAVE_LONG_LONG
+    case 'q': case 'Q': return sizeof(__Pyx_st_longlong) - sizeof(PY_LONG_LONG);
+#endif
+    case 'f': return sizeof(__Pyx_st_float) - sizeof(float);
+    case 'd': return sizeof(__Pyx_st_double) - sizeof(double);
+    case 'g': return sizeof(__Pyx_st_longdouble) - sizeof(long double);
+    case 'P': case 'O': return sizeof(__Pyx_st_void_p) - sizeof(void*);
+    default:
+      __Pyx_BufFmt_RaiseUnexpectedChar(ch);
+      return 0;
+    }
+}
+/* These are for computing the padding at the end of the struct to align
+   on the first member of the struct. This will probably the same as above,
+   but we don't have any guarantees.
+ */
+typedef struct { short x; char c; } __Pyx_pad_short;
+typedef struct { int x; char c; } __Pyx_pad_int;
+typedef struct { long x; char c; } __Pyx_pad_long;
+typedef struct { float x; char c; } __Pyx_pad_float;
+typedef struct { double x; char c; } __Pyx_pad_double;
+typedef struct { long double x; char c; } __Pyx_pad_longdouble;
+typedef struct { void *x; char c; } __Pyx_pad_void_p;
+#ifdef HAVE_LONG_LONG
+typedef struct { PY_LONG_LONG x; char c; } __Pyx_pad_longlong;
+#endif
+static size_t __Pyx_BufFmt_TypeCharToPadding(char ch, CYTHON_UNUSED int is_complex) {
+  switch (ch) {
+    case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1;
+    case 'h': case 'H': return sizeof(__Pyx_pad_short) - sizeof(short);
+    case 'i': case 'I': return sizeof(__Pyx_pad_int) - sizeof(int);
+    case 'l': case 'L': return sizeof(__Pyx_pad_long) - sizeof(long);
+#ifdef HAVE_LONG_LONG
+    case 'q': case 'Q': return sizeof(__Pyx_pad_longlong) - sizeof(PY_LONG_LONG);
+#endif
+    case 'f': return sizeof(__Pyx_pad_float) - sizeof(float);
+    case 'd': return sizeof(__Pyx_pad_double) - sizeof(double);
+    case 'g': return sizeof(__Pyx_pad_longdouble) - sizeof(long double);
+    case 'P': case 'O': return sizeof(__Pyx_pad_void_p) - sizeof(void*);
+    default:
+      __Pyx_BufFmt_RaiseUnexpectedChar(ch);
+      return 0;
+    }
+}
+static char __Pyx_BufFmt_TypeCharToGroup(char ch, int is_complex) {
+  switch (ch) {
+    case 'c':
+        return 'H';
+    case 'b': case 'h': case 'i':
+    case 'l': case 'q': case 's': case 'p':
+        return 'I';
+    case 'B': case 'H': case 'I': case 'L': case 'Q':
+        return 'U';
+    case 'f': case 'd': case 'g':
+        return (is_complex ? 'C' : 'R');
+    case 'O':
+        return 'O';
+    case 'P':
+        return 'P';
+    default: {
+      __Pyx_BufFmt_RaiseUnexpectedChar(ch);
+      return 0;
+    }
+  }
+}
+static void __Pyx_BufFmt_RaiseExpected(__Pyx_BufFmt_Context* ctx) {
+  if (ctx->head == NULL || ctx->head->field == &ctx->root) {
+    const char* expected;
+    const char* quote;
+    if (ctx->head == NULL) {
+      expected = "end";
+      quote = "";
+    } else {
+      expected = ctx->head->field->type->name;
+      quote = "'";
+    }
+    PyErr_Format(PyExc_ValueError,
+                 "Buffer dtype mismatch, expected %s%s%s but got %s",
+                 quote, expected, quote,
+                 __Pyx_BufFmt_DescribeTypeChar(ctx->enc_type, ctx->is_complex));
+  } else {
+    __Pyx_StructField* field = ctx->head->field;
+    __Pyx_StructField* parent = (ctx->head - 1)->field;
+    PyErr_Format(PyExc_ValueError,
+                 "Buffer dtype mismatch, expected '%s' but got %s in '%s.%s'",
+                 field->type->name, __Pyx_BufFmt_DescribeTypeChar(ctx->enc_type, ctx->is_complex),
+                 parent->type->name, field->name);
+  }
+}
+static int __Pyx_BufFmt_ProcessTypeChunk(__Pyx_BufFmt_Context* ctx) {
+  char group;
+  size_t size, offset, arraysize = 1;
+  if (ctx->enc_type == 0) return 0;
+  if (ctx->head->field->type->arraysize[0]) {
+    int i, ndim = 0;
+    if (ctx->enc_type == 's' || ctx->enc_type == 'p') {
+        ctx->is_valid_array = ctx->head->field->type->ndim == 1;
+        ndim = 1;
+        if (ctx->enc_count != ctx->head->field->type->arraysize[0]) {
+            PyErr_Format(PyExc_ValueError,
+                         "Expected a dimension of size %zu, got %zu",
+                         ctx->head->field->type->arraysize[0], ctx->enc_count);
+            return -1;
+        }
+    }
+    if (!ctx->is_valid_array) {
+      PyErr_Format(PyExc_ValueError, "Expected %d dimensions, got %d",
+                   ctx->head->field->type->ndim, ndim);
+      return -1;
+    }
+    for (i = 0; i < ctx->head->field->type->ndim; i++) {
+      arraysize *= ctx->head->field->type->arraysize[i];
+    }
+    ctx->is_valid_array = 0;
+    ctx->enc_count = 1;
+  }
+  group = __Pyx_BufFmt_TypeCharToGroup(ctx->enc_type, ctx->is_complex);
+  do {
+    __Pyx_StructField* field = ctx->head->field;
+    __Pyx_TypeInfo* type = field->type;
+    if (ctx->enc_packmode == '@' || ctx->enc_packmode == '^') {
+      size = __Pyx_BufFmt_TypeCharToNativeSize(ctx->enc_type, ctx->is_complex);
+    } else {
+      size = __Pyx_BufFmt_TypeCharToStandardSize(ctx->enc_type, ctx->is_complex);
+    }
+    if (ctx->enc_packmode == '@') {
+      size_t align_at = __Pyx_BufFmt_TypeCharToAlignment(ctx->enc_type, ctx->is_complex);
+      size_t align_mod_offset;
+      if (align_at == 0) return -1;
+      align_mod_offset = ctx->fmt_offset % align_at;
+      if (align_mod_offset > 0) ctx->fmt_offset += align_at - align_mod_offset;
+      if (ctx->struct_alignment == 0)
+          ctx->struct_alignment = __Pyx_BufFmt_TypeCharToPadding(ctx->enc_type,
+                                                                 ctx->is_complex);
+    }
+    if (type->size != size || type->typegroup != group) {
+      if (type->typegroup == 'C' && type->fields != NULL) {
+        size_t parent_offset = ctx->head->parent_offset + field->offset;
+        ++ctx->head;
+        ctx->head->field = type->fields;
+        ctx->head->parent_offset = parent_offset;
+        continue;
+      }
+      if ((type->typegroup == 'H' || group == 'H') && type->size == size) {
+      } else {
+          __Pyx_BufFmt_RaiseExpected(ctx);
+          return -1;
+      }
+    }
+    offset = ctx->head->parent_offset + field->offset;
+    if (ctx->fmt_offset != offset) {
+      PyErr_Format(PyExc_ValueError,
+                   "Buffer dtype mismatch; next field is at offset %" CYTHON_FORMAT_SSIZE_T "d but %" CYTHON_FORMAT_SSIZE_T "d expected",
+                   (Py_ssize_t)ctx->fmt_offset, (Py_ssize_t)offset);
+      return -1;
+    }
+    ctx->fmt_offset += size;
+    if (arraysize)
+      ctx->fmt_offset += (arraysize - 1) * size;
+    --ctx->enc_count;
+    while (1) {
+      if (field == &ctx->root) {
+        ctx->head = NULL;
+        if (ctx->enc_count != 0) {
+          __Pyx_BufFmt_RaiseExpected(ctx);
+          return -1;
+        }
+        break;
+      }
+      ctx->head->field = ++field;
+      if (field->type == NULL) {
+        --ctx->head;
+        field = ctx->head->field;
+        continue;
+      } else if (field->type->typegroup == 'S') {
+        size_t parent_offset = ctx->head->parent_offset + field->offset;
+        if (field->type->fields->type == NULL) continue;
+        field = field->type->fields;
+        ++ctx->head;
+        ctx->head->field = field;
+        ctx->head->parent_offset = parent_offset;
+        break;
+      } else {
+        break;
+      }
+    }
+  } while (ctx->enc_count);
+  ctx->enc_type = 0;
+  ctx->is_complex = 0;
+  return 0;
+}
+static CYTHON_INLINE PyObject *
+__pyx_buffmt_parse_array(__Pyx_BufFmt_Context* ctx, const char** tsp)
+{
+    const char *ts = *tsp;
+    int i = 0, number;
+    int ndim = ctx->head->field->type->ndim;
+;
+    ++ts;
+    if (ctx->new_count != 1) {
+        PyErr_SetString(PyExc_ValueError,
+                        "Cannot handle repeated arrays in format string");
+        return NULL;
+    }
+    if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
+    while (*ts && *ts != ')') {
+        switch (*ts) {
+            case ' ': case '\f': case '\r': case '\n': case '\t': case '\v':  continue;
+            default:  break;
+        }
+        number = __Pyx_BufFmt_ExpectNumber(&ts);
+        if (number == -1) return NULL;
+        if (i < ndim && (size_t) number != ctx->head->field->type->arraysize[i])
+            return PyErr_Format(PyExc_ValueError,
+                        "Expected a dimension of size %zu, got %d",
+                        ctx->head->field->type->arraysize[i], number);
+        if (*ts != ',' && *ts != ')')
+            return PyErr_Format(PyExc_ValueError,
+                                "Expected a comma in format string, got '%c'", *ts);
+        if (*ts == ',') ts++;
+        i++;
+    }
+    if (i != ndim)
+        return PyErr_Format(PyExc_ValueError, "Expected %d dimension(s), got %d",
+                            ctx->head->field->type->ndim, i);
+    if (!*ts) {
+        PyErr_SetString(PyExc_ValueError,
+                        "Unexpected end of format string, expected ')'");
+        return NULL;
+    }
+    ctx->is_valid_array = 1;
+    ctx->new_count = 1;
+    *tsp = ++ts;
+    return Py_None;
+}
+static const char* __Pyx_BufFmt_CheckString(__Pyx_BufFmt_Context* ctx, const char* ts) {
+  int got_Z = 0;
+  while (1) {
+    switch(*ts) {
+      case 0:
+        if (ctx->enc_type != 0 && ctx->head == NULL) {
+          __Pyx_BufFmt_RaiseExpected(ctx);
+          return NULL;
+        }
+        if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
+        if (ctx->head != NULL) {
+          __Pyx_BufFmt_RaiseExpected(ctx);
+          return NULL;
+        }
+        return ts;
+      case ' ':
+      case '\r':
+      case '\n':
+        ++ts;
+        break;
+      case '<':
+        if (!__Pyx_IsLittleEndian()) {
+          PyErr_SetString(PyExc_ValueError, "Little-endian buffer not supported on big-endian compiler");
+          return NULL;
+        }
+        ctx->new_packmode = '=';
+        ++ts;
+        break;
+      case '>':
+      case '!':
+        if (__Pyx_IsLittleEndian()) {
+          PyErr_SetString(PyExc_ValueError, "Big-endian buffer not supported on little-endian compiler");
+          return NULL;
+        }
+        ctx->new_packmode = '=';
+        ++ts;
+        break;
+      case '=':
+      case '@':
+      case '^':
+        ctx->new_packmode = *ts++;
+        break;
+      case 'T':
+        {
+          const char* ts_after_sub;
+          size_t i, struct_count = ctx->new_count;
+          size_t struct_alignment = ctx->struct_alignment;
+          ctx->new_count = 1;
+          ++ts;
+          if (*ts != '{') {
+            PyErr_SetString(PyExc_ValueError, "Buffer acquisition: Expected '{' after 'T'");
+            return NULL;
+          }
+          if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
+          ctx->enc_type = 0;
+          ctx->enc_count = 0;
+          ctx->struct_alignment = 0;
+          ++ts;
+          ts_after_sub = ts;
+          for (i = 0; i != struct_count; ++i) {
+            ts_after_sub = __Pyx_BufFmt_CheckString(ctx, ts);
+            if (!ts_after_sub) return NULL;
+          }
+          ts = ts_after_sub;
+          if (struct_alignment) ctx->struct_alignment = struct_alignment;
+        }
+        break;
+      case '}':
+        {
+          size_t alignment = ctx->struct_alignment;
+          ++ts;
+          if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
+          ctx->enc_type = 0;
+          if (alignment && ctx->fmt_offset % alignment) {
+            ctx->fmt_offset += alignment - (ctx->fmt_offset % alignment);
+          }
+        }
+        return ts;
+      case 'x':
+        if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
+        ctx->fmt_offset += ctx->new_count;
+        ctx->new_count = 1;
+        ctx->enc_count = 0;
+        ctx->enc_type = 0;
+        ctx->enc_packmode = ctx->new_packmode;
+        ++ts;
+        break;
+      case 'Z':
+        got_Z = 1;
+        ++ts;
+        if (*ts != 'f' && *ts != 'd' && *ts != 'g') {
+          __Pyx_BufFmt_RaiseUnexpectedChar('Z');
+          return NULL;
+        }
+      case 'c': case 'b': case 'B': case 'h': case 'H': case 'i': case 'I':
+      case 'l': case 'L': case 'q': case 'Q':
+      case 'f': case 'd': case 'g':
+      case 'O': case 'p':
+        if (ctx->enc_type == *ts && got_Z == ctx->is_complex &&
+            ctx->enc_packmode == ctx->new_packmode) {
+          ctx->enc_count += ctx->new_count;
+          ctx->new_count = 1;
+          got_Z = 0;
+          ++ts;
+          break;
+        }
+      case 's':
+        if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
+        ctx->enc_count = ctx->new_count;
+        ctx->enc_packmode = ctx->new_packmode;
+        ctx->enc_type = *ts;
+        ctx->is_complex = got_Z;
+        ++ts;
+        ctx->new_count = 1;
+        got_Z = 0;
+        break;
+      case ':':
+        ++ts;
+        while(*ts != ':') ++ts;
+        ++ts;
+        break;
+      case '(':
+        if (!__pyx_buffmt_parse_array(ctx, &ts)) return NULL;
+        break;
+      default:
+        {
+          int number = __Pyx_BufFmt_ExpectNumber(&ts);
+          if (number == -1) return NULL;
+          ctx->new_count = (size_t)number;
+        }
+    }
+  }
+}
+static CYTHON_INLINE void __Pyx_ZeroBuffer(Py_buffer* buf) {
+  buf->buf = NULL;
+  buf->obj = NULL;
+  buf->strides = __Pyx_zeros;
+  buf->shape = __Pyx_zeros;
+  buf->suboffsets = __Pyx_minusones;
+}
+static CYTHON_INLINE int __Pyx_GetBufferAndValidate(
+        Py_buffer* buf, PyObject* obj,  __Pyx_TypeInfo* dtype, int flags,
+        int nd, int cast, __Pyx_BufFmt_StackElem* stack)
+{
+  if (obj == Py_None || obj == NULL) {
+    __Pyx_ZeroBuffer(buf);
+    return 0;
+  }
+  buf->buf = NULL;
+  if (__Pyx_GetBuffer(obj, buf, flags) == -1) goto fail;
+  if (buf->ndim != nd) {
+    PyErr_Format(PyExc_ValueError,
+                 "Buffer has wrong number of dimensions (expected %d, got %d)",
+                 nd, buf->ndim);
+    goto fail;
+  }
+  if (!cast) {
+    __Pyx_BufFmt_Context ctx;
+    __Pyx_BufFmt_Init(&ctx, stack, dtype);
+    if (!__Pyx_BufFmt_CheckString(&ctx, buf->format)) goto fail;
+  }
+  if ((unsigned)buf->itemsize != dtype->size) {
+    PyErr_Format(PyExc_ValueError,
+      "Item size of buffer (%" CYTHON_FORMAT_SSIZE_T "d byte%s) does not match size of '%s' (%" CYTHON_FORMAT_SSIZE_T "d byte%s)",
+      buf->itemsize, (buf->itemsize > 1) ? "s" : "",
+      dtype->name, (Py_ssize_t)dtype->size, (dtype->size > 1) ? "s" : "");
+    goto fail;
+  }
+  if (buf->suboffsets == NULL) buf->suboffsets = __Pyx_minusones;
+  return 0;
+fail:;
+  __Pyx_ZeroBuffer(buf);
+  return -1;
+}
+static CYTHON_INLINE void __Pyx_SafeReleaseBuffer(Py_buffer* info) {
+  if (info->buf == NULL) return;
+  if (info->suboffsets == __Pyx_minusones) info->suboffsets = NULL;
+  __Pyx_ReleaseBuffer(info);
+}
+
+static void __Pyx_RaiseBufferIndexError(int axis) {
+  PyErr_Format(PyExc_IndexError,
+     "Out of bounds on buffer access (axis %d)", axis);
+}
+
+static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    PyObject *tmp_type, *tmp_value, *tmp_tb;
+    PyThreadState *tstate = PyThreadState_GET();
+    tmp_type = tstate->curexc_type;
+    tmp_value = tstate->curexc_value;
+    tmp_tb = tstate->curexc_traceback;
+    tstate->curexc_type = type;
+    tstate->curexc_value = value;
+    tstate->curexc_traceback = tb;
+    Py_XDECREF(tmp_type);
+    Py_XDECREF(tmp_value);
+    Py_XDECREF(tmp_tb);
+#else
+    PyErr_Restore(type, value, tb);
+#endif
+}
+static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    PyThreadState *tstate = PyThreadState_GET();
+    *type = tstate->curexc_type;
+    *value = tstate->curexc_value;
+    *tb = tstate->curexc_traceback;
+    tstate->curexc_type = 0;
+    tstate->curexc_value = 0;
+    tstate->curexc_traceback = 0;
+#else
+    PyErr_Fetch(type, value, tb);
+#endif
+}
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg) {
+    PyObject *self, *result;
+    PyCFunction cfunc;
+    cfunc = PyCFunction_GET_FUNCTION(func);
+    self = PyCFunction_GET_SELF(func);
+    if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object")))
+        return NULL;
+    result = cfunc(self, arg);
+    Py_LeaveRecursiveCall();
+    if (unlikely(!result) && unlikely(!PyErr_Occurred())) {
+        PyErr_SetString(
+            PyExc_SystemError,
+            "NULL result without error in PyObject_Call");
+    }
+    return result;
+}
+#endif
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static PyObject* __Pyx__PyObject_CallOneArg(PyObject *func, PyObject *arg) {
+    PyObject *result;
+    PyObject *args = PyTuple_New(1);
+    if (unlikely(!args)) return NULL;
+    Py_INCREF(arg);
+    PyTuple_SET_ITEM(args, 0, arg);
+    result = __Pyx_PyObject_Call(func, args, NULL);
+    Py_DECREF(args);
+    return result;
+}
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) {
+#ifdef __Pyx_CyFunction_USED
+    if (likely(PyCFunction_Check(func) || PyObject_TypeCheck(func, __pyx_CyFunctionType))) {
+#else
+    if (likely(PyCFunction_Check(func))) {
+#endif
+        if (likely(PyCFunction_GET_FLAGS(func) & METH_O)) {
+            return __Pyx_PyObject_CallMethO(func, arg);
+        }
+    }
+    return __Pyx__PyObject_CallOneArg(func, arg);
+}
+#else
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) {
+    PyObject* args = PyTuple_Pack(1, arg);
+    return (likely(args)) ? __Pyx_PyObject_Call(func, args, NULL) : NULL;
+}
+#endif
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func) {
+#ifdef __Pyx_CyFunction_USED
+    if (likely(PyCFunction_Check(func) || PyObject_TypeCheck(func, __pyx_CyFunctionType))) {
+#else
+    if (likely(PyCFunction_Check(func))) {
+#endif
+        if (likely(PyCFunction_GET_FLAGS(func) & METH_NOARGS)) {
+            return __Pyx_PyObject_CallMethO(func, NULL);
+        }
+    }
+    return __Pyx_PyObject_Call(func, __pyx_empty_tuple, NULL);
+}
+#endif
+
+static PyObject* __Pyx_PyObject_CallMethod1(PyObject* obj, PyObject* method_name, PyObject* arg) {
+    PyObject *method, *result = NULL;
+    method = __Pyx_PyObject_GetAttrStr(obj, method_name);
+    if (unlikely(!method)) goto bad;
+#if CYTHON_COMPILING_IN_CPYTHON
+    if (likely(PyMethod_Check(method))) {
+        PyObject *self = PyMethod_GET_SELF(method);
+        if (likely(self)) {
+            PyObject *args;
+            PyObject *function = PyMethod_GET_FUNCTION(method);
+            args = PyTuple_New(2);
+            if (unlikely(!args)) goto bad;
+            Py_INCREF(self);
+            PyTuple_SET_ITEM(args, 0, self);
+            Py_INCREF(arg);
+            PyTuple_SET_ITEM(args, 1, arg);
+            Py_INCREF(function);
+            Py_DECREF(method); method = NULL;
+            result = __Pyx_PyObject_Call(function, args, NULL);
+            Py_DECREF(args);
+            Py_DECREF(function);
+            return result;
+        }
+    }
+#endif
+    result = __Pyx_PyObject_CallOneArg(method, arg);
+bad:
+    Py_XDECREF(method);
+    return result;
+}
+
+static CYTHON_INLINE int __Pyx_PyObject_Append(PyObject* L, PyObject* x) {
+    if (likely(PyList_CheckExact(L))) {
+        if (unlikely(__Pyx_PyList_Append(L, x) < 0)) return -1;
+    } else {
+        PyObject* retval = __Pyx_PyObject_CallMethod1(L, __pyx_n_s_append, x);
+        if (unlikely(!retval))
+            return -1;
+        Py_DECREF(retval);
+    }
+    return 0;
+}
+
+static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected) {
+    PyErr_Format(PyExc_ValueError,
+                 "too many values to unpack (expected %" CYTHON_FORMAT_SSIZE_T "d)", expected);
+}
+
+static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index) {
+    PyErr_Format(PyExc_ValueError,
+                 "need more than %" CYTHON_FORMAT_SSIZE_T "d value%.1s to unpack",
+                 index, (index == 1) ? "" : "s");
+}
+
+static CYTHON_INLINE int __Pyx_IterFinish(void) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    PyThreadState *tstate = PyThreadState_GET();
+    PyObject* exc_type = tstate->curexc_type;
+    if (unlikely(exc_type)) {
+        if (likely(exc_type == PyExc_StopIteration) || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration)) {
+            PyObject *exc_value, *exc_tb;
+            exc_value = tstate->curexc_value;
+            exc_tb = tstate->curexc_traceback;
+            tstate->curexc_type = 0;
+            tstate->curexc_value = 0;
+            tstate->curexc_traceback = 0;
+            Py_DECREF(exc_type);
+            Py_XDECREF(exc_value);
+            Py_XDECREF(exc_tb);
+            return 0;
+        } else {
+            return -1;
+        }
+    }
+    return 0;
+#else
+    if (unlikely(PyErr_Occurred())) {
+        if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) {
+            PyErr_Clear();
+            return 0;
+        } else {
+            return -1;
+        }
+    }
+    return 0;
+#endif
+}
+
+static int __Pyx_IternextUnpackEndCheck(PyObject *retval, Py_ssize_t expected) {
+    if (unlikely(retval)) {
+        Py_DECREF(retval);
+        __Pyx_RaiseTooManyValuesError(expected);
+        return -1;
+    } else {
+        return __Pyx_IterFinish();
+    }
+    return 0;
+}
+
+static CYTHON_INLINE long __Pyx_div_long(long a, long b) {
+    long q = a / b;
+    long r = a - q*b;
+    q -= ((r != 0) & ((r ^ b) < 0));
+    return q;
+}
+
+#if PY_MAJOR_VERSION < 3
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb,
+                        CYTHON_UNUSED PyObject *cause) {
+    Py_XINCREF(type);
+    if (!value || value == Py_None)
+        value = NULL;
+    else
+        Py_INCREF(value);
+    if (!tb || tb == Py_None)
+        tb = NULL;
+    else {
+        Py_INCREF(tb);
+        if (!PyTraceBack_Check(tb)) {
+            PyErr_SetString(PyExc_TypeError,
+                "raise: arg 3 must be a traceback or None");
+            goto raise_error;
+        }
+    }
+    if (PyType_Check(type)) {
+#if CYTHON_COMPILING_IN_PYPY
+        if (!value) {
+            Py_INCREF(Py_None);
+            value = Py_None;
+        }
+#endif
+        PyErr_NormalizeException(&type, &value, &tb);
+    } else {
+        if (value) {
+            PyErr_SetString(PyExc_TypeError,
+                "instance exception may not have a separate value");
+            goto raise_error;
+        }
+        value = type;
+        type = (PyObject*) Py_TYPE(type);
+        Py_INCREF(type);
+        if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
+            PyErr_SetString(PyExc_TypeError,
+                "raise: exception class must be a subclass of BaseException");
+            goto raise_error;
+        }
+    }
+    __Pyx_ErrRestore(type, value, tb);
+    return;
+raise_error:
+    Py_XDECREF(value);
+    Py_XDECREF(type);
+    Py_XDECREF(tb);
+    return;
+}
+#else
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause) {
+    PyObject* owned_instance = NULL;
+    if (tb == Py_None) {
+        tb = 0;
+    } else if (tb && !PyTraceBack_Check(tb)) {
+        PyErr_SetString(PyExc_TypeError,
+            "raise: arg 3 must be a traceback or None");
+        goto bad;
+    }
+    if (value == Py_None)
+        value = 0;
+    if (PyExceptionInstance_Check(type)) {
+        if (value) {
+            PyErr_SetString(PyExc_TypeError,
+                "instance exception may not have a separate value");
+            goto bad;
+        }
+        value = type;
+        type = (PyObject*) Py_TYPE(value);
+    } else if (PyExceptionClass_Check(type)) {
+        PyObject *instance_class = NULL;
+        if (value && PyExceptionInstance_Check(value)) {
+            instance_class = (PyObject*) Py_TYPE(value);
+            if (instance_class != type) {
+                if (PyObject_IsSubclass(instance_class, type)) {
+                    type = instance_class;
+                } else {
+                    instance_class = NULL;
+                }
+            }
+        }
+        if (!instance_class) {
+            PyObject *args;
+            if (!value)
+                args = PyTuple_New(0);
+            else if (PyTuple_Check(value)) {
+                Py_INCREF(value);
+                args = value;
+            } else
+                args = PyTuple_Pack(1, value);
+            if (!args)
+                goto bad;
+            owned_instance = PyObject_Call(type, args, NULL);
+            Py_DECREF(args);
+            if (!owned_instance)
+                goto bad;
+            value = owned_instance;
+            if (!PyExceptionInstance_Check(value)) {
+                PyErr_Format(PyExc_TypeError,
+                             "calling %R should have returned an instance of "
+                             "BaseException, not %R",
+                             type, Py_TYPE(value));
+                goto bad;
+            }
+        }
+    } else {
+        PyErr_SetString(PyExc_TypeError,
+            "raise: exception class must be a subclass of BaseException");
+        goto bad;
+    }
+#if PY_VERSION_HEX >= 0x03030000
+    if (cause) {
+#else
+    if (cause && cause != Py_None) {
+#endif
+        PyObject *fixed_cause;
+        if (cause == Py_None) {
+            fixed_cause = NULL;
+        } else if (PyExceptionClass_Check(cause)) {
+            fixed_cause = PyObject_CallObject(cause, NULL);
+            if (fixed_cause == NULL)
+                goto bad;
+        } else if (PyExceptionInstance_Check(cause)) {
+            fixed_cause = cause;
+            Py_INCREF(fixed_cause);
+        } else {
+            PyErr_SetString(PyExc_TypeError,
+                            "exception causes must derive from "
+                            "BaseException");
+            goto bad;
+        }
+        PyException_SetCause(value, fixed_cause);
+    }
+    PyErr_SetObject(type, value);
+    if (tb) {
+#if CYTHON_COMPILING_IN_PYPY
+        PyObject *tmp_type, *tmp_value, *tmp_tb;
+        PyErr_Fetch(tmp_type, tmp_value, tmp_tb);
+        Py_INCREF(tb);
+        PyErr_Restore(tmp_type, tmp_value, tb);
+        Py_XDECREF(tmp_tb);
+#else
+        PyThreadState *tstate = PyThreadState_GET();
+        PyObject* tmp_tb = tstate->curexc_traceback;
+        if (tb != tmp_tb) {
+            Py_INCREF(tb);
+            tstate->curexc_traceback = tb;
+            Py_XDECREF(tmp_tb);
+        }
+#endif
+    }
+bad:
+    Py_XDECREF(owned_instance);
+    return;
+}
+#endif
+
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j) {
+    PyObject *r;
+    if (!j) return NULL;
+    r = PyObject_GetItem(o, j);
+    Py_DECREF(j);
+    return r;
+}
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i,
+                                                              int wraparound, int boundscheck) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    if (wraparound & unlikely(i < 0)) i += PyList_GET_SIZE(o);
+    if ((!boundscheck) || likely((0 <= i) & (i < PyList_GET_SIZE(o)))) {
+        PyObject *r = PyList_GET_ITEM(o, i);
+        Py_INCREF(r);
+        return r;
+    }
+    return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
+#else
+    return PySequence_GetItem(o, i);
+#endif
+}
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i,
+                                                              int wraparound, int boundscheck) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    if (wraparound & unlikely(i < 0)) i += PyTuple_GET_SIZE(o);
+    if ((!boundscheck) || likely((0 <= i) & (i < PyTuple_GET_SIZE(o)))) {
+        PyObject *r = PyTuple_GET_ITEM(o, i);
+        Py_INCREF(r);
+        return r;
+    }
+    return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
+#else
+    return PySequence_GetItem(o, i);
+#endif
+}
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i,
+                                                     int is_list, int wraparound, int boundscheck) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    if (is_list || PyList_CheckExact(o)) {
+        Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyList_GET_SIZE(o);
+        if ((!boundscheck) || (likely((n >= 0) & (n < PyList_GET_SIZE(o))))) {
+            PyObject *r = PyList_GET_ITEM(o, n);
+            Py_INCREF(r);
+            return r;
+        }
+    }
+    else if (PyTuple_CheckExact(o)) {
+        Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyTuple_GET_SIZE(o);
+        if ((!boundscheck) || likely((n >= 0) & (n < PyTuple_GET_SIZE(o)))) {
+            PyObject *r = PyTuple_GET_ITEM(o, n);
+            Py_INCREF(r);
+            return r;
+        }
+    } else {
+        PySequenceMethods *m = Py_TYPE(o)->tp_as_sequence;
+        if (likely(m && m->sq_item)) {
+            if (wraparound && unlikely(i < 0) && likely(m->sq_length)) {
+                Py_ssize_t l = m->sq_length(o);
+                if (likely(l >= 0)) {
+                    i += l;
+                } else {
+                    if (PyErr_ExceptionMatches(PyExc_OverflowError))
+                        PyErr_Clear();
+                    else
+                        return NULL;
+                }
+            }
+            return m->sq_item(o, i);
+        }
+    }
+#else
+    if (is_list || PySequence_Check(o)) {
+        return PySequence_GetItem(o, i);
+    }
+#endif
+    return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
+}
+
+static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void) {
+    PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable");
+}
+
+static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
+#if PY_VERSION_HEX >= 0x02070000
+    PyObject *ob = PyCapsule_New(vtable, 0, 0);
+#else
+    PyObject *ob = PyCObject_FromVoidPtr(vtable, 0);
+#endif
+    if (!ob)
+        goto bad;
+    if (PyDict_SetItem(dict, __pyx_n_s_pyx_vtable, ob) < 0)
+        goto bad;
+    Py_DECREF(ob);
+    return 0;
+bad:
+    Py_XDECREF(ob);
+    return -1;
+}
+
+static PyObject* __Pyx_ImportFrom(PyObject* module, PyObject* name) {
+    PyObject* value = __Pyx_PyObject_GetAttrStr(module, name);
+    if (unlikely(!value) && PyErr_ExceptionMatches(PyExc_AttributeError)) {
+        PyErr_Format(PyExc_ImportError,
+        #if PY_MAJOR_VERSION < 3
+            "cannot import name %.230s", PyString_AS_STRING(name));
+        #else
+            "cannot import name %S", name);
+        #endif
+    }
+    return value;
+}
+
+static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) {
+    int start = 0, mid = 0, end = count - 1;
+    if (end >= 0 && code_line > entries[end].code_line) {
+        return count;
+    }
+    while (start < end) {
+        mid = (start + end) / 2;
+        if (code_line < entries[mid].code_line) {
+            end = mid;
+        } else if (code_line > entries[mid].code_line) {
+             start = mid + 1;
+        } else {
+            return mid;
+        }
+    }
+    if (code_line <= entries[mid].code_line) {
+        return mid;
+    } else {
+        return mid + 1;
+    }
+}
+static PyCodeObject *__pyx_find_code_object(int code_line) {
+    PyCodeObject* code_object;
+    int pos;
+    if (unlikely(!code_line) || unlikely(!__pyx_code_cache.entries)) {
+        return NULL;
+    }
+    pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line);
+    if (unlikely(pos >= __pyx_code_cache.count) || unlikely(__pyx_code_cache.entries[pos].code_line != code_line)) {
+        return NULL;
+    }
+    code_object = __pyx_code_cache.entries[pos].code_object;
+    Py_INCREF(code_object);
+    return code_object;
+}
+static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) {
+    int pos, i;
+    __Pyx_CodeObjectCacheEntry* entries = __pyx_code_cache.entries;
+    if (unlikely(!code_line)) {
+        return;
+    }
+    if (unlikely(!entries)) {
+        entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Malloc(64*sizeof(__Pyx_CodeObjectCacheEntry));
+        if (likely(entries)) {
+            __pyx_code_cache.entries = entries;
+            __pyx_code_cache.max_count = 64;
+            __pyx_code_cache.count = 1;
+            entries[0].code_line = code_line;
+            entries[0].code_object = code_object;
+            Py_INCREF(code_object);
+        }
+        return;
+    }
+    pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line);
+    if ((pos < __pyx_code_cache.count) && unlikely(__pyx_code_cache.entries[pos].code_line == code_line)) {
+        PyCodeObject* tmp = entries[pos].code_object;
+        entries[pos].code_object = code_object;
+        Py_DECREF(tmp);
+        return;
+    }
+    if (__pyx_code_cache.count == __pyx_code_cache.max_count) {
+        int new_max = __pyx_code_cache.max_count + 64;
+        entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Realloc(
+            __pyx_code_cache.entries, (size_t)new_max*sizeof(__Pyx_CodeObjectCacheEntry));
+        if (unlikely(!entries)) {
+            return;
+        }
+        __pyx_code_cache.entries = entries;
+        __pyx_code_cache.max_count = new_max;
+    }
+    for (i=__pyx_code_cache.count; i>pos; i--) {
+        entries[i] = entries[i-1];
+    }
+    entries[pos].code_line = code_line;
+    entries[pos].code_object = code_object;
+    __pyx_code_cache.count++;
+    Py_INCREF(code_object);
+}
+
+#include "compile.h"
+#include "frameobject.h"
+#include "traceback.h"
+static PyCodeObject* __Pyx_CreateCodeObjectForTraceback(
+            const char *funcname, int c_line,
+            int py_line, const char *filename) {
+    PyCodeObject *py_code = 0;
+    PyObject *py_srcfile = 0;
+    PyObject *py_funcname = 0;
+    #if PY_MAJOR_VERSION < 3
+    py_srcfile = PyString_FromString(filename);
+    #else
+    py_srcfile = PyUnicode_FromString(filename);
+    #endif
+    if (!py_srcfile) goto bad;
+    if (c_line) {
+        #if PY_MAJOR_VERSION < 3
+        py_funcname = PyString_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line);
+        #else
+        py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line);
+        #endif
+    }
+    else {
+        #if PY_MAJOR_VERSION < 3
+        py_funcname = PyString_FromString(funcname);
+        #else
+        py_funcname = PyUnicode_FromString(funcname);
+        #endif
+    }
+    if (!py_funcname) goto bad;
+    py_code = __Pyx_PyCode_New(
+        0,
+        0,
+        0,
+        0,
+        0,
+        __pyx_empty_bytes, /*PyObject *code,*/
+        __pyx_empty_tuple, /*PyObject *consts,*/
+        __pyx_empty_tuple, /*PyObject *names,*/
+        __pyx_empty_tuple, /*PyObject *varnames,*/
+        __pyx_empty_tuple, /*PyObject *freevars,*/
+        __pyx_empty_tuple, /*PyObject *cellvars,*/
+        py_srcfile,   /*PyObject *filename,*/
+        py_funcname,  /*PyObject *name,*/
+        py_line,
+        __pyx_empty_bytes  /*PyObject *lnotab*/
+    );
+    Py_DECREF(py_srcfile);
+    Py_DECREF(py_funcname);
+    return py_code;
+bad:
+    Py_XDECREF(py_srcfile);
+    Py_XDECREF(py_funcname);
+    return NULL;
+}
+static void __Pyx_AddTraceback(const char *funcname, int c_line,
+                               int py_line, const char *filename) {
+    PyCodeObject *py_code = 0;
+    PyFrameObject *py_frame = 0;
+    py_code = __pyx_find_code_object(c_line ? c_line : py_line);
+    if (!py_code) {
+        py_code = __Pyx_CreateCodeObjectForTraceback(
+            funcname, c_line, py_line, filename);
+        if (!py_code) goto bad;
+        __pyx_insert_code_object(c_line ? c_line : py_line, py_code);
+    }
+    py_frame = PyFrame_New(
+        PyThreadState_GET(), /*PyThreadState *tstate,*/
+        py_code,             /*PyCodeObject *code,*/
+        __pyx_d,      /*PyObject *globals,*/
+        0                    /*PyObject *locals*/
+    );
+    if (!py_frame) goto bad;
+    py_frame->f_lineno = py_line;
+    PyTraceBack_Here(py_frame);
+bad:
+    Py_XDECREF(py_code);
+    Py_XDECREF(py_frame);
+}
+
+static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level) {
+    PyObject *empty_list = 0;
+    PyObject *module = 0;
+    PyObject *global_dict = 0;
+    PyObject *empty_dict = 0;
+    PyObject *list;
+    #if PY_VERSION_HEX < 0x03030000
+    PyObject *py_import;
+    py_import = __Pyx_PyObject_GetAttrStr(__pyx_b, __pyx_n_s_import);
+    if (!py_import)
+        goto bad;
+    #endif
+    if (from_list)
+        list = from_list;
+    else {
+        empty_list = PyList_New(0);
+        if (!empty_list)
+            goto bad;
+        list = empty_list;
+    }
+    global_dict = PyModule_GetDict(__pyx_m);
+    if (!global_dict)
+        goto bad;
+    empty_dict = PyDict_New();
+    if (!empty_dict)
+        goto bad;
+    {
+        #if PY_MAJOR_VERSION >= 3
+        if (level == -1) {
+            if (strchr(__Pyx_MODULE_NAME, '.')) {
+                #if PY_VERSION_HEX < 0x03030000
+                PyObject *py_level = PyInt_FromLong(1);
+                if (!py_level)
+                    goto bad;
+                module = PyObject_CallFunctionObjArgs(py_import,
+                    name, global_dict, empty_dict, list, py_level, NULL);
+                Py_DECREF(py_level);
+                #else
+                module = PyImport_ImportModuleLevelObject(
+                    name, global_dict, empty_dict, list, 1);
+                #endif
+                if (!module) {
+                    if (!PyErr_ExceptionMatches(PyExc_ImportError))
+                        goto bad;
+                    PyErr_Clear();
+                }
+            }
+            level = 0;
+        }
+        #endif
+        if (!module) {
+            #if PY_VERSION_HEX < 0x03030000
+            PyObject *py_level = PyInt_FromLong(level);
+            if (!py_level)
+                goto bad;
+            module = PyObject_CallFunctionObjArgs(py_import,
+                name, global_dict, empty_dict, list, py_level, NULL);
+            Py_DECREF(py_level);
+            #else
+            module = PyImport_ImportModuleLevelObject(
+                name, global_dict, empty_dict, list, level);
+            #endif
+        }
+    }
+bad:
+    #if PY_VERSION_HEX < 0x03030000
+    Py_XDECREF(py_import);
+    #endif
+    Py_XDECREF(empty_list);
+    Py_XDECREF(empty_dict);
+    return module;
+}
+
+#if PY_MAJOR_VERSION < 3
+static int __Pyx_GetBuffer(PyObject *obj, Py_buffer *view, int flags) {
+    if (PyObject_CheckBuffer(obj)) return PyObject_GetBuffer(obj, view, flags);
+        if (PyObject_TypeCheck(obj, __pyx_ptype_5numpy_ndarray)) return __pyx_pw_5numpy_7ndarray_1__getbuffer__(obj, view, flags);
+    PyErr_Format(PyExc_TypeError, "'%.200s' does not have the buffer interface", Py_TYPE(obj)->tp_name);
+    return -1;
+}
+static void __Pyx_ReleaseBuffer(Py_buffer *view) {
+    PyObject *obj = view->obj;
+    if (!obj) return;
+    if (PyObject_CheckBuffer(obj)) {
+        PyBuffer_Release(view);
+        return;
+    }
+        if (PyObject_TypeCheck(obj, __pyx_ptype_5numpy_ndarray)) { __pyx_pw_5numpy_7ndarray_3__releasebuffer__(obj, view); return; }
+    Py_DECREF(obj);
+    view->obj = NULL;
+}
+#endif
+
+
+          #define __PYX_VERIFY_RETURN_INT(target_type, func_type, func_value)       \
+    {                                                                     \
+        func_type value = func_value;                                     \
+        if (sizeof(target_type) < sizeof(func_type)) {                    \
+            if (unlikely(value != (func_type) (target_type) value)) {     \
+                func_type zero = 0;                                       \
+                if (is_unsigned && unlikely(value < zero))                \
+                    goto raise_neg_overflow;                              \
+                else                                                      \
+                    goto raise_overflow;                                  \
+            }                                                             \
+        }                                                                 \
+        return (target_type) value;                                       \
+    }
+
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+  #include "longintrepr.h"
+ #endif
+#endif
+
+static CYTHON_INLINE unsigned int __Pyx_PyInt_As_unsigned_int(PyObject *x) {
+    const unsigned int neg_one = (unsigned int) -1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_MAJOR_VERSION < 3
+    if (likely(PyInt_Check(x))) {
+        if (sizeof(unsigned int) < sizeof(long)) {
+            __PYX_VERIFY_RETURN_INT(unsigned int, long, PyInt_AS_LONG(x))
+        } else {
+            long val = PyInt_AS_LONG(x);
+            if (is_unsigned && unlikely(val < 0)) {
+                goto raise_neg_overflow;
+            }
+            return (unsigned int) val;
+        }
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+            switch (Py_SIZE(x)) {
+                case  0: return 0;
+                case  1: __PYX_VERIFY_RETURN_INT(unsigned int, digit, ((PyLongObject*)x)->ob_digit[0]);
+            }
+ #endif
+#endif
+            if (unlikely(Py_SIZE(x) < 0)) {
+                goto raise_neg_overflow;
+            }
+            if (sizeof(unsigned int) <= sizeof(unsigned long)) {
+                __PYX_VERIFY_RETURN_INT(unsigned int, unsigned long, PyLong_AsUnsignedLong(x))
+            } else if (sizeof(unsigned int) <= sizeof(unsigned long long)) {
+                __PYX_VERIFY_RETURN_INT(unsigned int, unsigned long long, PyLong_AsUnsignedLongLong(x))
+            }
+        } else {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+            switch (Py_SIZE(x)) {
+                case  0: return 0;
+                case  1: __PYX_VERIFY_RETURN_INT(unsigned int,  digit, +(((PyLongObject*)x)->ob_digit[0]));
+                case -1: __PYX_VERIFY_RETURN_INT(unsigned int, sdigit, -(sdigit) ((PyLongObject*)x)->ob_digit[0]);
+            }
+ #endif
+#endif
+            if (sizeof(unsigned int) <= sizeof(long)) {
+                __PYX_VERIFY_RETURN_INT(unsigned int, long, PyLong_AsLong(x))
+            } else if (sizeof(unsigned int) <= sizeof(long long)) {
+                __PYX_VERIFY_RETURN_INT(unsigned int, long long, PyLong_AsLongLong(x))
+            }
+        }
+        {
+#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray)
+            PyErr_SetString(PyExc_RuntimeError,
+                            "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers");
+#else
+            unsigned int val;
+            PyObject *v = __Pyx_PyNumber_Int(x);
+ #if PY_MAJOR_VERSION < 3
+            if (likely(v) && !PyLong_Check(v)) {
+                PyObject *tmp = v;
+                v = PyNumber_Long(tmp);
+                Py_DECREF(tmp);
+            }
+ #endif
+            if (likely(v)) {
+                int one = 1; int is_little = (int)*(unsigned char *)&one;
+                unsigned char *bytes = (unsigned char *)&val;
+                int ret = _PyLong_AsByteArray((PyLongObject *)v,
+                                              bytes, sizeof(val),
+                                              is_little, !is_unsigned);
+                Py_DECREF(v);
+                if (likely(!ret))
+                    return val;
+            }
+#endif
+            return (unsigned int) -1;
+        }
+    } else {
+        unsigned int val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (unsigned int) -1;
+        val = __Pyx_PyInt_As_unsigned_int(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+raise_overflow:
+    PyErr_SetString(PyExc_OverflowError,
+        "value too large to convert to unsigned int");
+    return (unsigned int) -1;
+raise_neg_overflow:
+    PyErr_SetString(PyExc_OverflowError,
+        "can't convert negative value to unsigned int");
+    return (unsigned int) -1;
+}
+
+static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *x) {
+    const int neg_one = (int) -1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_MAJOR_VERSION < 3
+    if (likely(PyInt_Check(x))) {
+        if (sizeof(int) < sizeof(long)) {
+            __PYX_VERIFY_RETURN_INT(int, long, PyInt_AS_LONG(x))
+        } else {
+            long val = PyInt_AS_LONG(x);
+            if (is_unsigned && unlikely(val < 0)) {
+                goto raise_neg_overflow;
+            }
+            return (int) val;
+        }
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+            switch (Py_SIZE(x)) {
+                case  0: return 0;
+                case  1: __PYX_VERIFY_RETURN_INT(int, digit, ((PyLongObject*)x)->ob_digit[0]);
+            }
+ #endif
+#endif
+            if (unlikely(Py_SIZE(x) < 0)) {
+                goto raise_neg_overflow;
+            }
+            if (sizeof(int) <= sizeof(unsigned long)) {
+                __PYX_VERIFY_RETURN_INT(int, unsigned long, PyLong_AsUnsignedLong(x))
+            } else if (sizeof(int) <= sizeof(unsigned long long)) {
+                __PYX_VERIFY_RETURN_INT(int, unsigned long long, PyLong_AsUnsignedLongLong(x))
+            }
+        } else {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+            switch (Py_SIZE(x)) {
+                case  0: return 0;
+                case  1: __PYX_VERIFY_RETURN_INT(int,  digit, +(((PyLongObject*)x)->ob_digit[0]));
+                case -1: __PYX_VERIFY_RETURN_INT(int, sdigit, -(sdigit) ((PyLongObject*)x)->ob_digit[0]);
+            }
+ #endif
+#endif
+            if (sizeof(int) <= sizeof(long)) {
+                __PYX_VERIFY_RETURN_INT(int, long, PyLong_AsLong(x))
+            } else if (sizeof(int) <= sizeof(long long)) {
+                __PYX_VERIFY_RETURN_INT(int, long long, PyLong_AsLongLong(x))
+            }
+        }
+        {
+#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray)
+            PyErr_SetString(PyExc_RuntimeError,
+                            "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers");
+#else
+            int val;
+            PyObject *v = __Pyx_PyNumber_Int(x);
+ #if PY_MAJOR_VERSION < 3
+            if (likely(v) && !PyLong_Check(v)) {
+                PyObject *tmp = v;
+                v = PyNumber_Long(tmp);
+                Py_DECREF(tmp);
+            }
+ #endif
+            if (likely(v)) {
+                int one = 1; int is_little = (int)*(unsigned char *)&one;
+                unsigned char *bytes = (unsigned char *)&val;
+                int ret = _PyLong_AsByteArray((PyLongObject *)v,
+                                              bytes, sizeof(val),
+                                              is_little, !is_unsigned);
+                Py_DECREF(v);
+                if (likely(!ret))
+                    return val;
+            }
+#endif
+            return (int) -1;
+        }
+    } else {
+        int val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (int) -1;
+        val = __Pyx_PyInt_As_int(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+raise_overflow:
+    PyErr_SetString(PyExc_OverflowError,
+        "value too large to convert to int");
+    return (int) -1;
+raise_neg_overflow:
+    PyErr_SetString(PyExc_OverflowError,
+        "can't convert negative value to int");
+    return (int) -1;
+}
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_unsigned_int(unsigned int value) {
+    const unsigned int neg_one = (unsigned int) -1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (is_unsigned) {
+        if (sizeof(unsigned int) < sizeof(long)) {
+            return PyInt_FromLong((long) value);
+        } else if (sizeof(unsigned int) <= sizeof(unsigned long)) {
+            return PyLong_FromUnsignedLong((unsigned long) value);
+        } else if (sizeof(unsigned int) <= sizeof(unsigned long long)) {
+            return PyLong_FromUnsignedLongLong((unsigned long long) value);
+        }
+    } else {
+        if (sizeof(unsigned int) <= sizeof(long)) {
+            return PyInt_FromLong((long) value);
+        } else if (sizeof(unsigned int) <= sizeof(long long)) {
+            return PyLong_FromLongLong((long long) value);
+        }
+    }
+    {
+        int one = 1; int little = (int)*(unsigned char *)&one;
+        unsigned char *bytes = (unsigned char *)&value;
+        return _PyLong_FromByteArray(bytes, sizeof(unsigned int),
+                                     little, !is_unsigned);
+    }
+}
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value) {
+    const int neg_one = (int) -1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (is_unsigned) {
+        if (sizeof(int) < sizeof(long)) {
+            return PyInt_FromLong((long) value);
+        } else if (sizeof(int) <= sizeof(unsigned long)) {
+            return PyLong_FromUnsignedLong((unsigned long) value);
+        } else if (sizeof(int) <= sizeof(unsigned long long)) {
+            return PyLong_FromUnsignedLongLong((unsigned long long) value);
+        }
+    } else {
+        if (sizeof(int) <= sizeof(long)) {
+            return PyInt_FromLong((long) value);
+        } else if (sizeof(int) <= sizeof(long long)) {
+            return PyLong_FromLongLong((long long) value);
+        }
+    }
+    {
+        int one = 1; int little = (int)*(unsigned char *)&one;
+        unsigned char *bytes = (unsigned char *)&value;
+        return _PyLong_FromByteArray(bytes, sizeof(int),
+                                     little, !is_unsigned);
+    }
+}
+
+static CYTHON_INLINE unsigned short __Pyx_PyInt_As_unsigned_short(PyObject *x) {
+    const unsigned short neg_one = (unsigned short) -1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_MAJOR_VERSION < 3
+    if (likely(PyInt_Check(x))) {
+        if (sizeof(unsigned short) < sizeof(long)) {
+            __PYX_VERIFY_RETURN_INT(unsigned short, long, PyInt_AS_LONG(x))
+        } else {
+            long val = PyInt_AS_LONG(x);
+            if (is_unsigned && unlikely(val < 0)) {
+                goto raise_neg_overflow;
+            }
+            return (unsigned short) val;
+        }
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+            switch (Py_SIZE(x)) {
+                case  0: return 0;
+                case  1: __PYX_VERIFY_RETURN_INT(unsigned short, digit, ((PyLongObject*)x)->ob_digit[0]);
+            }
+ #endif
+#endif
+            if (unlikely(Py_SIZE(x) < 0)) {
+                goto raise_neg_overflow;
+            }
+            if (sizeof(unsigned short) <= sizeof(unsigned long)) {
+                __PYX_VERIFY_RETURN_INT(unsigned short, unsigned long, PyLong_AsUnsignedLong(x))
+            } else if (sizeof(unsigned short) <= sizeof(unsigned long long)) {
+                __PYX_VERIFY_RETURN_INT(unsigned short, unsigned long long, PyLong_AsUnsignedLongLong(x))
+            }
+        } else {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+            switch (Py_SIZE(x)) {
+                case  0: return 0;
+                case  1: __PYX_VERIFY_RETURN_INT(unsigned short,  digit, +(((PyLongObject*)x)->ob_digit[0]));
+                case -1: __PYX_VERIFY_RETURN_INT(unsigned short, sdigit, -(sdigit) ((PyLongObject*)x)->ob_digit[0]);
+            }
+ #endif
+#endif
+            if (sizeof(unsigned short) <= sizeof(long)) {
+                __PYX_VERIFY_RETURN_INT(unsigned short, long, PyLong_AsLong(x))
+            } else if (sizeof(unsigned short) <= sizeof(long long)) {
+                __PYX_VERIFY_RETURN_INT(unsigned short, long long, PyLong_AsLongLong(x))
+            }
+        }
+        {
+#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray)
+            PyErr_SetString(PyExc_RuntimeError,
+                            "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers");
+#else
+            unsigned short val;
+            PyObject *v = __Pyx_PyNumber_Int(x);
+ #if PY_MAJOR_VERSION < 3
+            if (likely(v) && !PyLong_Check(v)) {
+                PyObject *tmp = v;
+                v = PyNumber_Long(tmp);
+                Py_DECREF(tmp);
+            }
+ #endif
+            if (likely(v)) {
+                int one = 1; int is_little = (int)*(unsigned char *)&one;
+                unsigned char *bytes = (unsigned char *)&val;
+                int ret = _PyLong_AsByteArray((PyLongObject *)v,
+                                              bytes, sizeof(val),
+                                              is_little, !is_unsigned);
+                Py_DECREF(v);
+                if (likely(!ret))
+                    return val;
+            }
+#endif
+            return (unsigned short) -1;
+        }
+    } else {
+        unsigned short val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (unsigned short) -1;
+        val = __Pyx_PyInt_As_unsigned_short(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+raise_overflow:
+    PyErr_SetString(PyExc_OverflowError,
+        "value too large to convert to unsigned short");
+    return (unsigned short) -1;
+raise_neg_overflow:
+    PyErr_SetString(PyExc_OverflowError,
+        "can't convert negative value to unsigned short");
+    return (unsigned short) -1;
+}
+
+static CYTHON_INLINE unsigned PY_LONG_LONG __Pyx_PyInt_As_unsigned_PY_LONG_LONG(PyObject *x) {
+    const unsigned PY_LONG_LONG neg_one = (unsigned PY_LONG_LONG) -1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_MAJOR_VERSION < 3
+    if (likely(PyInt_Check(x))) {
+        if (sizeof(unsigned PY_LONG_LONG) < sizeof(long)) {
+            __PYX_VERIFY_RETURN_INT(unsigned PY_LONG_LONG, long, PyInt_AS_LONG(x))
+        } else {
+            long val = PyInt_AS_LONG(x);
+            if (is_unsigned && unlikely(val < 0)) {
+                goto raise_neg_overflow;
+            }
+            return (unsigned PY_LONG_LONG) val;
+        }
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+            switch (Py_SIZE(x)) {
+                case  0: return 0;
+                case  1: __PYX_VERIFY_RETURN_INT(unsigned PY_LONG_LONG, digit, ((PyLongObject*)x)->ob_digit[0]);
+            }
+ #endif
+#endif
+            if (unlikely(Py_SIZE(x) < 0)) {
+                goto raise_neg_overflow;
+            }
+            if (sizeof(unsigned PY_LONG_LONG) <= sizeof(unsigned long)) {
+                __PYX_VERIFY_RETURN_INT(unsigned PY_LONG_LONG, unsigned long, PyLong_AsUnsignedLong(x))
+            } else if (sizeof(unsigned PY_LONG_LONG) <= sizeof(unsigned long long)) {
+                __PYX_VERIFY_RETURN_INT(unsigned PY_LONG_LONG, unsigned long long, PyLong_AsUnsignedLongLong(x))
+            }
+        } else {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+            switch (Py_SIZE(x)) {
+                case  0: return 0;
+                case  1: __PYX_VERIFY_RETURN_INT(unsigned PY_LONG_LONG,  digit, +(((PyLongObject*)x)->ob_digit[0]));
+                case -1: __PYX_VERIFY_RETURN_INT(unsigned PY_LONG_LONG, sdigit, -(sdigit) ((PyLongObject*)x)->ob_digit[0]);
+            }
+ #endif
+#endif
+            if (sizeof(unsigned PY_LONG_LONG) <= sizeof(long)) {
+                __PYX_VERIFY_RETURN_INT(unsigned PY_LONG_LONG, long, PyLong_AsLong(x))
+            } else if (sizeof(unsigned PY_LONG_LONG) <= sizeof(long long)) {
+                __PYX_VERIFY_RETURN_INT(unsigned PY_LONG_LONG, long long, PyLong_AsLongLong(x))
+            }
+        }
+        {
+#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray)
+            PyErr_SetString(PyExc_RuntimeError,
+                            "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers");
+#else
+            unsigned PY_LONG_LONG val;
+            PyObject *v = __Pyx_PyNumber_Int(x);
+ #if PY_MAJOR_VERSION < 3
+            if (likely(v) && !PyLong_Check(v)) {
+                PyObject *tmp = v;
+                v = PyNumber_Long(tmp);
+                Py_DECREF(tmp);
+            }
+ #endif
+            if (likely(v)) {
+                int one = 1; int is_little = (int)*(unsigned char *)&one;
+                unsigned char *bytes = (unsigned char *)&val;
+                int ret = _PyLong_AsByteArray((PyLongObject *)v,
+                                              bytes, sizeof(val),
+                                              is_little, !is_unsigned);
+                Py_DECREF(v);
+                if (likely(!ret))
+                    return val;
+            }
+#endif
+            return (unsigned PY_LONG_LONG) -1;
+        }
+    } else {
+        unsigned PY_LONG_LONG val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (unsigned PY_LONG_LONG) -1;
+        val = __Pyx_PyInt_As_unsigned_PY_LONG_LONG(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+raise_overflow:
+    PyErr_SetString(PyExc_OverflowError,
+        "value too large to convert to unsigned PY_LONG_LONG");
+    return (unsigned PY_LONG_LONG) -1;
+raise_neg_overflow:
+    PyErr_SetString(PyExc_OverflowError,
+        "can't convert negative value to unsigned PY_LONG_LONG");
+    return (unsigned PY_LONG_LONG) -1;
+}
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_unsigned_PY_LONG_LONG(unsigned PY_LONG_LONG value) {
+    const unsigned PY_LONG_LONG neg_one = (unsigned PY_LONG_LONG) -1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (is_unsigned) {
+        if (sizeof(unsigned PY_LONG_LONG) < sizeof(long)) {
+            return PyInt_FromLong((long) value);
+        } else if (sizeof(unsigned PY_LONG_LONG) <= sizeof(unsigned long)) {
+            return PyLong_FromUnsignedLong((unsigned long) value);
+        } else if (sizeof(unsigned PY_LONG_LONG) <= sizeof(unsigned long long)) {
+            return PyLong_FromUnsignedLongLong((unsigned long long) value);
+        }
+    } else {
+        if (sizeof(unsigned PY_LONG_LONG) <= sizeof(long)) {
+            return PyInt_FromLong((long) value);
+        } else if (sizeof(unsigned PY_LONG_LONG) <= sizeof(long long)) {
+            return PyLong_FromLongLong((long long) value);
+        }
+    }
+    {
+        int one = 1; int little = (int)*(unsigned char *)&one;
+        unsigned char *bytes = (unsigned char *)&value;
+        return _PyLong_FromByteArray(bytes, sizeof(unsigned PY_LONG_LONG),
+                                     little, !is_unsigned);
+    }
+}
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value) {
+    const long neg_one = (long) -1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (is_unsigned) {
+        if (sizeof(long) < sizeof(long)) {
+            return PyInt_FromLong((long) value);
+        } else if (sizeof(long) <= sizeof(unsigned long)) {
+            return PyLong_FromUnsignedLong((unsigned long) value);
+        } else if (sizeof(long) <= sizeof(unsigned long long)) {
+            return PyLong_FromUnsignedLongLong((unsigned long long) value);
+        }
+    } else {
+        if (sizeof(long) <= sizeof(long)) {
+            return PyInt_FromLong((long) value);
+        } else if (sizeof(long) <= sizeof(long long)) {
+            return PyLong_FromLongLong((long long) value);
+        }
+    }
+    {
+        int one = 1; int little = (int)*(unsigned char *)&one;
+        unsigned char *bytes = (unsigned char *)&value;
+        return _PyLong_FromByteArray(bytes, sizeof(long),
+                                     little, !is_unsigned);
+    }
+}
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_unsigned_short(unsigned short value) {
+    const unsigned short neg_one = (unsigned short) -1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (is_unsigned) {
+        if (sizeof(unsigned short) < sizeof(long)) {
+            return PyInt_FromLong((long) value);
+        } else if (sizeof(unsigned short) <= sizeof(unsigned long)) {
+            return PyLong_FromUnsignedLong((unsigned long) value);
+        } else if (sizeof(unsigned short) <= sizeof(unsigned long long)) {
+            return PyLong_FromUnsignedLongLong((unsigned long long) value);
+        }
+    } else {
+        if (sizeof(unsigned short) <= sizeof(long)) {
+            return PyInt_FromLong((long) value);
+        } else if (sizeof(unsigned short) <= sizeof(long long)) {
+            return PyLong_FromLongLong((long long) value);
+        }
+    }
+    {
+        int one = 1; int little = (int)*(unsigned char *)&one;
+        unsigned char *bytes = (unsigned char *)&value;
+        return _PyLong_FromByteArray(bytes, sizeof(unsigned short),
+                                     little, !is_unsigned);
+    }
+}
+
+#if CYTHON_CCOMPLEX
+  #ifdef __cplusplus
+    static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float x, float y) {
+      return ::std::complex< float >(x, y);
+    }
+  #else
+    static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float x, float y) {
+      return x + y*(__pyx_t_float_complex)_Complex_I;
+    }
+  #endif
+#else
+    static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float x, float y) {
+      __pyx_t_float_complex z;
+      z.real = x;
+      z.imag = y;
+      return z;
+    }
+#endif
+
+#if CYTHON_CCOMPLEX
+#else
+    static CYTHON_INLINE int __Pyx_c_eqf(__pyx_t_float_complex a, __pyx_t_float_complex b) {
+       return (a.real == b.real) && (a.imag == b.imag);
+    }
+    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_sumf(__pyx_t_float_complex a, __pyx_t_float_complex b) {
+        __pyx_t_float_complex z;
+        z.real = a.real + b.real;
+        z.imag = a.imag + b.imag;
+        return z;
+    }
+    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_difff(__pyx_t_float_complex a, __pyx_t_float_complex b) {
+        __pyx_t_float_complex z;
+        z.real = a.real - b.real;
+        z.imag = a.imag - b.imag;
+        return z;
+    }
+    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_prodf(__pyx_t_float_complex a, __pyx_t_float_complex b) {
+        __pyx_t_float_complex z;
+        z.real = a.real * b.real - a.imag * b.imag;
+        z.imag = a.real * b.imag + a.imag * b.real;
+        return z;
+    }
+    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_quotf(__pyx_t_float_complex a, __pyx_t_float_complex b) {
+        __pyx_t_float_complex z;
+        float denom = b.real * b.real + b.imag * b.imag;
+        z.real = (a.real * b.real + a.imag * b.imag) / denom;
+        z.imag = (a.imag * b.real - a.real * b.imag) / denom;
+        return z;
+    }
+    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_negf(__pyx_t_float_complex a) {
+        __pyx_t_float_complex z;
+        z.real = -a.real;
+        z.imag = -a.imag;
+        return z;
+    }
+    static CYTHON_INLINE int __Pyx_c_is_zerof(__pyx_t_float_complex a) {
+       return (a.real == 0) && (a.imag == 0);
+    }
+    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_conjf(__pyx_t_float_complex a) {
+        __pyx_t_float_complex z;
+        z.real =  a.real;
+        z.imag = -a.imag;
+        return z;
+    }
+    #if 1
+        static CYTHON_INLINE float __Pyx_c_absf(__pyx_t_float_complex z) {
+          #if !defined(HAVE_HYPOT) || defined(_MSC_VER)
+            return sqrtf(z.real*z.real + z.imag*z.imag);
+          #else
+            return hypotf(z.real, z.imag);
+          #endif
+        }
+        static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_powf(__pyx_t_float_complex a, __pyx_t_float_complex b) {
+            __pyx_t_float_complex z;
+            float r, lnr, theta, z_r, z_theta;
+            if (b.imag == 0 && b.real == (int)b.real) {
+                if (b.real < 0) {
+                    float denom = a.real * a.real + a.imag * a.imag;
+                    a.real = a.real / denom;
+                    a.imag = -a.imag / denom;
+                    b.real = -b.real;
+                }
+                switch ((int)b.real) {
+                    case 0:
+                        z.real = 1;
+                        z.imag = 0;
+                        return z;
+                    case 1:
+                        return a;
+                    case 2:
+                        z = __Pyx_c_prodf(a, a);
+                        return __Pyx_c_prodf(a, a);
+                    case 3:
+                        z = __Pyx_c_prodf(a, a);
+                        return __Pyx_c_prodf(z, a);
+                    case 4:
+                        z = __Pyx_c_prodf(a, a);
+                        return __Pyx_c_prodf(z, z);
+                }
+            }
+            if (a.imag == 0) {
+                if (a.real == 0) {
+                    return a;
+                }
+                r = a.real;
+                theta = 0;
+            } else {
+                r = __Pyx_c_absf(a);
+                theta = atan2f(a.imag, a.real);
+            }
+            lnr = logf(r);
+            z_r = expf(lnr * b.real - theta * b.imag);
+            z_theta = theta * b.real + lnr * b.imag;
+            z.real = z_r * cosf(z_theta);
+            z.imag = z_r * sinf(z_theta);
+            return z;
+        }
+    #endif
+#endif
+
+#if CYTHON_CCOMPLEX
+  #ifdef __cplusplus
+    static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) {
+      return ::std::complex< double >(x, y);
+    }
+  #else
+    static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) {
+      return x + y*(__pyx_t_double_complex)_Complex_I;
+    }
+  #endif
+#else
+    static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) {
+      __pyx_t_double_complex z;
+      z.real = x;
+      z.imag = y;
+      return z;
+    }
+#endif
+
+#if CYTHON_CCOMPLEX
+#else
+    static CYTHON_INLINE int __Pyx_c_eq(__pyx_t_double_complex a, __pyx_t_double_complex b) {
+       return (a.real == b.real) && (a.imag == b.imag);
+    }
+    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_sum(__pyx_t_double_complex a, __pyx_t_double_complex b) {
+        __pyx_t_double_complex z;
+        z.real = a.real + b.real;
+        z.imag = a.imag + b.imag;
+        return z;
+    }
+    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_diff(__pyx_t_double_complex a, __pyx_t_double_complex b) {
+        __pyx_t_double_complex z;
+        z.real = a.real - b.real;
+        z.imag = a.imag - b.imag;
+        return z;
+    }
+    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_prod(__pyx_t_double_complex a, __pyx_t_double_complex b) {
+        __pyx_t_double_complex z;
+        z.real = a.real * b.real - a.imag * b.imag;
+        z.imag = a.real * b.imag + a.imag * b.real;
+        return z;
+    }
+    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_quot(__pyx_t_double_complex a, __pyx_t_double_complex b) {
+        __pyx_t_double_complex z;
+        double denom = b.real * b.real + b.imag * b.imag;
+        z.real = (a.real * b.real + a.imag * b.imag) / denom;
+        z.imag = (a.imag * b.real - a.real * b.imag) / denom;
+        return z;
+    }
+    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_neg(__pyx_t_double_complex a) {
+        __pyx_t_double_complex z;
+        z.real = -a.real;
+        z.imag = -a.imag;
+        return z;
+    }
+    static CYTHON_INLINE int __Pyx_c_is_zero(__pyx_t_double_complex a) {
+       return (a.real == 0) && (a.imag == 0);
+    }
+    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_conj(__pyx_t_double_complex a) {
+        __pyx_t_double_complex z;
+        z.real =  a.real;
+        z.imag = -a.imag;
+        return z;
+    }
+    #if 1
+        static CYTHON_INLINE double __Pyx_c_abs(__pyx_t_double_complex z) {
+          #if !defined(HAVE_HYPOT) || defined(_MSC_VER)
+            return sqrt(z.real*z.real + z.imag*z.imag);
+          #else
+            return hypot(z.real, z.imag);
+          #endif
+        }
+        static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_pow(__pyx_t_double_complex a, __pyx_t_double_complex b) {
+            __pyx_t_double_complex z;
+            double r, lnr, theta, z_r, z_theta;
+            if (b.imag == 0 && b.real == (int)b.real) {
+                if (b.real < 0) {
+                    double denom = a.real * a.real + a.imag * a.imag;
+                    a.real = a.real / denom;
+                    a.imag = -a.imag / denom;
+                    b.real = -b.real;
+                }
+                switch ((int)b.real) {
+                    case 0:
+                        z.real = 1;
+                        z.imag = 0;
+                        return z;
+                    case 1:
+                        return a;
+                    case 2:
+                        z = __Pyx_c_prod(a, a);
+                        return __Pyx_c_prod(a, a);
+                    case 3:
+                        z = __Pyx_c_prod(a, a);
+                        return __Pyx_c_prod(z, a);
+                    case 4:
+                        z = __Pyx_c_prod(a, a);
+                        return __Pyx_c_prod(z, z);
+                }
+            }
+            if (a.imag == 0) {
+                if (a.real == 0) {
+                    return a;
+                }
+                r = a.real;
+                theta = 0;
+            } else {
+                r = __Pyx_c_abs(a);
+                theta = atan2(a.imag, a.real);
+            }
+            lnr = log(r);
+            z_r = exp(lnr * b.real - theta * b.imag);
+            z_theta = theta * b.real + lnr * b.imag;
+            z.real = z_r * cos(z_theta);
+            z.imag = z_r * sin(z_theta);
+            return z;
+        }
+    #endif
+#endif
+
+static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *x) {
+    const long neg_one = (long) -1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_MAJOR_VERSION < 3
+    if (likely(PyInt_Check(x))) {
+        if (sizeof(long) < sizeof(long)) {
+            __PYX_VERIFY_RETURN_INT(long, long, PyInt_AS_LONG(x))
+        } else {
+            long val = PyInt_AS_LONG(x);
+            if (is_unsigned && unlikely(val < 0)) {
+                goto raise_neg_overflow;
+            }
+            return (long) val;
+        }
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+            switch (Py_SIZE(x)) {
+                case  0: return 0;
+                case  1: __PYX_VERIFY_RETURN_INT(long, digit, ((PyLongObject*)x)->ob_digit[0]);
+            }
+ #endif
+#endif
+            if (unlikely(Py_SIZE(x) < 0)) {
+                goto raise_neg_overflow;
+            }
+            if (sizeof(long) <= sizeof(unsigned long)) {
+                __PYX_VERIFY_RETURN_INT(long, unsigned long, PyLong_AsUnsignedLong(x))
+            } else if (sizeof(long) <= sizeof(unsigned long long)) {
+                __PYX_VERIFY_RETURN_INT(long, unsigned long long, PyLong_AsUnsignedLongLong(x))
+            }
+        } else {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+            switch (Py_SIZE(x)) {
+                case  0: return 0;
+                case  1: __PYX_VERIFY_RETURN_INT(long,  digit, +(((PyLongObject*)x)->ob_digit[0]));
+                case -1: __PYX_VERIFY_RETURN_INT(long, sdigit, -(sdigit) ((PyLongObject*)x)->ob_digit[0]);
+            }
+ #endif
+#endif
+            if (sizeof(long) <= sizeof(long)) {
+                __PYX_VERIFY_RETURN_INT(long, long, PyLong_AsLong(x))
+            } else if (sizeof(long) <= sizeof(long long)) {
+                __PYX_VERIFY_RETURN_INT(long, long long, PyLong_AsLongLong(x))
+            }
+        }
+        {
+#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray)
+            PyErr_SetString(PyExc_RuntimeError,
+                            "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers");
+#else
+            long val;
+            PyObject *v = __Pyx_PyNumber_Int(x);
+ #if PY_MAJOR_VERSION < 3
+            if (likely(v) && !PyLong_Check(v)) {
+                PyObject *tmp = v;
+                v = PyNumber_Long(tmp);
+                Py_DECREF(tmp);
+            }
+ #endif
+            if (likely(v)) {
+                int one = 1; int is_little = (int)*(unsigned char *)&one;
+                unsigned char *bytes = (unsigned char *)&val;
+                int ret = _PyLong_AsByteArray((PyLongObject *)v,
+                                              bytes, sizeof(val),
+                                              is_little, !is_unsigned);
+                Py_DECREF(v);
+                if (likely(!ret))
+                    return val;
+            }
+#endif
+            return (long) -1;
+        }
+    } else {
+        long val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (long) -1;
+        val = __Pyx_PyInt_As_long(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+raise_overflow:
+    PyErr_SetString(PyExc_OverflowError,
+        "value too large to convert to long");
+    return (long) -1;
+raise_neg_overflow:
+    PyErr_SetString(PyExc_OverflowError,
+        "can't convert negative value to long");
+    return (long) -1;
+}
+
+static int __Pyx_check_binary_version(void) {
+    char ctversion[4], rtversion[4];
+    PyOS_snprintf(ctversion, 4, "%d.%d", PY_MAJOR_VERSION, PY_MINOR_VERSION);
+    PyOS_snprintf(rtversion, 4, "%s", Py_GetVersion());
+    if (ctversion[0] != rtversion[0] || ctversion[2] != rtversion[2]) {
+        char message[200];
+        PyOS_snprintf(message, sizeof(message),
+                      "compiletime version %s of module '%.100s' "
+                      "does not match runtime version %s",
+                      ctversion, __Pyx_MODULE_NAME, rtversion);
+        return PyErr_WarnEx(NULL, message, 1);
+    }
+    return 0;
+}
+
+#ifndef __PYX_HAVE_RT_ImportModule
+#define __PYX_HAVE_RT_ImportModule
+static PyObject *__Pyx_ImportModule(const char *name) {
+    PyObject *py_name = 0;
+    PyObject *py_module = 0;
+    py_name = __Pyx_PyIdentifier_FromString(name);
+    if (!py_name)
+        goto bad;
+    py_module = PyImport_Import(py_name);
+    Py_DECREF(py_name);
+    return py_module;
+bad:
+    Py_XDECREF(py_name);
+    return 0;
+}
+#endif
+
+#ifndef __PYX_HAVE_RT_ImportType
+#define __PYX_HAVE_RT_ImportType
+static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name,
+    size_t size, int strict)
+{
+    PyObject *py_module = 0;
+    PyObject *result = 0;
+    PyObject *py_name = 0;
+    char warning[200];
+    Py_ssize_t basicsize;
+#ifdef Py_LIMITED_API
+    PyObject *py_basicsize;
+#endif
+    py_module = __Pyx_ImportModule(module_name);
+    if (!py_module)
+        goto bad;
+    py_name = __Pyx_PyIdentifier_FromString(class_name);
+    if (!py_name)
+        goto bad;
+    result = PyObject_GetAttr(py_module, py_name);
+    Py_DECREF(py_name);
+    py_name = 0;
+    Py_DECREF(py_module);
+    py_module = 0;
+    if (!result)
+        goto bad;
+    if (!PyType_Check(result)) {
+        PyErr_Format(PyExc_TypeError,
+            "%.200s.%.200s is not a type object",
+            module_name, class_name);
+        goto bad;
+    }
+#ifndef Py_LIMITED_API
+    basicsize = ((PyTypeObject *)result)->tp_basicsize;
+#else
+    py_basicsize = PyObject_GetAttrString(result, "__basicsize__");
+    if (!py_basicsize)
+        goto bad;
+    basicsize = PyLong_AsSsize_t(py_basicsize);
+    Py_DECREF(py_basicsize);
+    py_basicsize = 0;
+    if (basicsize == (Py_ssize_t)-1 && PyErr_Occurred())
+        goto bad;
+#endif
+    if (!strict && (size_t)basicsize > size) {
+        PyOS_snprintf(warning, sizeof(warning),
+            "%s.%s size changed, may indicate binary incompatibility",
+            module_name, class_name);
+        if (PyErr_WarnEx(NULL, warning, 0) < 0) goto bad;
+    }
+    else if ((size_t)basicsize != size) {
+        PyErr_Format(PyExc_ValueError,
+            "%.200s.%.200s has the wrong size, try recompiling",
+            module_name, class_name);
+        goto bad;
+    }
+    return (PyTypeObject *)result;
+bad:
+    Py_XDECREF(py_module);
+    Py_XDECREF(result);
+    return NULL;
+}
+#endif
+
+static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
+    while (t->p) {
+        #if PY_MAJOR_VERSION < 3
+        if (t->is_unicode) {
+            *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
+        } else if (t->intern) {
+            *t->p = PyString_InternFromString(t->s);
+        } else {
+            *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
+        }
+        #else
+        if (t->is_unicode | t->is_str) {
+            if (t->intern) {
+                *t->p = PyUnicode_InternFromString(t->s);
+            } else if (t->encoding) {
+                *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL);
+            } else {
+                *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
+            }
+        } else {
+            *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
+        }
+        #endif
+        if (!*t->p)
+            return -1;
+        ++t;
+    }
+    return 0;
+}
+
+static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char* c_str) {
+    return __Pyx_PyUnicode_FromStringAndSize(c_str, (Py_ssize_t)strlen(c_str));
+}
+static CYTHON_INLINE char* __Pyx_PyObject_AsString(PyObject* o) {
+    Py_ssize_t ignore;
+    return __Pyx_PyObject_AsStringAndSize(o, &ignore);
+}
+static CYTHON_INLINE char* __Pyx_PyObject_AsStringAndSize(PyObject* o, Py_ssize_t *length) {
+#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT
+    if (
+#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII
+            __Pyx_sys_getdefaultencoding_not_ascii &&
+#endif
+            PyUnicode_Check(o)) {
+#if PY_VERSION_HEX < 0x03030000
+        char* defenc_c;
+        PyObject* defenc = _PyUnicode_AsDefaultEncodedString(o, NULL);
+        if (!defenc) return NULL;
+        defenc_c = PyBytes_AS_STRING(defenc);
+#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII
+        {
+            char* end = defenc_c + PyBytes_GET_SIZE(defenc);
+            char* c;
+            for (c = defenc_c; c < end; c++) {
+                if ((unsigned char) (*c) >= 128) {
+                    PyUnicode_AsASCIIString(o);
+                    return NULL;
+                }
+            }
+        }
+#endif
+        *length = PyBytes_GET_SIZE(defenc);
+        return defenc_c;
+#else
+        if (__Pyx_PyUnicode_READY(o) == -1) return NULL;
+#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII
+        if (PyUnicode_IS_ASCII(o)) {
+            *length = PyUnicode_GET_LENGTH(o);
+            return PyUnicode_AsUTF8(o);
+        } else {
+            PyUnicode_AsASCIIString(o);
+            return NULL;
+        }
+#else
+        return PyUnicode_AsUTF8AndSize(o, length);
+#endif
+#endif
+    } else
+#endif
+#if !CYTHON_COMPILING_IN_PYPY
+    if (PyByteArray_Check(o)) {
+        *length = PyByteArray_GET_SIZE(o);
+        return PyByteArray_AS_STRING(o);
+    } else
+#endif
+    {
+        char* result;
+        int r = PyBytes_AsStringAndSize(o, &result, length);
+        if (unlikely(r < 0)) {
+            return NULL;
+        } else {
+            return result;
+        }
+    }
+}
+static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) {
+   int is_true = x == Py_True;
+   if (is_true | (x == Py_False) | (x == Py_None)) return is_true;
+   else return PyObject_IsTrue(x);
+}
+static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x) {
+  PyNumberMethods *m;
+  const char *name = NULL;
+  PyObject *res = NULL;
+#if PY_MAJOR_VERSION < 3
+  if (PyInt_Check(x) || PyLong_Check(x))
+#else
+  if (PyLong_Check(x))
+#endif
+    return Py_INCREF(x), x;
+  m = Py_TYPE(x)->tp_as_number;
+#if PY_MAJOR_VERSION < 3
+  if (m && m->nb_int) {
+    name = "int";
+    res = PyNumber_Int(x);
+  }
+  else if (m && m->nb_long) {
+    name = "long";
+    res = PyNumber_Long(x);
+  }
+#else
+  if (m && m->nb_int) {
+    name = "int";
+    res = PyNumber_Long(x);
+  }
+#endif
+  if (res) {
+#if PY_MAJOR_VERSION < 3
+    if (!PyInt_Check(res) && !PyLong_Check(res)) {
+#else
+    if (!PyLong_Check(res)) {
+#endif
+      PyErr_Format(PyExc_TypeError,
+                   "__%.4s__ returned non-%.4s (type %.200s)",
+                   name, name, Py_TYPE(res)->tp_name);
+      Py_DECREF(res);
+      return NULL;
+    }
+  }
+  else if (!PyErr_Occurred()) {
+    PyErr_SetString(PyExc_TypeError,
+                    "an integer is required");
+  }
+  return res;
+}
+static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) {
+  Py_ssize_t ival;
+  PyObject *x;
+#if PY_MAJOR_VERSION < 3
+  if (likely(PyInt_CheckExact(b)))
+      return PyInt_AS_LONG(b);
+#endif
+  if (likely(PyLong_CheckExact(b))) {
+    #if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+     #if CYTHON_USE_PYLONG_INTERNALS
+       switch (Py_SIZE(b)) {
+       case -1: return -(sdigit)((PyLongObject*)b)->ob_digit[0];
+       case  0: return 0;
+       case  1: return ((PyLongObject*)b)->ob_digit[0];
+       }
+     #endif
+    #endif
+    return PyLong_AsSsize_t(b);
+  }
+  x = PyNumber_Index(b);
+  if (!x) return -1;
+  ival = PyInt_AsSsize_t(x);
+  Py_DECREF(x);
+  return ival;
+}
+static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) {
+    return PyInt_FromSize_t(ival);
+}
+
+
+#endif /* Py_PYTHON_H */
diff --git a/lib/bx/bbi/bbi_file.pxd b/lib/bx/bbi/bbi_file.pxd
new file mode 100644
index 0000000..2cf291e
--- /dev/null
+++ b/lib/bx/bbi/bbi_file.pxd
@@ -0,0 +1,91 @@
+from bpt_file cimport BPTFile
+from cirtree_file cimport CIRTreeFile
+from types cimport *
+
+import numpy
+cimport numpy
+
+cdef class SummaryBlock:
+    """
+    A block of summary data from disk
+    """
+    cdef public bits32 chrom_id
+    cdef public bits32 start
+    cdef public bits32 end
+    cdef public bits32 valid_count
+    cdef public double min_val
+    cdef public double max_val
+    cdef public double sum_data
+    cdef public double sum_squares
+
+cdef class SummarizedData:
+    """
+    The result of using SummaryBlocks read from the file to produce a 
+    aggregation over a particular range and resolution
+    """
+    cdef public bits32 start
+    cdef public bits32 end
+    cdef public int size
+    cdef public numpy.ndarray valid_count
+    cdef public numpy.ndarray min_val 
+    cdef public numpy.ndarray max_val
+    cdef public numpy.ndarray sum_data
+    cdef public numpy.ndarray sum_squares
+
+    cdef accumulate_interval_value( self, bits32 s, bits32 e, float val )
+
+cdef class BBIFile
+
+cdef class BlockHandler:
+    """
+    Callback for `BBIFile.visit_blocks_in_region`
+    """
+    cdef handle_block( self, str block_data, BBIFile bbi_file )
+
+cdef class BBIFile:
+    """
+    A "big binary indexed" file. Stores blocks of raw data and numeric 
+    summaries of that data at different levels of aggregation ("zoom levels").
+    Generic enough to accommodate both wiggle and bed data. 
+    """
+    # Probably a PyFileObject, or any seekable file-like
+    cdef object file
+    # A BinaryFileReader created from file
+    cdef object reader
+    # The magic number or type signature (whether the file is bigWig or bigBed or...)
+    cdef public bits32 magic
+    # Is the file byteswapped relative to our native byte order?
+    cdef boolean is_byteswapped
+    # The index to the chromosomes, an embedded BPT file
+    cdef BPTFile chrom_bpt
+    # Version number
+    cdef public bits16 version
+    # Number of zoom levels
+    cdef public bits16 zoom_levels
+    # Offset to chromosome index
+    cdef bits64 chrom_tree_offset
+    # Offset to unzoomed data
+    cdef bits64 unzoomed_data_offset
+    # Offset to unzoomed index
+    cdef bits64 unzoomed_index_offset
+    # If bed, number of columns
+    cdef bits16 field_count
+    cdef bits16 defined_field_count
+    # Offset to an embedded string containing "AutoSQL" format data that defines the columns
+    cdef bits64 as_offset
+    # Offset to total summary information (if any)
+    cdef bits64 total_summary_offset
+    # Size of uncompression buffer, 0 if no compression
+    cdef bits32 uncompress_buf_size
+    # Zoom levels list
+    cdef public object level_list
+
+    cdef visit_blocks_in_region( self, bits32 chrom_id, bits32 start, bits32 end, BlockHandler handler )
+    cdef _get_chrom_id_and_size( self, char * chrom )
+    cdef _best_zoom_level( self, int desired_reduction )
+    cpdef summarize( self, char * chrom, bits32 start, bits32 end, int summary_size )
+    cpdef summarize_from_full( self, char * chrom, bits32 start, bits32 end, int summary_size )
+    cpdef query( self, char * chrom, bits32 start, bits32 end, int summary_size )
+    cdef _summarize_from_full( self, bits32 chrom_id, bits32 start, bits32 end, int summary_size )    
+
+
diff --git a/lib/bx/bbi/bbi_file.pyx b/lib/bx/bbi/bbi_file.pyx
new file mode 100644
index 0000000..1b8424e
--- /dev/null
+++ b/lib/bx/bbi/bbi_file.pyx
@@ -0,0 +1,393 @@
+# cython: profile=False
+
+"""
+Core implementation for reading UCSC "big binary indexed" files.
+
+There isn't really any specification for the format beyond the code, so this
+mirrors Jim Kent's 'bbiRead.c' mostly. 
+"""
+
+cimport cython
+
+from collections import deque
+from bpt_file cimport BPTFile
+from cirtree_file cimport CIRTreeFile
+from types cimport *
+
+from libc cimport limits
+
+import numpy
+cimport numpy
+cimport numpy as np
+import numpy as np
+
+from bx.misc.binary_file import BinaryFileReader
+from cStringIO import StringIO
+import zlib, math
+
+# Signatures for bbi related file types
+
+cdef public int big_wig_sig = 0x888FFC26
+cdef public int big_bed_sig = 0x8789F2EB
+
+# Some record sizes for parsing
+DEF summary_on_disk_size = 32
+
+ at cython.profile(False)
+cdef inline int range_intersection( int start1, int end1, int start2, int end2 ):
+    return min( end1, end2 ) - max( start1, start2 )
+
+ at cython.profile(False)
+cdef inline int imax(int a, int b): return a if a >= b else b
+ at cython.profile(False)
+cdef inline int imin(int a, int b): return a if a <= b else b
+
+cdef enum summary_type:
+    summary_type_mean = 0
+    summary_type_max = 1
+    summary_type_min = 2
+    summary_type_coverage = 3
+    summary_type_sd = 4
+
+cdef class SummaryBlock:
+    """
+    A block of summary data from disk
+    """
+    pass
+
+cdef class SummarizedData:
+    """
+    The result of using SummaryBlocks read from the file to produce a 
+    aggregation over a particular range and resolution
+    """
+    def __init__( self, bits32 start, bits32 end, int size ):
+        self.start = start
+        self.end = end
+        self.size = size
+        self.valid_count = numpy.zeros( self.size, dtype=numpy.float64 )
+        self.min_val = numpy.zeros( self.size, dtype=numpy.float64 )
+        self.max_val = numpy.zeros( self.size, dtype=numpy.float64 )
+        self.sum_data = numpy.zeros( self.size, dtype=numpy.float64 )
+        self.sum_squares = numpy.zeros( self.size, dtype=numpy.float64 )
+    cdef accumulate_interval_value( self, bits32 s, bits32 e, float val ):
+        cdef int base_start, base_end, base_step, overlap, j, interval_size
+        cdef double overlap_factor, interval_weight
+        # We locally cdef the arrays so all indexing will be at C speeds
+        cdef numpy.ndarray[numpy.float64_t, ndim=1] valid_count = self.valid_count
+        cdef numpy.ndarray[numpy.float64_t, ndim=1] min_val = self.min_val
+        cdef numpy.ndarray[numpy.float64_t, ndim=1] max_val = self.max_val
+        cdef numpy.ndarray[numpy.float64_t, ndim=1] sum_data = self.sum_data
+        cdef numpy.ndarray[numpy.float64_t, ndim=1] sum_squares = self.sum_squares
+        # Trim interval down to region of interest
+        if s < self.start: 
+            s = self.start
+        if e > self.end: 
+            e = self.end
+        if s >= e: 
+            return
+        base_step = ( self.end - self.start ) / self.size
+        for j from 0 <= j < self.size:
+            base_start = self.start + ( base_step * j )
+            base_end = base_start + base_step
+            overlap = range_intersection( base_start, base_end, s, e )
+            if overlap > 0:
+                interval_size = e - s
+                overlap_factor = <double> overlap / interval_size
+                interval_weight = interval_size * overlap_factor
+                valid_count[j] += interval_weight
+                sum_data[j] += val * interval_weight
+                sum_squares[j] += val * val * interval_weight
+                if max_val[j] < val:
+                    max_val[j] = val
+                if min_val[j] > val:
+                    min_val[j] = val 
+
+cdef class BlockHandler:
+    """
+    Callback for `BBIFile.visit_blocks_in_region`
+    """
+    cdef handle_block( self, str block_data, BBIFile bbi_file ):
+        pass
+
+cdef class BBIFile:
+    """
+    A "big binary indexed" file. Stores blocks of raw data and numeric 
+    summaries of that data at different levels of aggregation ("zoom levels").
+    Generic enough to accommodate both wiggle and bed data. 
+    """
+
+    def __init__( self, file=None, expected_sig=None, type_name=None ):
+        if file is not None:
+            self.open( file, expected_sig, type_name )
+
+    def open( self, file, expected_sig, type_name ):
+        """
+        Initialize from an existing bbi file, signature (magic) must be passed
+        in since this is generic. 
+        """
+        assert expected_sig is not None
+        self.file = file
+        # Open the file in a BinaryFileReader, handles magic and byteswapping
+        self.reader = reader = BinaryFileReader( file, expected_sig )
+        self.magic = expected_sig
+        self.is_byteswapped = self.reader.byteswap_needed
+        # Read header stuff
+        self.version = reader.read_uint16()
+        self.zoom_levels = reader.read_uint16()
+        self.chrom_tree_offset = reader.read_uint64()
+        self.unzoomed_data_offset = reader.read_uint64()
+        self.unzoomed_index_offset = reader.read_uint64()
+        self.field_count = reader.read_uint16()
+        self.defined_field_count = reader.read_uint16()
+        self.as_offset = reader.read_uint64()
+        self.total_summary_offset = reader.read_uint64()
+        self.uncompress_buf_size = reader.read_uint32()
+        # Skip reserved
+        reader.seek( 64 )
+        # Read zoom headers
+        self.level_list = []
+        for i from 0 <= i < self.zoom_levels:
+            level = ZoomLevel() 
+            level.bbi_file = self
+            level.reduction_level = reader.read_uint32()
+            level.reserved = reader.read_uint32()
+            level.data_offset = reader.read_uint64()
+            level.index_offset = reader.read_uint64()
+            self.level_list.append( level )
+        # Initialize and attach embedded BPTFile containing chromosome names and ids
+        reader.seek( self.chrom_tree_offset )
+        self.chrom_bpt = BPTFile( file=self.file )
+
+    cdef visit_blocks_in_region( self, bits32 chrom_id, bits32 start, bits32 end, BlockHandler handler ):
+        """
+        Visit each block from the full data that overlaps a specific region
+        """
+        cdef CIRTreeFile ctf
+        reader = self.reader
+        reader.seek( self.unzoomed_index_offset )
+        ctf = CIRTreeFile( reader.file )
+        block_list = ctf.find_overlapping_blocks( chrom_id, start, end )
+        for offset, size in block_list:
+            # Seek to and read all data for the block
+            reader.seek( offset )
+            block_data = reader.read( size )
+            # Might need to uncompress
+            if self.uncompress_buf_size > 0:
+                block_data = zlib.decompress( block_data )
+            handler.handle_block( block_data, self )
+        
+    cpdef summarize( self, char * chrom, bits32 start, bits32 end, int summary_size ):
+        """
+        Gets `summary_size` data points over the regions `chrom`:`start`-`end`.
+        """
+        if start >= end:
+            return None
+        chrom_id, chrom_size = self._get_chrom_id_and_size( chrom )
+        if chrom_id is None:
+            return None
+        # Return value will be a structured array (rather than an array
+        # of summary element structures
+
+        # Find appropriate zoom level
+        cdef bits32 base_size = end - start
+        cdef int full_reduction = base_size / summary_size
+        cdef int zoom = full_reduction / 2
+        if zoom < 0:
+            zoom = 0
+        cdef ZoomLevel zoom_level = self._best_zoom_level( zoom )
+        if zoom_level is not None:
+            return zoom_level._summarize( chrom_id, start, end, summary_size )
+        else:
+            return self._summarize_from_full( chrom_id, start, end, summary_size )
+
+    cpdef summarize_from_full( self, char * chrom, bits32 start, bits32 end, int summary_size ):
+        """
+        Gets `summary_size` data points over the regions `chrom`:`start`-`end`, 
+        always using the raw data points
+        """
+        if start >= end:
+            return None
+        chrom_id, chrom_size = self._get_chrom_id_and_size( chrom )
+        if chrom_id is None:
+            return None
+        # Return value will be a structured array (rather than an array
+        # of summary element structures
+        return self._summarize_from_full( chrom_id, start, end, summary_size )
+
+    cpdef query( self, char * chrom, bits32 start, bits32 end, int summary_size ):
+        """
+        Provides a different view of summary for region, a list of dictionaries
+        with keys: mean, max, min, coverage, std_dev
+        """
+        
+        if end > 2147483647 or start < 0:
+            raise ValueError
+        results = self.summarize(chrom, start, end, summary_size)
+        if not results:
+            return None
+        
+        rval = []
+        for i in range(summary_size):
+            sum_data = results.sum_data[i]
+            valid_count = results.valid_count[i]
+            mean = sum_data / valid_count
+            coverage = <double> summary_size / (end - start) * valid_count
+            
+            # print results.sum_squares[i], sum_data, valid_count
+            variance = results.sum_squares[i] - sum_data * sum_data / valid_count
+            if valid_count > 1:
+                variance /= valid_count - 1
+            std_dev = math.sqrt(max(variance, 0))
+
+            rval.append( { "mean": mean, "max": results.max_val[i], "min": results.min_val[i], \
+                        "coverage": coverage, "std_dev": std_dev } )
+        
+        return rval
+
+    cdef _get_chrom_id_and_size( self, char * chrom ):
+        """
+        Lookup id and size from the chromosome named `chrom`
+        """
+        bytes = self.chrom_bpt.find( chrom )
+        if bytes is not None:
+            # The value is two 32 bit uints, use the BPT's reader for checking byteswapping
+            assert len( bytes ) == 8
+            chrom_id, chrom_size = self.chrom_bpt.reader.unpack( "II", bytes )
+            return chrom_id, chrom_size
+        else:
+            return None, None
+    
+    cdef _summarize_from_full( self, bits32 chrom_id, bits32 start, bits32 end, int summary_size ):
+        """
+        Create summary from full data. This is data specific so must be overridden.
+        """
+        pass
+        
+    cdef _best_zoom_level( self, int desired_reduction ):
+        if desired_reduction <= 1:
+            return None
+            
+        cdef ZoomLevel level, closest_level
+        cdef int diff, closest_diff = limits.INT_MAX
+        
+        closest_level = None
+        for level in self.level_list:
+            diff = desired_reduction - level.reduction_level
+            if diff >= 0 and diff < closest_diff:
+                closest_diff = diff
+                closest_level = level
+        return closest_level
+
+cdef class ZoomLevel:
+    cdef BBIFile bbi_file
+    cdef public bits32 reduction_level
+    cdef bits32 reserved
+    cdef public bits64 data_offset
+    cdef public bits64 index_offset
+    cdef int item_count
+
+    def _summary_blocks_in_region( self, bits32 chrom_id, bits32 start, bits32 end ):
+        """
+        Return a list of all SummaryBlocks that overlap the region 
+        `chrom_id`:`start`-`end`
+        """
+        cdef CIRTreeFile ctf
+        cdef SummaryBlock summary
+        rval = deque()
+        reader = self.bbi_file.reader
+        reader.seek( self.index_offset )
+        ctf = CIRTreeFile( reader.file )
+        block_list = ctf.find_overlapping_blocks( chrom_id, start, end )
+
+        sum_dtype = np.dtype([('chrom_id', np.uint32),
+                              ('start', np.uint32),
+                              ('end', np.uint32),
+                              ('valid_count', np.uint32),
+                              ('min_val', np.float32),
+                              ('max_val', np.float32),
+                              ('sum_data', np.float32),
+                              ('sum_squares', np.float32)])
+
+        for offset, size in block_list:
+            # Seek to and read all data for the block
+            reader.seek( offset )
+            block_data = reader.read( size )
+            # Might need to uncompress
+            if self.bbi_file.uncompress_buf_size > 0:
+                ## block_data = zlib.decompress( block_data, buf_size = self.bbi_file.uncompress_buf_size )
+                block_data = zlib.decompress( block_data )
+            block_size = len( block_data )
+            # The block should be a bunch of summaries. 
+            assert block_size % summary_on_disk_size == 0
+            item_count = block_size / summary_on_disk_size
+
+            arr = np.fromstring(block_data, sum_dtype, item_count)
+            # covert to dict to match old implementation:
+            d = [dict(zip(arr.dtype.names, x)) for x in arr]
+            rval.extend(d)
+
+
+            """
+            block_reader = BinaryFileReader( StringIO( block_data ), is_little_endian=reader.is_little_endian )
+            for i from 0 <= i < item_count:
+                ## NOTE: Look carefully at bbiRead again to be sure the endian
+                ##       conversion here is all correct. It looks like it is 
+                ##       just pushing raw data into memory and not swapping
+                
+                sum_chrom_id = block_reader.read_uint32()
+                # A block can contain summaries from more that one chrom_id
+                if sum_chrom_id != chrom_id:
+                    block_reader.skip(7*4)
+                    continue
+                       
+                summary = SummaryBlock()
+                summary.chrom_id = sum_chrom_id
+                summary.start = block_reader.read_uint32()
+                summary.end = block_reader.read_uint32()
+                summary.valid_count = block_reader.read_uint32()
+                summary.min_val = block_reader.read_float()
+                summary.max_val = block_reader.read_float()
+                summary.sum_data = block_reader.read_float()
+                summary.sum_squares = block_reader.read_float()
+                rval.append( summary )
+                
+            """
+        return rval
+    
+    cdef _get_summary_slice( self, bits32 base_start, bits32 base_end, summaries ):
+        cdef float valid_count = 0.0
+        cdef float sum_data = 0.0
+        cdef float sum_squares = 0.0
+        cdef float min_val = numpy.nan
+        cdef float max_val = numpy.nan
+        cdef float overlap_factor
+        cdef int overlap
+        
+        if summaries:
+            
+            # TODO: if we keep this a an array from summary_blocks in region,
+            # this will be much faster.
+            min_val = summaries[0]['min_val']
+            max_val = summaries[0]['max_val']
+            
+            for summary in summaries:
+                if summary['start'] >= base_end:
+                    break
+            
+                overlap = range_intersection( base_start, base_end, summary['start'], summary['end'] )
+                if overlap > 0:
+                    overlap_factor = <double> overlap / (summary['end'] - summary['start'])
+                
+                    valid_count += summary['valid_count'] * overlap_factor
+                    sum_data += summary['sum_data'] * overlap_factor
+                    sum_squares += summary['sum_squares'] * overlap_factor
+
+                    if max_val < summary['max_val']:
+                        max_val = summary['max_val']
+                    if min_val > summary['min_val']:
+                        min_val = summary['min_val']
+
+        return valid_count, sum_data, sum_squares, min_val, max_val
+        
+    cdef _summarize( self, bits32 chrom_id, bits32 start, bits32 end, int summary_size ):
+        return SummarizedData( start, end, summary_size )
diff --git a/lib/bx/bbi/bigbed_file.c b/lib/bx/bbi/bigbed_file.c
new file mode 100644
index 0000000..2797459
--- /dev/null
+++ b/lib/bx/bbi/bigbed_file.c
@@ -0,0 +1,8876 @@
+/* Generated by Cython 0.22 */
+
+#define PY_SSIZE_T_CLEAN
+#ifndef CYTHON_USE_PYLONG_INTERNALS
+#ifdef PYLONG_BITS_IN_DIGIT
+#define CYTHON_USE_PYLONG_INTERNALS 0
+#else
+#include "pyconfig.h"
+#ifdef PYLONG_BITS_IN_DIGIT
+#define CYTHON_USE_PYLONG_INTERNALS 1
+#else
+#define CYTHON_USE_PYLONG_INTERNALS 0
+#endif
+#endif
+#endif
+#include "Python.h"
+#ifndef Py_PYTHON_H
+    #error Python headers needed to compile C extensions, please install development version of Python.
+#elif PY_VERSION_HEX < 0x02060000 || (0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03020000)
+    #error Cython requires Python 2.6+ or Python 3.2+.
+#else
+#define CYTHON_ABI "0_22"
+#include <stddef.h>
+#ifndef offsetof
+#define offsetof(type, member) ( (size_t) & ((type*)0) -> member )
+#endif
+#if !defined(WIN32) && !defined(MS_WINDOWS)
+  #ifndef __stdcall
+    #define __stdcall
+  #endif
+  #ifndef __cdecl
+    #define __cdecl
+  #endif
+  #ifndef __fastcall
+    #define __fastcall
+  #endif
+#endif
+#ifndef DL_IMPORT
+  #define DL_IMPORT(t) t
+#endif
+#ifndef DL_EXPORT
+  #define DL_EXPORT(t) t
+#endif
+#ifndef PY_LONG_LONG
+  #define PY_LONG_LONG LONG_LONG
+#endif
+#ifndef Py_HUGE_VAL
+  #define Py_HUGE_VAL HUGE_VAL
+#endif
+#ifdef PYPY_VERSION
+#define CYTHON_COMPILING_IN_PYPY 1
+#define CYTHON_COMPILING_IN_CPYTHON 0
+#else
+#define CYTHON_COMPILING_IN_PYPY 0
+#define CYTHON_COMPILING_IN_CPYTHON 1
+#endif
+#if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX < 0x02070600 && !defined(Py_OptimizeFlag)
+#define Py_OptimizeFlag 0
+#endif
+#define __PYX_BUILD_PY_SSIZE_T "n"
+#define CYTHON_FORMAT_SSIZE_T "z"
+#if PY_MAJOR_VERSION < 3
+  #define __Pyx_BUILTIN_MODULE_NAME "__builtin__"
+  #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \
+          PyCode_New(a+k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
+  #define __Pyx_DefaultClassType PyClass_Type
+#else
+  #define __Pyx_BUILTIN_MODULE_NAME "builtins"
+  #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \
+          PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
+  #define __Pyx_DefaultClassType PyType_Type
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define Py_TPFLAGS_CHECKTYPES 0
+  #define Py_TPFLAGS_HAVE_INDEX 0
+  #define Py_TPFLAGS_HAVE_NEWBUFFER 0
+#endif
+#if PY_VERSION_HEX < 0x030400a1 && !defined(Py_TPFLAGS_HAVE_FINALIZE)
+  #define Py_TPFLAGS_HAVE_FINALIZE 0
+#endif
+#if PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND)
+  #define CYTHON_PEP393_ENABLED 1
+  #define __Pyx_PyUnicode_READY(op)       (likely(PyUnicode_IS_READY(op)) ? \
+                                              0 : _PyUnicode_Ready((PyObject *)(op)))
+  #define __Pyx_PyUnicode_GET_LENGTH(u)   PyUnicode_GET_LENGTH(u)
+  #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_READ_CHAR(u, i)
+  #define __Pyx_PyUnicode_KIND(u)         PyUnicode_KIND(u)
+  #define __Pyx_PyUnicode_DATA(u)         PyUnicode_DATA(u)
+  #define __Pyx_PyUnicode_READ(k, d, i)   PyUnicode_READ(k, d, i)
+#else
+  #define CYTHON_PEP393_ENABLED 0
+  #define __Pyx_PyUnicode_READY(op)       (0)
+  #define __Pyx_PyUnicode_GET_LENGTH(u)   PyUnicode_GET_SIZE(u)
+  #define __Pyx_PyUnicode_READ_CHAR(u, i) ((Py_UCS4)(PyUnicode_AS_UNICODE(u)[i]))
+  #define __Pyx_PyUnicode_KIND(u)         (sizeof(Py_UNICODE))
+  #define __Pyx_PyUnicode_DATA(u)         ((void*)PyUnicode_AS_UNICODE(u))
+  #define __Pyx_PyUnicode_READ(k, d, i)   ((void)(k), (Py_UCS4)(((Py_UNICODE*)d)[i]))
+#endif
+#if CYTHON_COMPILING_IN_PYPY
+  #define __Pyx_PyUnicode_Concat(a, b)      PyNumber_Add(a, b)
+  #define __Pyx_PyUnicode_ConcatSafe(a, b)  PyNumber_Add(a, b)
+  #define __Pyx_PyFrozenSet_Size(s)         PyObject_Size(s)
+#else
+  #define __Pyx_PyUnicode_Concat(a, b)      PyUnicode_Concat(a, b)
+  #define __Pyx_PyUnicode_ConcatSafe(a, b)  ((unlikely((a) == Py_None) || unlikely((b) == Py_None)) ? \
+      PyNumber_Add(a, b) : __Pyx_PyUnicode_Concat(a, b))
+  #define __Pyx_PyFrozenSet_Size(s)         PySet_Size(s)
+#endif
+#define __Pyx_PyString_FormatSafe(a, b)   ((unlikely((a) == Py_None)) ? PyNumber_Remainder(a, b) : __Pyx_PyString_Format(a, b))
+#define __Pyx_PyUnicode_FormatSafe(a, b)  ((unlikely((a) == Py_None)) ? PyNumber_Remainder(a, b) : PyUnicode_Format(a, b))
+#if PY_MAJOR_VERSION >= 3
+  #define __Pyx_PyString_Format(a, b)  PyUnicode_Format(a, b)
+#else
+  #define __Pyx_PyString_Format(a, b)  PyString_Format(a, b)
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define PyBaseString_Type            PyUnicode_Type
+  #define PyStringObject               PyUnicodeObject
+  #define PyString_Type                PyUnicode_Type
+  #define PyString_Check               PyUnicode_Check
+  #define PyString_CheckExact          PyUnicode_CheckExact
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define __Pyx_PyBaseString_Check(obj) PyUnicode_Check(obj)
+  #define __Pyx_PyBaseString_CheckExact(obj) PyUnicode_CheckExact(obj)
+#else
+  #define __Pyx_PyBaseString_Check(obj) (PyString_Check(obj) || PyUnicode_Check(obj))
+  #define __Pyx_PyBaseString_CheckExact(obj) (PyString_CheckExact(obj) || PyUnicode_CheckExact(obj))
+#endif
+#ifndef PySet_CheckExact
+  #define PySet_CheckExact(obj)        (Py_TYPE(obj) == &PySet_Type)
+#endif
+#define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type)
+#if PY_MAJOR_VERSION >= 3
+  #define PyIntObject                  PyLongObject
+  #define PyInt_Type                   PyLong_Type
+  #define PyInt_Check(op)              PyLong_Check(op)
+  #define PyInt_CheckExact(op)         PyLong_CheckExact(op)
+  #define PyInt_FromString             PyLong_FromString
+  #define PyInt_FromUnicode            PyLong_FromUnicode
+  #define PyInt_FromLong               PyLong_FromLong
+  #define PyInt_FromSize_t             PyLong_FromSize_t
+  #define PyInt_FromSsize_t            PyLong_FromSsize_t
+  #define PyInt_AsLong                 PyLong_AsLong
+  #define PyInt_AS_LONG                PyLong_AS_LONG
+  #define PyInt_AsSsize_t              PyLong_AsSsize_t
+  #define PyInt_AsUnsignedLongMask     PyLong_AsUnsignedLongMask
+  #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask
+  #define PyNumber_Int                 PyNumber_Long
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define PyBoolObject                 PyLongObject
+#endif
+#if PY_MAJOR_VERSION >= 3 && CYTHON_COMPILING_IN_PYPY
+  #ifndef PyUnicode_InternFromString
+    #define PyUnicode_InternFromString(s) PyUnicode_FromString(s)
+  #endif
+#endif
+#if PY_VERSION_HEX < 0x030200A4
+  typedef long Py_hash_t;
+  #define __Pyx_PyInt_FromHash_t PyInt_FromLong
+  #define __Pyx_PyInt_AsHash_t   PyInt_AsLong
+#else
+  #define __Pyx_PyInt_FromHash_t PyInt_FromSsize_t
+  #define __Pyx_PyInt_AsHash_t   PyInt_AsSsize_t
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define __Pyx_PyMethod_New(func, self, klass) ((self) ? PyMethod_New(func, self) : PyInstanceMethod_New(func))
+#else
+  #define __Pyx_PyMethod_New(func, self, klass) PyMethod_New(func, self, klass)
+#endif
+#ifndef CYTHON_INLINE
+  #if defined(__GNUC__)
+    #define CYTHON_INLINE __inline__
+  #elif defined(_MSC_VER)
+    #define CYTHON_INLINE __inline
+  #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+    #define CYTHON_INLINE inline
+  #else
+    #define CYTHON_INLINE
+  #endif
+#endif
+#ifndef CYTHON_RESTRICT
+  #if defined(__GNUC__)
+    #define CYTHON_RESTRICT __restrict__
+  #elif defined(_MSC_VER) && _MSC_VER >= 1400
+    #define CYTHON_RESTRICT __restrict
+  #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+    #define CYTHON_RESTRICT restrict
+  #else
+    #define CYTHON_RESTRICT
+  #endif
+#endif
+#ifdef NAN
+#define __PYX_NAN() ((float) NAN)
+#else
+static CYTHON_INLINE float __PYX_NAN() {
+  /* Initialize NaN. The sign is irrelevant, an exponent with all bits 1 and
+   a nonzero mantissa means NaN. If the first bit in the mantissa is 1, it is
+   a quiet NaN. */
+  float value;
+  memset(&value, 0xFF, sizeof(value));
+  return value;
+}
+#endif
+#define __Pyx_void_to_None(void_result) (void_result, Py_INCREF(Py_None), Py_None)
+#ifdef __cplusplus
+template<typename T>
+void __Pyx_call_destructor(T* x) {
+    x->~T();
+}
+template<typename T>
+class __Pyx_FakeReference {
+  public:
+    __Pyx_FakeReference() : ptr(NULL) { }
+    __Pyx_FakeReference(T& ref) : ptr(&ref) { }
+    T *operator->() { return ptr; }
+    operator T&() { return *ptr; }
+  private:
+    T *ptr;
+};
+#endif
+
+
+#if PY_MAJOR_VERSION >= 3
+  #define __Pyx_PyNumber_Divide(x,y)         PyNumber_TrueDivide(x,y)
+  #define __Pyx_PyNumber_InPlaceDivide(x,y)  PyNumber_InPlaceTrueDivide(x,y)
+#else
+  #define __Pyx_PyNumber_Divide(x,y)         PyNumber_Divide(x,y)
+  #define __Pyx_PyNumber_InPlaceDivide(x,y)  PyNumber_InPlaceDivide(x,y)
+#endif
+
+#ifndef __PYX_EXTERN_C
+  #ifdef __cplusplus
+    #define __PYX_EXTERN_C extern "C"
+  #else
+    #define __PYX_EXTERN_C extern
+  #endif
+#endif
+
+#if defined(WIN32) || defined(MS_WINDOWS)
+#define _USE_MATH_DEFINES
+#endif
+#include <math.h>
+#define __PYX_HAVE__bx__bbi__bigbed_file
+#define __PYX_HAVE_API__bx__bbi__bigbed_file
+#include "string.h"
+#include "stdio.h"
+#include "stdlib.h"
+#include "numpy/arrayobject.h"
+#include "numpy/ufuncobject.h"
+#ifdef _OPENMP
+#include <omp.h>
+#endif /* _OPENMP */
+
+#ifdef PYREX_WITHOUT_ASSERTIONS
+#define CYTHON_WITHOUT_ASSERTIONS
+#endif
+
+#ifndef CYTHON_UNUSED
+# if defined(__GNUC__)
+#   if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
+#     define CYTHON_UNUSED __attribute__ ((__unused__))
+#   else
+#     define CYTHON_UNUSED
+#   endif
+# elif defined(__ICC) || (defined(__INTEL_COMPILER) && !defined(_MSC_VER))
+#   define CYTHON_UNUSED __attribute__ ((__unused__))
+# else
+#   define CYTHON_UNUSED
+# endif
+#endif
+typedef struct {PyObject **p; char *s; const Py_ssize_t n; const char* encoding;
+                const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry;
+
+#define __PYX_DEFAULT_STRING_ENCODING_IS_ASCII 0
+#define __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT 0
+#define __PYX_DEFAULT_STRING_ENCODING ""
+#define __Pyx_PyObject_FromString __Pyx_PyBytes_FromString
+#define __Pyx_PyObject_FromStringAndSize __Pyx_PyBytes_FromStringAndSize
+#define __Pyx_fits_Py_ssize_t(v, type, is_signed)  (    \
+    (sizeof(type) < sizeof(Py_ssize_t))  ||             \
+    (sizeof(type) > sizeof(Py_ssize_t) &&               \
+          likely(v < (type)PY_SSIZE_T_MAX ||            \
+                 v == (type)PY_SSIZE_T_MAX)  &&         \
+          (!is_signed || likely(v > (type)PY_SSIZE_T_MIN ||       \
+                                v == (type)PY_SSIZE_T_MIN)))  ||  \
+    (sizeof(type) == sizeof(Py_ssize_t) &&              \
+          (is_signed || likely(v < (type)PY_SSIZE_T_MAX ||        \
+                               v == (type)PY_SSIZE_T_MAX)))  )
+static CYTHON_INLINE char* __Pyx_PyObject_AsString(PyObject*);
+static CYTHON_INLINE char* __Pyx_PyObject_AsStringAndSize(PyObject*, Py_ssize_t* length);
+#define __Pyx_PyByteArray_FromString(s) PyByteArray_FromStringAndSize((const char*)s, strlen((const char*)s))
+#define __Pyx_PyByteArray_FromStringAndSize(s, l) PyByteArray_FromStringAndSize((const char*)s, l)
+#define __Pyx_PyBytes_FromString        PyBytes_FromString
+#define __Pyx_PyBytes_FromStringAndSize PyBytes_FromStringAndSize
+static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char*);
+#if PY_MAJOR_VERSION < 3
+    #define __Pyx_PyStr_FromString        __Pyx_PyBytes_FromString
+    #define __Pyx_PyStr_FromStringAndSize __Pyx_PyBytes_FromStringAndSize
+#else
+    #define __Pyx_PyStr_FromString        __Pyx_PyUnicode_FromString
+    #define __Pyx_PyStr_FromStringAndSize __Pyx_PyUnicode_FromStringAndSize
+#endif
+#define __Pyx_PyObject_AsSString(s)    ((signed char*) __Pyx_PyObject_AsString(s))
+#define __Pyx_PyObject_AsUString(s)    ((unsigned char*) __Pyx_PyObject_AsString(s))
+#define __Pyx_PyObject_FromCString(s)  __Pyx_PyObject_FromString((const char*)s)
+#define __Pyx_PyBytes_FromCString(s)   __Pyx_PyBytes_FromString((const char*)s)
+#define __Pyx_PyByteArray_FromCString(s)   __Pyx_PyByteArray_FromString((const char*)s)
+#define __Pyx_PyStr_FromCString(s)     __Pyx_PyStr_FromString((const char*)s)
+#define __Pyx_PyUnicode_FromCString(s) __Pyx_PyUnicode_FromString((const char*)s)
+#if PY_MAJOR_VERSION < 3
+static CYTHON_INLINE size_t __Pyx_Py_UNICODE_strlen(const Py_UNICODE *u)
+{
+    const Py_UNICODE *u_end = u;
+    while (*u_end++) ;
+    return (size_t)(u_end - u - 1);
+}
+#else
+#define __Pyx_Py_UNICODE_strlen Py_UNICODE_strlen
+#endif
+#define __Pyx_PyUnicode_FromUnicode(u)       PyUnicode_FromUnicode(u, __Pyx_Py_UNICODE_strlen(u))
+#define __Pyx_PyUnicode_FromUnicodeAndLength PyUnicode_FromUnicode
+#define __Pyx_PyUnicode_AsUnicode            PyUnicode_AsUnicode
+#define __Pyx_Owned_Py_None(b) (Py_INCREF(Py_None), Py_None)
+#define __Pyx_PyBool_FromLong(b) ((b) ? (Py_INCREF(Py_True), Py_True) : (Py_INCREF(Py_False), Py_False))
+static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*);
+static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x);
+static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*);
+static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t);
+#if CYTHON_COMPILING_IN_CPYTHON
+#define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x))
+#else
+#define __pyx_PyFloat_AsDouble(x) PyFloat_AsDouble(x)
+#endif
+#define __pyx_PyFloat_AsFloat(x) ((float) __pyx_PyFloat_AsDouble(x))
+#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII
+static int __Pyx_sys_getdefaultencoding_not_ascii;
+static int __Pyx_init_sys_getdefaultencoding_params(void) {
+    PyObject* sys;
+    PyObject* default_encoding = NULL;
+    PyObject* ascii_chars_u = NULL;
+    PyObject* ascii_chars_b = NULL;
+    const char* default_encoding_c;
+    sys = PyImport_ImportModule("sys");
+    if (!sys) goto bad;
+    default_encoding = PyObject_CallMethod(sys, (char*) "getdefaultencoding", NULL);
+    Py_DECREF(sys);
+    if (!default_encoding) goto bad;
+    default_encoding_c = PyBytes_AsString(default_encoding);
+    if (!default_encoding_c) goto bad;
+    if (strcmp(default_encoding_c, "ascii") == 0) {
+        __Pyx_sys_getdefaultencoding_not_ascii = 0;
+    } else {
+        char ascii_chars[128];
+        int c;
+        for (c = 0; c < 128; c++) {
+            ascii_chars[c] = c;
+        }
+        __Pyx_sys_getdefaultencoding_not_ascii = 1;
+        ascii_chars_u = PyUnicode_DecodeASCII(ascii_chars, 128, NULL);
+        if (!ascii_chars_u) goto bad;
+        ascii_chars_b = PyUnicode_AsEncodedString(ascii_chars_u, default_encoding_c, NULL);
+        if (!ascii_chars_b || !PyBytes_Check(ascii_chars_b) || memcmp(ascii_chars, PyBytes_AS_STRING(ascii_chars_b), 128) != 0) {
+            PyErr_Format(
+                PyExc_ValueError,
+                "This module compiled with c_string_encoding=ascii, but default encoding '%.200s' is not a superset of ascii.",
+                default_encoding_c);
+            goto bad;
+        }
+        Py_DECREF(ascii_chars_u);
+        Py_DECREF(ascii_chars_b);
+    }
+    Py_DECREF(default_encoding);
+    return 0;
+bad:
+    Py_XDECREF(default_encoding);
+    Py_XDECREF(ascii_chars_u);
+    Py_XDECREF(ascii_chars_b);
+    return -1;
+}
+#endif
+#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT && PY_MAJOR_VERSION >= 3
+#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_DecodeUTF8(c_str, size, NULL)
+#else
+#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_Decode(c_str, size, __PYX_DEFAULT_STRING_ENCODING, NULL)
+#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT
+static char* __PYX_DEFAULT_STRING_ENCODING;
+static int __Pyx_init_sys_getdefaultencoding_params(void) {
+    PyObject* sys;
+    PyObject* default_encoding = NULL;
+    char* default_encoding_c;
+    sys = PyImport_ImportModule("sys");
+    if (!sys) goto bad;
+    default_encoding = PyObject_CallMethod(sys, (char*) (const char*) "getdefaultencoding", NULL);
+    Py_DECREF(sys);
+    if (!default_encoding) goto bad;
+    default_encoding_c = PyBytes_AsString(default_encoding);
+    if (!default_encoding_c) goto bad;
+    __PYX_DEFAULT_STRING_ENCODING = (char*) malloc(strlen(default_encoding_c));
+    if (!__PYX_DEFAULT_STRING_ENCODING) goto bad;
+    strcpy(__PYX_DEFAULT_STRING_ENCODING, default_encoding_c);
+    Py_DECREF(default_encoding);
+    return 0;
+bad:
+    Py_XDECREF(default_encoding);
+    return -1;
+}
+#endif
+#endif
+
+
+/* Test for GCC > 2.95 */
+#if defined(__GNUC__)     && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95)))
+  #define likely(x)   __builtin_expect(!!(x), 1)
+  #define unlikely(x) __builtin_expect(!!(x), 0)
+#else /* !__GNUC__ or GCC < 2.95 */
+  #define likely(x)   (x)
+  #define unlikely(x) (x)
+#endif /* __GNUC__ */
+
+static PyObject *__pyx_m;
+static PyObject *__pyx_d;
+static PyObject *__pyx_b;
+static PyObject *__pyx_empty_tuple;
+static PyObject *__pyx_empty_bytes;
+static int __pyx_lineno;
+static int __pyx_clineno = 0;
+static const char * __pyx_cfilenm= __FILE__;
+static const char *__pyx_filename;
+
+#if !defined(CYTHON_CCOMPLEX)
+  #if defined(__cplusplus)
+    #define CYTHON_CCOMPLEX 1
+  #elif defined(_Complex_I)
+    #define CYTHON_CCOMPLEX 1
+  #else
+    #define CYTHON_CCOMPLEX 0
+  #endif
+#endif
+#if CYTHON_CCOMPLEX
+  #ifdef __cplusplus
+    #include <complex>
+  #else
+    #include <complex.h>
+  #endif
+#endif
+#if CYTHON_CCOMPLEX && !defined(__cplusplus) && defined(__sun__) && defined(__GNUC__)
+  #undef _Complex_I
+  #define _Complex_I 1.0fj
+#endif
+
+
+static const char *__pyx_f[] = {
+  "bx/bbi/bigbed_file.pyx",
+  "__init__.pxd",
+  "bx/bbi/bpt_file.pxd",
+  "bx/bbi/cirtree_file.pxd",
+  "type.pxd",
+  "bx/bbi/bbi_file.pxd",
+};
+
+/* "types.pxd":1
+ * ctypedef unsigned char UBYTE             # <<<<<<<<<<<<<<
+ * ctypedef signed char BYTE
+ * ctypedef unsigned short UWORD
+ */
+typedef unsigned char __pyx_t_2bx_3bbi_5types_UBYTE;
+
+/* "types.pxd":2
+ * ctypedef unsigned char UBYTE
+ * ctypedef signed char BYTE             # <<<<<<<<<<<<<<
+ * ctypedef unsigned short UWORD
+ * ctypedef short WORD
+ */
+typedef signed char __pyx_t_2bx_3bbi_5types_BYTE;
+
+/* "types.pxd":3
+ * ctypedef unsigned char UBYTE
+ * ctypedef signed char BYTE
+ * ctypedef unsigned short UWORD             # <<<<<<<<<<<<<<
+ * ctypedef short WORD
+ * ctypedef unsigned long long bits64
+ */
+typedef unsigned short __pyx_t_2bx_3bbi_5types_UWORD;
+
+/* "types.pxd":4
+ * ctypedef signed char BYTE
+ * ctypedef unsigned short UWORD
+ * ctypedef short WORD             # <<<<<<<<<<<<<<
+ * ctypedef unsigned long long bits64
+ * ctypedef unsigned bits32
+ */
+typedef short __pyx_t_2bx_3bbi_5types_WORD;
+
+/* "types.pxd":5
+ * ctypedef unsigned short UWORD
+ * ctypedef short WORD
+ * ctypedef unsigned long long bits64             # <<<<<<<<<<<<<<
+ * ctypedef unsigned bits32
+ * ctypedef unsigned short bits16
+ */
+typedef unsigned PY_LONG_LONG __pyx_t_2bx_3bbi_5types_bits64;
+
+/* "types.pxd":6
+ * ctypedef short WORD
+ * ctypedef unsigned long long bits64
+ * ctypedef unsigned bits32             # <<<<<<<<<<<<<<
+ * ctypedef unsigned short bits16
+ * ctypedef unsigned char bits8
+ */
+typedef unsigned int __pyx_t_2bx_3bbi_5types_bits32;
+
+/* "types.pxd":7
+ * ctypedef unsigned long long bits64
+ * ctypedef unsigned bits32
+ * ctypedef unsigned short bits16             # <<<<<<<<<<<<<<
+ * ctypedef unsigned char bits8
+ * ctypedef int signed32
+ */
+typedef unsigned short __pyx_t_2bx_3bbi_5types_bits16;
+
+/* "types.pxd":8
+ * ctypedef unsigned bits32
+ * ctypedef unsigned short bits16
+ * ctypedef unsigned char bits8             # <<<<<<<<<<<<<<
+ * ctypedef int signed32
+ * 
+ */
+typedef unsigned char __pyx_t_2bx_3bbi_5types_bits8;
+
+/* "types.pxd":9
+ * ctypedef unsigned short bits16
+ * ctypedef unsigned char bits8
+ * ctypedef int signed32             # <<<<<<<<<<<<<<
+ * 
+ * ctypedef bint boolean
+ */
+typedef int __pyx_t_2bx_3bbi_5types_signed32;
+
+/* "types.pxd":11
+ * ctypedef int signed32
+ * 
+ * ctypedef bint boolean             # <<<<<<<<<<<<<<
+ * 
+ */
+typedef int __pyx_t_2bx_3bbi_5types_boolean;
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":726
+ * # in Cython to enable them only on the right systems.
+ * 
+ * ctypedef npy_int8       int8_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_int16      int16_t
+ * ctypedef npy_int32      int32_t
+ */
+typedef npy_int8 __pyx_t_5numpy_int8_t;
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":727
+ * 
+ * ctypedef npy_int8       int8_t
+ * ctypedef npy_int16      int16_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_int32      int32_t
+ * ctypedef npy_int64      int64_t
+ */
+typedef npy_int16 __pyx_t_5numpy_int16_t;
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":728
+ * ctypedef npy_int8       int8_t
+ * ctypedef npy_int16      int16_t
+ * ctypedef npy_int32      int32_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_int64      int64_t
+ * #ctypedef npy_int96      int96_t
+ */
+typedef npy_int32 __pyx_t_5numpy_int32_t;
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":729
+ * ctypedef npy_int16      int16_t
+ * ctypedef npy_int32      int32_t
+ * ctypedef npy_int64      int64_t             # <<<<<<<<<<<<<<
+ * #ctypedef npy_int96      int96_t
+ * #ctypedef npy_int128     int128_t
+ */
+typedef npy_int64 __pyx_t_5numpy_int64_t;
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":733
+ * #ctypedef npy_int128     int128_t
+ * 
+ * ctypedef npy_uint8      uint8_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_uint16     uint16_t
+ * ctypedef npy_uint32     uint32_t
+ */
+typedef npy_uint8 __pyx_t_5numpy_uint8_t;
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":734
+ * 
+ * ctypedef npy_uint8      uint8_t
+ * ctypedef npy_uint16     uint16_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_uint32     uint32_t
+ * ctypedef npy_uint64     uint64_t
+ */
+typedef npy_uint16 __pyx_t_5numpy_uint16_t;
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":735
+ * ctypedef npy_uint8      uint8_t
+ * ctypedef npy_uint16     uint16_t
+ * ctypedef npy_uint32     uint32_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_uint64     uint64_t
+ * #ctypedef npy_uint96     uint96_t
+ */
+typedef npy_uint32 __pyx_t_5numpy_uint32_t;
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":736
+ * ctypedef npy_uint16     uint16_t
+ * ctypedef npy_uint32     uint32_t
+ * ctypedef npy_uint64     uint64_t             # <<<<<<<<<<<<<<
+ * #ctypedef npy_uint96     uint96_t
+ * #ctypedef npy_uint128    uint128_t
+ */
+typedef npy_uint64 __pyx_t_5numpy_uint64_t;
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":740
+ * #ctypedef npy_uint128    uint128_t
+ * 
+ * ctypedef npy_float32    float32_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_float64    float64_t
+ * #ctypedef npy_float80    float80_t
+ */
+typedef npy_float32 __pyx_t_5numpy_float32_t;
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":741
+ * 
+ * ctypedef npy_float32    float32_t
+ * ctypedef npy_float64    float64_t             # <<<<<<<<<<<<<<
+ * #ctypedef npy_float80    float80_t
+ * #ctypedef npy_float128   float128_t
+ */
+typedef npy_float64 __pyx_t_5numpy_float64_t;
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":750
+ * # The int types are mapped a bit surprising --
+ * # numpy.int corresponds to 'l' and numpy.long to 'q'
+ * ctypedef npy_long       int_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_longlong   long_t
+ * ctypedef npy_longlong   longlong_t
+ */
+typedef npy_long __pyx_t_5numpy_int_t;
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":751
+ * # numpy.int corresponds to 'l' and numpy.long to 'q'
+ * ctypedef npy_long       int_t
+ * ctypedef npy_longlong   long_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_longlong   longlong_t
+ * 
+ */
+typedef npy_longlong __pyx_t_5numpy_long_t;
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":752
+ * ctypedef npy_long       int_t
+ * ctypedef npy_longlong   long_t
+ * ctypedef npy_longlong   longlong_t             # <<<<<<<<<<<<<<
+ * 
+ * ctypedef npy_ulong      uint_t
+ */
+typedef npy_longlong __pyx_t_5numpy_longlong_t;
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":754
+ * ctypedef npy_longlong   longlong_t
+ * 
+ * ctypedef npy_ulong      uint_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_ulonglong  ulong_t
+ * ctypedef npy_ulonglong  ulonglong_t
+ */
+typedef npy_ulong __pyx_t_5numpy_uint_t;
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":755
+ * 
+ * ctypedef npy_ulong      uint_t
+ * ctypedef npy_ulonglong  ulong_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_ulonglong  ulonglong_t
+ * 
+ */
+typedef npy_ulonglong __pyx_t_5numpy_ulong_t;
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":756
+ * ctypedef npy_ulong      uint_t
+ * ctypedef npy_ulonglong  ulong_t
+ * ctypedef npy_ulonglong  ulonglong_t             # <<<<<<<<<<<<<<
+ * 
+ * ctypedef npy_intp       intp_t
+ */
+typedef npy_ulonglong __pyx_t_5numpy_ulonglong_t;
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":758
+ * ctypedef npy_ulonglong  ulonglong_t
+ * 
+ * ctypedef npy_intp       intp_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_uintp      uintp_t
+ * 
+ */
+typedef npy_intp __pyx_t_5numpy_intp_t;
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":759
+ * 
+ * ctypedef npy_intp       intp_t
+ * ctypedef npy_uintp      uintp_t             # <<<<<<<<<<<<<<
+ * 
+ * ctypedef npy_double     float_t
+ */
+typedef npy_uintp __pyx_t_5numpy_uintp_t;
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":761
+ * ctypedef npy_uintp      uintp_t
+ * 
+ * ctypedef npy_double     float_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_double     double_t
+ * ctypedef npy_longdouble longdouble_t
+ */
+typedef npy_double __pyx_t_5numpy_float_t;
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":762
+ * 
+ * ctypedef npy_double     float_t
+ * ctypedef npy_double     double_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_longdouble longdouble_t
+ * 
+ */
+typedef npy_double __pyx_t_5numpy_double_t;
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":763
+ * ctypedef npy_double     float_t
+ * ctypedef npy_double     double_t
+ * ctypedef npy_longdouble longdouble_t             # <<<<<<<<<<<<<<
+ * 
+ * ctypedef npy_cfloat      cfloat_t
+ */
+typedef npy_longdouble __pyx_t_5numpy_longdouble_t;
+#if CYTHON_CCOMPLEX
+  #ifdef __cplusplus
+    typedef ::std::complex< float > __pyx_t_float_complex;
+  #else
+    typedef float _Complex __pyx_t_float_complex;
+  #endif
+#else
+    typedef struct { float real, imag; } __pyx_t_float_complex;
+#endif
+
+#if CYTHON_CCOMPLEX
+  #ifdef __cplusplus
+    typedef ::std::complex< double > __pyx_t_double_complex;
+  #else
+    typedef double _Complex __pyx_t_double_complex;
+  #endif
+#else
+    typedef struct { double real, imag; } __pyx_t_double_complex;
+#endif
+
+
+/*--- Type declarations ---*/
+struct __pyx_obj_2bx_3bbi_8bpt_file_BPTFile;
+struct __pyx_obj_2bx_3bbi_12cirtree_file_CIRTreeFile;
+struct __pyx_obj_2bx_3bbi_8bbi_file_SummaryBlock;
+struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData;
+struct __pyx_obj_2bx_3bbi_8bbi_file_BlockHandler;
+struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile;
+struct __pyx_obj_2bx_3bbi_11bigbed_file_BigBedBlockHandler;
+struct __pyx_obj_2bx_3bbi_11bigbed_file_SummarizingBlockHandler;
+struct __pyx_obj_2bx_3bbi_11bigbed_file_IntervalAccumulatingBlockHandler;
+struct __pyx_obj_2bx_3bbi_11bigbed_file_BigBedFile;
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":765
+ * ctypedef npy_longdouble longdouble_t
+ * 
+ * ctypedef npy_cfloat      cfloat_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_cdouble     cdouble_t
+ * ctypedef npy_clongdouble clongdouble_t
+ */
+typedef npy_cfloat __pyx_t_5numpy_cfloat_t;
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":766
+ * 
+ * ctypedef npy_cfloat      cfloat_t
+ * ctypedef npy_cdouble     cdouble_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_clongdouble clongdouble_t
+ * 
+ */
+typedef npy_cdouble __pyx_t_5numpy_cdouble_t;
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":767
+ * ctypedef npy_cfloat      cfloat_t
+ * ctypedef npy_cdouble     cdouble_t
+ * ctypedef npy_clongdouble clongdouble_t             # <<<<<<<<<<<<<<
+ * 
+ * ctypedef npy_cdouble     complex_t
+ */
+typedef npy_clongdouble __pyx_t_5numpy_clongdouble_t;
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":769
+ * ctypedef npy_clongdouble clongdouble_t
+ * 
+ * ctypedef npy_cdouble     complex_t             # <<<<<<<<<<<<<<
+ * 
+ * cdef inline object PyArray_MultiIterNew1(a):
+ */
+typedef npy_cdouble __pyx_t_5numpy_complex_t;
+
+/* "bpt_file.pxd":5
+ * from types cimport *
+ * 
+ * cdef class BPTFile:             # <<<<<<<<<<<<<<
+ *     """
+ *     On disk B+ tree compatible with Jim Kent's bPlusTree.c
+ */
+struct __pyx_obj_2bx_3bbi_8bpt_file_BPTFile {
+  PyObject_HEAD
+  PyObject *file;
+  PyObject *reader;
+  __pyx_t_2bx_3bbi_5types_boolean is_byteswapped;
+  __pyx_t_2bx_3bbi_5types_bits32 block_size;
+  __pyx_t_2bx_3bbi_5types_bits32 key_size;
+  __pyx_t_2bx_3bbi_5types_bits32 value_size;
+  __pyx_t_2bx_3bbi_5types_bits64 item_count;
+  __pyx_t_2bx_3bbi_5types_bits64 root_offset;
+};
+
+
+/* "cirtree_file.pxd":3
+ * from types cimport *
+ * 
+ * cdef class CIRTreeFile:             # <<<<<<<<<<<<<<
+ *     cdef object file
+ *     cdef object reader
+ */
+struct __pyx_obj_2bx_3bbi_12cirtree_file_CIRTreeFile {
+  PyObject_HEAD
+  PyObject *file;
+  PyObject *reader;
+  __pyx_t_2bx_3bbi_5types_boolean is_byteswapped;
+  __pyx_t_2bx_3bbi_5types_bits64 root_offset;
+  __pyx_t_2bx_3bbi_5types_bits32 block_size;
+  __pyx_t_2bx_3bbi_5types_bits64 item_count;
+  __pyx_t_2bx_3bbi_5types_bits32 start_chrom_ix;
+  __pyx_t_2bx_3bbi_5types_bits32 start_base;
+  __pyx_t_2bx_3bbi_5types_bits32 end_chrom_ix;
+  __pyx_t_2bx_3bbi_5types_bits32 end_base;
+  __pyx_t_2bx_3bbi_5types_bits64 file_size;
+  __pyx_t_2bx_3bbi_5types_bits32 items_per_slot;
+};
+
+
+/* "bbi_file.pxd":8
+ * cimport numpy
+ * 
+ * cdef class SummaryBlock:             # <<<<<<<<<<<<<<
+ *     """
+ *     A block of summary data from disk
+ */
+struct __pyx_obj_2bx_3bbi_8bbi_file_SummaryBlock {
+  PyObject_HEAD
+  __pyx_t_2bx_3bbi_5types_bits32 chrom_id;
+  __pyx_t_2bx_3bbi_5types_bits32 start;
+  __pyx_t_2bx_3bbi_5types_bits32 end;
+  __pyx_t_2bx_3bbi_5types_bits32 valid_count;
+  double min_val;
+  double max_val;
+  double sum_data;
+  double sum_squares;
+};
+
+
+/* "bbi_file.pxd":21
+ *     cdef public double sum_squares
+ * 
+ * cdef class SummarizedData:             # <<<<<<<<<<<<<<
+ *     """
+ *     The result of using SummaryBlocks read from the file to produce a
+ */
+struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData {
+  PyObject_HEAD
+  struct __pyx_vtabstruct_2bx_3bbi_8bbi_file_SummarizedData *__pyx_vtab;
+  __pyx_t_2bx_3bbi_5types_bits32 start;
+  __pyx_t_2bx_3bbi_5types_bits32 end;
+  int size;
+  PyArrayObject *valid_count;
+  PyArrayObject *min_val;
+  PyArrayObject *max_val;
+  PyArrayObject *sum_data;
+  PyArrayObject *sum_squares;
+};
+
+
+/* "bbi_file.pxd":39
+ * cdef class BBIFile
+ * 
+ * cdef class BlockHandler:             # <<<<<<<<<<<<<<
+ *     """
+ *     Callback for `BBIFile.visit_blocks_in_region`
+ */
+struct __pyx_obj_2bx_3bbi_8bbi_file_BlockHandler {
+  PyObject_HEAD
+  struct __pyx_vtabstruct_2bx_3bbi_8bbi_file_BlockHandler *__pyx_vtab;
+};
+
+
+/* "bbi_file.pxd":37
+ *     cdef accumulate_interval_value( self, bits32 s, bits32 e, float val )
+ * 
+ * cdef class BBIFile             # <<<<<<<<<<<<<<
+ * 
+ * cdef class BlockHandler:
+ */
+struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile {
+  PyObject_HEAD
+  struct __pyx_vtabstruct_2bx_3bbi_8bbi_file_BBIFile *__pyx_vtab;
+  PyObject *file;
+  PyObject *reader;
+  __pyx_t_2bx_3bbi_5types_bits32 magic;
+  __pyx_t_2bx_3bbi_5types_boolean is_byteswapped;
+  struct __pyx_obj_2bx_3bbi_8bpt_file_BPTFile *chrom_bpt;
+  __pyx_t_2bx_3bbi_5types_bits16 version;
+  __pyx_t_2bx_3bbi_5types_bits16 zoom_levels;
+  __pyx_t_2bx_3bbi_5types_bits64 chrom_tree_offset;
+  __pyx_t_2bx_3bbi_5types_bits64 unzoomed_data_offset;
+  __pyx_t_2bx_3bbi_5types_bits64 unzoomed_index_offset;
+  __pyx_t_2bx_3bbi_5types_bits16 field_count;
+  __pyx_t_2bx_3bbi_5types_bits16 defined_field_count;
+  __pyx_t_2bx_3bbi_5types_bits64 as_offset;
+  __pyx_t_2bx_3bbi_5types_bits64 total_summary_offset;
+  __pyx_t_2bx_3bbi_5types_bits32 uncompress_buf_size;
+  PyObject *level_list;
+};
+
+
+/* "bx/bbi/bigbed_file.pyx":44
+ *     return "".join(read) if len(read) > 1 else read[0]
+ * 
+ * cdef class BigBedBlockHandler( BlockHandler ):             # <<<<<<<<<<<<<<
+ *     """
+ *     BlockHandler that parses the block into a series of BED records
+ */
+struct __pyx_obj_2bx_3bbi_11bigbed_file_BigBedBlockHandler {
+  struct __pyx_obj_2bx_3bbi_8bbi_file_BlockHandler __pyx_base;
+  __pyx_t_2bx_3bbi_5types_bits32 chrom_id;
+  __pyx_t_2bx_3bbi_5types_bits32 start;
+  __pyx_t_2bx_3bbi_5types_bits32 end;
+};
+
+
+/* "bx/bbi/bigbed_file.pyx":76
+ *         pass
+ * 
+ * cdef class SummarizingBlockHandler( BigBedBlockHandler ):             # <<<<<<<<<<<<<<
+ *     """
+ *     Accumulates intervals into a SummarizedData
+ */
+struct __pyx_obj_2bx_3bbi_11bigbed_file_SummarizingBlockHandler {
+  struct __pyx_obj_2bx_3bbi_11bigbed_file_BigBedBlockHandler __pyx_base;
+  struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData *sd;
+};
+
+
+/* "bx/bbi/bigbed_file.pyx":95
+ *         self.sd.accumulate_interval_value( s, e, 1 )
+ * 
+ * cdef class IntervalAccumulatingBlockHandler( BigBedBlockHandler ):             # <<<<<<<<<<<<<<
+ *     cdef list intervals
+ *     """
+ */
+struct __pyx_obj_2bx_3bbi_11bigbed_file_IntervalAccumulatingBlockHandler {
+  struct __pyx_obj_2bx_3bbi_11bigbed_file_BigBedBlockHandler __pyx_base;
+  PyObject *intervals;
+};
+
+
+/* "bx/bbi/bigbed_file.pyx":107
+ *         self.intervals.append( ( s, e, rest ) )
+ * 
+ * cdef class BigBedFile( BBIFile ):             # <<<<<<<<<<<<<<
+ *     """
+ *     A "big binary indexed" file whose raw data is in BED format.
+ */
+struct __pyx_obj_2bx_3bbi_11bigbed_file_BigBedFile {
+  struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile __pyx_base;
+};
+
+
+
+/* "bbi_file.pxd":21
+ *     cdef public double sum_squares
+ * 
+ * cdef class SummarizedData:             # <<<<<<<<<<<<<<
+ *     """
+ *     The result of using SummaryBlocks read from the file to produce a
+ */
+
+struct __pyx_vtabstruct_2bx_3bbi_8bbi_file_SummarizedData {
+  PyObject *(*accumulate_interval_value)(struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData *, __pyx_t_2bx_3bbi_5types_bits32, __pyx_t_2bx_3bbi_5types_bits32, float);
+};
+static struct __pyx_vtabstruct_2bx_3bbi_8bbi_file_SummarizedData *__pyx_vtabptr_2bx_3bbi_8bbi_file_SummarizedData;
+
+
+/* "bbi_file.pxd":37
+ *     cdef accumulate_interval_value( self, bits32 s, bits32 e, float val )
+ * 
+ * cdef class BBIFile             # <<<<<<<<<<<<<<
+ * 
+ * cdef class BlockHandler:
+ */
+
+struct __pyx_vtabstruct_2bx_3bbi_8bbi_file_BBIFile {
+  PyObject *(*visit_blocks_in_region)(struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *, __pyx_t_2bx_3bbi_5types_bits32, __pyx_t_2bx_3bbi_5types_bits32, __pyx_t_2bx_3bbi_5types_bits32, struct __pyx_obj_2bx_3bbi_8bbi_file_BlockHandler *);
+  PyObject *(*_get_chrom_id_and_size)(struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *, char *);
+  PyObject *(*_best_zoom_level)(struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *, int);
+  PyObject *(*summarize)(struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *, char *, __pyx_t_2bx_3bbi_5types_bits32, __pyx_t_2bx_3bbi_5types_bits32, int, int __pyx_skip_dispatch);
+  PyObject *(*summarize_from_full)(struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *, char *, __pyx_t_2bx_3bbi_5types_bits32, __pyx_t_2bx_3bbi_5types_bits32, int, int __pyx_skip_dispatch);
+  PyObject *(*query)(struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *, char *, __pyx_t_2bx_3bbi_5types_bits32, __pyx_t_2bx_3bbi_5types_bits32, int, int __pyx_skip_dispatch);
+  PyObject *(*_summarize_from_full)(struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *, __pyx_t_2bx_3bbi_5types_bits32, __pyx_t_2bx_3bbi_5types_bits32, __pyx_t_2bx_3bbi_5types_bits32, int);
+};
+static struct __pyx_vtabstruct_2bx_3bbi_8bbi_file_BBIFile *__pyx_vtabptr_2bx_3bbi_8bbi_file_BBIFile;
+
+
+/* "bbi_file.pxd":39
+ * cdef class BBIFile
+ * 
+ * cdef class BlockHandler:             # <<<<<<<<<<<<<<
+ *     """
+ *     Callback for `BBIFile.visit_blocks_in_region`
+ */
+
+struct __pyx_vtabstruct_2bx_3bbi_8bbi_file_BlockHandler {
+  PyObject *(*handle_block)(struct __pyx_obj_2bx_3bbi_8bbi_file_BlockHandler *, PyObject *, struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *);
+};
+static struct __pyx_vtabstruct_2bx_3bbi_8bbi_file_BlockHandler *__pyx_vtabptr_2bx_3bbi_8bbi_file_BlockHandler;
+
+
+/* "bx/bbi/bigbed_file.pyx":44
+ *     return "".join(read) if len(read) > 1 else read[0]
+ * 
+ * cdef class BigBedBlockHandler( BlockHandler ):             # <<<<<<<<<<<<<<
+ *     """
+ *     BlockHandler that parses the block into a series of BED records
+ */
+
+struct __pyx_vtabstruct_2bx_3bbi_11bigbed_file_BigBedBlockHandler {
+  struct __pyx_vtabstruct_2bx_3bbi_8bbi_file_BlockHandler __pyx_base;
+  PyObject *(*handle_interval_value)(struct __pyx_obj_2bx_3bbi_11bigbed_file_BigBedBlockHandler *, __pyx_t_2bx_3bbi_5types_bits32, __pyx_t_2bx_3bbi_5types_bits32, PyObject *);
+};
+static struct __pyx_vtabstruct_2bx_3bbi_11bigbed_file_BigBedBlockHandler *__pyx_vtabptr_2bx_3bbi_11bigbed_file_BigBedBlockHandler;
+
+
+/* "bx/bbi/bigbed_file.pyx":76
+ *         pass
+ * 
+ * cdef class SummarizingBlockHandler( BigBedBlockHandler ):             # <<<<<<<<<<<<<<
+ *     """
+ *     Accumulates intervals into a SummarizedData
+ */
+
+struct __pyx_vtabstruct_2bx_3bbi_11bigbed_file_SummarizingBlockHandler {
+  struct __pyx_vtabstruct_2bx_3bbi_11bigbed_file_BigBedBlockHandler __pyx_base;
+};
+static struct __pyx_vtabstruct_2bx_3bbi_11bigbed_file_SummarizingBlockHandler *__pyx_vtabptr_2bx_3bbi_11bigbed_file_SummarizingBlockHandler;
+
+
+/* "bx/bbi/bigbed_file.pyx":95
+ *         self.sd.accumulate_interval_value( s, e, 1 )
+ * 
+ * cdef class IntervalAccumulatingBlockHandler( BigBedBlockHandler ):             # <<<<<<<<<<<<<<
+ *     cdef list intervals
+ *     """
+ */
+
+struct __pyx_vtabstruct_2bx_3bbi_11bigbed_file_IntervalAccumulatingBlockHandler {
+  struct __pyx_vtabstruct_2bx_3bbi_11bigbed_file_BigBedBlockHandler __pyx_base;
+};
+static struct __pyx_vtabstruct_2bx_3bbi_11bigbed_file_IntervalAccumulatingBlockHandler *__pyx_vtabptr_2bx_3bbi_11bigbed_file_IntervalAccumulatingBlockHandler;
+
+
+/* "bx/bbi/bigbed_file.pyx":107
+ *         self.intervals.append( ( s, e, rest ) )
+ * 
+ * cdef class BigBedFile( BBIFile ):             # <<<<<<<<<<<<<<
+ *     """
+ *     A "big binary indexed" file whose raw data is in BED format.
+ */
+
+struct __pyx_vtabstruct_2bx_3bbi_11bigbed_file_BigBedFile {
+  struct __pyx_vtabstruct_2bx_3bbi_8bbi_file_BBIFile __pyx_base;
+  PyObject *(*get)(struct __pyx_obj_2bx_3bbi_11bigbed_file_BigBedFile *, char *, __pyx_t_2bx_3bbi_5types_bits32, __pyx_t_2bx_3bbi_5types_bits32, int __pyx_skip_dispatch);
+};
+static struct __pyx_vtabstruct_2bx_3bbi_11bigbed_file_BigBedFile *__pyx_vtabptr_2bx_3bbi_11bigbed_file_BigBedFile;
+
+/* --- Runtime support code (head) --- */
+#ifndef CYTHON_REFNANNY
+  #define CYTHON_REFNANNY 0
+#endif
+#if CYTHON_REFNANNY
+  typedef struct {
+    void (*INCREF)(void*, PyObject*, int);
+    void (*DECREF)(void*, PyObject*, int);
+    void (*GOTREF)(void*, PyObject*, int);
+    void (*GIVEREF)(void*, PyObject*, int);
+    void* (*SetupContext)(const char*, int, const char*);
+    void (*FinishContext)(void**);
+  } __Pyx_RefNannyAPIStruct;
+  static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL;
+  static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname);
+  #define __Pyx_RefNannyDeclarations void *__pyx_refnanny = NULL;
+#ifdef WITH_THREAD
+  #define __Pyx_RefNannySetupContext(name, acquire_gil) \
+          if (acquire_gil) { \
+              PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure(); \
+              __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__); \
+              PyGILState_Release(__pyx_gilstate_save); \
+          } else { \
+              __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__); \
+          }
+#else
+  #define __Pyx_RefNannySetupContext(name, acquire_gil) \
+          __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__)
+#endif
+  #define __Pyx_RefNannyFinishContext() \
+          __Pyx_RefNanny->FinishContext(&__pyx_refnanny)
+  #define __Pyx_INCREF(r)  __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_DECREF(r)  __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_GOTREF(r)  __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_XINCREF(r)  do { if((r) != NULL) {__Pyx_INCREF(r); }} while(0)
+  #define __Pyx_XDECREF(r)  do { if((r) != NULL) {__Pyx_DECREF(r); }} while(0)
+  #define __Pyx_XGOTREF(r)  do { if((r) != NULL) {__Pyx_GOTREF(r); }} while(0)
+  #define __Pyx_XGIVEREF(r) do { if((r) != NULL) {__Pyx_GIVEREF(r);}} while(0)
+#else
+  #define __Pyx_RefNannyDeclarations
+  #define __Pyx_RefNannySetupContext(name, acquire_gil)
+  #define __Pyx_RefNannyFinishContext()
+  #define __Pyx_INCREF(r) Py_INCREF(r)
+  #define __Pyx_DECREF(r) Py_DECREF(r)
+  #define __Pyx_GOTREF(r)
+  #define __Pyx_GIVEREF(r)
+  #define __Pyx_XINCREF(r) Py_XINCREF(r)
+  #define __Pyx_XDECREF(r) Py_XDECREF(r)
+  #define __Pyx_XGOTREF(r)
+  #define __Pyx_XGIVEREF(r)
+#endif
+#define __Pyx_XDECREF_SET(r, v) do {                            \
+        PyObject *tmp = (PyObject *) r;                         \
+        r = v; __Pyx_XDECREF(tmp);                              \
+    } while (0)
+#define __Pyx_DECREF_SET(r, v) do {                             \
+        PyObject *tmp = (PyObject *) r;                         \
+        r = v; __Pyx_DECREF(tmp);                               \
+    } while (0)
+#define __Pyx_CLEAR(r)    do { PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);} while(0)
+#define __Pyx_XCLEAR(r)   do { if((r) != NULL) {PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);}} while(0)
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name) {
+    PyTypeObject* tp = Py_TYPE(obj);
+    if (likely(tp->tp_getattro))
+        return tp->tp_getattro(obj, attr_name);
+#if PY_MAJOR_VERSION < 3
+    if (likely(tp->tp_getattr))
+        return tp->tp_getattr(obj, PyString_AS_STRING(attr_name));
+#endif
+    return PyObject_GetAttr(obj, attr_name);
+}
+#else
+#define __Pyx_PyObject_GetAttrStr(o,n) PyObject_GetAttr(o,n)
+#endif
+
+static PyObject *__Pyx_GetBuiltinName(PyObject *name);
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw);
+#else
+#define __Pyx_PyObject_Call(func, arg, kw) PyObject_Call(func, arg, kw)
+#endif
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg);
+#endif
+
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg);
+
+#define __Pyx_GetItemInt(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck) \
+    (__Pyx_fits_Py_ssize_t(i, type, is_signed) ? \
+    __Pyx_GetItemInt_Fast(o, (Py_ssize_t)i, is_list, wraparound, boundscheck) : \
+    (is_list ? (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL) : \
+               __Pyx_GetItemInt_Generic(o, to_py_func(i))))
+#define __Pyx_GetItemInt_List(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck) \
+    (__Pyx_fits_Py_ssize_t(i, type, is_signed) ? \
+    __Pyx_GetItemInt_List_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) : \
+    (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL))
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i,
+                                                              int wraparound, int boundscheck);
+#define __Pyx_GetItemInt_Tuple(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck) \
+    (__Pyx_fits_Py_ssize_t(i, type, is_signed) ? \
+    __Pyx_GetItemInt_Tuple_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) : \
+    (PyErr_SetString(PyExc_IndexError, "tuple index out of range"), (PyObject*)NULL))
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i,
+                                                              int wraparound, int boundscheck);
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j);
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i,
+                                                     int is_list, int wraparound, int boundscheck);
+
+static CYTHON_INLINE int __Pyx_PySequence_Contains(PyObject* item, PyObject* seq, int eq) {
+    int result = PySequence_Contains(seq, item);
+    return unlikely(result < 0) ? result : (result == (eq == Py_EQ));
+}
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE int __Pyx_PyList_Append(PyObject* list, PyObject* x) {
+    PyListObject* L = (PyListObject*) list;
+    Py_ssize_t len = Py_SIZE(list);
+    if (likely(L->allocated > len) & likely(len > (L->allocated >> 1))) {
+        Py_INCREF(x);
+        PyList_SET_ITEM(list, len, x);
+        Py_SIZE(list) = len+1;
+        return 0;
+    }
+    return PyList_Append(list, x);
+}
+#else
+#define __Pyx_PyList_Append(L,x) PyList_Append(L,x)
+#endif
+
+static CYTHON_INLINE PyObject* __Pyx_PyObject_GetSlice(
+        PyObject* obj, Py_ssize_t cstart, Py_ssize_t cstop,
+        PyObject** py_start, PyObject** py_stop, PyObject** py_slice,
+        int has_cstart, int has_cstop, int wraparound);
+
+#define __Pyx_SetItemInt(o, i, v, type, is_signed, to_py_func, is_list, wraparound, boundscheck) \
+    (__Pyx_fits_Py_ssize_t(i, type, is_signed) ? \
+    __Pyx_SetItemInt_Fast(o, (Py_ssize_t)i, v, is_list, wraparound, boundscheck) : \
+    (is_list ? (PyErr_SetString(PyExc_IndexError, "list assignment index out of range"), -1) : \
+               __Pyx_SetItemInt_Generic(o, to_py_func(i), v)))
+static CYTHON_INLINE int __Pyx_SetItemInt_Generic(PyObject *o, PyObject *j, PyObject *v);
+static CYTHON_INLINE int __Pyx_SetItemInt_Fast(PyObject *o, Py_ssize_t i, PyObject *v,
+                                               int is_list, int wraparound, int boundscheck);
+
+#if PY_MAJOR_VERSION < 3
+#define __Pyx_PyString_Join __Pyx_PyBytes_Join
+#define __Pyx_PyBaseString_Join(s, v) (PyUnicode_CheckExact(s) ? PyUnicode_Join(s, v) : __Pyx_PyBytes_Join(s, v))
+#else
+#define __Pyx_PyString_Join PyUnicode_Join
+#define __Pyx_PyBaseString_Join PyUnicode_Join
+#endif
+#if CYTHON_COMPILING_IN_CPYTHON
+    #if PY_MAJOR_VERSION < 3
+    #define __Pyx_PyBytes_Join _PyString_Join
+    #else
+    #define __Pyx_PyBytes_Join _PyBytes_Join
+    #endif
+#else
+static CYTHON_INLINE PyObject* __Pyx_PyBytes_Join(PyObject* sep, PyObject* values);
+#endif
+
+static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
+    Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found);
+
+static void __Pyx_RaiseDoubleKeywordsError(const char* func_name, PyObject* kw_name);
+
+static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
+    PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
+    const char* function_name);
+
+static CYTHON_INLINE PyObject *__Pyx_GetModuleGlobalName(PyObject *name);
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func);
+#else
+#define __Pyx_PyObject_CallNoArg(func) __Pyx_PyObject_Call(func, __pyx_empty_tuple, NULL)
+#endif
+
+static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected);
+
+static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index);
+
+static CYTHON_INLINE int __Pyx_IterFinish(void);
+
+static int __Pyx_IternextUnpackEndCheck(PyObject *retval, Py_ssize_t expected);
+
+static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb);
+static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb);
+
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause);
+
+#if PY_MAJOR_VERSION >= 3
+static PyObject *__Pyx_PyDict_GetItem(PyObject *d, PyObject* key) {
+    PyObject *value;
+    value = PyDict_GetItemWithError(d, key);
+    if (unlikely(!value)) {
+        if (!PyErr_Occurred()) {
+            PyObject* args = PyTuple_Pack(1, key);
+            if (likely(args))
+                PyErr_SetObject(PyExc_KeyError, args);
+            Py_XDECREF(args);
+        }
+        return NULL;
+    }
+    Py_INCREF(value);
+    return value;
+}
+#else
+    #define __Pyx_PyDict_GetItem(d, key) PyObject_GetItem(d, key)
+#endif
+
+static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void);
+
+static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type);
+
+static void __Pyx_call_next_tp_dealloc(PyObject* obj, destructor current_tp_dealloc);
+
+static int __Pyx_call_next_tp_traverse(PyObject* obj, visitproc v, void *a, traverseproc current_tp_traverse);
+
+static void __Pyx_call_next_tp_clear(PyObject* obj, inquiry current_tp_dealloc);
+
+static void* __Pyx_GetVtable(PyObject *dict);
+
+static int __Pyx_SetVtable(PyObject *dict, void *vtable);
+
+static PyObject* __Pyx_ImportFrom(PyObject* module, PyObject* name);
+
+typedef struct {
+    int code_line;
+    PyCodeObject* code_object;
+} __Pyx_CodeObjectCacheEntry;
+struct __Pyx_CodeObjectCache {
+    int count;
+    int max_count;
+    __Pyx_CodeObjectCacheEntry* entries;
+};
+static struct __Pyx_CodeObjectCache __pyx_code_cache = {0,0,NULL};
+static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line);
+static PyCodeObject *__pyx_find_code_object(int code_line);
+static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object);
+
+static void __Pyx_AddTraceback(const char *funcname, int c_line,
+                               int py_line, const char *filename);
+
+static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level);
+
+static CYTHON_INLINE unsigned int __Pyx_PyInt_As_unsigned_int(PyObject *);
+
+static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *);
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value);
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value);
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_unsigned_int(unsigned int value);
+
+#if CYTHON_CCOMPLEX
+  #ifdef __cplusplus
+    #define __Pyx_CREAL(z) ((z).real())
+    #define __Pyx_CIMAG(z) ((z).imag())
+  #else
+    #define __Pyx_CREAL(z) (__real__(z))
+    #define __Pyx_CIMAG(z) (__imag__(z))
+  #endif
+#else
+    #define __Pyx_CREAL(z) ((z).real)
+    #define __Pyx_CIMAG(z) ((z).imag)
+#endif
+#if (defined(_WIN32) || defined(__clang__)) && defined(__cplusplus) && CYTHON_CCOMPLEX
+    #define __Pyx_SET_CREAL(z,x) ((z).real(x))
+    #define __Pyx_SET_CIMAG(z,y) ((z).imag(y))
+#else
+    #define __Pyx_SET_CREAL(z,x) __Pyx_CREAL(z) = (x)
+    #define __Pyx_SET_CIMAG(z,y) __Pyx_CIMAG(z) = (y)
+#endif
+
+static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float, float);
+
+#if CYTHON_CCOMPLEX
+    #define __Pyx_c_eqf(a, b)   ((a)==(b))
+    #define __Pyx_c_sumf(a, b)  ((a)+(b))
+    #define __Pyx_c_difff(a, b) ((a)-(b))
+    #define __Pyx_c_prodf(a, b) ((a)*(b))
+    #define __Pyx_c_quotf(a, b) ((a)/(b))
+    #define __Pyx_c_negf(a)     (-(a))
+  #ifdef __cplusplus
+    #define __Pyx_c_is_zerof(z) ((z)==(float)0)
+    #define __Pyx_c_conjf(z)    (::std::conj(z))
+    #if 1
+        #define __Pyx_c_absf(z)     (::std::abs(z))
+        #define __Pyx_c_powf(a, b)  (::std::pow(a, b))
+    #endif
+  #else
+    #define __Pyx_c_is_zerof(z) ((z)==0)
+    #define __Pyx_c_conjf(z)    (conjf(z))
+    #if 1
+        #define __Pyx_c_absf(z)     (cabsf(z))
+        #define __Pyx_c_powf(a, b)  (cpowf(a, b))
+    #endif
+ #endif
+#else
+    static CYTHON_INLINE int __Pyx_c_eqf(__pyx_t_float_complex, __pyx_t_float_complex);
+    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_sumf(__pyx_t_float_complex, __pyx_t_float_complex);
+    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_difff(__pyx_t_float_complex, __pyx_t_float_complex);
+    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_prodf(__pyx_t_float_complex, __pyx_t_float_complex);
+    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_quotf(__pyx_t_float_complex, __pyx_t_float_complex);
+    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_negf(__pyx_t_float_complex);
+    static CYTHON_INLINE int __Pyx_c_is_zerof(__pyx_t_float_complex);
+    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_conjf(__pyx_t_float_complex);
+    #if 1
+        static CYTHON_INLINE float __Pyx_c_absf(__pyx_t_float_complex);
+        static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_powf(__pyx_t_float_complex, __pyx_t_float_complex);
+    #endif
+#endif
+
+static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double, double);
+
+#if CYTHON_CCOMPLEX
+    #define __Pyx_c_eq(a, b)   ((a)==(b))
+    #define __Pyx_c_sum(a, b)  ((a)+(b))
+    #define __Pyx_c_diff(a, b) ((a)-(b))
+    #define __Pyx_c_prod(a, b) ((a)*(b))
+    #define __Pyx_c_quot(a, b) ((a)/(b))
+    #define __Pyx_c_neg(a)     (-(a))
+  #ifdef __cplusplus
+    #define __Pyx_c_is_zero(z) ((z)==(double)0)
+    #define __Pyx_c_conj(z)    (::std::conj(z))
+    #if 1
+        #define __Pyx_c_abs(z)     (::std::abs(z))
+        #define __Pyx_c_pow(a, b)  (::std::pow(a, b))
+    #endif
+  #else
+    #define __Pyx_c_is_zero(z) ((z)==0)
+    #define __Pyx_c_conj(z)    (conj(z))
+    #if 1
+        #define __Pyx_c_abs(z)     (cabs(z))
+        #define __Pyx_c_pow(a, b)  (cpow(a, b))
+    #endif
+ #endif
+#else
+    static CYTHON_INLINE int __Pyx_c_eq(__pyx_t_double_complex, __pyx_t_double_complex);
+    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_sum(__pyx_t_double_complex, __pyx_t_double_complex);
+    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_diff(__pyx_t_double_complex, __pyx_t_double_complex);
+    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_prod(__pyx_t_double_complex, __pyx_t_double_complex);
+    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_quot(__pyx_t_double_complex, __pyx_t_double_complex);
+    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_neg(__pyx_t_double_complex);
+    static CYTHON_INLINE int __Pyx_c_is_zero(__pyx_t_double_complex);
+    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_conj(__pyx_t_double_complex);
+    #if 1
+        static CYTHON_INLINE double __Pyx_c_abs(__pyx_t_double_complex);
+        static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_pow(__pyx_t_double_complex, __pyx_t_double_complex);
+    #endif
+#endif
+
+static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *);
+
+static int __Pyx_check_binary_version(void);
+
+#if !defined(__Pyx_PyIdentifier_FromString)
+#if PY_MAJOR_VERSION < 3
+  #define __Pyx_PyIdentifier_FromString(s) PyString_FromString(s)
+#else
+  #define __Pyx_PyIdentifier_FromString(s) PyUnicode_FromString(s)
+#endif
+#endif
+
+static PyObject *__Pyx_ImportModule(const char *name);
+
+static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name, size_t size, int strict);
+
+static int __Pyx_InitStrings(__Pyx_StringTabEntry *t);
+
+static PyObject *__pyx_f_2bx_3bbi_11bigbed_file_18BigBedBlockHandler_handle_block(struct __pyx_obj_2bx_3bbi_11bigbed_file_BigBedBlockHandler *__pyx_v_self, PyObject *__pyx_v_block_data, struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *__pyx_v_bbi_file); /* proto*/
+static PyObject *__pyx_f_2bx_3bbi_11bigbed_file_18BigBedBlockHandler_handle_interval_value(CYTHON_UNUSED struct __pyx_obj_2bx_3bbi_11bigbed_file_BigBedBlockHandler *__pyx_v_self, CYTHON_UNUSED __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_s, CYTHON_UNUSED __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_e, CYTHON_UNUSED PyObject *__pyx_v_rest); /* proto*/
+static PyObject *__pyx_f_2bx_3bbi_11bigbed_file_23SummarizingBlockHandler_handle_interval_value(struct __pyx_obj_2bx_3bbi_11bigbed_file_SummarizingBlockHandler *__pyx_v_self, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_s, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_e, CYTHON_UNUSED PyObject *__pyx_v_rest); /* proto*/
+static PyObject *__pyx_f_2bx_3bbi_11bigbed_file_32IntervalAccumulatingBlockHandler_handle_interval_value(struct __pyx_obj_2bx_3bbi_11bigbed_file_IntervalAccumulatingBlockHandler *__pyx_v_self, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_s, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_e, PyObject *__pyx_v_rest); /* proto*/
+static PyObject *__pyx_f_2bx_3bbi_11bigbed_file_10BigBedFile__summarize_from_full(struct __pyx_obj_2bx_3bbi_11bigbed_file_BigBedFile *__pyx_v_self, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_chrom_id, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_start, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_end, int __pyx_v_summary_size); /* proto*/
+static PyObject *__pyx_f_2bx_3bbi_11bigbed_file_10BigBedFile_get(struct __pyx_obj_2bx_3bbi_11bigbed_file_BigBedFile *__pyx_v_self, char *__pyx_v_chrom, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_start, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_end, int __pyx_skip_dispatch); /* proto*/
+
+/* Module declarations from 'bx.bbi.types' */
+
+/* Module declarations from 'bx.bbi.bpt_file' */
+static PyTypeObject *__pyx_ptype_2bx_3bbi_8bpt_file_BPTFile = 0;
+
+/* Module declarations from 'bx.bbi.cirtree_file' */
+static PyTypeObject *__pyx_ptype_2bx_3bbi_12cirtree_file_CIRTreeFile = 0;
+
+/* Module declarations from 'cpython.buffer' */
+
+/* Module declarations from 'cpython.ref' */
+
+/* Module declarations from 'libc.string' */
+
+/* Module declarations from 'libc.stdio' */
+
+/* Module declarations from 'cpython.object' */
+
+/* Module declarations from '__builtin__' */
+
+/* Module declarations from 'cpython.type' */
+static PyTypeObject *__pyx_ptype_7cpython_4type_type = 0;
+
+/* Module declarations from 'libc.stdlib' */
+
+/* Module declarations from 'numpy' */
+
+/* Module declarations from 'numpy' */
+static PyTypeObject *__pyx_ptype_5numpy_dtype = 0;
+static PyTypeObject *__pyx_ptype_5numpy_flatiter = 0;
+static PyTypeObject *__pyx_ptype_5numpy_broadcast = 0;
+static PyTypeObject *__pyx_ptype_5numpy_ndarray = 0;
+static PyTypeObject *__pyx_ptype_5numpy_ufunc = 0;
+static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *, char *, char *, int *); /*proto*/
+
+/* Module declarations from 'bx.bbi.bbi_file' */
+static PyTypeObject *__pyx_ptype_2bx_3bbi_8bbi_file_SummaryBlock = 0;
+static PyTypeObject *__pyx_ptype_2bx_3bbi_8bbi_file_SummarizedData = 0;
+static PyTypeObject *__pyx_ptype_2bx_3bbi_8bbi_file_BBIFile = 0;
+static PyTypeObject *__pyx_ptype_2bx_3bbi_8bbi_file_BlockHandler = 0;
+
+/* Module declarations from 'bx.bbi.bigbed_file' */
+static PyTypeObject *__pyx_ptype_2bx_3bbi_11bigbed_file_BigBedBlockHandler = 0;
+static PyTypeObject *__pyx_ptype_2bx_3bbi_11bigbed_file_SummarizingBlockHandler = 0;
+static PyTypeObject *__pyx_ptype_2bx_3bbi_11bigbed_file_IntervalAccumulatingBlockHandler = 0;
+static PyTypeObject *__pyx_ptype_2bx_3bbi_11bigbed_file_BigBedFile = 0;
+static PyObject *__pyx_f_2bx_3bbi_11bigbed_file_read_c_string(PyObject *); /*proto*/
+#define __Pyx_MODULE_NAME "bx.bbi.bigbed_file"
+int __pyx_module_is_main_bx__bbi__bigbed_file = 0;
+
+/* Implementation of 'bx.bbi.bigbed_file' */
+static PyObject *__pyx_builtin_range;
+static PyObject *__pyx_builtin_ValueError;
+static PyObject *__pyx_builtin_RuntimeError;
+static int __pyx_pf_2bx_3bbi_11bigbed_file_18BigBedBlockHandler___init__(struct __pyx_obj_2bx_3bbi_11bigbed_file_BigBedBlockHandler *__pyx_v_self, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_chrom_id, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_start, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_end); /* proto */
+static int __pyx_pf_2bx_3bbi_11bigbed_file_23SummarizingBlockHandler___init__(struct __pyx_obj_2bx_3bbi_11bigbed_file_SummarizingBlockHandler *__pyx_v_self, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_chrom_id, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_start, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_end, int __pyx_v_summary_size); /* proto */
+static int __pyx_pf_2bx_3bbi_11bigbed_file_32IntervalAccumulatingBlockHandler___init__(struct __pyx_obj_2bx_3bbi_11bigbed_file_IntervalAccumulatingBlockHandler *__pyx_v_self, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_chrom_id, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_start, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_end); /* proto */
+static int __pyx_pf_2bx_3bbi_11bigbed_file_10BigBedFile___init__(struct __pyx_obj_2bx_3bbi_11bigbed_file_BigBedFile *__pyx_v_self, PyObject *__pyx_v_file); /* proto */
+static PyObject *__pyx_pf_2bx_3bbi_11bigbed_file_10BigBedFile_2get(struct __pyx_obj_2bx_3bbi_11bigbed_file_BigBedFile *__pyx_v_self, char *__pyx_v_chrom, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_start, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_end); /* proto */
+static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /* proto */
+static void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info); /* proto */
+static PyObject *__pyx_tp_new_2bx_3bbi_11bigbed_file_BigBedBlockHandler(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
+static PyObject *__pyx_tp_new_2bx_3bbi_11bigbed_file_SummarizingBlockHandler(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
+static PyObject *__pyx_tp_new_2bx_3bbi_11bigbed_file_IntervalAccumulatingBlockHandler(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
+static PyObject *__pyx_tp_new_2bx_3bbi_11bigbed_file_BigBedFile(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
+static char __pyx_k_[] = "\000";
+static char __pyx_k_B[] = "B";
+static char __pyx_k_H[] = "H";
+static char __pyx_k_I[] = "I";
+static char __pyx_k_L[] = "L";
+static char __pyx_k_O[] = "O";
+static char __pyx_k_Q[] = "Q";
+static char __pyx_k_b[] = "b";
+static char __pyx_k_d[] = "d";
+static char __pyx_k_f[] = "f";
+static char __pyx_k_g[] = "g";
+static char __pyx_k_h[] = "h";
+static char __pyx_k_i[] = "i";
+static char __pyx_k_l[] = "l";
+static char __pyx_k_q[] = "q";
+static char __pyx_k_Zd[] = "Zd";
+static char __pyx_k_Zf[] = "Zf";
+static char __pyx_k_Zg[] = "Zg";
+static char __pyx_k__3[] = "";
+static char __pyx_k__5[] = "\t";
+static char __pyx_k__7[] = "+";
+static char __pyx_k_np[] = "np";
+static char __pyx_k_LLL[] = "LLL";
+static char __pyx_k_end[] = "end";
+static char __pyx_k_get[] = "get";
+static char __pyx_k_inf[] = "inf";
+static char __pyx_k_out[] = "out";
+static char __pyx_k_file[] = "file";
+static char __pyx_k_find[] = "find";
+static char __pyx_k_init[] = "__init__";
+static char __pyx_k_join[] = "join";
+static char __pyx_k_main[] = "__main__";
+static char __pyx_k_read[] = "read";
+static char __pyx_k_seek[] = "seek";
+static char __pyx_k_tell[] = "tell";
+static char __pyx_k_test[] = "__test__";
+static char __pyx_k_zlib[] = "zlib";
+static char __pyx_k_chrom[] = "chrom";
+static char __pyx_k_numpy[] = "numpy";
+static char __pyx_k_range[] = "range";
+static char __pyx_k_round[] = "round";
+static char __pyx_k_split[] = "split";
+static char __pyx_k_start[] = "start";
+static char __pyx_k_bigbed[] = "bigbed";
+static char __pyx_k_import[] = "__import__";
+static char __pyx_k_StringIO[] = "StringIO";
+static char __pyx_k_chrom_id[] = "chrom_id";
+static char __pyx_k_cStringIO[] = "cStringIO";
+static char __pyx_k_ValueError[] = "ValueError";
+static char __pyx_k_pyx_vtable[] = "__pyx_vtable__";
+static char __pyx_k_BigBed_file[] = "\nBigBed file.\n";
+static char __pyx_k_RuntimeError[] = "RuntimeError";
+static char __pyx_k_summary_size[] = "summary_size";
+static char __pyx_k_GenomicInterval[] = "GenomicInterval";
+static char __pyx_k_bx_intervals_io[] = "bx.intervals.io";
+static char __pyx_k_read_and_unpack[] = "read_and_unpack";
+static char __pyx_k_BinaryFileReader[] = "BinaryFileReader";
+static char __pyx_k_is_little_endian[] = "is_little_endian";
+static char __pyx_k_bx_misc_binary_file[] = "bx.misc.binary_file";
+static char __pyx_k_ndarray_is_not_C_contiguous[] = "ndarray is not C contiguous";
+static char __pyx_k_unknown_dtype_code_in_numpy_pxd[] = "unknown dtype code in numpy.pxd (%d)";
+static char __pyx_k_Format_string_allocated_too_shor[] = "Format string allocated too short, see comment in numpy.pxd";
+static char __pyx_k_Non_native_byte_order_not_suppor[] = "Non-native byte order not supported";
+static char __pyx_k_ndarray_is_not_Fortran_contiguou[] = "ndarray is not Fortran contiguous";
+static char __pyx_k_Format_string_allocated_too_shor_2[] = "Format string allocated too short.";
+static PyObject *__pyx_kp_s_;
+static PyObject *__pyx_n_s_BinaryFileReader;
+static PyObject *__pyx_kp_u_Format_string_allocated_too_shor;
+static PyObject *__pyx_kp_u_Format_string_allocated_too_shor_2;
+static PyObject *__pyx_n_s_GenomicInterval;
+static PyObject *__pyx_n_s_LLL;
+static PyObject *__pyx_kp_u_Non_native_byte_order_not_suppor;
+static PyObject *__pyx_n_s_RuntimeError;
+static PyObject *__pyx_n_s_StringIO;
+static PyObject *__pyx_n_s_ValueError;
+static PyObject *__pyx_kp_s__3;
+static PyObject *__pyx_kp_s__5;
+static PyObject *__pyx_kp_s__7;
+static PyObject *__pyx_n_s_bigbed;
+static PyObject *__pyx_n_s_bx_intervals_io;
+static PyObject *__pyx_n_s_bx_misc_binary_file;
+static PyObject *__pyx_n_s_cStringIO;
+static PyObject *__pyx_n_s_chrom;
+static PyObject *__pyx_n_s_chrom_id;
+static PyObject *__pyx_n_s_end;
+static PyObject *__pyx_n_s_file;
+static PyObject *__pyx_n_s_find;
+static PyObject *__pyx_n_s_get;
+static PyObject *__pyx_n_s_import;
+static PyObject *__pyx_n_s_inf;
+static PyObject *__pyx_n_s_init;
+static PyObject *__pyx_n_s_is_little_endian;
+static PyObject *__pyx_n_s_join;
+static PyObject *__pyx_n_s_main;
+static PyObject *__pyx_kp_u_ndarray_is_not_C_contiguous;
+static PyObject *__pyx_kp_u_ndarray_is_not_Fortran_contiguou;
+static PyObject *__pyx_n_s_np;
+static PyObject *__pyx_n_s_numpy;
+static PyObject *__pyx_n_s_out;
+static PyObject *__pyx_n_s_pyx_vtable;
+static PyObject *__pyx_n_s_range;
+static PyObject *__pyx_n_s_read;
+static PyObject *__pyx_n_s_read_and_unpack;
+static PyObject *__pyx_n_s_round;
+static PyObject *__pyx_n_s_seek;
+static PyObject *__pyx_n_s_split;
+static PyObject *__pyx_n_s_start;
+static PyObject *__pyx_n_s_summary_size;
+static PyObject *__pyx_n_s_tell;
+static PyObject *__pyx_n_s_test;
+static PyObject *__pyx_kp_u_unknown_dtype_code_in_numpy_pxd;
+static PyObject *__pyx_n_s_zlib;
+static PyObject *__pyx_int_0;
+static PyObject *__pyx_int_1;
+static PyObject *__pyx_int_2;
+static PyObject *__pyx_int_5;
+static PyObject *__pyx_int_8;
+static PyObject *__pyx_int_12;
+static PyObject *__pyx_int_2273964779;
+static PyObject *__pyx_tuple__2;
+static PyObject *__pyx_tuple__4;
+static PyObject *__pyx_tuple__6;
+static PyObject *__pyx_tuple__8;
+static PyObject *__pyx_tuple__9;
+static PyObject *__pyx_tuple__10;
+static PyObject *__pyx_tuple__11;
+static PyObject *__pyx_tuple__12;
+static PyObject *__pyx_tuple__13;
+
+/* "bx/bbi/bigbed_file.pyx":18
+ * DEF big_bed_sig = 0x8789F2EB
+ * 
+ * cdef inline int range_intersection( int start1, int end1, int start2, int end2 ):             # <<<<<<<<<<<<<<
+ *     return min( end1, end2 ) - max( start1, start2 )
+ * 
+ */
+
+static CYTHON_INLINE int __pyx_f_2bx_3bbi_11bigbed_file_range_intersection(int __pyx_v_start1, int __pyx_v_end1, int __pyx_v_start2, int __pyx_v_end2) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  int __pyx_t_2;
+  int __pyx_t_3;
+  int __pyx_t_4;
+  __Pyx_RefNannySetupContext("range_intersection", 0);
+
+  /* "bx/bbi/bigbed_file.pyx":19
+ * 
+ * cdef inline int range_intersection( int start1, int end1, int start2, int end2 ):
+ *     return min( end1, end2 ) - max( start1, start2 )             # <<<<<<<<<<<<<<
+ * 
+ * cdef str read_c_string(fh):
+ */
+  __pyx_t_1 = __pyx_v_end2;
+  __pyx_t_2 = __pyx_v_end1;
+  if (((__pyx_t_1 < __pyx_t_2) != 0)) {
+    __pyx_t_3 = __pyx_t_1;
+  } else {
+    __pyx_t_3 = __pyx_t_2;
+  }
+  __pyx_t_1 = __pyx_v_start2;
+  __pyx_t_2 = __pyx_v_start1;
+  if (((__pyx_t_1 > __pyx_t_2) != 0)) {
+    __pyx_t_4 = __pyx_t_1;
+  } else {
+    __pyx_t_4 = __pyx_t_2;
+  }
+  __pyx_r = (__pyx_t_3 - __pyx_t_4);
+  goto __pyx_L0;
+
+  /* "bx/bbi/bigbed_file.pyx":18
+ * DEF big_bed_sig = 0x8789F2EB
+ * 
+ * cdef inline int range_intersection( int start1, int end1, int start2, int end2 ):             # <<<<<<<<<<<<<<
+ *     return min( end1, end2 ) - max( start1, start2 )
+ * 
+ */
+
+  /* function exit code */
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bbi/bigbed_file.pyx":21
+ *     return min( end1, end2 ) - max( start1, start2 )
+ * 
+ * cdef str read_c_string(fh):             # <<<<<<<<<<<<<<
+ *     """
+ *     Read a zero terminated (C style) string
+ */
+
+static PyObject *__pyx_f_2bx_3bbi_11bigbed_file_read_c_string(PyObject *__pyx_v_fh) {
+  PyObject *__pyx_v_chunksize = NULL;
+  PyObject *__pyx_v_read = NULL;
+  PyObject *__pyx_v_r = NULL;
+  PyObject *__pyx_v_pos = NULL;
+  Py_ssize_t __pyx_v_l;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  int __pyx_t_5;
+  int __pyx_t_6;
+  int __pyx_t_7;
+  Py_ssize_t __pyx_t_8;
+  PyObject *__pyx_t_9 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("read_c_string", 0);
+
+  /* "bx/bbi/bigbed_file.pyx":27
+ *     If we read to much then seek back to the correct place.
+ *     """
+ *     chunksize = 8             # <<<<<<<<<<<<<<
+ *     read = [fh.read(chunksize)]
+ *     while not '\0' in read[-1]:
+ */
+  __Pyx_INCREF(__pyx_int_8);
+  __pyx_v_chunksize = __pyx_int_8;
+
+  /* "bx/bbi/bigbed_file.pyx":28
+ *     """
+ *     chunksize = 8
+ *     read = [fh.read(chunksize)]             # <<<<<<<<<<<<<<
+ *     while not '\0' in read[-1]:
+ *         r = fh.read(chunksize)
+ */
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_fh, __pyx_n_s_read); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 28; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = NULL;
+  if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_2))) {
+    __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2);
+    if (likely(__pyx_t_3)) {
+      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+      __Pyx_INCREF(__pyx_t_3);
+      __Pyx_INCREF(function);
+      __Pyx_DECREF_SET(__pyx_t_2, function);
+    }
+  }
+  if (!__pyx_t_3) {
+    __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_v_chunksize); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 28; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+  } else {
+    __pyx_t_4 = PyTuple_New(1+1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 28; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3); __Pyx_GIVEREF(__pyx_t_3); __pyx_t_3 = NULL;
+    __Pyx_INCREF(__pyx_v_chunksize);
+    PyTuple_SET_ITEM(__pyx_t_4, 0+1, __pyx_v_chunksize);
+    __Pyx_GIVEREF(__pyx_v_chunksize);
+    __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_4, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 28; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  }
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_2 = PyList_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 28; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  PyList_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
+  __Pyx_GIVEREF(__pyx_t_1);
+  __pyx_t_1 = 0;
+  __pyx_v_read = ((PyObject*)__pyx_t_2);
+  __pyx_t_2 = 0;
+
+  /* "bx/bbi/bigbed_file.pyx":29
+ *     chunksize = 8
+ *     read = [fh.read(chunksize)]
+ *     while not '\0' in read[-1]:             # <<<<<<<<<<<<<<
+ *         r = fh.read(chunksize)
+ *         read.append(r)
+ */
+  while (1) {
+    __pyx_t_2 = __Pyx_GetItemInt_List(__pyx_v_read, -1, long, 1, __Pyx_PyInt_From_long, 1, 1, 1); if (unlikely(__pyx_t_2 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 29; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_t_5 = (__Pyx_PySequence_Contains(__pyx_kp_s_, __pyx_t_2, Py_NE)); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 29; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    __pyx_t_6 = (__pyx_t_5 != 0);
+    if (!__pyx_t_6) break;
+
+    /* "bx/bbi/bigbed_file.pyx":30
+ *     read = [fh.read(chunksize)]
+ *     while not '\0' in read[-1]:
+ *         r = fh.read(chunksize)             # <<<<<<<<<<<<<<
+ *         read.append(r)
+ *         if len(r) != chunksize:
+ */
+    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_fh, __pyx_n_s_read); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 30; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __pyx_t_4 = NULL;
+    if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_1))) {
+      __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_1);
+      if (likely(__pyx_t_4)) {
+        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_1);
+        __Pyx_INCREF(__pyx_t_4);
+        __Pyx_INCREF(function);
+        __Pyx_DECREF_SET(__pyx_t_1, function);
+      }
+    }
+    if (!__pyx_t_4) {
+      __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_1, __pyx_v_chunksize); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 30; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_2);
+    } else {
+      __pyx_t_3 = PyTuple_New(1+1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 30; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_4); __Pyx_GIVEREF(__pyx_t_4); __pyx_t_4 = NULL;
+      __Pyx_INCREF(__pyx_v_chunksize);
+      PyTuple_SET_ITEM(__pyx_t_3, 0+1, __pyx_v_chunksize);
+      __Pyx_GIVEREF(__pyx_v_chunksize);
+      __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_3, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 30; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_2);
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    }
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    __Pyx_XDECREF_SET(__pyx_v_r, __pyx_t_2);
+    __pyx_t_2 = 0;
+
+    /* "bx/bbi/bigbed_file.pyx":31
+ *     while not '\0' in read[-1]:
+ *         r = fh.read(chunksize)
+ *         read.append(r)             # <<<<<<<<<<<<<<
+ *         if len(r) != chunksize:
+ *             break
+ */
+    __pyx_t_7 = __Pyx_PyList_Append(__pyx_v_read, __pyx_v_r); if (unlikely(__pyx_t_7 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 31; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+    /* "bx/bbi/bigbed_file.pyx":32
+ *         r = fh.read(chunksize)
+ *         read.append(r)
+ *         if len(r) != chunksize:             # <<<<<<<<<<<<<<
+ *             break
+ * 
+ */
+    __pyx_t_8 = PyObject_Length(__pyx_v_r); if (unlikely(__pyx_t_8 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 32; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = PyInt_FromSsize_t(__pyx_t_8); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 32; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_t_1 = PyObject_RichCompare(__pyx_t_2, __pyx_v_chunksize, Py_NE); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 32; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 32; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    if (__pyx_t_6) {
+
+      /* "bx/bbi/bigbed_file.pyx":33
+ *         read.append(r)
+ *         if len(r) != chunksize:
+ *             break             # <<<<<<<<<<<<<<
+ * 
+ *     pos = read[-1].find('\0')
+ */
+      goto __pyx_L4_break;
+    }
+  }
+  __pyx_L4_break:;
+
+  /* "bx/bbi/bigbed_file.pyx":35
+ *             break
+ * 
+ *     pos = read[-1].find('\0')             # <<<<<<<<<<<<<<
+ *     l = len(read[-1])
+ *     if l == chunksize:
+ */
+  __pyx_t_1 = __Pyx_GetItemInt_List(__pyx_v_read, -1, long, 1, __Pyx_PyInt_From_long, 1, 1, 1); if (unlikely(__pyx_t_1 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 35; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_find); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 35; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_tuple__2, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 35; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_v_pos = __pyx_t_1;
+  __pyx_t_1 = 0;
+
+  /* "bx/bbi/bigbed_file.pyx":36
+ * 
+ *     pos = read[-1].find('\0')
+ *     l = len(read[-1])             # <<<<<<<<<<<<<<
+ *     if l == chunksize:
+ *         fh.seek(-(chunksize - pos) + 1, 1)
+ */
+  __pyx_t_1 = __Pyx_GetItemInt_List(__pyx_v_read, -1, long, 1, __Pyx_PyInt_From_long, 1, 1, 1); if (unlikely(__pyx_t_1 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 36; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_8 = PyObject_Length(__pyx_t_1); if (unlikely(__pyx_t_8 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 36; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_v_l = __pyx_t_8;
+
+  /* "bx/bbi/bigbed_file.pyx":37
+ *     pos = read[-1].find('\0')
+ *     l = len(read[-1])
+ *     if l == chunksize:             # <<<<<<<<<<<<<<
+ *         fh.seek(-(chunksize - pos) + 1, 1)
+ *     if l != chunksize:
+ */
+  __pyx_t_1 = PyInt_FromSsize_t(__pyx_v_l); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 37; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = PyObject_RichCompare(__pyx_t_1, __pyx_v_chunksize, Py_EQ); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 37; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 37; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  if (__pyx_t_6) {
+
+    /* "bx/bbi/bigbed_file.pyx":38
+ *     l = len(read[-1])
+ *     if l == chunksize:
+ *         fh.seek(-(chunksize - pos) + 1, 1)             # <<<<<<<<<<<<<<
+ *     if l != chunksize:
+ *         read[-1] = read[-1][:pos]
+ */
+    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_fh, __pyx_n_s_seek); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 38; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __pyx_t_3 = PyNumber_Subtract(__pyx_v_chunksize, __pyx_v_pos); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 38; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __pyx_t_4 = PyNumber_Negative(__pyx_t_3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 38; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __pyx_t_3 = PyNumber_Add(__pyx_t_4, __pyx_int_1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 38; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    __pyx_t_4 = NULL;
+    __pyx_t_8 = 0;
+    if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_1))) {
+      __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_1);
+      if (likely(__pyx_t_4)) {
+        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_1);
+        __Pyx_INCREF(__pyx_t_4);
+        __Pyx_INCREF(function);
+        __Pyx_DECREF_SET(__pyx_t_1, function);
+        __pyx_t_8 = 1;
+      }
+    }
+    __pyx_t_9 = PyTuple_New(2+__pyx_t_8); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 38; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_9);
+    if (__pyx_t_4) {
+      PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_4); __Pyx_GIVEREF(__pyx_t_4); __pyx_t_4 = NULL;
+    }
+    PyTuple_SET_ITEM(__pyx_t_9, 0+__pyx_t_8, __pyx_t_3);
+    __Pyx_GIVEREF(__pyx_t_3);
+    __Pyx_INCREF(__pyx_int_1);
+    PyTuple_SET_ITEM(__pyx_t_9, 1+__pyx_t_8, __pyx_int_1);
+    __Pyx_GIVEREF(__pyx_int_1);
+    __pyx_t_3 = 0;
+    __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_9, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 38; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    goto __pyx_L6;
+  }
+  __pyx_L6:;
+
+  /* "bx/bbi/bigbed_file.pyx":39
+ *     if l == chunksize:
+ *         fh.seek(-(chunksize - pos) + 1, 1)
+ *     if l != chunksize:             # <<<<<<<<<<<<<<
+ *         read[-1] = read[-1][:pos]
+ * 
+ */
+  __pyx_t_2 = PyInt_FromSsize_t(__pyx_v_l); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 39; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_1 = PyObject_RichCompare(__pyx_t_2, __pyx_v_chunksize, Py_NE); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 39; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 39; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  if (__pyx_t_6) {
+
+    /* "bx/bbi/bigbed_file.pyx":40
+ *         fh.seek(-(chunksize - pos) + 1, 1)
+ *     if l != chunksize:
+ *         read[-1] = read[-1][:pos]             # <<<<<<<<<<<<<<
+ * 
+ *     return "".join(read) if len(read) > 1 else read[0]
+ */
+    __pyx_t_1 = __Pyx_GetItemInt_List(__pyx_v_read, -1, long, 1, __Pyx_PyInt_From_long, 1, 1, 1); if (unlikely(__pyx_t_1 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 40; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+    __Pyx_GOTREF(__pyx_t_1);
+    __pyx_t_2 = __Pyx_PyObject_GetSlice(__pyx_t_1, 0, 0, NULL, &__pyx_v_pos, NULL, 0, 0, 1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 40; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    if (unlikely(__Pyx_SetItemInt(__pyx_v_read, -1, __pyx_t_2, long, 1, __Pyx_PyInt_From_long, 1, 1, 1) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 40; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    goto __pyx_L7;
+  }
+  __pyx_L7:;
+
+  /* "bx/bbi/bigbed_file.pyx":42
+ *         read[-1] = read[-1][:pos]
+ * 
+ *     return "".join(read) if len(read) > 1 else read[0]             # <<<<<<<<<<<<<<
+ * 
+ * cdef class BigBedBlockHandler( BlockHandler ):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_8 = PyList_GET_SIZE(__pyx_v_read); if (unlikely(__pyx_t_8 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 42; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (((__pyx_t_8 > 1) != 0)) {
+    __pyx_t_1 = __Pyx_PyString_Join(__pyx_kp_s__3, __pyx_v_read); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 42; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    if (!(likely(PyString_CheckExact(__pyx_t_1))||((__pyx_t_1) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "str", Py_TYPE(__pyx_t_1)->tp_name), 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 42; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = __pyx_t_1;
+    __pyx_t_1 = 0;
+  } else {
+    __pyx_t_1 = __Pyx_GetItemInt_List(__pyx_v_read, 0, long, 1, __Pyx_PyInt_From_long, 1, 0, 1); if (unlikely(__pyx_t_1 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 42; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+    __Pyx_GOTREF(__pyx_t_1);
+    if (!(likely(PyString_CheckExact(__pyx_t_1))||((__pyx_t_1) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "str", Py_TYPE(__pyx_t_1)->tp_name), 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 42; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = __pyx_t_1;
+    __pyx_t_1 = 0;
+  }
+  __pyx_r = ((PyObject*)__pyx_t_2);
+  __pyx_t_2 = 0;
+  goto __pyx_L0;
+
+  /* "bx/bbi/bigbed_file.pyx":21
+ *     return min( end1, end2 ) - max( start1, start2 )
+ * 
+ * cdef str read_c_string(fh):             # <<<<<<<<<<<<<<
+ *     """
+ *     Read a zero terminated (C style) string
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_XDECREF(__pyx_t_9);
+  __Pyx_AddTraceback("bx.bbi.bigbed_file.read_c_string", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_chunksize);
+  __Pyx_XDECREF(__pyx_v_read);
+  __Pyx_XDECREF(__pyx_v_r);
+  __Pyx_XDECREF(__pyx_v_pos);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bbi/bigbed_file.pyx":51
+ *     cdef bits32 start
+ *     cdef bits32 end
+ *     def __init__( self, bits32 chrom_id, bits32 start, bits32 end ):             # <<<<<<<<<<<<<<
+ *         BlockHandler.__init__( self )
+ *         self.chrom_id = chrom_id
+ */
+
+/* Python wrapper */
+static int __pyx_pw_2bx_3bbi_11bigbed_file_18BigBedBlockHandler_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static int __pyx_pw_2bx_3bbi_11bigbed_file_18BigBedBlockHandler_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_chrom_id;
+  __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_start;
+  __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_end;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__init__ (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_chrom_id,&__pyx_n_s_start,&__pyx_n_s_end,0};
+    PyObject* values[3] = {0,0,0};
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_chrom_id)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_start)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("__init__", 1, 3, 3, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 51; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+        case  2:
+        if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_end)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("__init__", 1, 3, 3, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 51; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 51; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else if (PyTuple_GET_SIZE(__pyx_args) != 3) {
+      goto __pyx_L5_argtuple_error;
+    } else {
+      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+      values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+    }
+    __pyx_v_chrom_id = __Pyx_PyInt_As_unsigned_int(values[0]); if (unlikely((__pyx_v_chrom_id == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 51; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_start = __Pyx_PyInt_As_unsigned_int(values[1]); if (unlikely((__pyx_v_start == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 51; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_end = __Pyx_PyInt_As_unsigned_int(values[2]); if (unlikely((__pyx_v_end == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 51; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("__init__", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 51; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.bbi.bigbed_file.BigBedBlockHandler.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return -1;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_3bbi_11bigbed_file_18BigBedBlockHandler___init__(((struct __pyx_obj_2bx_3bbi_11bigbed_file_BigBedBlockHandler *)__pyx_v_self), __pyx_v_chrom_id, __pyx_v_start, __pyx_v_end);
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_2bx_3bbi_11bigbed_file_18BigBedBlockHandler___init__(struct __pyx_obj_2bx_3bbi_11bigbed_file_BigBedBlockHandler *__pyx_v_self, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_chrom_id, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_start, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_end) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__init__", 0);
+
+  /* "bx/bbi/bigbed_file.pyx":52
+ *     cdef bits32 end
+ *     def __init__( self, bits32 chrom_id, bits32 start, bits32 end ):
+ *         BlockHandler.__init__( self )             # <<<<<<<<<<<<<<
+ *         self.chrom_id = chrom_id
+ *         self.start = start
+ */
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(((PyObject *)((PyObject*)__pyx_ptype_2bx_3bbi_8bbi_file_BlockHandler)), __pyx_n_s_init); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 52; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = NULL;
+  if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_2))) {
+    __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2);
+    if (likely(__pyx_t_3)) {
+      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+      __Pyx_INCREF(__pyx_t_3);
+      __Pyx_INCREF(function);
+      __Pyx_DECREF_SET(__pyx_t_2, function);
+    }
+  }
+  if (!__pyx_t_3) {
+    __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 52; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+  } else {
+    __pyx_t_4 = PyTuple_New(1+1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 52; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3); __Pyx_GIVEREF(__pyx_t_3); __pyx_t_3 = NULL;
+    __Pyx_INCREF(((PyObject *)__pyx_v_self));
+    PyTuple_SET_ITEM(__pyx_t_4, 0+1, ((PyObject *)__pyx_v_self));
+    __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
+    __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_4, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 52; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  }
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "bx/bbi/bigbed_file.pyx":53
+ *     def __init__( self, bits32 chrom_id, bits32 start, bits32 end ):
+ *         BlockHandler.__init__( self )
+ *         self.chrom_id = chrom_id             # <<<<<<<<<<<<<<
+ *         self.start = start
+ *         self.end = end
+ */
+  __pyx_v_self->chrom_id = __pyx_v_chrom_id;
+
+  /* "bx/bbi/bigbed_file.pyx":54
+ *         BlockHandler.__init__( self )
+ *         self.chrom_id = chrom_id
+ *         self.start = start             # <<<<<<<<<<<<<<
+ *         self.end = end
+ *     cdef handle_block( self, str block_data, BBIFile bbi_file ):
+ */
+  __pyx_v_self->start = __pyx_v_start;
+
+  /* "bx/bbi/bigbed_file.pyx":55
+ *         self.chrom_id = chrom_id
+ *         self.start = start
+ *         self.end = end             # <<<<<<<<<<<<<<
+ *     cdef handle_block( self, str block_data, BBIFile bbi_file ):
+ *         cdef object string_io
+ */
+  __pyx_v_self->end = __pyx_v_end;
+
+  /* "bx/bbi/bigbed_file.pyx":51
+ *     cdef bits32 start
+ *     cdef bits32 end
+ *     def __init__( self, bits32 chrom_id, bits32 start, bits32 end ):             # <<<<<<<<<<<<<<
+ *         BlockHandler.__init__( self )
+ *         self.chrom_id = chrom_id
+ */
+
+  /* function exit code */
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_AddTraceback("bx.bbi.bigbed_file.BigBedBlockHandler.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = -1;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bbi/bigbed_file.pyx":56
+ *         self.start = start
+ *         self.end = end
+ *     cdef handle_block( self, str block_data, BBIFile bbi_file ):             # <<<<<<<<<<<<<<
+ *         cdef object string_io
+ *         cdef int length
+ */
+
+static PyObject *__pyx_f_2bx_3bbi_11bigbed_file_18BigBedBlockHandler_handle_block(struct __pyx_obj_2bx_3bbi_11bigbed_file_BigBedBlockHandler *__pyx_v_self, PyObject *__pyx_v_block_data, struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *__pyx_v_bbi_file) {
+  PyObject *__pyx_v_string_io = 0;
+  int __pyx_v_length;
+  __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_chrom_id;
+  __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_s;
+  __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_e;
+  PyObject *__pyx_v_rest = 0;
+  PyObject *__pyx_v_block_reader = NULL;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  Py_ssize_t __pyx_t_5;
+  int __pyx_t_6;
+  PyObject *__pyx_t_7 = NULL;
+  PyObject *(*__pyx_t_8)(PyObject *);
+  __pyx_t_2bx_3bbi_5types_bits32 __pyx_t_9;
+  __pyx_t_2bx_3bbi_5types_bits32 __pyx_t_10;
+  __pyx_t_2bx_3bbi_5types_bits32 __pyx_t_11;
+  int __pyx_t_12;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("handle_block", 0);
+
+  /* "bx/bbi/bigbed_file.pyx":62
+ *         cdef str rest
+ *         # Now we parse the block, which should just be a bunch of BED records
+ *         string_io = StringIO( block_data )             # <<<<<<<<<<<<<<
+ *         block_reader = BinaryFileReader( string_io, is_little_endian=bbi_file.reader.is_little_endian )
+ *         length = len( block_data )
+ */
+  __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_StringIO); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 62; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = NULL;
+  if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_2))) {
+    __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2);
+    if (likely(__pyx_t_3)) {
+      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+      __Pyx_INCREF(__pyx_t_3);
+      __Pyx_INCREF(function);
+      __Pyx_DECREF_SET(__pyx_t_2, function);
+    }
+  }
+  if (!__pyx_t_3) {
+    __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_v_block_data); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 62; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+  } else {
+    __pyx_t_4 = PyTuple_New(1+1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 62; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3); __Pyx_GIVEREF(__pyx_t_3); __pyx_t_3 = NULL;
+    __Pyx_INCREF(__pyx_v_block_data);
+    PyTuple_SET_ITEM(__pyx_t_4, 0+1, __pyx_v_block_data);
+    __Pyx_GIVEREF(__pyx_v_block_data);
+    __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_4, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 62; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  }
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_v_string_io = __pyx_t_1;
+  __pyx_t_1 = 0;
+
+  /* "bx/bbi/bigbed_file.pyx":63
+ *         # Now we parse the block, which should just be a bunch of BED records
+ *         string_io = StringIO( block_data )
+ *         block_reader = BinaryFileReader( string_io, is_little_endian=bbi_file.reader.is_little_endian )             # <<<<<<<<<<<<<<
+ *         length = len( block_data )
+ *         while string_io.tell() < length:
+ */
+  __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_BinaryFileReader); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 63; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 63; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_INCREF(__pyx_v_string_io);
+  PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_string_io);
+  __Pyx_GIVEREF(__pyx_v_string_io);
+  __pyx_t_4 = PyDict_New(); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 63; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_bbi_file->reader, __pyx_n_s_is_little_endian); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 63; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_is_little_endian, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 63; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_2, __pyx_t_4); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 63; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  __pyx_v_block_reader = __pyx_t_3;
+  __pyx_t_3 = 0;
+
+  /* "bx/bbi/bigbed_file.pyx":64
+ *         string_io = StringIO( block_data )
+ *         block_reader = BinaryFileReader( string_io, is_little_endian=bbi_file.reader.is_little_endian )
+ *         length = len( block_data )             # <<<<<<<<<<<<<<
+ *         while string_io.tell() < length:
+ *             chrom_id, s, e = block_reader.read_and_unpack("LLL", 12)
+ */
+  __pyx_t_5 = PyObject_Length(__pyx_v_block_data); if (unlikely(__pyx_t_5 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 64; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_v_length = __pyx_t_5;
+
+  /* "bx/bbi/bigbed_file.pyx":65
+ *         block_reader = BinaryFileReader( string_io, is_little_endian=bbi_file.reader.is_little_endian )
+ *         length = len( block_data )
+ *         while string_io.tell() < length:             # <<<<<<<<<<<<<<
+ *             chrom_id, s, e = block_reader.read_and_unpack("LLL", 12)
+ *             rest = read_c_string(string_io)
+ */
+  while (1) {
+    __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_string_io, __pyx_n_s_tell); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 65; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    __pyx_t_2 = NULL;
+    if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_4))) {
+      __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_4);
+      if (likely(__pyx_t_2)) {
+        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
+        __Pyx_INCREF(__pyx_t_2);
+        __Pyx_INCREF(function);
+        __Pyx_DECREF_SET(__pyx_t_4, function);
+      }
+    }
+    if (__pyx_t_2) {
+      __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 65; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    } else {
+      __pyx_t_3 = __Pyx_PyObject_CallNoArg(__pyx_t_4); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 65; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    __pyx_t_4 = __Pyx_PyInt_From_int(__pyx_v_length); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 65; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    __pyx_t_2 = PyObject_RichCompare(__pyx_t_3, __pyx_t_4, Py_LT); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 65; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 65; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    if (!__pyx_t_6) break;
+
+    /* "bx/bbi/bigbed_file.pyx":66
+ *         length = len( block_data )
+ *         while string_io.tell() < length:
+ *             chrom_id, s, e = block_reader.read_and_unpack("LLL", 12)             # <<<<<<<<<<<<<<
+ *             rest = read_c_string(string_io)
+ * 
+ */
+    __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_block_reader, __pyx_n_s_read_and_unpack); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 66; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_tuple__4, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 66; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    if ((likely(PyTuple_CheckExact(__pyx_t_4))) || (PyList_CheckExact(__pyx_t_4))) {
+      PyObject* sequence = __pyx_t_4;
+      #if CYTHON_COMPILING_IN_CPYTHON
+      Py_ssize_t size = Py_SIZE(sequence);
+      #else
+      Py_ssize_t size = PySequence_Size(sequence);
+      #endif
+      if (unlikely(size != 3)) {
+        if (size > 3) __Pyx_RaiseTooManyValuesError(3);
+        else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
+        {__pyx_filename = __pyx_f[0]; __pyx_lineno = 66; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      }
+      #if CYTHON_COMPILING_IN_CPYTHON
+      if (likely(PyTuple_CheckExact(sequence))) {
+        __pyx_t_2 = PyTuple_GET_ITEM(sequence, 0); 
+        __pyx_t_3 = PyTuple_GET_ITEM(sequence, 1); 
+        __pyx_t_1 = PyTuple_GET_ITEM(sequence, 2); 
+      } else {
+        __pyx_t_2 = PyList_GET_ITEM(sequence, 0); 
+        __pyx_t_3 = PyList_GET_ITEM(sequence, 1); 
+        __pyx_t_1 = PyList_GET_ITEM(sequence, 2); 
+      }
+      __Pyx_INCREF(__pyx_t_2);
+      __Pyx_INCREF(__pyx_t_3);
+      __Pyx_INCREF(__pyx_t_1);
+      #else
+      __pyx_t_2 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 66; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_2);
+      __pyx_t_3 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 66; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_1 = PySequence_ITEM(sequence, 2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 66; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_1);
+      #endif
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    } else {
+      Py_ssize_t index = -1;
+      __pyx_t_7 = PyObject_GetIter(__pyx_t_4); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 66; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_7);
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      __pyx_t_8 = Py_TYPE(__pyx_t_7)->tp_iternext;
+      index = 0; __pyx_t_2 = __pyx_t_8(__pyx_t_7); if (unlikely(!__pyx_t_2)) goto __pyx_L5_unpacking_failed;
+      __Pyx_GOTREF(__pyx_t_2);
+      index = 1; __pyx_t_3 = __pyx_t_8(__pyx_t_7); if (unlikely(!__pyx_t_3)) goto __pyx_L5_unpacking_failed;
+      __Pyx_GOTREF(__pyx_t_3);
+      index = 2; __pyx_t_1 = __pyx_t_8(__pyx_t_7); if (unlikely(!__pyx_t_1)) goto __pyx_L5_unpacking_failed;
+      __Pyx_GOTREF(__pyx_t_1);
+      if (__Pyx_IternextUnpackEndCheck(__pyx_t_8(__pyx_t_7), 3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 66; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_8 = NULL;
+      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+      goto __pyx_L6_unpacking_done;
+      __pyx_L5_unpacking_failed:;
+      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+      __pyx_t_8 = NULL;
+      if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
+      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 66; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_L6_unpacking_done:;
+    }
+    __pyx_t_9 = __Pyx_PyInt_As_unsigned_int(__pyx_t_2); if (unlikely((__pyx_t_9 == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 66; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    __pyx_t_10 = __Pyx_PyInt_As_unsigned_int(__pyx_t_3); if (unlikely((__pyx_t_10 == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 66; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __pyx_t_11 = __Pyx_PyInt_As_unsigned_int(__pyx_t_1); if (unlikely((__pyx_t_11 == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 66; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    __pyx_v_chrom_id = __pyx_t_9;
+    __pyx_v_s = __pyx_t_10;
+    __pyx_v_e = __pyx_t_11;
+
+    /* "bx/bbi/bigbed_file.pyx":67
+ *         while string_io.tell() < length:
+ *             chrom_id, s, e = block_reader.read_and_unpack("LLL", 12)
+ *             rest = read_c_string(string_io)             # <<<<<<<<<<<<<<
+ * 
+ *             if chrom_id != self.chrom_id:
+ */
+    __pyx_t_4 = __pyx_f_2bx_3bbi_11bigbed_file_read_c_string(__pyx_v_string_io); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 67; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    __Pyx_XDECREF_SET(__pyx_v_rest, ((PyObject*)__pyx_t_4));
+    __pyx_t_4 = 0;
+
+    /* "bx/bbi/bigbed_file.pyx":69
+ *             rest = read_c_string(string_io)
+ * 
+ *             if chrom_id != self.chrom_id:             # <<<<<<<<<<<<<<
+ *                 continue
+ *             if s < self.end and e > self.start:
+ */
+    __pyx_t_6 = ((__pyx_v_chrom_id != __pyx_v_self->chrom_id) != 0);
+    if (__pyx_t_6) {
+
+      /* "bx/bbi/bigbed_file.pyx":70
+ * 
+ *             if chrom_id != self.chrom_id:
+ *                 continue             # <<<<<<<<<<<<<<
+ *             if s < self.end and e > self.start:
+ *                 self.handle_interval_value( s, e, rest )
+ */
+      goto __pyx_L3_continue;
+    }
+
+    /* "bx/bbi/bigbed_file.pyx":71
+ *             if chrom_id != self.chrom_id:
+ *                 continue
+ *             if s < self.end and e > self.start:             # <<<<<<<<<<<<<<
+ *                 self.handle_interval_value( s, e, rest )
+ *     cdef handle_interval_value( self, bits32 s, bits32 e, str rest ):
+ */
+    __pyx_t_12 = ((__pyx_v_s < __pyx_v_self->end) != 0);
+    if (__pyx_t_12) {
+    } else {
+      __pyx_t_6 = __pyx_t_12;
+      goto __pyx_L9_bool_binop_done;
+    }
+    __pyx_t_12 = ((__pyx_v_e > __pyx_v_self->start) != 0);
+    __pyx_t_6 = __pyx_t_12;
+    __pyx_L9_bool_binop_done:;
+    if (__pyx_t_6) {
+
+      /* "bx/bbi/bigbed_file.pyx":72
+ *                 continue
+ *             if s < self.end and e > self.start:
+ *                 self.handle_interval_value( s, e, rest )             # <<<<<<<<<<<<<<
+ *     cdef handle_interval_value( self, bits32 s, bits32 e, str rest ):
+ *         pass
+ */
+      __pyx_t_4 = ((struct __pyx_vtabstruct_2bx_3bbi_11bigbed_file_BigBedBlockHandler *)__pyx_v_self->__pyx_base.__pyx_vtab)->handle_interval_value(__pyx_v_self, __pyx_v_s, __pyx_v_e, __pyx_v_rest); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 72; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      goto __pyx_L8;
+    }
+    __pyx_L8:;
+    __pyx_L3_continue:;
+  }
+
+  /* "bx/bbi/bigbed_file.pyx":56
+ *         self.start = start
+ *         self.end = end
+ *     cdef handle_block( self, str block_data, BBIFile bbi_file ):             # <<<<<<<<<<<<<<
+ *         cdef object string_io
+ *         cdef int length
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_XDECREF(__pyx_t_7);
+  __Pyx_AddTraceback("bx.bbi.bigbed_file.BigBedBlockHandler.handle_block", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_string_io);
+  __Pyx_XDECREF(__pyx_v_rest);
+  __Pyx_XDECREF(__pyx_v_block_reader);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bbi/bigbed_file.pyx":73
+ *             if s < self.end and e > self.start:
+ *                 self.handle_interval_value( s, e, rest )
+ *     cdef handle_interval_value( self, bits32 s, bits32 e, str rest ):             # <<<<<<<<<<<<<<
+ *         pass
+ * 
+ */
+
+static PyObject *__pyx_f_2bx_3bbi_11bigbed_file_18BigBedBlockHandler_handle_interval_value(CYTHON_UNUSED struct __pyx_obj_2bx_3bbi_11bigbed_file_BigBedBlockHandler *__pyx_v_self, CYTHON_UNUSED __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_s, CYTHON_UNUSED __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_e, CYTHON_UNUSED PyObject *__pyx_v_rest) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("handle_interval_value", 0);
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bbi/bigbed_file.pyx":81
+ *     """
+ *     cdef SummarizedData sd
+ *     def __init__( self, bits32 chrom_id, bits32 start, bits32 end, int summary_size ):             # <<<<<<<<<<<<<<
+ *         BigBedBlockHandler.__init__( self, chrom_id, start, end )
+ *         # What we will load into
+ */
+
+/* Python wrapper */
+static int __pyx_pw_2bx_3bbi_11bigbed_file_23SummarizingBlockHandler_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static int __pyx_pw_2bx_3bbi_11bigbed_file_23SummarizingBlockHandler_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_chrom_id;
+  __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_start;
+  __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_end;
+  int __pyx_v_summary_size;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__init__ (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_chrom_id,&__pyx_n_s_start,&__pyx_n_s_end,&__pyx_n_s_summary_size,0};
+    PyObject* values[4] = {0,0,0,0};
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_chrom_id)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_start)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("__init__", 1, 4, 4, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 81; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+        case  2:
+        if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_end)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("__init__", 1, 4, 4, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 81; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+        case  3:
+        if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_summary_size)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("__init__", 1, 4, 4, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 81; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 81; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else if (PyTuple_GET_SIZE(__pyx_args) != 4) {
+      goto __pyx_L5_argtuple_error;
+    } else {
+      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+      values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+      values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+    }
+    __pyx_v_chrom_id = __Pyx_PyInt_As_unsigned_int(values[0]); if (unlikely((__pyx_v_chrom_id == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 81; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_start = __Pyx_PyInt_As_unsigned_int(values[1]); if (unlikely((__pyx_v_start == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 81; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_end = __Pyx_PyInt_As_unsigned_int(values[2]); if (unlikely((__pyx_v_end == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 81; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_summary_size = __Pyx_PyInt_As_int(values[3]); if (unlikely((__pyx_v_summary_size == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 81; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("__init__", 1, 4, 4, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 81; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.bbi.bigbed_file.SummarizingBlockHandler.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return -1;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_3bbi_11bigbed_file_23SummarizingBlockHandler___init__(((struct __pyx_obj_2bx_3bbi_11bigbed_file_SummarizingBlockHandler *)__pyx_v_self), __pyx_v_chrom_id, __pyx_v_start, __pyx_v_end, __pyx_v_summary_size);
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_2bx_3bbi_11bigbed_file_23SummarizingBlockHandler___init__(struct __pyx_obj_2bx_3bbi_11bigbed_file_SummarizingBlockHandler *__pyx_v_self, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_chrom_id, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_start, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_end, int __pyx_v_summary_size) {
+  int __pyx_v_i;
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  PyObject *__pyx_t_5 = NULL;
+  PyObject *__pyx_t_6 = NULL;
+  Py_ssize_t __pyx_t_7;
+  PyObject *__pyx_t_8 = NULL;
+  int __pyx_t_9;
+  int __pyx_t_10;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__init__", 0);
+
+  /* "bx/bbi/bigbed_file.pyx":82
+ *     cdef SummarizedData sd
+ *     def __init__( self, bits32 chrom_id, bits32 start, bits32 end, int summary_size ):
+ *         BigBedBlockHandler.__init__( self, chrom_id, start, end )             # <<<<<<<<<<<<<<
+ *         # What we will load into
+ *         self.sd = SummarizedData( start, end, summary_size )
+ */
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(((PyObject *)((PyObject*)__pyx_ptype_2bx_3bbi_11bigbed_file_BigBedBlockHandler)), __pyx_n_s_init); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 82; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = __Pyx_PyInt_From_unsigned_int(__pyx_v_chrom_id); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 82; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_4 = __Pyx_PyInt_From_unsigned_int(__pyx_v_start); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 82; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __pyx_t_5 = __Pyx_PyInt_From_unsigned_int(__pyx_v_end); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 82; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __pyx_t_6 = NULL;
+  __pyx_t_7 = 0;
+  if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_2))) {
+    __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_2);
+    if (likely(__pyx_t_6)) {
+      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+      __Pyx_INCREF(__pyx_t_6);
+      __Pyx_INCREF(function);
+      __Pyx_DECREF_SET(__pyx_t_2, function);
+      __pyx_t_7 = 1;
+    }
+  }
+  __pyx_t_8 = PyTuple_New(4+__pyx_t_7); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 82; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_8);
+  if (__pyx_t_6) {
+    PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_6); __Pyx_GIVEREF(__pyx_t_6); __pyx_t_6 = NULL;
+  }
+  __Pyx_INCREF(((PyObject *)__pyx_v_self));
+  PyTuple_SET_ITEM(__pyx_t_8, 0+__pyx_t_7, ((PyObject *)__pyx_v_self));
+  __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
+  PyTuple_SET_ITEM(__pyx_t_8, 1+__pyx_t_7, __pyx_t_3);
+  __Pyx_GIVEREF(__pyx_t_3);
+  PyTuple_SET_ITEM(__pyx_t_8, 2+__pyx_t_7, __pyx_t_4);
+  __Pyx_GIVEREF(__pyx_t_4);
+  PyTuple_SET_ITEM(__pyx_t_8, 3+__pyx_t_7, __pyx_t_5);
+  __Pyx_GIVEREF(__pyx_t_5);
+  __pyx_t_3 = 0;
+  __pyx_t_4 = 0;
+  __pyx_t_5 = 0;
+  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_8, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 82; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "bx/bbi/bigbed_file.pyx":84
+ *         BigBedBlockHandler.__init__( self, chrom_id, start, end )
+ *         # What we will load into
+ *         self.sd = SummarizedData( start, end, summary_size )             # <<<<<<<<<<<<<<
+ *         for i in range(summary_size):
+ *             self.sd.min_val[i] = +np.inf
+ */
+  __pyx_t_1 = __Pyx_PyInt_From_unsigned_int(__pyx_v_start); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 84; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = __Pyx_PyInt_From_unsigned_int(__pyx_v_end); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 84; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_8 = __Pyx_PyInt_From_int(__pyx_v_summary_size); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 84; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_8);
+  __pyx_t_5 = PyTuple_New(3); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 84; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_1);
+  __Pyx_GIVEREF(__pyx_t_1);
+  PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_t_2);
+  __Pyx_GIVEREF(__pyx_t_2);
+  PyTuple_SET_ITEM(__pyx_t_5, 2, __pyx_t_8);
+  __Pyx_GIVEREF(__pyx_t_8);
+  __pyx_t_1 = 0;
+  __pyx_t_2 = 0;
+  __pyx_t_8 = 0;
+  __pyx_t_8 = __Pyx_PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_2bx_3bbi_8bbi_file_SummarizedData)), __pyx_t_5, NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 84; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_8);
+  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+  __Pyx_GIVEREF(__pyx_t_8);
+  __Pyx_GOTREF(__pyx_v_self->sd);
+  __Pyx_DECREF(((PyObject *)__pyx_v_self->sd));
+  __pyx_v_self->sd = ((struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData *)__pyx_t_8);
+  __pyx_t_8 = 0;
+
+  /* "bx/bbi/bigbed_file.pyx":85
+ *         # What we will load into
+ *         self.sd = SummarizedData( start, end, summary_size )
+ *         for i in range(summary_size):             # <<<<<<<<<<<<<<
+ *             self.sd.min_val[i] = +np.inf
+ *         for i in range(summary_size):
+ */
+  __pyx_t_9 = __pyx_v_summary_size;
+  for (__pyx_t_10 = 0; __pyx_t_10 < __pyx_t_9; __pyx_t_10+=1) {
+    __pyx_v_i = __pyx_t_10;
+
+    /* "bx/bbi/bigbed_file.pyx":86
+ *         self.sd = SummarizedData( start, end, summary_size )
+ *         for i in range(summary_size):
+ *             self.sd.min_val[i] = +np.inf             # <<<<<<<<<<<<<<
+ *         for i in range(summary_size):
+ *             self.sd.max_val[i] = -np.inf
+ */
+    __pyx_t_8 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 86; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_8);
+    __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_8, __pyx_n_s_inf); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 86; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_5);
+    __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+    __pyx_t_8 = PyNumber_Positive(__pyx_t_5); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 86; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_8);
+    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+    if (unlikely(__Pyx_SetItemInt(((PyObject *)__pyx_v_self->sd->min_val), __pyx_v_i, __pyx_t_8, int, 1, __Pyx_PyInt_From_int, 0, 1, 1) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 86; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+  }
+
+  /* "bx/bbi/bigbed_file.pyx":87
+ *         for i in range(summary_size):
+ *             self.sd.min_val[i] = +np.inf
+ *         for i in range(summary_size):             # <<<<<<<<<<<<<<
+ *             self.sd.max_val[i] = -np.inf
+ * 
+ */
+  __pyx_t_9 = __pyx_v_summary_size;
+  for (__pyx_t_10 = 0; __pyx_t_10 < __pyx_t_9; __pyx_t_10+=1) {
+    __pyx_v_i = __pyx_t_10;
+
+    /* "bx/bbi/bigbed_file.pyx":88
+ *             self.sd.min_val[i] = +np.inf
+ *         for i in range(summary_size):
+ *             self.sd.max_val[i] = -np.inf             # <<<<<<<<<<<<<<
+ * 
+ *     cdef handle_interval_value( self, bits32 s, bits32 e, str rest ):
+ */
+    __pyx_t_8 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 88; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_8);
+    __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_8, __pyx_n_s_inf); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 88; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_5);
+    __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+    __pyx_t_8 = PyNumber_Negative(__pyx_t_5); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 88; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_8);
+    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+    if (unlikely(__Pyx_SetItemInt(((PyObject *)__pyx_v_self->sd->max_val), __pyx_v_i, __pyx_t_8, int, 1, __Pyx_PyInt_From_int, 0, 1, 1) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 88; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+  }
+
+  /* "bx/bbi/bigbed_file.pyx":81
+ *     """
+ *     cdef SummarizedData sd
+ *     def __init__( self, bits32 chrom_id, bits32 start, bits32 end, int summary_size ):             # <<<<<<<<<<<<<<
+ *         BigBedBlockHandler.__init__( self, chrom_id, start, end )
+ *         # What we will load into
+ */
+
+  /* function exit code */
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_XDECREF(__pyx_t_5);
+  __Pyx_XDECREF(__pyx_t_6);
+  __Pyx_XDECREF(__pyx_t_8);
+  __Pyx_AddTraceback("bx.bbi.bigbed_file.SummarizingBlockHandler.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = -1;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bbi/bigbed_file.pyx":90
+ *             self.sd.max_val[i] = -np.inf
+ * 
+ *     cdef handle_interval_value( self, bits32 s, bits32 e, str rest ):             # <<<<<<<<<<<<<<
+ *         # FIXME: Does this really obvious thing actually do what we want?
+ *         #        No... sum_data will end up being the coverage, but min/max/etc are wrong
+ */
+
+static PyObject *__pyx_f_2bx_3bbi_11bigbed_file_23SummarizingBlockHandler_handle_interval_value(struct __pyx_obj_2bx_3bbi_11bigbed_file_SummarizingBlockHandler *__pyx_v_self, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_s, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_e, CYTHON_UNUSED PyObject *__pyx_v_rest) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("handle_interval_value", 0);
+
+  /* "bx/bbi/bigbed_file.pyx":93
+ *         # FIXME: Does this really obvious thing actually do what we want?
+ *         #        No... sum_data will end up being the coverage, but min/max/etc are wrong
+ *         self.sd.accumulate_interval_value( s, e, 1 )             # <<<<<<<<<<<<<<
+ * 
+ * cdef class IntervalAccumulatingBlockHandler( BigBedBlockHandler ):
+ */
+  __pyx_t_1 = ((struct __pyx_vtabstruct_2bx_3bbi_8bbi_file_SummarizedData *)__pyx_v_self->sd->__pyx_vtab)->accumulate_interval_value(__pyx_v_self->sd, __pyx_v_s, __pyx_v_e, 1.0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 93; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "bx/bbi/bigbed_file.pyx":90
+ *             self.sd.max_val[i] = -np.inf
+ * 
+ *     cdef handle_interval_value( self, bits32 s, bits32 e, str rest ):             # <<<<<<<<<<<<<<
+ *         # FIXME: Does this really obvious thing actually do what we want?
+ *         #        No... sum_data will end up being the coverage, but min/max/etc are wrong
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("bx.bbi.bigbed_file.SummarizingBlockHandler.handle_interval_value", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bbi/bigbed_file.pyx":100
+ *     Accumulates intervals into a list of intervals with values
+ *     """
+ *     def __init__( self, bits32 chrom_id, bits32 start, bits32 end ):             # <<<<<<<<<<<<<<
+ *         BigBedBlockHandler.__init__( self, chrom_id, start, end )
+ *         self.intervals = []
+ */
+
+/* Python wrapper */
+static int __pyx_pw_2bx_3bbi_11bigbed_file_32IntervalAccumulatingBlockHandler_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static int __pyx_pw_2bx_3bbi_11bigbed_file_32IntervalAccumulatingBlockHandler_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_chrom_id;
+  __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_start;
+  __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_end;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__init__ (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_chrom_id,&__pyx_n_s_start,&__pyx_n_s_end,0};
+    PyObject* values[3] = {0,0,0};
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_chrom_id)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_start)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("__init__", 1, 3, 3, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 100; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+        case  2:
+        if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_end)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("__init__", 1, 3, 3, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 100; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 100; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else if (PyTuple_GET_SIZE(__pyx_args) != 3) {
+      goto __pyx_L5_argtuple_error;
+    } else {
+      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+      values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+    }
+    __pyx_v_chrom_id = __Pyx_PyInt_As_unsigned_int(values[0]); if (unlikely((__pyx_v_chrom_id == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 100; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_start = __Pyx_PyInt_As_unsigned_int(values[1]); if (unlikely((__pyx_v_start == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 100; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_end = __Pyx_PyInt_As_unsigned_int(values[2]); if (unlikely((__pyx_v_end == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 100; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("__init__", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 100; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.bbi.bigbed_file.IntervalAccumulatingBlockHandler.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return -1;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_3bbi_11bigbed_file_32IntervalAccumulatingBlockHandler___init__(((struct __pyx_obj_2bx_3bbi_11bigbed_file_IntervalAccumulatingBlockHandler *)__pyx_v_self), __pyx_v_chrom_id, __pyx_v_start, __pyx_v_end);
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_2bx_3bbi_11bigbed_file_32IntervalAccumulatingBlockHandler___init__(struct __pyx_obj_2bx_3bbi_11bigbed_file_IntervalAccumulatingBlockHandler *__pyx_v_self, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_chrom_id, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_start, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_end) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  PyObject *__pyx_t_5 = NULL;
+  PyObject *__pyx_t_6 = NULL;
+  Py_ssize_t __pyx_t_7;
+  PyObject *__pyx_t_8 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__init__", 0);
+
+  /* "bx/bbi/bigbed_file.pyx":101
+ *     """
+ *     def __init__( self, bits32 chrom_id, bits32 start, bits32 end ):
+ *         BigBedBlockHandler.__init__( self, chrom_id, start, end )             # <<<<<<<<<<<<<<
+ *         self.intervals = []
+ * 
+ */
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(((PyObject *)((PyObject*)__pyx_ptype_2bx_3bbi_11bigbed_file_BigBedBlockHandler)), __pyx_n_s_init); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 101; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = __Pyx_PyInt_From_unsigned_int(__pyx_v_chrom_id); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 101; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_4 = __Pyx_PyInt_From_unsigned_int(__pyx_v_start); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 101; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __pyx_t_5 = __Pyx_PyInt_From_unsigned_int(__pyx_v_end); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 101; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __pyx_t_6 = NULL;
+  __pyx_t_7 = 0;
+  if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_2))) {
+    __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_2);
+    if (likely(__pyx_t_6)) {
+      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+      __Pyx_INCREF(__pyx_t_6);
+      __Pyx_INCREF(function);
+      __Pyx_DECREF_SET(__pyx_t_2, function);
+      __pyx_t_7 = 1;
+    }
+  }
+  __pyx_t_8 = PyTuple_New(4+__pyx_t_7); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 101; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_8);
+  if (__pyx_t_6) {
+    PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_6); __Pyx_GIVEREF(__pyx_t_6); __pyx_t_6 = NULL;
+  }
+  __Pyx_INCREF(((PyObject *)__pyx_v_self));
+  PyTuple_SET_ITEM(__pyx_t_8, 0+__pyx_t_7, ((PyObject *)__pyx_v_self));
+  __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
+  PyTuple_SET_ITEM(__pyx_t_8, 1+__pyx_t_7, __pyx_t_3);
+  __Pyx_GIVEREF(__pyx_t_3);
+  PyTuple_SET_ITEM(__pyx_t_8, 2+__pyx_t_7, __pyx_t_4);
+  __Pyx_GIVEREF(__pyx_t_4);
+  PyTuple_SET_ITEM(__pyx_t_8, 3+__pyx_t_7, __pyx_t_5);
+  __Pyx_GIVEREF(__pyx_t_5);
+  __pyx_t_3 = 0;
+  __pyx_t_4 = 0;
+  __pyx_t_5 = 0;
+  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_8, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 101; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "bx/bbi/bigbed_file.pyx":102
+ *     def __init__( self, bits32 chrom_id, bits32 start, bits32 end ):
+ *         BigBedBlockHandler.__init__( self, chrom_id, start, end )
+ *         self.intervals = []             # <<<<<<<<<<<<<<
+ * 
+ *     cdef handle_interval_value( self, bits32 s, bits32 e, str rest ):
+ */
+  __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 102; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_GIVEREF(__pyx_t_1);
+  __Pyx_GOTREF(__pyx_v_self->intervals);
+  __Pyx_DECREF(__pyx_v_self->intervals);
+  __pyx_v_self->intervals = ((PyObject*)__pyx_t_1);
+  __pyx_t_1 = 0;
+
+  /* "bx/bbi/bigbed_file.pyx":100
+ *     Accumulates intervals into a list of intervals with values
+ *     """
+ *     def __init__( self, bits32 chrom_id, bits32 start, bits32 end ):             # <<<<<<<<<<<<<<
+ *         BigBedBlockHandler.__init__( self, chrom_id, start, end )
+ *         self.intervals = []
+ */
+
+  /* function exit code */
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_XDECREF(__pyx_t_5);
+  __Pyx_XDECREF(__pyx_t_6);
+  __Pyx_XDECREF(__pyx_t_8);
+  __Pyx_AddTraceback("bx.bbi.bigbed_file.IntervalAccumulatingBlockHandler.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = -1;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bbi/bigbed_file.pyx":104
+ *         self.intervals = []
+ * 
+ *     cdef handle_interval_value( self, bits32 s, bits32 e, str rest ):             # <<<<<<<<<<<<<<
+ *         self.intervals.append( ( s, e, rest ) )
+ * 
+ */
+
+static PyObject *__pyx_f_2bx_3bbi_11bigbed_file_32IntervalAccumulatingBlockHandler_handle_interval_value(struct __pyx_obj_2bx_3bbi_11bigbed_file_IntervalAccumulatingBlockHandler *__pyx_v_self, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_s, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_e, PyObject *__pyx_v_rest) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  int __pyx_t_4;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("handle_interval_value", 0);
+
+  /* "bx/bbi/bigbed_file.pyx":105
+ * 
+ *     cdef handle_interval_value( self, bits32 s, bits32 e, str rest ):
+ *         self.intervals.append( ( s, e, rest ) )             # <<<<<<<<<<<<<<
+ * 
+ * cdef class BigBedFile( BBIFile ):
+ */
+  if (unlikely(__pyx_v_self->intervals == Py_None)) {
+    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "append");
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 105; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  __pyx_t_1 = __Pyx_PyInt_From_unsigned_int(__pyx_v_s); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 105; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = __Pyx_PyInt_From_unsigned_int(__pyx_v_e); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 105; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = PyTuple_New(3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 105; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1);
+  __Pyx_GIVEREF(__pyx_t_1);
+  PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_2);
+  __Pyx_GIVEREF(__pyx_t_2);
+  __Pyx_INCREF(__pyx_v_rest);
+  PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_v_rest);
+  __Pyx_GIVEREF(__pyx_v_rest);
+  __pyx_t_1 = 0;
+  __pyx_t_2 = 0;
+  __pyx_t_4 = __Pyx_PyList_Append(__pyx_v_self->intervals, __pyx_t_3); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 105; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+  /* "bx/bbi/bigbed_file.pyx":104
+ *         self.intervals = []
+ * 
+ *     cdef handle_interval_value( self, bits32 s, bits32 e, str rest ):             # <<<<<<<<<<<<<<
+ *         self.intervals.append( ( s, e, rest ) )
+ * 
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_AddTraceback("bx.bbi.bigbed_file.IntervalAccumulatingBlockHandler.handle_interval_value", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bbi/bigbed_file.pyx":111
+ *     A "big binary indexed" file whose raw data is in BED format.
+ *     """
+ *     def __init__( self, file=None ):             # <<<<<<<<<<<<<<
+ *         BBIFile.__init__( self, file, big_bed_sig, "bigbed" )
+ * 
+ */
+
+/* Python wrapper */
+static int __pyx_pw_2bx_3bbi_11bigbed_file_10BigBedFile_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static int __pyx_pw_2bx_3bbi_11bigbed_file_10BigBedFile_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_file = 0;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__init__ (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_file,0};
+    PyObject* values[1] = {0};
+    values[0] = ((PyObject *)Py_None);
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_file);
+          if (value) { values[0] = value; kw_args--; }
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 111; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else {
+      switch (PyTuple_GET_SIZE(__pyx_args)) {
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+    }
+    __pyx_v_file = values[0];
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("__init__", 0, 0, 1, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 111; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.bbi.bigbed_file.BigBedFile.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return -1;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_3bbi_11bigbed_file_10BigBedFile___init__(((struct __pyx_obj_2bx_3bbi_11bigbed_file_BigBedFile *)__pyx_v_self), __pyx_v_file);
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_2bx_3bbi_11bigbed_file_10BigBedFile___init__(struct __pyx_obj_2bx_3bbi_11bigbed_file_BigBedFile *__pyx_v_self, PyObject *__pyx_v_file) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  Py_ssize_t __pyx_t_4;
+  PyObject *__pyx_t_5 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__init__", 0);
+
+  /* "bx/bbi/bigbed_file.pyx":112
+ *     """
+ *     def __init__( self, file=None ):
+ *         BBIFile.__init__( self, file, big_bed_sig, "bigbed" )             # <<<<<<<<<<<<<<
+ * 
+ *     cdef _summarize_from_full( self, bits32 chrom_id, bits32 start, bits32 end, int summary_size ):
+ */
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(((PyObject *)((PyObject*)__pyx_ptype_2bx_3bbi_8bbi_file_BBIFile)), __pyx_n_s_init); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 112; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = NULL;
+  __pyx_t_4 = 0;
+  if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_2))) {
+    __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2);
+    if (likely(__pyx_t_3)) {
+      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+      __Pyx_INCREF(__pyx_t_3);
+      __Pyx_INCREF(function);
+      __Pyx_DECREF_SET(__pyx_t_2, function);
+      __pyx_t_4 = 1;
+    }
+  }
+  __pyx_t_5 = PyTuple_New(4+__pyx_t_4); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 112; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  if (__pyx_t_3) {
+    PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_3); __Pyx_GIVEREF(__pyx_t_3); __pyx_t_3 = NULL;
+  }
+  __Pyx_INCREF(((PyObject *)__pyx_v_self));
+  PyTuple_SET_ITEM(__pyx_t_5, 0+__pyx_t_4, ((PyObject *)__pyx_v_self));
+  __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
+  __Pyx_INCREF(__pyx_v_file);
+  PyTuple_SET_ITEM(__pyx_t_5, 1+__pyx_t_4, __pyx_v_file);
+  __Pyx_GIVEREF(__pyx_v_file);
+  __Pyx_INCREF(__pyx_int_2273964779);
+  PyTuple_SET_ITEM(__pyx_t_5, 2+__pyx_t_4, __pyx_int_2273964779);
+  __Pyx_GIVEREF(__pyx_int_2273964779);
+  __Pyx_INCREF(__pyx_n_s_bigbed);
+  PyTuple_SET_ITEM(__pyx_t_5, 3+__pyx_t_4, __pyx_n_s_bigbed);
+  __Pyx_GIVEREF(__pyx_n_s_bigbed);
+  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_5, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 112; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "bx/bbi/bigbed_file.pyx":111
+ *     A "big binary indexed" file whose raw data is in BED format.
+ *     """
+ *     def __init__( self, file=None ):             # <<<<<<<<<<<<<<
+ *         BBIFile.__init__( self, file, big_bed_sig, "bigbed" )
+ * 
+ */
+
+  /* function exit code */
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_5);
+  __Pyx_AddTraceback("bx.bbi.bigbed_file.BigBedFile.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = -1;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bbi/bigbed_file.pyx":114
+ *         BBIFile.__init__( self, file, big_bed_sig, "bigbed" )
+ * 
+ *     cdef _summarize_from_full( self, bits32 chrom_id, bits32 start, bits32 end, int summary_size ):             # <<<<<<<<<<<<<<
+ *         """
+ *         Create summary from full data.
+ */
+
+static PyObject *__pyx_f_2bx_3bbi_11bigbed_file_10BigBedFile__summarize_from_full(struct __pyx_obj_2bx_3bbi_11bigbed_file_BigBedFile *__pyx_v_self, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_chrom_id, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_start, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_end, int __pyx_v_summary_size) {
+  struct __pyx_obj_2bx_3bbi_11bigbed_file_SummarizingBlockHandler *__pyx_v_v = NULL;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  PyObject *__pyx_t_5 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("_summarize_from_full", 0);
+
+  /* "bx/bbi/bigbed_file.pyx":118
+ *         Create summary from full data.
+ *         """
+ *         v = SummarizingBlockHandler( chrom_id, start, end, summary_size )             # <<<<<<<<<<<<<<
+ *         self.visit_blocks_in_region( chrom_id, start, end, v )
+ *         np.round(v.sd.valid_count, out=v.sd.valid_count)
+ */
+  __pyx_t_1 = __Pyx_PyInt_From_unsigned_int(__pyx_v_chrom_id); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 118; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = __Pyx_PyInt_From_unsigned_int(__pyx_v_start); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 118; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = __Pyx_PyInt_From_unsigned_int(__pyx_v_end); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 118; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_4 = __Pyx_PyInt_From_int(__pyx_v_summary_size); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 118; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __pyx_t_5 = PyTuple_New(4); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 118; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_1);
+  __Pyx_GIVEREF(__pyx_t_1);
+  PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_t_2);
+  __Pyx_GIVEREF(__pyx_t_2);
+  PyTuple_SET_ITEM(__pyx_t_5, 2, __pyx_t_3);
+  __Pyx_GIVEREF(__pyx_t_3);
+  PyTuple_SET_ITEM(__pyx_t_5, 3, __pyx_t_4);
+  __Pyx_GIVEREF(__pyx_t_4);
+  __pyx_t_1 = 0;
+  __pyx_t_2 = 0;
+  __pyx_t_3 = 0;
+  __pyx_t_4 = 0;
+  __pyx_t_4 = __Pyx_PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_2bx_3bbi_11bigbed_file_SummarizingBlockHandler)), __pyx_t_5, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 118; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+  __pyx_v_v = ((struct __pyx_obj_2bx_3bbi_11bigbed_file_SummarizingBlockHandler *)__pyx_t_4);
+  __pyx_t_4 = 0;
+
+  /* "bx/bbi/bigbed_file.pyx":119
+ *         """
+ *         v = SummarizingBlockHandler( chrom_id, start, end, summary_size )
+ *         self.visit_blocks_in_region( chrom_id, start, end, v )             # <<<<<<<<<<<<<<
+ *         np.round(v.sd.valid_count, out=v.sd.valid_count)
+ *         return v.sd
+ */
+  __pyx_t_4 = ((struct __pyx_vtabstruct_2bx_3bbi_11bigbed_file_BigBedFile *)__pyx_v_self->__pyx_base.__pyx_vtab)->__pyx_base.visit_blocks_in_region(((struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *)__pyx_v_self), __pyx_v_chrom_id, __pyx_v_start, __pyx_v_end, ((struct __pyx_obj_2bx_3bbi_8bbi_file_BlockHandler *)__pyx_v_v)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+
+  /* "bx/bbi/bigbed_file.pyx":120
+ *         v = SummarizingBlockHandler( chrom_id, start, end, summary_size )
+ *         self.visit_blocks_in_region( chrom_id, start, end, v )
+ *         np.round(v.sd.valid_count, out=v.sd.valid_count)             # <<<<<<<<<<<<<<
+ *         return v.sd
+ * 
+ */
+  __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_round); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __Pyx_INCREF(((PyObject *)__pyx_v_v->sd->valid_count));
+  PyTuple_SET_ITEM(__pyx_t_4, 0, ((PyObject *)__pyx_v_v->sd->valid_count));
+  __Pyx_GIVEREF(((PyObject *)__pyx_v_v->sd->valid_count));
+  __pyx_t_3 = PyDict_New(); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_out, ((PyObject *)__pyx_v_v->sd->valid_count)) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_4, __pyx_t_3); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+  /* "bx/bbi/bigbed_file.pyx":121
+ *         self.visit_blocks_in_region( chrom_id, start, end, v )
+ *         np.round(v.sd.valid_count, out=v.sd.valid_count)
+ *         return v.sd             # <<<<<<<<<<<<<<
+ * 
+ *     cpdef get( self, char * chrom, bits32 start, bits32 end ):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __Pyx_INCREF(((PyObject *)__pyx_v_v->sd));
+  __pyx_r = ((PyObject *)__pyx_v_v->sd);
+  goto __pyx_L0;
+
+  /* "bx/bbi/bigbed_file.pyx":114
+ *         BBIFile.__init__( self, file, big_bed_sig, "bigbed" )
+ * 
+ *     cdef _summarize_from_full( self, bits32 chrom_id, bits32 start, bits32 end, int summary_size ):             # <<<<<<<<<<<<<<
+ *         """
+ *         Create summary from full data.
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_XDECREF(__pyx_t_5);
+  __Pyx_AddTraceback("bx.bbi.bigbed_file.BigBedFile._summarize_from_full", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XDECREF((PyObject *)__pyx_v_v);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bbi/bigbed_file.pyx":123
+ *         return v.sd
+ * 
+ *     cpdef get( self, char * chrom, bits32 start, bits32 end ):             # <<<<<<<<<<<<<<
+ *         """
+ *         Gets all data points over the regions `chrom`:`start`-`end`.
+ */
+
+static PyObject *__pyx_pw_2bx_3bbi_11bigbed_file_10BigBedFile_3get(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyObject *__pyx_f_2bx_3bbi_11bigbed_file_10BigBedFile_get(struct __pyx_obj_2bx_3bbi_11bigbed_file_BigBedFile *__pyx_v_self, char *__pyx_v_chrom, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_start, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_end, int __pyx_skip_dispatch) {
+  PyObject *__pyx_v_chrom_id = NULL;
+  CYTHON_UNUSED PyObject *__pyx_v_chrom_size = NULL;
+  struct __pyx_obj_2bx_3bbi_11bigbed_file_IntervalAccumulatingBlockHandler *__pyx_v_v = NULL;
+  PyObject *__pyx_v_rval = NULL;
+  PyObject *__pyx_v_s = NULL;
+  PyObject *__pyx_v_e = NULL;
+  PyObject *__pyx_v_rest = NULL;
+  PyObject *__pyx_v_fields = NULL;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  PyObject *__pyx_t_5 = NULL;
+  PyObject *__pyx_t_6 = NULL;
+  PyObject *__pyx_t_7 = NULL;
+  Py_ssize_t __pyx_t_8;
+  PyObject *__pyx_t_9 = NULL;
+  int __pyx_t_10;
+  PyObject *(*__pyx_t_11)(PyObject *);
+  int __pyx_t_12;
+  __pyx_t_2bx_3bbi_5types_bits32 __pyx_t_13;
+  Py_ssize_t __pyx_t_14;
+  int __pyx_t_15;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("get", 0);
+  /* Check if called by wrapper */
+  if (unlikely(__pyx_skip_dispatch)) ;
+  /* Check if overridden in Python */
+  else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
+    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_get); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_2bx_3bbi_11bigbed_file_10BigBedFile_3get)) {
+      __Pyx_XDECREF(__pyx_r);
+      __pyx_t_3 = __Pyx_PyBytes_FromString(__pyx_v_chrom); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_4 = __Pyx_PyInt_From_unsigned_int(__pyx_v_start); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __pyx_t_5 = __Pyx_PyInt_From_unsigned_int(__pyx_v_end); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_5);
+      __Pyx_INCREF(__pyx_t_1);
+      __pyx_t_6 = __pyx_t_1; __pyx_t_7 = NULL;
+      __pyx_t_8 = 0;
+      if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_6))) {
+        __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_6);
+        if (likely(__pyx_t_7)) {
+          PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6);
+          __Pyx_INCREF(__pyx_t_7);
+          __Pyx_INCREF(function);
+          __Pyx_DECREF_SET(__pyx_t_6, function);
+          __pyx_t_8 = 1;
+        }
+      }
+      __pyx_t_9 = PyTuple_New(3+__pyx_t_8); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_9);
+      if (__pyx_t_7) {
+        PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_7); __Pyx_GIVEREF(__pyx_t_7); __pyx_t_7 = NULL;
+      }
+      PyTuple_SET_ITEM(__pyx_t_9, 0+__pyx_t_8, __pyx_t_3);
+      __Pyx_GIVEREF(__pyx_t_3);
+      PyTuple_SET_ITEM(__pyx_t_9, 1+__pyx_t_8, __pyx_t_4);
+      __Pyx_GIVEREF(__pyx_t_4);
+      PyTuple_SET_ITEM(__pyx_t_9, 2+__pyx_t_8, __pyx_t_5);
+      __Pyx_GIVEREF(__pyx_t_5);
+      __pyx_t_3 = 0;
+      __pyx_t_4 = 0;
+      __pyx_t_5 = 0;
+      __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_t_9, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_2);
+      __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+      __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+      __pyx_r = __pyx_t_2;
+      __pyx_t_2 = 0;
+      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+      goto __pyx_L0;
+    }
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  }
+
+  /* "bx/bbi/bigbed_file.pyx":127
+ *         Gets all data points over the regions `chrom`:`start`-`end`.
+ *         """
+ *         if start >= end:             # <<<<<<<<<<<<<<
+ *             return None
+ *         chrom_id, chrom_size = self._get_chrom_id_and_size( chrom )
+ */
+  __pyx_t_10 = ((__pyx_v_start >= __pyx_v_end) != 0);
+  if (__pyx_t_10) {
+
+    /* "bx/bbi/bigbed_file.pyx":128
+ *         """
+ *         if start >= end:
+ *             return None             # <<<<<<<<<<<<<<
+ *         chrom_id, chrom_size = self._get_chrom_id_and_size( chrom )
+ *         if chrom_id is None:
+ */
+    __Pyx_XDECREF(__pyx_r);
+    __Pyx_INCREF(Py_None);
+    __pyx_r = Py_None;
+    goto __pyx_L0;
+  }
+
+  /* "bx/bbi/bigbed_file.pyx":129
+ *         if start >= end:
+ *             return None
+ *         chrom_id, chrom_size = self._get_chrom_id_and_size( chrom )             # <<<<<<<<<<<<<<
+ *         if chrom_id is None:
+ *             return None
+ */
+  __pyx_t_1 = ((struct __pyx_vtabstruct_2bx_3bbi_11bigbed_file_BigBedFile *)__pyx_v_self->__pyx_base.__pyx_vtab)->__pyx_base._get_chrom_id_and_size(((struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *)__pyx_v_self), __pyx_v_chrom); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 129; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if ((likely(PyTuple_CheckExact(__pyx_t_1))) || (PyList_CheckExact(__pyx_t_1))) {
+    PyObject* sequence = __pyx_t_1;
+    #if CYTHON_COMPILING_IN_CPYTHON
+    Py_ssize_t size = Py_SIZE(sequence);
+    #else
+    Py_ssize_t size = PySequence_Size(sequence);
+    #endif
+    if (unlikely(size != 2)) {
+      if (size > 2) __Pyx_RaiseTooManyValuesError(2);
+      else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
+      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 129; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+    #if CYTHON_COMPILING_IN_CPYTHON
+    if (likely(PyTuple_CheckExact(sequence))) {
+      __pyx_t_2 = PyTuple_GET_ITEM(sequence, 0); 
+      __pyx_t_6 = PyTuple_GET_ITEM(sequence, 1); 
+    } else {
+      __pyx_t_2 = PyList_GET_ITEM(sequence, 0); 
+      __pyx_t_6 = PyList_GET_ITEM(sequence, 1); 
+    }
+    __Pyx_INCREF(__pyx_t_2);
+    __Pyx_INCREF(__pyx_t_6);
+    #else
+    __pyx_t_2 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 129; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_t_6 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 129; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_6);
+    #endif
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  } else {
+    Py_ssize_t index = -1;
+    __pyx_t_9 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 129; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_9);
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    __pyx_t_11 = Py_TYPE(__pyx_t_9)->tp_iternext;
+    index = 0; __pyx_t_2 = __pyx_t_11(__pyx_t_9); if (unlikely(!__pyx_t_2)) goto __pyx_L4_unpacking_failed;
+    __Pyx_GOTREF(__pyx_t_2);
+    index = 1; __pyx_t_6 = __pyx_t_11(__pyx_t_9); if (unlikely(!__pyx_t_6)) goto __pyx_L4_unpacking_failed;
+    __Pyx_GOTREF(__pyx_t_6);
+    if (__Pyx_IternextUnpackEndCheck(__pyx_t_11(__pyx_t_9), 2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 129; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_11 = NULL;
+    __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+    goto __pyx_L5_unpacking_done;
+    __pyx_L4_unpacking_failed:;
+    __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+    __pyx_t_11 = NULL;
+    if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 129; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_L5_unpacking_done:;
+  }
+  __pyx_v_chrom_id = __pyx_t_2;
+  __pyx_t_2 = 0;
+  __pyx_v_chrom_size = __pyx_t_6;
+  __pyx_t_6 = 0;
+
+  /* "bx/bbi/bigbed_file.pyx":130
+ *             return None
+ *         chrom_id, chrom_size = self._get_chrom_id_and_size( chrom )
+ *         if chrom_id is None:             # <<<<<<<<<<<<<<
+ *             return None
+ *         v = IntervalAccumulatingBlockHandler( chrom_id, start, end )
+ */
+  __pyx_t_10 = (__pyx_v_chrom_id == Py_None);
+  __pyx_t_12 = (__pyx_t_10 != 0);
+  if (__pyx_t_12) {
+
+    /* "bx/bbi/bigbed_file.pyx":131
+ *         chrom_id, chrom_size = self._get_chrom_id_and_size( chrom )
+ *         if chrom_id is None:
+ *             return None             # <<<<<<<<<<<<<<
+ *         v = IntervalAccumulatingBlockHandler( chrom_id, start, end )
+ *         self.visit_blocks_in_region( chrom_id, start, end, v )
+ */
+    __Pyx_XDECREF(__pyx_r);
+    __Pyx_INCREF(Py_None);
+    __pyx_r = Py_None;
+    goto __pyx_L0;
+  }
+
+  /* "bx/bbi/bigbed_file.pyx":132
+ *         if chrom_id is None:
+ *             return None
+ *         v = IntervalAccumulatingBlockHandler( chrom_id, start, end )             # <<<<<<<<<<<<<<
+ *         self.visit_blocks_in_region( chrom_id, start, end, v )
+ *         rval = []
+ */
+  __pyx_t_1 = __Pyx_PyInt_From_unsigned_int(__pyx_v_start); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_6 = __Pyx_PyInt_From_unsigned_int(__pyx_v_end); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_6);
+  __pyx_t_2 = PyTuple_New(3); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_INCREF(__pyx_v_chrom_id);
+  PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_chrom_id);
+  __Pyx_GIVEREF(__pyx_v_chrom_id);
+  PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_1);
+  __Pyx_GIVEREF(__pyx_t_1);
+  PyTuple_SET_ITEM(__pyx_t_2, 2, __pyx_t_6);
+  __Pyx_GIVEREF(__pyx_t_6);
+  __pyx_t_1 = 0;
+  __pyx_t_6 = 0;
+  __pyx_t_6 = __Pyx_PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_2bx_3bbi_11bigbed_file_IntervalAccumulatingBlockHandler)), __pyx_t_2, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_6);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_v_v = ((struct __pyx_obj_2bx_3bbi_11bigbed_file_IntervalAccumulatingBlockHandler *)__pyx_t_6);
+  __pyx_t_6 = 0;
+
+  /* "bx/bbi/bigbed_file.pyx":133
+ *             return None
+ *         v = IntervalAccumulatingBlockHandler( chrom_id, start, end )
+ *         self.visit_blocks_in_region( chrom_id, start, end, v )             # <<<<<<<<<<<<<<
+ *         rval = []
+ *         # FIXME: Not sure the best way to return, will user GenomicInterval for
+ */
+  __pyx_t_13 = __Pyx_PyInt_As_unsigned_int(__pyx_v_chrom_id); if (unlikely((__pyx_t_13 == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 133; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_6 = ((struct __pyx_vtabstruct_2bx_3bbi_11bigbed_file_BigBedFile *)__pyx_v_self->__pyx_base.__pyx_vtab)->__pyx_base.visit_blocks_in_region(((struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *)__pyx_v_self), __pyx_t_13, __pyx_v_start, __pyx_v_end, ((struct __pyx_obj_2bx_3bbi_8bbi_file_BlockHandler *)__pyx_v_v)); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 133; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_6);
+  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+
+  /* "bx/bbi/bigbed_file.pyx":134
+ *         v = IntervalAccumulatingBlockHandler( chrom_id, start, end )
+ *         self.visit_blocks_in_region( chrom_id, start, end, v )
+ *         rval = []             # <<<<<<<<<<<<<<
+ *         # FIXME: Not sure the best way to return, will user GenomicInterval for
+ *         # now.
+ */
+  __pyx_t_6 = PyList_New(0); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 134; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_6);
+  __pyx_v_rval = ((PyObject*)__pyx_t_6);
+  __pyx_t_6 = 0;
+
+  /* "bx/bbi/bigbed_file.pyx":137
+ *         # FIXME: Not sure the best way to return, will user GenomicInterval for
+ *         # now.
+ *         for ( s, e, rest ) in v.intervals:             # <<<<<<<<<<<<<<
+ *             fields = [ chrom, str( s ), str( e ) ] + rest.split( "\t" )
+ *             rval.append( GenomicInterval( None, fields, 0, 1, 2, 5, "+" ) )
+ */
+  if (unlikely(__pyx_v_v->intervals == Py_None)) {
+    PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable");
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 137; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  __pyx_t_6 = __pyx_v_v->intervals; __Pyx_INCREF(__pyx_t_6); __pyx_t_8 = 0;
+  for (;;) {
+    if (__pyx_t_8 >= PyList_GET_SIZE(__pyx_t_6)) break;
+    #if CYTHON_COMPILING_IN_CPYTHON
+    __pyx_t_2 = PyList_GET_ITEM(__pyx_t_6, __pyx_t_8); __Pyx_INCREF(__pyx_t_2); __pyx_t_8++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 137; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    #else
+    __pyx_t_2 = PySequence_ITEM(__pyx_t_6, __pyx_t_8); __pyx_t_8++; if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 137; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    #endif
+    if ((likely(PyTuple_CheckExact(__pyx_t_2))) || (PyList_CheckExact(__pyx_t_2))) {
+      PyObject* sequence = __pyx_t_2;
+      #if CYTHON_COMPILING_IN_CPYTHON
+      Py_ssize_t size = Py_SIZE(sequence);
+      #else
+      Py_ssize_t size = PySequence_Size(sequence);
+      #endif
+      if (unlikely(size != 3)) {
+        if (size > 3) __Pyx_RaiseTooManyValuesError(3);
+        else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
+        {__pyx_filename = __pyx_f[0]; __pyx_lineno = 137; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      }
+      #if CYTHON_COMPILING_IN_CPYTHON
+      if (likely(PyTuple_CheckExact(sequence))) {
+        __pyx_t_1 = PyTuple_GET_ITEM(sequence, 0); 
+        __pyx_t_9 = PyTuple_GET_ITEM(sequence, 1); 
+        __pyx_t_5 = PyTuple_GET_ITEM(sequence, 2); 
+      } else {
+        __pyx_t_1 = PyList_GET_ITEM(sequence, 0); 
+        __pyx_t_9 = PyList_GET_ITEM(sequence, 1); 
+        __pyx_t_5 = PyList_GET_ITEM(sequence, 2); 
+      }
+      __Pyx_INCREF(__pyx_t_1);
+      __Pyx_INCREF(__pyx_t_9);
+      __Pyx_INCREF(__pyx_t_5);
+      #else
+      __pyx_t_1 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 137; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_1);
+      __pyx_t_9 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 137; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_9);
+      __pyx_t_5 = PySequence_ITEM(sequence, 2); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 137; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_5);
+      #endif
+      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    } else {
+      Py_ssize_t index = -1;
+      __pyx_t_4 = PyObject_GetIter(__pyx_t_2); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 137; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+      __pyx_t_11 = Py_TYPE(__pyx_t_4)->tp_iternext;
+      index = 0; __pyx_t_1 = __pyx_t_11(__pyx_t_4); if (unlikely(!__pyx_t_1)) goto __pyx_L9_unpacking_failed;
+      __Pyx_GOTREF(__pyx_t_1);
+      index = 1; __pyx_t_9 = __pyx_t_11(__pyx_t_4); if (unlikely(!__pyx_t_9)) goto __pyx_L9_unpacking_failed;
+      __Pyx_GOTREF(__pyx_t_9);
+      index = 2; __pyx_t_5 = __pyx_t_11(__pyx_t_4); if (unlikely(!__pyx_t_5)) goto __pyx_L9_unpacking_failed;
+      __Pyx_GOTREF(__pyx_t_5);
+      if (__Pyx_IternextUnpackEndCheck(__pyx_t_11(__pyx_t_4), 3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 137; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_11 = NULL;
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      goto __pyx_L10_unpacking_done;
+      __pyx_L9_unpacking_failed:;
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      __pyx_t_11 = NULL;
+      if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
+      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 137; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_L10_unpacking_done:;
+    }
+    __Pyx_XDECREF_SET(__pyx_v_s, __pyx_t_1);
+    __pyx_t_1 = 0;
+    __Pyx_XDECREF_SET(__pyx_v_e, __pyx_t_9);
+    __pyx_t_9 = 0;
+    __Pyx_XDECREF_SET(__pyx_v_rest, __pyx_t_5);
+    __pyx_t_5 = 0;
+
+    /* "bx/bbi/bigbed_file.pyx":138
+ *         # now.
+ *         for ( s, e, rest ) in v.intervals:
+ *             fields = [ chrom, str( s ), str( e ) ] + rest.split( "\t" )             # <<<<<<<<<<<<<<
+ *             rval.append( GenomicInterval( None, fields, 0, 1, 2, 5, "+" ) )
+ *         return rval
+ */
+    __pyx_t_2 = __Pyx_PyBytes_FromString(__pyx_v_chrom); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 138; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 138; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_5);
+    __Pyx_INCREF(__pyx_v_s);
+    PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_v_s);
+    __Pyx_GIVEREF(__pyx_v_s);
+    __pyx_t_9 = __Pyx_PyObject_Call(((PyObject *)((PyObject*)(&PyString_Type))), __pyx_t_5, NULL); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 138; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_9);
+    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+    __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 138; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_5);
+    __Pyx_INCREF(__pyx_v_e);
+    PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_v_e);
+    __Pyx_GIVEREF(__pyx_v_e);
+    __pyx_t_1 = __Pyx_PyObject_Call(((PyObject *)((PyObject*)(&PyString_Type))), __pyx_t_5, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 138; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+    __pyx_t_5 = PyList_New(3); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 138; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_5);
+    PyList_SET_ITEM(__pyx_t_5, 0, __pyx_t_2);
+    __Pyx_GIVEREF(__pyx_t_2);
+    PyList_SET_ITEM(__pyx_t_5, 1, __pyx_t_9);
+    __Pyx_GIVEREF(__pyx_t_9);
+    PyList_SET_ITEM(__pyx_t_5, 2, __pyx_t_1);
+    __Pyx_GIVEREF(__pyx_t_1);
+    __pyx_t_2 = 0;
+    __pyx_t_9 = 0;
+    __pyx_t_1 = 0;
+    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_rest, __pyx_n_s_split); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 138; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __pyx_t_9 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_tuple__6, NULL); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 138; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_9);
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    __pyx_t_1 = PyNumber_Add(__pyx_t_5, __pyx_t_9); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 138; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+    __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+    __Pyx_XDECREF_SET(__pyx_v_fields, __pyx_t_1);
+    __pyx_t_1 = 0;
+
+    /* "bx/bbi/bigbed_file.pyx":139
+ *         for ( s, e, rest ) in v.intervals:
+ *             fields = [ chrom, str( s ), str( e ) ] + rest.split( "\t" )
+ *             rval.append( GenomicInterval( None, fields, 0, 1, 2, 5, "+" ) )             # <<<<<<<<<<<<<<
+ *         return rval
+ * 
+ */
+    __pyx_t_9 = __Pyx_GetModuleGlobalName(__pyx_n_s_GenomicInterval); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 139; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_9);
+    __pyx_t_5 = NULL;
+    __pyx_t_14 = 0;
+    if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_9))) {
+      __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_9);
+      if (likely(__pyx_t_5)) {
+        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_9);
+        __Pyx_INCREF(__pyx_t_5);
+        __Pyx_INCREF(function);
+        __Pyx_DECREF_SET(__pyx_t_9, function);
+        __pyx_t_14 = 1;
+      }
+    }
+    __pyx_t_2 = PyTuple_New(7+__pyx_t_14); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 139; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    if (__pyx_t_5) {
+      PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_5); __Pyx_GIVEREF(__pyx_t_5); __pyx_t_5 = NULL;
+    }
+    __Pyx_INCREF(Py_None);
+    PyTuple_SET_ITEM(__pyx_t_2, 0+__pyx_t_14, Py_None);
+    __Pyx_GIVEREF(Py_None);
+    __Pyx_INCREF(__pyx_v_fields);
+    PyTuple_SET_ITEM(__pyx_t_2, 1+__pyx_t_14, __pyx_v_fields);
+    __Pyx_GIVEREF(__pyx_v_fields);
+    __Pyx_INCREF(__pyx_int_0);
+    PyTuple_SET_ITEM(__pyx_t_2, 2+__pyx_t_14, __pyx_int_0);
+    __Pyx_GIVEREF(__pyx_int_0);
+    __Pyx_INCREF(__pyx_int_1);
+    PyTuple_SET_ITEM(__pyx_t_2, 3+__pyx_t_14, __pyx_int_1);
+    __Pyx_GIVEREF(__pyx_int_1);
+    __Pyx_INCREF(__pyx_int_2);
+    PyTuple_SET_ITEM(__pyx_t_2, 4+__pyx_t_14, __pyx_int_2);
+    __Pyx_GIVEREF(__pyx_int_2);
+    __Pyx_INCREF(__pyx_int_5);
+    PyTuple_SET_ITEM(__pyx_t_2, 5+__pyx_t_14, __pyx_int_5);
+    __Pyx_GIVEREF(__pyx_int_5);
+    __Pyx_INCREF(__pyx_kp_s__7);
+    PyTuple_SET_ITEM(__pyx_t_2, 6+__pyx_t_14, __pyx_kp_s__7);
+    __Pyx_GIVEREF(__pyx_kp_s__7);
+    __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_9, __pyx_t_2, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 139; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+    __pyx_t_15 = __Pyx_PyList_Append(__pyx_v_rval, __pyx_t_1); if (unlikely(__pyx_t_15 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 139; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+    /* "bx/bbi/bigbed_file.pyx":137
+ *         # FIXME: Not sure the best way to return, will user GenomicInterval for
+ *         # now.
+ *         for ( s, e, rest ) in v.intervals:             # <<<<<<<<<<<<<<
+ *             fields = [ chrom, str( s ), str( e ) ] + rest.split( "\t" )
+ *             rval.append( GenomicInterval( None, fields, 0, 1, 2, 5, "+" ) )
+ */
+  }
+  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+
+  /* "bx/bbi/bigbed_file.pyx":140
+ *             fields = [ chrom, str( s ), str( e ) ] + rest.split( "\t" )
+ *             rval.append( GenomicInterval( None, fields, 0, 1, 2, 5, "+" ) )
+ *         return rval             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __Pyx_INCREF(__pyx_v_rval);
+  __pyx_r = __pyx_v_rval;
+  goto __pyx_L0;
+
+  /* "bx/bbi/bigbed_file.pyx":123
+ *         return v.sd
+ * 
+ *     cpdef get( self, char * chrom, bits32 start, bits32 end ):             # <<<<<<<<<<<<<<
+ *         """
+ *         Gets all data points over the regions `chrom`:`start`-`end`.
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_XDECREF(__pyx_t_5);
+  __Pyx_XDECREF(__pyx_t_6);
+  __Pyx_XDECREF(__pyx_t_7);
+  __Pyx_XDECREF(__pyx_t_9);
+  __Pyx_AddTraceback("bx.bbi.bigbed_file.BigBedFile.get", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_chrom_id);
+  __Pyx_XDECREF(__pyx_v_chrom_size);
+  __Pyx_XDECREF((PyObject *)__pyx_v_v);
+  __Pyx_XDECREF(__pyx_v_rval);
+  __Pyx_XDECREF(__pyx_v_s);
+  __Pyx_XDECREF(__pyx_v_e);
+  __Pyx_XDECREF(__pyx_v_rest);
+  __Pyx_XDECREF(__pyx_v_fields);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_3bbi_11bigbed_file_10BigBedFile_3get(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_2bx_3bbi_11bigbed_file_10BigBedFile_2get[] = "\n        Gets all data points over the regions `chrom`:`start`-`end`.\n        ";
+static PyObject *__pyx_pw_2bx_3bbi_11bigbed_file_10BigBedFile_3get(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  char *__pyx_v_chrom;
+  __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_start;
+  __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_end;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("get (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_chrom,&__pyx_n_s_start,&__pyx_n_s_end,0};
+    PyObject* values[3] = {0,0,0};
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_chrom)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_start)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("get", 1, 3, 3, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+        case  2:
+        if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_end)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("get", 1, 3, 3, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "get") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else if (PyTuple_GET_SIZE(__pyx_args) != 3) {
+      goto __pyx_L5_argtuple_error;
+    } else {
+      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+      values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+    }
+    __pyx_v_chrom = __Pyx_PyObject_AsString(values[0]); if (unlikely((!__pyx_v_chrom) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_start = __Pyx_PyInt_As_unsigned_int(values[1]); if (unlikely((__pyx_v_start == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_end = __Pyx_PyInt_As_unsigned_int(values[2]); if (unlikely((__pyx_v_end == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("get", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.bbi.bigbed_file.BigBedFile.get", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_3bbi_11bigbed_file_10BigBedFile_2get(((struct __pyx_obj_2bx_3bbi_11bigbed_file_BigBedFile *)__pyx_v_self), __pyx_v_chrom, __pyx_v_start, __pyx_v_end);
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_2bx_3bbi_11bigbed_file_10BigBedFile_2get(struct __pyx_obj_2bx_3bbi_11bigbed_file_BigBedFile *__pyx_v_self, char *__pyx_v_chrom, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_start, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_end) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("get", 0);
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = __pyx_f_2bx_3bbi_11bigbed_file_10BigBedFile_get(__pyx_v_self, __pyx_v_chrom, __pyx_v_start, __pyx_v_end, 1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("bx.bbi.bigbed_file.BigBedFile.get", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":197
+ *         # experimental exception made for __getbuffer__ and __releasebuffer__
+ *         # -- the details of this may change.
+ *         def __getbuffer__(ndarray self, Py_buffer* info, int flags):             # <<<<<<<<<<<<<<
+ *             # This implementation of getbuffer is geared towards Cython
+ *             # requirements, and does not yet fullfill the PEP.
+ */
+
+/* Python wrapper */
+static CYTHON_UNUSED int __pyx_pw_5numpy_7ndarray_1__getbuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /*proto*/
+static CYTHON_UNUSED int __pyx_pw_5numpy_7ndarray_1__getbuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__getbuffer__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_5numpy_7ndarray___getbuffer__(((PyArrayObject *)__pyx_v_self), ((Py_buffer *)__pyx_v_info), ((int)__pyx_v_flags));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) {
+  int __pyx_v_copy_shape;
+  int __pyx_v_i;
+  int __pyx_v_ndim;
+  int __pyx_v_endian_detector;
+  int __pyx_v_little_endian;
+  int __pyx_v_t;
+  char *__pyx_v_f;
+  PyArray_Descr *__pyx_v_descr = 0;
+  int __pyx_v_offset;
+  int __pyx_v_hasfields;
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  int __pyx_t_2;
+  PyObject *__pyx_t_3 = NULL;
+  int __pyx_t_4;
+  int __pyx_t_5;
+  PyObject *__pyx_t_6 = NULL;
+  char *__pyx_t_7;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__getbuffer__", 0);
+  if (__pyx_v_info != NULL) {
+    __pyx_v_info->obj = Py_None; __Pyx_INCREF(Py_None);
+    __Pyx_GIVEREF(__pyx_v_info->obj);
+  }
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":203
+ *             # of flags
+ * 
+ *             if info == NULL: return             # <<<<<<<<<<<<<<
+ * 
+ *             cdef int copy_shape, i, ndim
+ */
+  __pyx_t_1 = ((__pyx_v_info == NULL) != 0);
+  if (__pyx_t_1) {
+    __pyx_r = 0;
+    goto __pyx_L0;
+  }
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":206
+ * 
+ *             cdef int copy_shape, i, ndim
+ *             cdef int endian_detector = 1             # <<<<<<<<<<<<<<
+ *             cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)
+ * 
+ */
+  __pyx_v_endian_detector = 1;
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":207
+ *             cdef int copy_shape, i, ndim
+ *             cdef int endian_detector = 1
+ *             cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)             # <<<<<<<<<<<<<<
+ * 
+ *             ndim = PyArray_NDIM(self)
+ */
+  __pyx_v_little_endian = ((((char *)(&__pyx_v_endian_detector))[0]) != 0);
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":209
+ *             cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)
+ * 
+ *             ndim = PyArray_NDIM(self)             # <<<<<<<<<<<<<<
+ * 
+ *             if sizeof(npy_intp) != sizeof(Py_ssize_t):
+ */
+  __pyx_v_ndim = PyArray_NDIM(__pyx_v_self);
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":211
+ *             ndim = PyArray_NDIM(self)
+ * 
+ *             if sizeof(npy_intp) != sizeof(Py_ssize_t):             # <<<<<<<<<<<<<<
+ *                 copy_shape = 1
+ *             else:
+ */
+  __pyx_t_1 = (((sizeof(npy_intp)) != (sizeof(Py_ssize_t))) != 0);
+  if (__pyx_t_1) {
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":212
+ * 
+ *             if sizeof(npy_intp) != sizeof(Py_ssize_t):
+ *                 copy_shape = 1             # <<<<<<<<<<<<<<
+ *             else:
+ *                 copy_shape = 0
+ */
+    __pyx_v_copy_shape = 1;
+    goto __pyx_L4;
+  }
+  /*else*/ {
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":214
+ *                 copy_shape = 1
+ *             else:
+ *                 copy_shape = 0             # <<<<<<<<<<<<<<
+ * 
+ *             if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)
+ */
+    __pyx_v_copy_shape = 0;
+  }
+  __pyx_L4:;
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":216
+ *                 copy_shape = 0
+ * 
+ *             if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)             # <<<<<<<<<<<<<<
+ *                 and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)):
+ *                 raise ValueError(u"ndarray is not C contiguous")
+ */
+  __pyx_t_2 = (((__pyx_v_flags & PyBUF_C_CONTIGUOUS) == PyBUF_C_CONTIGUOUS) != 0);
+  if (__pyx_t_2) {
+  } else {
+    __pyx_t_1 = __pyx_t_2;
+    goto __pyx_L6_bool_binop_done;
+  }
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":217
+ * 
+ *             if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)
+ *                 and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)):             # <<<<<<<<<<<<<<
+ *                 raise ValueError(u"ndarray is not C contiguous")
+ * 
+ */
+  __pyx_t_2 = ((!(PyArray_CHKFLAGS(__pyx_v_self, NPY_C_CONTIGUOUS) != 0)) != 0);
+  __pyx_t_1 = __pyx_t_2;
+  __pyx_L6_bool_binop_done:;
+  if (__pyx_t_1) {
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":218
+ *             if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)
+ *                 and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)):
+ *                 raise ValueError(u"ndarray is not C contiguous")             # <<<<<<<<<<<<<<
+ * 
+ *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
+ */
+    __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__8, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 218; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    {__pyx_filename = __pyx_f[1]; __pyx_lineno = 218; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":220
+ *                 raise ValueError(u"ndarray is not C contiguous")
+ * 
+ *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)             # <<<<<<<<<<<<<<
+ *                 and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)):
+ *                 raise ValueError(u"ndarray is not Fortran contiguous")
+ */
+  __pyx_t_2 = (((__pyx_v_flags & PyBUF_F_CONTIGUOUS) == PyBUF_F_CONTIGUOUS) != 0);
+  if (__pyx_t_2) {
+  } else {
+    __pyx_t_1 = __pyx_t_2;
+    goto __pyx_L9_bool_binop_done;
+  }
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":221
+ * 
+ *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
+ *                 and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)):             # <<<<<<<<<<<<<<
+ *                 raise ValueError(u"ndarray is not Fortran contiguous")
+ * 
+ */
+  __pyx_t_2 = ((!(PyArray_CHKFLAGS(__pyx_v_self, NPY_F_CONTIGUOUS) != 0)) != 0);
+  __pyx_t_1 = __pyx_t_2;
+  __pyx_L9_bool_binop_done:;
+  if (__pyx_t_1) {
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":222
+ *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
+ *                 and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)):
+ *                 raise ValueError(u"ndarray is not Fortran contiguous")             # <<<<<<<<<<<<<<
+ * 
+ *             info.buf = PyArray_DATA(self)
+ */
+    __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__9, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 222; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    {__pyx_filename = __pyx_f[1]; __pyx_lineno = 222; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":224
+ *                 raise ValueError(u"ndarray is not Fortran contiguous")
+ * 
+ *             info.buf = PyArray_DATA(self)             # <<<<<<<<<<<<<<
+ *             info.ndim = ndim
+ *             if copy_shape:
+ */
+  __pyx_v_info->buf = PyArray_DATA(__pyx_v_self);
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":225
+ * 
+ *             info.buf = PyArray_DATA(self)
+ *             info.ndim = ndim             # <<<<<<<<<<<<<<
+ *             if copy_shape:
+ *                 # Allocate new buffer for strides and shape info.
+ */
+  __pyx_v_info->ndim = __pyx_v_ndim;
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":226
+ *             info.buf = PyArray_DATA(self)
+ *             info.ndim = ndim
+ *             if copy_shape:             # <<<<<<<<<<<<<<
+ *                 # Allocate new buffer for strides and shape info.
+ *                 # This is allocated as one block, strides first.
+ */
+  __pyx_t_1 = (__pyx_v_copy_shape != 0);
+  if (__pyx_t_1) {
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":229
+ *                 # Allocate new buffer for strides and shape info.
+ *                 # This is allocated as one block, strides first.
+ *                 info.strides = <Py_ssize_t*>stdlib.malloc(sizeof(Py_ssize_t) * <size_t>ndim * 2)             # <<<<<<<<<<<<<<
+ *                 info.shape = info.strides + ndim
+ *                 for i in range(ndim):
+ */
+    __pyx_v_info->strides = ((Py_ssize_t *)malloc((((sizeof(Py_ssize_t)) * ((size_t)__pyx_v_ndim)) * 2)));
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":230
+ *                 # This is allocated as one block, strides first.
+ *                 info.strides = <Py_ssize_t*>stdlib.malloc(sizeof(Py_ssize_t) * <size_t>ndim * 2)
+ *                 info.shape = info.strides + ndim             # <<<<<<<<<<<<<<
+ *                 for i in range(ndim):
+ *                     info.strides[i] = PyArray_STRIDES(self)[i]
+ */
+    __pyx_v_info->shape = (__pyx_v_info->strides + __pyx_v_ndim);
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":231
+ *                 info.strides = <Py_ssize_t*>stdlib.malloc(sizeof(Py_ssize_t) * <size_t>ndim * 2)
+ *                 info.shape = info.strides + ndim
+ *                 for i in range(ndim):             # <<<<<<<<<<<<<<
+ *                     info.strides[i] = PyArray_STRIDES(self)[i]
+ *                     info.shape[i] = PyArray_DIMS(self)[i]
+ */
+    __pyx_t_4 = __pyx_v_ndim;
+    for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_4; __pyx_t_5+=1) {
+      __pyx_v_i = __pyx_t_5;
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":232
+ *                 info.shape = info.strides + ndim
+ *                 for i in range(ndim):
+ *                     info.strides[i] = PyArray_STRIDES(self)[i]             # <<<<<<<<<<<<<<
+ *                     info.shape[i] = PyArray_DIMS(self)[i]
+ *             else:
+ */
+      (__pyx_v_info->strides[__pyx_v_i]) = (PyArray_STRIDES(__pyx_v_self)[__pyx_v_i]);
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":233
+ *                 for i in range(ndim):
+ *                     info.strides[i] = PyArray_STRIDES(self)[i]
+ *                     info.shape[i] = PyArray_DIMS(self)[i]             # <<<<<<<<<<<<<<
+ *             else:
+ *                 info.strides = <Py_ssize_t*>PyArray_STRIDES(self)
+ */
+      (__pyx_v_info->shape[__pyx_v_i]) = (PyArray_DIMS(__pyx_v_self)[__pyx_v_i]);
+    }
+    goto __pyx_L11;
+  }
+  /*else*/ {
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":235
+ *                     info.shape[i] = PyArray_DIMS(self)[i]
+ *             else:
+ *                 info.strides = <Py_ssize_t*>PyArray_STRIDES(self)             # <<<<<<<<<<<<<<
+ *                 info.shape = <Py_ssize_t*>PyArray_DIMS(self)
+ *             info.suboffsets = NULL
+ */
+    __pyx_v_info->strides = ((Py_ssize_t *)PyArray_STRIDES(__pyx_v_self));
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":236
+ *             else:
+ *                 info.strides = <Py_ssize_t*>PyArray_STRIDES(self)
+ *                 info.shape = <Py_ssize_t*>PyArray_DIMS(self)             # <<<<<<<<<<<<<<
+ *             info.suboffsets = NULL
+ *             info.itemsize = PyArray_ITEMSIZE(self)
+ */
+    __pyx_v_info->shape = ((Py_ssize_t *)PyArray_DIMS(__pyx_v_self));
+  }
+  __pyx_L11:;
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":237
+ *                 info.strides = <Py_ssize_t*>PyArray_STRIDES(self)
+ *                 info.shape = <Py_ssize_t*>PyArray_DIMS(self)
+ *             info.suboffsets = NULL             # <<<<<<<<<<<<<<
+ *             info.itemsize = PyArray_ITEMSIZE(self)
+ *             info.readonly = not PyArray_ISWRITEABLE(self)
+ */
+  __pyx_v_info->suboffsets = NULL;
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":238
+ *                 info.shape = <Py_ssize_t*>PyArray_DIMS(self)
+ *             info.suboffsets = NULL
+ *             info.itemsize = PyArray_ITEMSIZE(self)             # <<<<<<<<<<<<<<
+ *             info.readonly = not PyArray_ISWRITEABLE(self)
+ * 
+ */
+  __pyx_v_info->itemsize = PyArray_ITEMSIZE(__pyx_v_self);
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":239
+ *             info.suboffsets = NULL
+ *             info.itemsize = PyArray_ITEMSIZE(self)
+ *             info.readonly = not PyArray_ISWRITEABLE(self)             # <<<<<<<<<<<<<<
+ * 
+ *             cdef int t
+ */
+  __pyx_v_info->readonly = (!(PyArray_ISWRITEABLE(__pyx_v_self) != 0));
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":242
+ * 
+ *             cdef int t
+ *             cdef char* f = NULL             # <<<<<<<<<<<<<<
+ *             cdef dtype descr = self.descr
+ *             cdef list stack
+ */
+  __pyx_v_f = NULL;
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":243
+ *             cdef int t
+ *             cdef char* f = NULL
+ *             cdef dtype descr = self.descr             # <<<<<<<<<<<<<<
+ *             cdef list stack
+ *             cdef int offset
+ */
+  __pyx_t_3 = ((PyObject *)__pyx_v_self->descr);
+  __Pyx_INCREF(__pyx_t_3);
+  __pyx_v_descr = ((PyArray_Descr *)__pyx_t_3);
+  __pyx_t_3 = 0;
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":247
+ *             cdef int offset
+ * 
+ *             cdef bint hasfields = PyDataType_HASFIELDS(descr)             # <<<<<<<<<<<<<<
+ * 
+ *             if not hasfields and not copy_shape:
+ */
+  __pyx_v_hasfields = PyDataType_HASFIELDS(__pyx_v_descr);
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":249
+ *             cdef bint hasfields = PyDataType_HASFIELDS(descr)
+ * 
+ *             if not hasfields and not copy_shape:             # <<<<<<<<<<<<<<
+ *                 # do not call releasebuffer
+ *                 info.obj = None
+ */
+  __pyx_t_2 = ((!(__pyx_v_hasfields != 0)) != 0);
+  if (__pyx_t_2) {
+  } else {
+    __pyx_t_1 = __pyx_t_2;
+    goto __pyx_L15_bool_binop_done;
+  }
+  __pyx_t_2 = ((!(__pyx_v_copy_shape != 0)) != 0);
+  __pyx_t_1 = __pyx_t_2;
+  __pyx_L15_bool_binop_done:;
+  if (__pyx_t_1) {
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":251
+ *             if not hasfields and not copy_shape:
+ *                 # do not call releasebuffer
+ *                 info.obj = None             # <<<<<<<<<<<<<<
+ *             else:
+ *                 # need to call releasebuffer
+ */
+    __Pyx_INCREF(Py_None);
+    __Pyx_GIVEREF(Py_None);
+    __Pyx_GOTREF(__pyx_v_info->obj);
+    __Pyx_DECREF(__pyx_v_info->obj);
+    __pyx_v_info->obj = Py_None;
+    goto __pyx_L14;
+  }
+  /*else*/ {
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":254
+ *             else:
+ *                 # need to call releasebuffer
+ *                 info.obj = self             # <<<<<<<<<<<<<<
+ * 
+ *             if not hasfields:
+ */
+    __Pyx_INCREF(((PyObject *)__pyx_v_self));
+    __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
+    __Pyx_GOTREF(__pyx_v_info->obj);
+    __Pyx_DECREF(__pyx_v_info->obj);
+    __pyx_v_info->obj = ((PyObject *)__pyx_v_self);
+  }
+  __pyx_L14:;
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":256
+ *                 info.obj = self
+ * 
+ *             if not hasfields:             # <<<<<<<<<<<<<<
+ *                 t = descr.type_num
+ *                 if ((descr.byteorder == c'>' and little_endian) or
+ */
+  __pyx_t_1 = ((!(__pyx_v_hasfields != 0)) != 0);
+  if (__pyx_t_1) {
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":257
+ * 
+ *             if not hasfields:
+ *                 t = descr.type_num             # <<<<<<<<<<<<<<
+ *                 if ((descr.byteorder == c'>' and little_endian) or
+ *                     (descr.byteorder == c'<' and not little_endian)):
+ */
+    __pyx_t_4 = __pyx_v_descr->type_num;
+    __pyx_v_t = __pyx_t_4;
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":258
+ *             if not hasfields:
+ *                 t = descr.type_num
+ *                 if ((descr.byteorder == c'>' and little_endian) or             # <<<<<<<<<<<<<<
+ *                     (descr.byteorder == c'<' and not little_endian)):
+ *                     raise ValueError(u"Non-native byte order not supported")
+ */
+    __pyx_t_2 = ((__pyx_v_descr->byteorder == '>') != 0);
+    if (!__pyx_t_2) {
+      goto __pyx_L20_next_or;
+    } else {
+    }
+    __pyx_t_2 = (__pyx_v_little_endian != 0);
+    if (!__pyx_t_2) {
+    } else {
+      __pyx_t_1 = __pyx_t_2;
+      goto __pyx_L19_bool_binop_done;
+    }
+    __pyx_L20_next_or:;
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":259
+ *                 t = descr.type_num
+ *                 if ((descr.byteorder == c'>' and little_endian) or
+ *                     (descr.byteorder == c'<' and not little_endian)):             # <<<<<<<<<<<<<<
+ *                     raise ValueError(u"Non-native byte order not supported")
+ *                 if   t == NPY_BYTE:        f = "b"
+ */
+    __pyx_t_2 = ((__pyx_v_descr->byteorder == '<') != 0);
+    if (__pyx_t_2) {
+    } else {
+      __pyx_t_1 = __pyx_t_2;
+      goto __pyx_L19_bool_binop_done;
+    }
+    __pyx_t_2 = ((!(__pyx_v_little_endian != 0)) != 0);
+    __pyx_t_1 = __pyx_t_2;
+    __pyx_L19_bool_binop_done:;
+    if (__pyx_t_1) {
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":260
+ *                 if ((descr.byteorder == c'>' and little_endian) or
+ *                     (descr.byteorder == c'<' and not little_endian)):
+ *                     raise ValueError(u"Non-native byte order not supported")             # <<<<<<<<<<<<<<
+ *                 if   t == NPY_BYTE:        f = "b"
+ *                 elif t == NPY_UBYTE:       f = "B"
+ */
+      __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__10, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 260; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      {__pyx_filename = __pyx_f[1]; __pyx_lineno = 260; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":277
+ *                 elif t == NPY_CDOUBLE:     f = "Zd"
+ *                 elif t == NPY_CLONGDOUBLE: f = "Zg"
+ *                 elif t == NPY_OBJECT:      f = "O"             # <<<<<<<<<<<<<<
+ *                 else:
+ *                     raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
+ */
+    switch (__pyx_v_t) {
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":261
+ *                     (descr.byteorder == c'<' and not little_endian)):
+ *                     raise ValueError(u"Non-native byte order not supported")
+ *                 if   t == NPY_BYTE:        f = "b"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_UBYTE:       f = "B"
+ *                 elif t == NPY_SHORT:       f = "h"
+ */
+      case NPY_BYTE:
+      __pyx_v_f = __pyx_k_b;
+      break;
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":262
+ *                     raise ValueError(u"Non-native byte order not supported")
+ *                 if   t == NPY_BYTE:        f = "b"
+ *                 elif t == NPY_UBYTE:       f = "B"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_SHORT:       f = "h"
+ *                 elif t == NPY_USHORT:      f = "H"
+ */
+      case NPY_UBYTE:
+      __pyx_v_f = __pyx_k_B;
+      break;
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":263
+ *                 if   t == NPY_BYTE:        f = "b"
+ *                 elif t == NPY_UBYTE:       f = "B"
+ *                 elif t == NPY_SHORT:       f = "h"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_USHORT:      f = "H"
+ *                 elif t == NPY_INT:         f = "i"
+ */
+      case NPY_SHORT:
+      __pyx_v_f = __pyx_k_h;
+      break;
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":264
+ *                 elif t == NPY_UBYTE:       f = "B"
+ *                 elif t == NPY_SHORT:       f = "h"
+ *                 elif t == NPY_USHORT:      f = "H"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_INT:         f = "i"
+ *                 elif t == NPY_UINT:        f = "I"
+ */
+      case NPY_USHORT:
+      __pyx_v_f = __pyx_k_H;
+      break;
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":265
+ *                 elif t == NPY_SHORT:       f = "h"
+ *                 elif t == NPY_USHORT:      f = "H"
+ *                 elif t == NPY_INT:         f = "i"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_UINT:        f = "I"
+ *                 elif t == NPY_LONG:        f = "l"
+ */
+      case NPY_INT:
+      __pyx_v_f = __pyx_k_i;
+      break;
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":266
+ *                 elif t == NPY_USHORT:      f = "H"
+ *                 elif t == NPY_INT:         f = "i"
+ *                 elif t == NPY_UINT:        f = "I"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_LONG:        f = "l"
+ *                 elif t == NPY_ULONG:       f = "L"
+ */
+      case NPY_UINT:
+      __pyx_v_f = __pyx_k_I;
+      break;
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":267
+ *                 elif t == NPY_INT:         f = "i"
+ *                 elif t == NPY_UINT:        f = "I"
+ *                 elif t == NPY_LONG:        f = "l"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_ULONG:       f = "L"
+ *                 elif t == NPY_LONGLONG:    f = "q"
+ */
+      case NPY_LONG:
+      __pyx_v_f = __pyx_k_l;
+      break;
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":268
+ *                 elif t == NPY_UINT:        f = "I"
+ *                 elif t == NPY_LONG:        f = "l"
+ *                 elif t == NPY_ULONG:       f = "L"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_LONGLONG:    f = "q"
+ *                 elif t == NPY_ULONGLONG:   f = "Q"
+ */
+      case NPY_ULONG:
+      __pyx_v_f = __pyx_k_L;
+      break;
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":269
+ *                 elif t == NPY_LONG:        f = "l"
+ *                 elif t == NPY_ULONG:       f = "L"
+ *                 elif t == NPY_LONGLONG:    f = "q"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_ULONGLONG:   f = "Q"
+ *                 elif t == NPY_FLOAT:       f = "f"
+ */
+      case NPY_LONGLONG:
+      __pyx_v_f = __pyx_k_q;
+      break;
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":270
+ *                 elif t == NPY_ULONG:       f = "L"
+ *                 elif t == NPY_LONGLONG:    f = "q"
+ *                 elif t == NPY_ULONGLONG:   f = "Q"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_FLOAT:       f = "f"
+ *                 elif t == NPY_DOUBLE:      f = "d"
+ */
+      case NPY_ULONGLONG:
+      __pyx_v_f = __pyx_k_Q;
+      break;
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":271
+ *                 elif t == NPY_LONGLONG:    f = "q"
+ *                 elif t == NPY_ULONGLONG:   f = "Q"
+ *                 elif t == NPY_FLOAT:       f = "f"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_DOUBLE:      f = "d"
+ *                 elif t == NPY_LONGDOUBLE:  f = "g"
+ */
+      case NPY_FLOAT:
+      __pyx_v_f = __pyx_k_f;
+      break;
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":272
+ *                 elif t == NPY_ULONGLONG:   f = "Q"
+ *                 elif t == NPY_FLOAT:       f = "f"
+ *                 elif t == NPY_DOUBLE:      f = "d"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_LONGDOUBLE:  f = "g"
+ *                 elif t == NPY_CFLOAT:      f = "Zf"
+ */
+      case NPY_DOUBLE:
+      __pyx_v_f = __pyx_k_d;
+      break;
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":273
+ *                 elif t == NPY_FLOAT:       f = "f"
+ *                 elif t == NPY_DOUBLE:      f = "d"
+ *                 elif t == NPY_LONGDOUBLE:  f = "g"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_CFLOAT:      f = "Zf"
+ *                 elif t == NPY_CDOUBLE:     f = "Zd"
+ */
+      case NPY_LONGDOUBLE:
+      __pyx_v_f = __pyx_k_g;
+      break;
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":274
+ *                 elif t == NPY_DOUBLE:      f = "d"
+ *                 elif t == NPY_LONGDOUBLE:  f = "g"
+ *                 elif t == NPY_CFLOAT:      f = "Zf"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_CDOUBLE:     f = "Zd"
+ *                 elif t == NPY_CLONGDOUBLE: f = "Zg"
+ */
+      case NPY_CFLOAT:
+      __pyx_v_f = __pyx_k_Zf;
+      break;
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":275
+ *                 elif t == NPY_LONGDOUBLE:  f = "g"
+ *                 elif t == NPY_CFLOAT:      f = "Zf"
+ *                 elif t == NPY_CDOUBLE:     f = "Zd"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_CLONGDOUBLE: f = "Zg"
+ *                 elif t == NPY_OBJECT:      f = "O"
+ */
+      case NPY_CDOUBLE:
+      __pyx_v_f = __pyx_k_Zd;
+      break;
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":276
+ *                 elif t == NPY_CFLOAT:      f = "Zf"
+ *                 elif t == NPY_CDOUBLE:     f = "Zd"
+ *                 elif t == NPY_CLONGDOUBLE: f = "Zg"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_OBJECT:      f = "O"
+ *                 else:
+ */
+      case NPY_CLONGDOUBLE:
+      __pyx_v_f = __pyx_k_Zg;
+      break;
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":277
+ *                 elif t == NPY_CDOUBLE:     f = "Zd"
+ *                 elif t == NPY_CLONGDOUBLE: f = "Zg"
+ *                 elif t == NPY_OBJECT:      f = "O"             # <<<<<<<<<<<<<<
+ *                 else:
+ *                     raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
+ */
+      case NPY_OBJECT:
+      __pyx_v_f = __pyx_k_O;
+      break;
+      default:
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":279
+ *                 elif t == NPY_OBJECT:      f = "O"
+ *                 else:
+ *                     raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)             # <<<<<<<<<<<<<<
+ *                 info.format = f
+ *                 return
+ */
+      __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_t); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 279; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_6 = PyUnicode_Format(__pyx_kp_u_unknown_dtype_code_in_numpy_pxd, __pyx_t_3); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 279; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_6);
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 279; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_6);
+      __Pyx_GIVEREF(__pyx_t_6);
+      __pyx_t_6 = 0;
+      __pyx_t_6 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_3, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 279; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_6);
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __Pyx_Raise(__pyx_t_6, 0, 0, 0);
+      __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+      {__pyx_filename = __pyx_f[1]; __pyx_lineno = 279; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      break;
+    }
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":280
+ *                 else:
+ *                     raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
+ *                 info.format = f             # <<<<<<<<<<<<<<
+ *                 return
+ *             else:
+ */
+    __pyx_v_info->format = __pyx_v_f;
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":281
+ *                     raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
+ *                 info.format = f
+ *                 return             # <<<<<<<<<<<<<<
+ *             else:
+ *                 info.format = <char*>stdlib.malloc(_buffer_format_string_len)
+ */
+    __pyx_r = 0;
+    goto __pyx_L0;
+  }
+  /*else*/ {
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":283
+ *                 return
+ *             else:
+ *                 info.format = <char*>stdlib.malloc(_buffer_format_string_len)             # <<<<<<<<<<<<<<
+ *                 info.format[0] = c'^' # Native data types, manual alignment
+ *                 offset = 0
+ */
+    __pyx_v_info->format = ((char *)malloc(255));
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":284
+ *             else:
+ *                 info.format = <char*>stdlib.malloc(_buffer_format_string_len)
+ *                 info.format[0] = c'^' # Native data types, manual alignment             # <<<<<<<<<<<<<<
+ *                 offset = 0
+ *                 f = _util_dtypestring(descr, info.format + 1,
+ */
+    (__pyx_v_info->format[0]) = '^';
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":285
+ *                 info.format = <char*>stdlib.malloc(_buffer_format_string_len)
+ *                 info.format[0] = c'^' # Native data types, manual alignment
+ *                 offset = 0             # <<<<<<<<<<<<<<
+ *                 f = _util_dtypestring(descr, info.format + 1,
+ *                                       info.format + _buffer_format_string_len,
+ */
+    __pyx_v_offset = 0;
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":286
+ *                 info.format[0] = c'^' # Native data types, manual alignment
+ *                 offset = 0
+ *                 f = _util_dtypestring(descr, info.format + 1,             # <<<<<<<<<<<<<<
+ *                                       info.format + _buffer_format_string_len,
+ *                                       &offset)
+ */
+    __pyx_t_7 = __pyx_f_5numpy__util_dtypestring(__pyx_v_descr, (__pyx_v_info->format + 1), (__pyx_v_info->format + 255), (&__pyx_v_offset)); if (unlikely(__pyx_t_7 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 286; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_v_f = __pyx_t_7;
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":289
+ *                                       info.format + _buffer_format_string_len,
+ *                                       &offset)
+ *                 f[0] = c'\0' # Terminate format string             # <<<<<<<<<<<<<<
+ * 
+ *         def __releasebuffer__(ndarray self, Py_buffer* info):
+ */
+    (__pyx_v_f[0]) = '\x00';
+  }
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":197
+ *         # experimental exception made for __getbuffer__ and __releasebuffer__
+ *         # -- the details of this may change.
+ *         def __getbuffer__(ndarray self, Py_buffer* info, int flags):             # <<<<<<<<<<<<<<
+ *             # This implementation of getbuffer is geared towards Cython
+ *             # requirements, and does not yet fullfill the PEP.
+ */
+
+  /* function exit code */
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_6);
+  __Pyx_AddTraceback("numpy.ndarray.__getbuffer__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = -1;
+  if (__pyx_v_info != NULL && __pyx_v_info->obj != NULL) {
+    __Pyx_GOTREF(__pyx_v_info->obj);
+    __Pyx_DECREF(__pyx_v_info->obj); __pyx_v_info->obj = NULL;
+  }
+  goto __pyx_L2;
+  __pyx_L0:;
+  if (__pyx_v_info != NULL && __pyx_v_info->obj == Py_None) {
+    __Pyx_GOTREF(Py_None);
+    __Pyx_DECREF(Py_None); __pyx_v_info->obj = NULL;
+  }
+  __pyx_L2:;
+  __Pyx_XDECREF((PyObject *)__pyx_v_descr);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":291
+ *                 f[0] = c'\0' # Terminate format string
+ * 
+ *         def __releasebuffer__(ndarray self, Py_buffer* info):             # <<<<<<<<<<<<<<
+ *             if PyArray_HASFIELDS(self):
+ *                 stdlib.free(info.format)
+ */
+
+/* Python wrapper */
+static CYTHON_UNUSED void __pyx_pw_5numpy_7ndarray_3__releasebuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info); /*proto*/
+static CYTHON_UNUSED void __pyx_pw_5numpy_7ndarray_3__releasebuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info) {
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__releasebuffer__ (wrapper)", 0);
+  __pyx_pf_5numpy_7ndarray_2__releasebuffer__(((PyArrayObject *)__pyx_v_self), ((Py_buffer *)__pyx_v_info));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+}
+
+static void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info) {
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("__releasebuffer__", 0);
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":292
+ * 
+ *         def __releasebuffer__(ndarray self, Py_buffer* info):
+ *             if PyArray_HASFIELDS(self):             # <<<<<<<<<<<<<<
+ *                 stdlib.free(info.format)
+ *             if sizeof(npy_intp) != sizeof(Py_ssize_t):
+ */
+  __pyx_t_1 = (PyArray_HASFIELDS(__pyx_v_self) != 0);
+  if (__pyx_t_1) {
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":293
+ *         def __releasebuffer__(ndarray self, Py_buffer* info):
+ *             if PyArray_HASFIELDS(self):
+ *                 stdlib.free(info.format)             # <<<<<<<<<<<<<<
+ *             if sizeof(npy_intp) != sizeof(Py_ssize_t):
+ *                 stdlib.free(info.strides)
+ */
+    free(__pyx_v_info->format);
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":294
+ *             if PyArray_HASFIELDS(self):
+ *                 stdlib.free(info.format)
+ *             if sizeof(npy_intp) != sizeof(Py_ssize_t):             # <<<<<<<<<<<<<<
+ *                 stdlib.free(info.strides)
+ *                 # info.shape was stored after info.strides in the same block
+ */
+  __pyx_t_1 = (((sizeof(npy_intp)) != (sizeof(Py_ssize_t))) != 0);
+  if (__pyx_t_1) {
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":295
+ *                 stdlib.free(info.format)
+ *             if sizeof(npy_intp) != sizeof(Py_ssize_t):
+ *                 stdlib.free(info.strides)             # <<<<<<<<<<<<<<
+ *                 # info.shape was stored after info.strides in the same block
+ * 
+ */
+    free(__pyx_v_info->strides);
+    goto __pyx_L4;
+  }
+  __pyx_L4:;
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":291
+ *                 f[0] = c'\0' # Terminate format string
+ * 
+ *         def __releasebuffer__(ndarray self, Py_buffer* info):             # <<<<<<<<<<<<<<
+ *             if PyArray_HASFIELDS(self):
+ *                 stdlib.free(info.format)
+ */
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+}
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":771
+ * ctypedef npy_cdouble     complex_t
+ * 
+ * cdef inline object PyArray_MultiIterNew1(a):             # <<<<<<<<<<<<<<
+ *     return PyArray_MultiIterNew(1, <void*>a)
+ * 
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew1(PyObject *__pyx_v_a) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("PyArray_MultiIterNew1", 0);
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":772
+ * 
+ * cdef inline object PyArray_MultiIterNew1(a):
+ *     return PyArray_MultiIterNew(1, <void*>a)             # <<<<<<<<<<<<<<
+ * 
+ * cdef inline object PyArray_MultiIterNew2(a, b):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = PyArray_MultiIterNew(1, ((void *)__pyx_v_a)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 772; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":771
+ * ctypedef npy_cdouble     complex_t
+ * 
+ * cdef inline object PyArray_MultiIterNew1(a):             # <<<<<<<<<<<<<<
+ *     return PyArray_MultiIterNew(1, <void*>a)
+ * 
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("numpy.PyArray_MultiIterNew1", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":774
+ *     return PyArray_MultiIterNew(1, <void*>a)
+ * 
+ * cdef inline object PyArray_MultiIterNew2(a, b):             # <<<<<<<<<<<<<<
+ *     return PyArray_MultiIterNew(2, <void*>a, <void*>b)
+ * 
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew2(PyObject *__pyx_v_a, PyObject *__pyx_v_b) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("PyArray_MultiIterNew2", 0);
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":775
+ * 
+ * cdef inline object PyArray_MultiIterNew2(a, b):
+ *     return PyArray_MultiIterNew(2, <void*>a, <void*>b)             # <<<<<<<<<<<<<<
+ * 
+ * cdef inline object PyArray_MultiIterNew3(a, b, c):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = PyArray_MultiIterNew(2, ((void *)__pyx_v_a), ((void *)__pyx_v_b)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 775; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":774
+ *     return PyArray_MultiIterNew(1, <void*>a)
+ * 
+ * cdef inline object PyArray_MultiIterNew2(a, b):             # <<<<<<<<<<<<<<
+ *     return PyArray_MultiIterNew(2, <void*>a, <void*>b)
+ * 
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("numpy.PyArray_MultiIterNew2", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":777
+ *     return PyArray_MultiIterNew(2, <void*>a, <void*>b)
+ * 
+ * cdef inline object PyArray_MultiIterNew3(a, b, c):             # <<<<<<<<<<<<<<
+ *     return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)
+ * 
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew3(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("PyArray_MultiIterNew3", 0);
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":778
+ * 
+ * cdef inline object PyArray_MultiIterNew3(a, b, c):
+ *     return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)             # <<<<<<<<<<<<<<
+ * 
+ * cdef inline object PyArray_MultiIterNew4(a, b, c, d):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = PyArray_MultiIterNew(3, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 778; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":777
+ *     return PyArray_MultiIterNew(2, <void*>a, <void*>b)
+ * 
+ * cdef inline object PyArray_MultiIterNew3(a, b, c):             # <<<<<<<<<<<<<<
+ *     return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)
+ * 
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("numpy.PyArray_MultiIterNew3", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":780
+ *     return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)
+ * 
+ * cdef inline object PyArray_MultiIterNew4(a, b, c, d):             # <<<<<<<<<<<<<<
+ *     return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)
+ * 
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew4(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c, PyObject *__pyx_v_d) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("PyArray_MultiIterNew4", 0);
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":781
+ * 
+ * cdef inline object PyArray_MultiIterNew4(a, b, c, d):
+ *     return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)             # <<<<<<<<<<<<<<
+ * 
+ * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = PyArray_MultiIterNew(4, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c), ((void *)__pyx_v_d)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 781; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":780
+ *     return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)
+ * 
+ * cdef inline object PyArray_MultiIterNew4(a, b, c, d):             # <<<<<<<<<<<<<<
+ *     return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)
+ * 
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("numpy.PyArray_MultiIterNew4", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":783
+ *     return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)
+ * 
+ * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e):             # <<<<<<<<<<<<<<
+ *     return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)
+ * 
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew5(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c, PyObject *__pyx_v_d, PyObject *__pyx_v_e) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("PyArray_MultiIterNew5", 0);
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":784
+ * 
+ * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e):
+ *     return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)             # <<<<<<<<<<<<<<
+ * 
+ * cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL:
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = PyArray_MultiIterNew(5, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c), ((void *)__pyx_v_d), ((void *)__pyx_v_e)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 784; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":783
+ *     return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)
+ * 
+ * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e):             # <<<<<<<<<<<<<<
+ *     return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)
+ * 
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("numpy.PyArray_MultiIterNew5", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":786
+ *     return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)
+ * 
+ * cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL:             # <<<<<<<<<<<<<<
+ *     # Recursive utility function used in __getbuffer__ to get format
+ *     # string. The new location in the format string is returned.
+ */
+
+static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx_v_descr, char *__pyx_v_f, char *__pyx_v_end, int *__pyx_v_offset) {
+  PyArray_Descr *__pyx_v_child = 0;
+  int __pyx_v_endian_detector;
+  int __pyx_v_little_endian;
+  PyObject *__pyx_v_fields = 0;
+  PyObject *__pyx_v_childname = NULL;
+  PyObject *__pyx_v_new_offset = NULL;
+  PyObject *__pyx_v_t = NULL;
+  char *__pyx_r;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  Py_ssize_t __pyx_t_2;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  int __pyx_t_5;
+  int __pyx_t_6;
+  int __pyx_t_7;
+  long __pyx_t_8;
+  char *__pyx_t_9;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("_util_dtypestring", 0);
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":793
+ *     cdef int delta_offset
+ *     cdef tuple i
+ *     cdef int endian_detector = 1             # <<<<<<<<<<<<<<
+ *     cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)
+ *     cdef tuple fields
+ */
+  __pyx_v_endian_detector = 1;
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":794
+ *     cdef tuple i
+ *     cdef int endian_detector = 1
+ *     cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)             # <<<<<<<<<<<<<<
+ *     cdef tuple fields
+ * 
+ */
+  __pyx_v_little_endian = ((((char *)(&__pyx_v_endian_detector))[0]) != 0);
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":797
+ *     cdef tuple fields
+ * 
+ *     for childname in descr.names:             # <<<<<<<<<<<<<<
+ *         fields = descr.fields[childname]
+ *         child, new_offset = fields
+ */
+  if (unlikely(__pyx_v_descr->names == Py_None)) {
+    PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable");
+    {__pyx_filename = __pyx_f[1]; __pyx_lineno = 797; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  __pyx_t_1 = __pyx_v_descr->names; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0;
+  for (;;) {
+    if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
+    #if CYTHON_COMPILING_IN_CPYTHON
+    __pyx_t_3 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_3); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 797; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    #else
+    __pyx_t_3 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 797; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    #endif
+    __Pyx_XDECREF_SET(__pyx_v_childname, __pyx_t_3);
+    __pyx_t_3 = 0;
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":798
+ * 
+ *     for childname in descr.names:
+ *         fields = descr.fields[childname]             # <<<<<<<<<<<<<<
+ *         child, new_offset = fields
+ * 
+ */
+    if (unlikely(__pyx_v_descr->fields == Py_None)) {
+      PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable");
+      {__pyx_filename = __pyx_f[1]; __pyx_lineno = 798; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+    __pyx_t_3 = __Pyx_PyDict_GetItem(__pyx_v_descr->fields, __pyx_v_childname); if (unlikely(__pyx_t_3 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 798; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+    __Pyx_GOTREF(__pyx_t_3);
+    if (!(likely(PyTuple_CheckExact(__pyx_t_3))||((__pyx_t_3) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "tuple", Py_TYPE(__pyx_t_3)->tp_name), 0))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 798; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_XDECREF_SET(__pyx_v_fields, ((PyObject*)__pyx_t_3));
+    __pyx_t_3 = 0;
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":799
+ *     for childname in descr.names:
+ *         fields = descr.fields[childname]
+ *         child, new_offset = fields             # <<<<<<<<<<<<<<
+ * 
+ *         if (end - f) - <int>(new_offset - offset[0]) < 15:
+ */
+    if (likely(__pyx_v_fields != Py_None)) {
+      PyObject* sequence = __pyx_v_fields;
+      #if CYTHON_COMPILING_IN_CPYTHON
+      Py_ssize_t size = Py_SIZE(sequence);
+      #else
+      Py_ssize_t size = PySequence_Size(sequence);
+      #endif
+      if (unlikely(size != 2)) {
+        if (size > 2) __Pyx_RaiseTooManyValuesError(2);
+        else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
+        {__pyx_filename = __pyx_f[1]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      }
+      #if CYTHON_COMPILING_IN_CPYTHON
+      __pyx_t_3 = PyTuple_GET_ITEM(sequence, 0); 
+      __pyx_t_4 = PyTuple_GET_ITEM(sequence, 1); 
+      __Pyx_INCREF(__pyx_t_3);
+      __Pyx_INCREF(__pyx_t_4);
+      #else
+      __pyx_t_3 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_4 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      #endif
+    } else {
+      __Pyx_RaiseNoneNotIterableError(); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+    if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_ptype_5numpy_dtype))))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_XDECREF_SET(__pyx_v_child, ((PyArray_Descr *)__pyx_t_3));
+    __pyx_t_3 = 0;
+    __Pyx_XDECREF_SET(__pyx_v_new_offset, __pyx_t_4);
+    __pyx_t_4 = 0;
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":801
+ *         child, new_offset = fields
+ * 
+ *         if (end - f) - <int>(new_offset - offset[0]) < 15:             # <<<<<<<<<<<<<<
+ *             raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd")
+ * 
+ */
+    __pyx_t_4 = __Pyx_PyInt_From_int((__pyx_v_offset[0])); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 801; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    __pyx_t_3 = PyNumber_Subtract(__pyx_v_new_offset, __pyx_t_4); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 801; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    __pyx_t_5 = __Pyx_PyInt_As_int(__pyx_t_3); if (unlikely((__pyx_t_5 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 801; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __pyx_t_6 = ((((__pyx_v_end - __pyx_v_f) - ((int)__pyx_t_5)) < 15) != 0);
+    if (__pyx_t_6) {
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":802
+ * 
+ *         if (end - f) - <int>(new_offset - offset[0]) < 15:
+ *             raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd")             # <<<<<<<<<<<<<<
+ * 
+ *         if ((child.byteorder == c'>' and little_endian) or
+ */
+      __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_RuntimeError, __pyx_tuple__11, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 802; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      {__pyx_filename = __pyx_f[1]; __pyx_lineno = 802; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":804
+ *             raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd")
+ * 
+ *         if ((child.byteorder == c'>' and little_endian) or             # <<<<<<<<<<<<<<
+ *             (child.byteorder == c'<' and not little_endian)):
+ *             raise ValueError(u"Non-native byte order not supported")
+ */
+    __pyx_t_7 = ((__pyx_v_child->byteorder == '>') != 0);
+    if (!__pyx_t_7) {
+      goto __pyx_L8_next_or;
+    } else {
+    }
+    __pyx_t_7 = (__pyx_v_little_endian != 0);
+    if (!__pyx_t_7) {
+    } else {
+      __pyx_t_6 = __pyx_t_7;
+      goto __pyx_L7_bool_binop_done;
+    }
+    __pyx_L8_next_or:;
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":805
+ * 
+ *         if ((child.byteorder == c'>' and little_endian) or
+ *             (child.byteorder == c'<' and not little_endian)):             # <<<<<<<<<<<<<<
+ *             raise ValueError(u"Non-native byte order not supported")
+ *             # One could encode it in the format string and have Cython
+ */
+    __pyx_t_7 = ((__pyx_v_child->byteorder == '<') != 0);
+    if (__pyx_t_7) {
+    } else {
+      __pyx_t_6 = __pyx_t_7;
+      goto __pyx_L7_bool_binop_done;
+    }
+    __pyx_t_7 = ((!(__pyx_v_little_endian != 0)) != 0);
+    __pyx_t_6 = __pyx_t_7;
+    __pyx_L7_bool_binop_done:;
+    if (__pyx_t_6) {
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":806
+ *         if ((child.byteorder == c'>' and little_endian) or
+ *             (child.byteorder == c'<' and not little_endian)):
+ *             raise ValueError(u"Non-native byte order not supported")             # <<<<<<<<<<<<<<
+ *             # One could encode it in the format string and have Cython
+ *             # complain instead, BUT: < and > in format strings also imply
+ */
+      __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__12, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 806; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      {__pyx_filename = __pyx_f[1]; __pyx_lineno = 806; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":816
+ * 
+ *         # Output padding bytes
+ *         while offset[0] < new_offset:             # <<<<<<<<<<<<<<
+ *             f[0] = 120 # "x"; pad byte
+ *             f += 1
+ */
+    while (1) {
+      __pyx_t_3 = __Pyx_PyInt_From_int((__pyx_v_offset[0])); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 816; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_4 = PyObject_RichCompare(__pyx_t_3, __pyx_v_new_offset, Py_LT); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 816; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 816; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      if (!__pyx_t_6) break;
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":817
+ *         # Output padding bytes
+ *         while offset[0] < new_offset:
+ *             f[0] = 120 # "x"; pad byte             # <<<<<<<<<<<<<<
+ *             f += 1
+ *             offset[0] += 1
+ */
+      (__pyx_v_f[0]) = 120;
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":818
+ *         while offset[0] < new_offset:
+ *             f[0] = 120 # "x"; pad byte
+ *             f += 1             # <<<<<<<<<<<<<<
+ *             offset[0] += 1
+ * 
+ */
+      __pyx_v_f = (__pyx_v_f + 1);
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":819
+ *             f[0] = 120 # "x"; pad byte
+ *             f += 1
+ *             offset[0] += 1             # <<<<<<<<<<<<<<
+ * 
+ *         offset[0] += child.itemsize
+ */
+      __pyx_t_8 = 0;
+      (__pyx_v_offset[__pyx_t_8]) = ((__pyx_v_offset[__pyx_t_8]) + 1);
+    }
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":821
+ *             offset[0] += 1
+ * 
+ *         offset[0] += child.itemsize             # <<<<<<<<<<<<<<
+ * 
+ *         if not PyDataType_HASFIELDS(child):
+ */
+    __pyx_t_8 = 0;
+    (__pyx_v_offset[__pyx_t_8]) = ((__pyx_v_offset[__pyx_t_8]) + __pyx_v_child->elsize);
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":823
+ *         offset[0] += child.itemsize
+ * 
+ *         if not PyDataType_HASFIELDS(child):             # <<<<<<<<<<<<<<
+ *             t = child.type_num
+ *             if end - f < 5:
+ */
+    __pyx_t_6 = ((!(PyDataType_HASFIELDS(__pyx_v_child) != 0)) != 0);
+    if (__pyx_t_6) {
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":824
+ * 
+ *         if not PyDataType_HASFIELDS(child):
+ *             t = child.type_num             # <<<<<<<<<<<<<<
+ *             if end - f < 5:
+ *                 raise RuntimeError(u"Format string allocated too short.")
+ */
+      __pyx_t_4 = __Pyx_PyInt_From_int(__pyx_v_child->type_num); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 824; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __Pyx_XDECREF_SET(__pyx_v_t, __pyx_t_4);
+      __pyx_t_4 = 0;
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":825
+ *         if not PyDataType_HASFIELDS(child):
+ *             t = child.type_num
+ *             if end - f < 5:             # <<<<<<<<<<<<<<
+ *                 raise RuntimeError(u"Format string allocated too short.")
+ * 
+ */
+      __pyx_t_6 = (((__pyx_v_end - __pyx_v_f) < 5) != 0);
+      if (__pyx_t_6) {
+
+        /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":826
+ *             t = child.type_num
+ *             if end - f < 5:
+ *                 raise RuntimeError(u"Format string allocated too short.")             # <<<<<<<<<<<<<<
+ * 
+ *             # Until ticket #99 is fixed, use integers to avoid warnings
+ */
+        __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_RuntimeError, __pyx_tuple__13, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 826; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_4);
+        __Pyx_Raise(__pyx_t_4, 0, 0, 0);
+        __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+        {__pyx_filename = __pyx_f[1]; __pyx_lineno = 826; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      }
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":829
+ * 
+ *             # Until ticket #99 is fixed, use integers to avoid warnings
+ *             if   t == NPY_BYTE:        f[0] =  98 #"b"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_UBYTE:       f[0] =  66 #"B"
+ *             elif t == NPY_SHORT:       f[0] = 104 #"h"
+ */
+      __pyx_t_4 = PyInt_FromLong(NPY_BYTE); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 829; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 829; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 829; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 98;
+        goto __pyx_L15;
+      }
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":830
+ *             # Until ticket #99 is fixed, use integers to avoid warnings
+ *             if   t == NPY_BYTE:        f[0] =  98 #"b"
+ *             elif t == NPY_UBYTE:       f[0] =  66 #"B"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_SHORT:       f[0] = 104 #"h"
+ *             elif t == NPY_USHORT:      f[0] =  72 #"H"
+ */
+      __pyx_t_3 = PyInt_FromLong(NPY_UBYTE); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 830; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 830; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 830; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 66;
+        goto __pyx_L15;
+      }
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":831
+ *             if   t == NPY_BYTE:        f[0] =  98 #"b"
+ *             elif t == NPY_UBYTE:       f[0] =  66 #"B"
+ *             elif t == NPY_SHORT:       f[0] = 104 #"h"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_USHORT:      f[0] =  72 #"H"
+ *             elif t == NPY_INT:         f[0] = 105 #"i"
+ */
+      __pyx_t_4 = PyInt_FromLong(NPY_SHORT); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 831; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 831; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 831; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 104;
+        goto __pyx_L15;
+      }
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":832
+ *             elif t == NPY_UBYTE:       f[0] =  66 #"B"
+ *             elif t == NPY_SHORT:       f[0] = 104 #"h"
+ *             elif t == NPY_USHORT:      f[0] =  72 #"H"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_INT:         f[0] = 105 #"i"
+ *             elif t == NPY_UINT:        f[0] =  73 #"I"
+ */
+      __pyx_t_3 = PyInt_FromLong(NPY_USHORT); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 832; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 832; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 832; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 72;
+        goto __pyx_L15;
+      }
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":833
+ *             elif t == NPY_SHORT:       f[0] = 104 #"h"
+ *             elif t == NPY_USHORT:      f[0] =  72 #"H"
+ *             elif t == NPY_INT:         f[0] = 105 #"i"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_UINT:        f[0] =  73 #"I"
+ *             elif t == NPY_LONG:        f[0] = 108 #"l"
+ */
+      __pyx_t_4 = PyInt_FromLong(NPY_INT); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 833; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 833; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 833; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 105;
+        goto __pyx_L15;
+      }
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":834
+ *             elif t == NPY_USHORT:      f[0] =  72 #"H"
+ *             elif t == NPY_INT:         f[0] = 105 #"i"
+ *             elif t == NPY_UINT:        f[0] =  73 #"I"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_LONG:        f[0] = 108 #"l"
+ *             elif t == NPY_ULONG:       f[0] = 76  #"L"
+ */
+      __pyx_t_3 = PyInt_FromLong(NPY_UINT); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 834; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 834; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 834; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 73;
+        goto __pyx_L15;
+      }
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":835
+ *             elif t == NPY_INT:         f[0] = 105 #"i"
+ *             elif t == NPY_UINT:        f[0] =  73 #"I"
+ *             elif t == NPY_LONG:        f[0] = 108 #"l"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_ULONG:       f[0] = 76  #"L"
+ *             elif t == NPY_LONGLONG:    f[0] = 113 #"q"
+ */
+      __pyx_t_4 = PyInt_FromLong(NPY_LONG); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 835; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 835; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 835; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 108;
+        goto __pyx_L15;
+      }
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":836
+ *             elif t == NPY_UINT:        f[0] =  73 #"I"
+ *             elif t == NPY_LONG:        f[0] = 108 #"l"
+ *             elif t == NPY_ULONG:       f[0] = 76  #"L"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_LONGLONG:    f[0] = 113 #"q"
+ *             elif t == NPY_ULONGLONG:   f[0] = 81  #"Q"
+ */
+      __pyx_t_3 = PyInt_FromLong(NPY_ULONG); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 836; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 836; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 836; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 76;
+        goto __pyx_L15;
+      }
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":837
+ *             elif t == NPY_LONG:        f[0] = 108 #"l"
+ *             elif t == NPY_ULONG:       f[0] = 76  #"L"
+ *             elif t == NPY_LONGLONG:    f[0] = 113 #"q"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_ULONGLONG:   f[0] = 81  #"Q"
+ *             elif t == NPY_FLOAT:       f[0] = 102 #"f"
+ */
+      __pyx_t_4 = PyInt_FromLong(NPY_LONGLONG); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 837; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 837; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 837; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 113;
+        goto __pyx_L15;
+      }
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":838
+ *             elif t == NPY_ULONG:       f[0] = 76  #"L"
+ *             elif t == NPY_LONGLONG:    f[0] = 113 #"q"
+ *             elif t == NPY_ULONGLONG:   f[0] = 81  #"Q"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_FLOAT:       f[0] = 102 #"f"
+ *             elif t == NPY_DOUBLE:      f[0] = 100 #"d"
+ */
+      __pyx_t_3 = PyInt_FromLong(NPY_ULONGLONG); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 838; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 838; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 838; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 81;
+        goto __pyx_L15;
+      }
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":839
+ *             elif t == NPY_LONGLONG:    f[0] = 113 #"q"
+ *             elif t == NPY_ULONGLONG:   f[0] = 81  #"Q"
+ *             elif t == NPY_FLOAT:       f[0] = 102 #"f"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_DOUBLE:      f[0] = 100 #"d"
+ *             elif t == NPY_LONGDOUBLE:  f[0] = 103 #"g"
+ */
+      __pyx_t_4 = PyInt_FromLong(NPY_FLOAT); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 839; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 839; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 839; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 102;
+        goto __pyx_L15;
+      }
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":840
+ *             elif t == NPY_ULONGLONG:   f[0] = 81  #"Q"
+ *             elif t == NPY_FLOAT:       f[0] = 102 #"f"
+ *             elif t == NPY_DOUBLE:      f[0] = 100 #"d"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_LONGDOUBLE:  f[0] = 103 #"g"
+ *             elif t == NPY_CFLOAT:      f[0] = 90; f[1] = 102; f += 1 # Zf
+ */
+      __pyx_t_3 = PyInt_FromLong(NPY_DOUBLE); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 840; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 840; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 840; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 100;
+        goto __pyx_L15;
+      }
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":841
+ *             elif t == NPY_FLOAT:       f[0] = 102 #"f"
+ *             elif t == NPY_DOUBLE:      f[0] = 100 #"d"
+ *             elif t == NPY_LONGDOUBLE:  f[0] = 103 #"g"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_CFLOAT:      f[0] = 90; f[1] = 102; f += 1 # Zf
+ *             elif t == NPY_CDOUBLE:     f[0] = 90; f[1] = 100; f += 1 # Zd
+ */
+      __pyx_t_4 = PyInt_FromLong(NPY_LONGDOUBLE); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 841; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 841; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 841; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 103;
+        goto __pyx_L15;
+      }
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":842
+ *             elif t == NPY_DOUBLE:      f[0] = 100 #"d"
+ *             elif t == NPY_LONGDOUBLE:  f[0] = 103 #"g"
+ *             elif t == NPY_CFLOAT:      f[0] = 90; f[1] = 102; f += 1 # Zf             # <<<<<<<<<<<<<<
+ *             elif t == NPY_CDOUBLE:     f[0] = 90; f[1] = 100; f += 1 # Zd
+ *             elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg
+ */
+      __pyx_t_3 = PyInt_FromLong(NPY_CFLOAT); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 842; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 842; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 842; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 90;
+        (__pyx_v_f[1]) = 102;
+        __pyx_v_f = (__pyx_v_f + 1);
+        goto __pyx_L15;
+      }
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":843
+ *             elif t == NPY_LONGDOUBLE:  f[0] = 103 #"g"
+ *             elif t == NPY_CFLOAT:      f[0] = 90; f[1] = 102; f += 1 # Zf
+ *             elif t == NPY_CDOUBLE:     f[0] = 90; f[1] = 100; f += 1 # Zd             # <<<<<<<<<<<<<<
+ *             elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg
+ *             elif t == NPY_OBJECT:      f[0] = 79 #"O"
+ */
+      __pyx_t_4 = PyInt_FromLong(NPY_CDOUBLE); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 843; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 843; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 843; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 90;
+        (__pyx_v_f[1]) = 100;
+        __pyx_v_f = (__pyx_v_f + 1);
+        goto __pyx_L15;
+      }
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":844
+ *             elif t == NPY_CFLOAT:      f[0] = 90; f[1] = 102; f += 1 # Zf
+ *             elif t == NPY_CDOUBLE:     f[0] = 90; f[1] = 100; f += 1 # Zd
+ *             elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg             # <<<<<<<<<<<<<<
+ *             elif t == NPY_OBJECT:      f[0] = 79 #"O"
+ *             else:
+ */
+      __pyx_t_3 = PyInt_FromLong(NPY_CLONGDOUBLE); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 844; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 844; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 844; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 90;
+        (__pyx_v_f[1]) = 103;
+        __pyx_v_f = (__pyx_v_f + 1);
+        goto __pyx_L15;
+      }
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":845
+ *             elif t == NPY_CDOUBLE:     f[0] = 90; f[1] = 100; f += 1 # Zd
+ *             elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg
+ *             elif t == NPY_OBJECT:      f[0] = 79 #"O"             # <<<<<<<<<<<<<<
+ *             else:
+ *                 raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
+ */
+      __pyx_t_4 = PyInt_FromLong(NPY_OBJECT); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 845; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 845; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 845; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 79;
+        goto __pyx_L15;
+      }
+      /*else*/ {
+
+        /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":847
+ *             elif t == NPY_OBJECT:      f[0] = 79 #"O"
+ *             else:
+ *                 raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)             # <<<<<<<<<<<<<<
+ *             f += 1
+ *         else:
+ */
+        __pyx_t_3 = PyUnicode_Format(__pyx_kp_u_unknown_dtype_code_in_numpy_pxd, __pyx_v_t); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 847; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_3);
+        __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 847; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_4);
+        PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
+        __Pyx_GIVEREF(__pyx_t_3);
+        __pyx_t_3 = 0;
+        __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 847; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_3);
+        __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+        __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+        __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+        {__pyx_filename = __pyx_f[1]; __pyx_lineno = 847; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      }
+      __pyx_L15:;
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":848
+ *             else:
+ *                 raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
+ *             f += 1             # <<<<<<<<<<<<<<
+ *         else:
+ *             # Cython ignores struct boundary information ("T{...}"),
+ */
+      __pyx_v_f = (__pyx_v_f + 1);
+      goto __pyx_L13;
+    }
+    /*else*/ {
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":852
+ *             # Cython ignores struct boundary information ("T{...}"),
+ *             # so don't output it
+ *             f = _util_dtypestring(child, f, end, offset)             # <<<<<<<<<<<<<<
+ *     return f
+ * 
+ */
+      __pyx_t_9 = __pyx_f_5numpy__util_dtypestring(__pyx_v_child, __pyx_v_f, __pyx_v_end, __pyx_v_offset); if (unlikely(__pyx_t_9 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 852; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_v_f = __pyx_t_9;
+    }
+    __pyx_L13:;
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":797
+ *     cdef tuple fields
+ * 
+ *     for childname in descr.names:             # <<<<<<<<<<<<<<
+ *         fields = descr.fields[childname]
+ *         child, new_offset = fields
+ */
+  }
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":853
+ *             # so don't output it
+ *             f = _util_dtypestring(child, f, end, offset)
+ *     return f             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+  __pyx_r = __pyx_v_f;
+  goto __pyx_L0;
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":786
+ *     return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)
+ * 
+ * cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL:             # <<<<<<<<<<<<<<
+ *     # Recursive utility function used in __getbuffer__ to get format
+ *     # string. The new location in the format string is returned.
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_AddTraceback("numpy._util_dtypestring", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XDECREF((PyObject *)__pyx_v_child);
+  __Pyx_XDECREF(__pyx_v_fields);
+  __Pyx_XDECREF(__pyx_v_childname);
+  __Pyx_XDECREF(__pyx_v_new_offset);
+  __Pyx_XDECREF(__pyx_v_t);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":969
+ * 
+ * 
+ * cdef inline void set_array_base(ndarray arr, object base):             # <<<<<<<<<<<<<<
+ *      cdef PyObject* baseptr
+ *      if base is None:
+ */
+
+static CYTHON_INLINE void __pyx_f_5numpy_set_array_base(PyArrayObject *__pyx_v_arr, PyObject *__pyx_v_base) {
+  PyObject *__pyx_v_baseptr;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  int __pyx_t_2;
+  __Pyx_RefNannySetupContext("set_array_base", 0);
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":971
+ * cdef inline void set_array_base(ndarray arr, object base):
+ *      cdef PyObject* baseptr
+ *      if base is None:             # <<<<<<<<<<<<<<
+ *          baseptr = NULL
+ *      else:
+ */
+  __pyx_t_1 = (__pyx_v_base == Py_None);
+  __pyx_t_2 = (__pyx_t_1 != 0);
+  if (__pyx_t_2) {
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":972
+ *      cdef PyObject* baseptr
+ *      if base is None:
+ *          baseptr = NULL             # <<<<<<<<<<<<<<
+ *      else:
+ *          Py_INCREF(base) # important to do this before decref below!
+ */
+    __pyx_v_baseptr = NULL;
+    goto __pyx_L3;
+  }
+  /*else*/ {
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":974
+ *          baseptr = NULL
+ *      else:
+ *          Py_INCREF(base) # important to do this before decref below!             # <<<<<<<<<<<<<<
+ *          baseptr = <PyObject*>base
+ *      Py_XDECREF(arr.base)
+ */
+    Py_INCREF(__pyx_v_base);
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":975
+ *      else:
+ *          Py_INCREF(base) # important to do this before decref below!
+ *          baseptr = <PyObject*>base             # <<<<<<<<<<<<<<
+ *      Py_XDECREF(arr.base)
+ *      arr.base = baseptr
+ */
+    __pyx_v_baseptr = ((PyObject *)__pyx_v_base);
+  }
+  __pyx_L3:;
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":976
+ *          Py_INCREF(base) # important to do this before decref below!
+ *          baseptr = <PyObject*>base
+ *      Py_XDECREF(arr.base)             # <<<<<<<<<<<<<<
+ *      arr.base = baseptr
+ * 
+ */
+  Py_XDECREF(__pyx_v_arr->base);
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":977
+ *          baseptr = <PyObject*>base
+ *      Py_XDECREF(arr.base)
+ *      arr.base = baseptr             # <<<<<<<<<<<<<<
+ * 
+ * cdef inline object get_array_base(ndarray arr):
+ */
+  __pyx_v_arr->base = __pyx_v_baseptr;
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":969
+ * 
+ * 
+ * cdef inline void set_array_base(ndarray arr, object base):             # <<<<<<<<<<<<<<
+ *      cdef PyObject* baseptr
+ *      if base is None:
+ */
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+}
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":979
+ *      arr.base = baseptr
+ * 
+ * cdef inline object get_array_base(ndarray arr):             # <<<<<<<<<<<<<<
+ *     if arr.base is NULL:
+ *         return None
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_5numpy_get_array_base(PyArrayObject *__pyx_v_arr) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("get_array_base", 0);
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":980
+ * 
+ * cdef inline object get_array_base(ndarray arr):
+ *     if arr.base is NULL:             # <<<<<<<<<<<<<<
+ *         return None
+ *     else:
+ */
+  __pyx_t_1 = ((__pyx_v_arr->base == NULL) != 0);
+  if (__pyx_t_1) {
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":981
+ * cdef inline object get_array_base(ndarray arr):
+ *     if arr.base is NULL:
+ *         return None             # <<<<<<<<<<<<<<
+ *     else:
+ *         return <object>arr.base
+ */
+    __Pyx_XDECREF(__pyx_r);
+    __Pyx_INCREF(Py_None);
+    __pyx_r = Py_None;
+    goto __pyx_L0;
+  }
+  /*else*/ {
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":983
+ *         return None
+ *     else:
+ *         return <object>arr.base             # <<<<<<<<<<<<<<
+ */
+    __Pyx_XDECREF(__pyx_r);
+    __Pyx_INCREF(((PyObject *)__pyx_v_arr->base));
+    __pyx_r = ((PyObject *)__pyx_v_arr->base);
+    goto __pyx_L0;
+  }
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":979
+ *      arr.base = baseptr
+ * 
+ * cdef inline object get_array_base(ndarray arr):             # <<<<<<<<<<<<<<
+ *     if arr.base is NULL:
+ *         return None
+ */
+
+  /* function exit code */
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+static struct __pyx_vtabstruct_2bx_3bbi_11bigbed_file_BigBedBlockHandler __pyx_vtable_2bx_3bbi_11bigbed_file_BigBedBlockHandler;
+
+static PyObject *__pyx_tp_new_2bx_3bbi_11bigbed_file_BigBedBlockHandler(PyTypeObject *t, PyObject *a, PyObject *k) {
+  struct __pyx_obj_2bx_3bbi_11bigbed_file_BigBedBlockHandler *p;
+  PyObject *o = __pyx_ptype_2bx_3bbi_8bbi_file_BlockHandler->tp_new(t, a, k);
+  if (unlikely(!o)) return 0;
+  p = ((struct __pyx_obj_2bx_3bbi_11bigbed_file_BigBedBlockHandler *)o);
+  p->__pyx_base.__pyx_vtab = (struct __pyx_vtabstruct_2bx_3bbi_8bbi_file_BlockHandler*)__pyx_vtabptr_2bx_3bbi_11bigbed_file_BigBedBlockHandler;
+  return o;
+}
+
+static void __pyx_tp_dealloc_2bx_3bbi_11bigbed_file_BigBedBlockHandler(PyObject *o) {
+  #if PY_VERSION_HEX >= 0x030400a1
+  if (unlikely(Py_TYPE(o)->tp_finalize) && (!PyType_IS_GC(Py_TYPE(o)) || !_PyGC_FINALIZED(o))) {
+    if (PyObject_CallFinalizerFromDealloc(o)) return;
+  }
+  #endif
+  if (likely(__pyx_ptype_2bx_3bbi_8bbi_file_BlockHandler)) __pyx_ptype_2bx_3bbi_8bbi_file_BlockHandler->tp_dealloc(o); else __Pyx_call_next_tp_dealloc(o, __pyx_tp_dealloc_2bx_3bbi_11bigbed_file_BigBedBlockHandler);
+}
+
+static PyMethodDef __pyx_methods_2bx_3bbi_11bigbed_file_BigBedBlockHandler[] = {
+  {0, 0, 0, 0}
+};
+
+static PyTypeObject __pyx_type_2bx_3bbi_11bigbed_file_BigBedBlockHandler = {
+  PyVarObject_HEAD_INIT(0, 0)
+  "bx.bbi.bigbed_file.BigBedBlockHandler", /*tp_name*/
+  sizeof(struct __pyx_obj_2bx_3bbi_11bigbed_file_BigBedBlockHandler), /*tp_basicsize*/
+  0, /*tp_itemsize*/
+  __pyx_tp_dealloc_2bx_3bbi_11bigbed_file_BigBedBlockHandler, /*tp_dealloc*/
+  0, /*tp_print*/
+  0, /*tp_getattr*/
+  0, /*tp_setattr*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*tp_compare*/
+  #else
+  0, /*reserved*/
+  #endif
+  0, /*tp_repr*/
+  0, /*tp_as_number*/
+  0, /*tp_as_sequence*/
+  0, /*tp_as_mapping*/
+  0, /*tp_hash*/
+  0, /*tp_call*/
+  0, /*tp_str*/
+  0, /*tp_getattro*/
+  0, /*tp_setattro*/
+  0, /*tp_as_buffer*/
+  Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE, /*tp_flags*/
+  "\n    BlockHandler that parses the block into a series of BED records\n    ", /*tp_doc*/
+  0, /*tp_traverse*/
+  0, /*tp_clear*/
+  0, /*tp_richcompare*/
+  0, /*tp_weaklistoffset*/
+  0, /*tp_iter*/
+  0, /*tp_iternext*/
+  __pyx_methods_2bx_3bbi_11bigbed_file_BigBedBlockHandler, /*tp_methods*/
+  0, /*tp_members*/
+  0, /*tp_getset*/
+  0, /*tp_base*/
+  0, /*tp_dict*/
+  0, /*tp_descr_get*/
+  0, /*tp_descr_set*/
+  0, /*tp_dictoffset*/
+  __pyx_pw_2bx_3bbi_11bigbed_file_18BigBedBlockHandler_1__init__, /*tp_init*/
+  0, /*tp_alloc*/
+  __pyx_tp_new_2bx_3bbi_11bigbed_file_BigBedBlockHandler, /*tp_new*/
+  0, /*tp_free*/
+  0, /*tp_is_gc*/
+  0, /*tp_bases*/
+  0, /*tp_mro*/
+  0, /*tp_cache*/
+  0, /*tp_subclasses*/
+  0, /*tp_weaklist*/
+  0, /*tp_del*/
+  0, /*tp_version_tag*/
+  #if PY_VERSION_HEX >= 0x030400a1
+  0, /*tp_finalize*/
+  #endif
+};
+static struct __pyx_vtabstruct_2bx_3bbi_11bigbed_file_SummarizingBlockHandler __pyx_vtable_2bx_3bbi_11bigbed_file_SummarizingBlockHandler;
+
+static PyObject *__pyx_tp_new_2bx_3bbi_11bigbed_file_SummarizingBlockHandler(PyTypeObject *t, PyObject *a, PyObject *k) {
+  struct __pyx_obj_2bx_3bbi_11bigbed_file_SummarizingBlockHandler *p;
+  PyObject *o = __pyx_tp_new_2bx_3bbi_11bigbed_file_BigBedBlockHandler(t, a, k);
+  if (unlikely(!o)) return 0;
+  p = ((struct __pyx_obj_2bx_3bbi_11bigbed_file_SummarizingBlockHandler *)o);
+  p->__pyx_base.__pyx_base.__pyx_vtab = (struct __pyx_vtabstruct_2bx_3bbi_8bbi_file_BlockHandler*)__pyx_vtabptr_2bx_3bbi_11bigbed_file_SummarizingBlockHandler;
+  p->sd = ((struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData *)Py_None); Py_INCREF(Py_None);
+  return o;
+}
+
+static void __pyx_tp_dealloc_2bx_3bbi_11bigbed_file_SummarizingBlockHandler(PyObject *o) {
+  struct __pyx_obj_2bx_3bbi_11bigbed_file_SummarizingBlockHandler *p = (struct __pyx_obj_2bx_3bbi_11bigbed_file_SummarizingBlockHandler *)o;
+  #if PY_VERSION_HEX >= 0x030400a1
+  if (unlikely(Py_TYPE(o)->tp_finalize) && !_PyGC_FINALIZED(o)) {
+    if (PyObject_CallFinalizerFromDealloc(o)) return;
+  }
+  #endif
+  PyObject_GC_UnTrack(o);
+  Py_CLEAR(p->sd);
+  #if CYTHON_COMPILING_IN_CPYTHON
+  if (PyType_IS_GC(Py_TYPE(o)->tp_base))
+  #endif
+  PyObject_GC_Track(o);
+  __pyx_tp_dealloc_2bx_3bbi_11bigbed_file_BigBedBlockHandler(o);
+}
+
+static int __pyx_tp_traverse_2bx_3bbi_11bigbed_file_SummarizingBlockHandler(PyObject *o, visitproc v, void *a) {
+  int e;
+  struct __pyx_obj_2bx_3bbi_11bigbed_file_SummarizingBlockHandler *p = (struct __pyx_obj_2bx_3bbi_11bigbed_file_SummarizingBlockHandler *)o;
+  e = ((likely(__pyx_ptype_2bx_3bbi_11bigbed_file_BigBedBlockHandler)) ? ((__pyx_ptype_2bx_3bbi_11bigbed_file_BigBedBlockHandler->tp_traverse) ? __pyx_ptype_2bx_3bbi_11bigbed_file_BigBedBlockHandler->tp_traverse(o, v, a) : 0) : __Pyx_call_next_tp_traverse(o, v, a, __pyx_tp_traverse_2bx_3bbi_11bigbed_file_SummarizingBlockHandler)); if (e) return e;
+  if (p->sd) {
+    e = (*v)(((PyObject*)p->sd), a); if (e) return e;
+  }
+  return 0;
+}
+
+static int __pyx_tp_clear_2bx_3bbi_11bigbed_file_SummarizingBlockHandler(PyObject *o) {
+  PyObject* tmp;
+  struct __pyx_obj_2bx_3bbi_11bigbed_file_SummarizingBlockHandler *p = (struct __pyx_obj_2bx_3bbi_11bigbed_file_SummarizingBlockHandler *)o;
+  if (likely(__pyx_ptype_2bx_3bbi_11bigbed_file_BigBedBlockHandler)) { if (__pyx_ptype_2bx_3bbi_11bigbed_file_BigBedBlockHandler->tp_clear) __pyx_ptype_2bx_3bbi_11bigbed_file_BigBedBlockHandler->tp_clear(o); } else __Pyx_call_next_tp_clear(o, __pyx_tp_clear_2bx_3bbi_11bigbed_file_SummarizingBlockHandler);
+  tmp = ((PyObject*)p->sd);
+  p->sd = ((struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData *)Py_None); Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  return 0;
+}
+
+static PyMethodDef __pyx_methods_2bx_3bbi_11bigbed_file_SummarizingBlockHandler[] = {
+  {0, 0, 0, 0}
+};
+
+static PyTypeObject __pyx_type_2bx_3bbi_11bigbed_file_SummarizingBlockHandler = {
+  PyVarObject_HEAD_INIT(0, 0)
+  "bx.bbi.bigbed_file.SummarizingBlockHandler", /*tp_name*/
+  sizeof(struct __pyx_obj_2bx_3bbi_11bigbed_file_SummarizingBlockHandler), /*tp_basicsize*/
+  0, /*tp_itemsize*/
+  __pyx_tp_dealloc_2bx_3bbi_11bigbed_file_SummarizingBlockHandler, /*tp_dealloc*/
+  0, /*tp_print*/
+  0, /*tp_getattr*/
+  0, /*tp_setattr*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*tp_compare*/
+  #else
+  0, /*reserved*/
+  #endif
+  0, /*tp_repr*/
+  0, /*tp_as_number*/
+  0, /*tp_as_sequence*/
+  0, /*tp_as_mapping*/
+  0, /*tp_hash*/
+  0, /*tp_call*/
+  0, /*tp_str*/
+  0, /*tp_getattro*/
+  0, /*tp_setattro*/
+  0, /*tp_as_buffer*/
+  Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+  "\n    Accumulates intervals into a SummarizedData\n    ", /*tp_doc*/
+  __pyx_tp_traverse_2bx_3bbi_11bigbed_file_SummarizingBlockHandler, /*tp_traverse*/
+  __pyx_tp_clear_2bx_3bbi_11bigbed_file_SummarizingBlockHandler, /*tp_clear*/
+  0, /*tp_richcompare*/
+  0, /*tp_weaklistoffset*/
+  0, /*tp_iter*/
+  0, /*tp_iternext*/
+  __pyx_methods_2bx_3bbi_11bigbed_file_SummarizingBlockHandler, /*tp_methods*/
+  0, /*tp_members*/
+  0, /*tp_getset*/
+  0, /*tp_base*/
+  0, /*tp_dict*/
+  0, /*tp_descr_get*/
+  0, /*tp_descr_set*/
+  0, /*tp_dictoffset*/
+  __pyx_pw_2bx_3bbi_11bigbed_file_23SummarizingBlockHandler_1__init__, /*tp_init*/
+  0, /*tp_alloc*/
+  __pyx_tp_new_2bx_3bbi_11bigbed_file_SummarizingBlockHandler, /*tp_new*/
+  0, /*tp_free*/
+  0, /*tp_is_gc*/
+  0, /*tp_bases*/
+  0, /*tp_mro*/
+  0, /*tp_cache*/
+  0, /*tp_subclasses*/
+  0, /*tp_weaklist*/
+  0, /*tp_del*/
+  0, /*tp_version_tag*/
+  #if PY_VERSION_HEX >= 0x030400a1
+  0, /*tp_finalize*/
+  #endif
+};
+static struct __pyx_vtabstruct_2bx_3bbi_11bigbed_file_IntervalAccumulatingBlockHandler __pyx_vtable_2bx_3bbi_11bigbed_file_IntervalAccumulatingBlockHandler;
+
+static PyObject *__pyx_tp_new_2bx_3bbi_11bigbed_file_IntervalAccumulatingBlockHandler(PyTypeObject *t, PyObject *a, PyObject *k) {
+  struct __pyx_obj_2bx_3bbi_11bigbed_file_IntervalAccumulatingBlockHandler *p;
+  PyObject *o = __pyx_tp_new_2bx_3bbi_11bigbed_file_BigBedBlockHandler(t, a, k);
+  if (unlikely(!o)) return 0;
+  p = ((struct __pyx_obj_2bx_3bbi_11bigbed_file_IntervalAccumulatingBlockHandler *)o);
+  p->__pyx_base.__pyx_base.__pyx_vtab = (struct __pyx_vtabstruct_2bx_3bbi_8bbi_file_BlockHandler*)__pyx_vtabptr_2bx_3bbi_11bigbed_file_IntervalAccumulatingBlockHandler;
+  p->intervals = ((PyObject*)Py_None); Py_INCREF(Py_None);
+  return o;
+}
+
+static void __pyx_tp_dealloc_2bx_3bbi_11bigbed_file_IntervalAccumulatingBlockHandler(PyObject *o) {
+  struct __pyx_obj_2bx_3bbi_11bigbed_file_IntervalAccumulatingBlockHandler *p = (struct __pyx_obj_2bx_3bbi_11bigbed_file_IntervalAccumulatingBlockHandler *)o;
+  #if PY_VERSION_HEX >= 0x030400a1
+  if (unlikely(Py_TYPE(o)->tp_finalize) && !_PyGC_FINALIZED(o)) {
+    if (PyObject_CallFinalizerFromDealloc(o)) return;
+  }
+  #endif
+  PyObject_GC_UnTrack(o);
+  Py_CLEAR(p->intervals);
+  #if CYTHON_COMPILING_IN_CPYTHON
+  if (PyType_IS_GC(Py_TYPE(o)->tp_base))
+  #endif
+  PyObject_GC_Track(o);
+  __pyx_tp_dealloc_2bx_3bbi_11bigbed_file_BigBedBlockHandler(o);
+}
+
+static int __pyx_tp_traverse_2bx_3bbi_11bigbed_file_IntervalAccumulatingBlockHandler(PyObject *o, visitproc v, void *a) {
+  int e;
+  struct __pyx_obj_2bx_3bbi_11bigbed_file_IntervalAccumulatingBlockHandler *p = (struct __pyx_obj_2bx_3bbi_11bigbed_file_IntervalAccumulatingBlockHandler *)o;
+  e = ((likely(__pyx_ptype_2bx_3bbi_11bigbed_file_BigBedBlockHandler)) ? ((__pyx_ptype_2bx_3bbi_11bigbed_file_BigBedBlockHandler->tp_traverse) ? __pyx_ptype_2bx_3bbi_11bigbed_file_BigBedBlockHandler->tp_traverse(o, v, a) : 0) : __Pyx_call_next_tp_traverse(o, v, a, __pyx_tp_traverse_2bx_3bbi_11bigbed_file_IntervalAccumulatingBlockHandler)); if (e) return e;
+  if (p->intervals) {
+    e = (*v)(p->intervals, a); if (e) return e;
+  }
+  return 0;
+}
+
+static int __pyx_tp_clear_2bx_3bbi_11bigbed_file_IntervalAccumulatingBlockHandler(PyObject *o) {
+  PyObject* tmp;
+  struct __pyx_obj_2bx_3bbi_11bigbed_file_IntervalAccumulatingBlockHandler *p = (struct __pyx_obj_2bx_3bbi_11bigbed_file_IntervalAccumulatingBlockHandler *)o;
+  if (likely(__pyx_ptype_2bx_3bbi_11bigbed_file_BigBedBlockHandler)) { if (__pyx_ptype_2bx_3bbi_11bigbed_file_BigBedBlockHandler->tp_clear) __pyx_ptype_2bx_3bbi_11bigbed_file_BigBedBlockHandler->tp_clear(o); } else __Pyx_call_next_tp_clear(o, __pyx_tp_clear_2bx_3bbi_11bigbed_file_IntervalAccumulatingBlockHandler);
+  tmp = ((PyObject*)p->intervals);
+  p->intervals = ((PyObject*)Py_None); Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  return 0;
+}
+
+static PyMethodDef __pyx_methods_2bx_3bbi_11bigbed_file_IntervalAccumulatingBlockHandler[] = {
+  {0, 0, 0, 0}
+};
+
+static PyTypeObject __pyx_type_2bx_3bbi_11bigbed_file_IntervalAccumulatingBlockHandler = {
+  PyVarObject_HEAD_INIT(0, 0)
+  "bx.bbi.bigbed_file.IntervalAccumulatingBlockHandler", /*tp_name*/
+  sizeof(struct __pyx_obj_2bx_3bbi_11bigbed_file_IntervalAccumulatingBlockHandler), /*tp_basicsize*/
+  0, /*tp_itemsize*/
+  __pyx_tp_dealloc_2bx_3bbi_11bigbed_file_IntervalAccumulatingBlockHandler, /*tp_dealloc*/
+  0, /*tp_print*/
+  0, /*tp_getattr*/
+  0, /*tp_setattr*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*tp_compare*/
+  #else
+  0, /*reserved*/
+  #endif
+  0, /*tp_repr*/
+  0, /*tp_as_number*/
+  0, /*tp_as_sequence*/
+  0, /*tp_as_mapping*/
+  0, /*tp_hash*/
+  0, /*tp_call*/
+  0, /*tp_str*/
+  0, /*tp_getattro*/
+  0, /*tp_setattro*/
+  0, /*tp_as_buffer*/
+  Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+  0, /*tp_doc*/
+  __pyx_tp_traverse_2bx_3bbi_11bigbed_file_IntervalAccumulatingBlockHandler, /*tp_traverse*/
+  __pyx_tp_clear_2bx_3bbi_11bigbed_file_IntervalAccumulatingBlockHandler, /*tp_clear*/
+  0, /*tp_richcompare*/
+  0, /*tp_weaklistoffset*/
+  0, /*tp_iter*/
+  0, /*tp_iternext*/
+  __pyx_methods_2bx_3bbi_11bigbed_file_IntervalAccumulatingBlockHandler, /*tp_methods*/
+  0, /*tp_members*/
+  0, /*tp_getset*/
+  0, /*tp_base*/
+  0, /*tp_dict*/
+  0, /*tp_descr_get*/
+  0, /*tp_descr_set*/
+  0, /*tp_dictoffset*/
+  __pyx_pw_2bx_3bbi_11bigbed_file_32IntervalAccumulatingBlockHandler_1__init__, /*tp_init*/
+  0, /*tp_alloc*/
+  __pyx_tp_new_2bx_3bbi_11bigbed_file_IntervalAccumulatingBlockHandler, /*tp_new*/
+  0, /*tp_free*/
+  0, /*tp_is_gc*/
+  0, /*tp_bases*/
+  0, /*tp_mro*/
+  0, /*tp_cache*/
+  0, /*tp_subclasses*/
+  0, /*tp_weaklist*/
+  0, /*tp_del*/
+  0, /*tp_version_tag*/
+  #if PY_VERSION_HEX >= 0x030400a1
+  0, /*tp_finalize*/
+  #endif
+};
+static struct __pyx_vtabstruct_2bx_3bbi_11bigbed_file_BigBedFile __pyx_vtable_2bx_3bbi_11bigbed_file_BigBedFile;
+
+static PyObject *__pyx_tp_new_2bx_3bbi_11bigbed_file_BigBedFile(PyTypeObject *t, PyObject *a, PyObject *k) {
+  struct __pyx_obj_2bx_3bbi_11bigbed_file_BigBedFile *p;
+  PyObject *o = __pyx_ptype_2bx_3bbi_8bbi_file_BBIFile->tp_new(t, a, k);
+  if (unlikely(!o)) return 0;
+  p = ((struct __pyx_obj_2bx_3bbi_11bigbed_file_BigBedFile *)o);
+  p->__pyx_base.__pyx_vtab = (struct __pyx_vtabstruct_2bx_3bbi_8bbi_file_BBIFile*)__pyx_vtabptr_2bx_3bbi_11bigbed_file_BigBedFile;
+  return o;
+}
+
+static void __pyx_tp_dealloc_2bx_3bbi_11bigbed_file_BigBedFile(PyObject *o) {
+  #if PY_VERSION_HEX >= 0x030400a1
+  if (unlikely(Py_TYPE(o)->tp_finalize) && !_PyGC_FINALIZED(o)) {
+    if (PyObject_CallFinalizerFromDealloc(o)) return;
+  }
+  #endif
+  PyObject_GC_UnTrack(o);
+  PyObject_GC_Track(o);
+  if (likely(__pyx_ptype_2bx_3bbi_8bbi_file_BBIFile)) __pyx_ptype_2bx_3bbi_8bbi_file_BBIFile->tp_dealloc(o); else __Pyx_call_next_tp_dealloc(o, __pyx_tp_dealloc_2bx_3bbi_11bigbed_file_BigBedFile);
+}
+
+static int __pyx_tp_traverse_2bx_3bbi_11bigbed_file_BigBedFile(PyObject *o, visitproc v, void *a) {
+  int e;
+  e = ((likely(__pyx_ptype_2bx_3bbi_8bbi_file_BBIFile)) ? ((__pyx_ptype_2bx_3bbi_8bbi_file_BBIFile->tp_traverse) ? __pyx_ptype_2bx_3bbi_8bbi_file_BBIFile->tp_traverse(o, v, a) : 0) : __Pyx_call_next_tp_traverse(o, v, a, __pyx_tp_traverse_2bx_3bbi_11bigbed_file_BigBedFile)); if (e) return e;
+  return 0;
+}
+
+static int __pyx_tp_clear_2bx_3bbi_11bigbed_file_BigBedFile(PyObject *o) {
+  if (likely(__pyx_ptype_2bx_3bbi_8bbi_file_BBIFile)) { if (__pyx_ptype_2bx_3bbi_8bbi_file_BBIFile->tp_clear) __pyx_ptype_2bx_3bbi_8bbi_file_BBIFile->tp_clear(o); } else __Pyx_call_next_tp_clear(o, __pyx_tp_clear_2bx_3bbi_11bigbed_file_BigBedFile);
+  return 0;
+}
+
+static PyMethodDef __pyx_methods_2bx_3bbi_11bigbed_file_BigBedFile[] = {
+  {"get", (PyCFunction)__pyx_pw_2bx_3bbi_11bigbed_file_10BigBedFile_3get, METH_VARARGS|METH_KEYWORDS, __pyx_doc_2bx_3bbi_11bigbed_file_10BigBedFile_2get},
+  {0, 0, 0, 0}
+};
+
+static PyTypeObject __pyx_type_2bx_3bbi_11bigbed_file_BigBedFile = {
+  PyVarObject_HEAD_INIT(0, 0)
+  "bx.bbi.bigbed_file.BigBedFile", /*tp_name*/
+  sizeof(struct __pyx_obj_2bx_3bbi_11bigbed_file_BigBedFile), /*tp_basicsize*/
+  0, /*tp_itemsize*/
+  __pyx_tp_dealloc_2bx_3bbi_11bigbed_file_BigBedFile, /*tp_dealloc*/
+  0, /*tp_print*/
+  0, /*tp_getattr*/
+  0, /*tp_setattr*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*tp_compare*/
+  #else
+  0, /*reserved*/
+  #endif
+  0, /*tp_repr*/
+  0, /*tp_as_number*/
+  0, /*tp_as_sequence*/
+  0, /*tp_as_mapping*/
+  0, /*tp_hash*/
+  0, /*tp_call*/
+  0, /*tp_str*/
+  0, /*tp_getattro*/
+  0, /*tp_setattro*/
+  0, /*tp_as_buffer*/
+  Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+  "\n    A \"big binary indexed\" file whose raw data is in BED format.\n    ", /*tp_doc*/
+  __pyx_tp_traverse_2bx_3bbi_11bigbed_file_BigBedFile, /*tp_traverse*/
+  __pyx_tp_clear_2bx_3bbi_11bigbed_file_BigBedFile, /*tp_clear*/
+  0, /*tp_richcompare*/
+  0, /*tp_weaklistoffset*/
+  0, /*tp_iter*/
+  0, /*tp_iternext*/
+  __pyx_methods_2bx_3bbi_11bigbed_file_BigBedFile, /*tp_methods*/
+  0, /*tp_members*/
+  0, /*tp_getset*/
+  0, /*tp_base*/
+  0, /*tp_dict*/
+  0, /*tp_descr_get*/
+  0, /*tp_descr_set*/
+  0, /*tp_dictoffset*/
+  __pyx_pw_2bx_3bbi_11bigbed_file_10BigBedFile_1__init__, /*tp_init*/
+  0, /*tp_alloc*/
+  __pyx_tp_new_2bx_3bbi_11bigbed_file_BigBedFile, /*tp_new*/
+  0, /*tp_free*/
+  0, /*tp_is_gc*/
+  0, /*tp_bases*/
+  0, /*tp_mro*/
+  0, /*tp_cache*/
+  0, /*tp_subclasses*/
+  0, /*tp_weaklist*/
+  0, /*tp_del*/
+  0, /*tp_version_tag*/
+  #if PY_VERSION_HEX >= 0x030400a1
+  0, /*tp_finalize*/
+  #endif
+};
+
+static PyMethodDef __pyx_methods[] = {
+  {0, 0, 0, 0}
+};
+
+#if PY_MAJOR_VERSION >= 3
+static struct PyModuleDef __pyx_moduledef = {
+  #if PY_VERSION_HEX < 0x03020000
+    { PyObject_HEAD_INIT(NULL) NULL, 0, NULL },
+  #else
+    PyModuleDef_HEAD_INIT,
+  #endif
+    "bigbed_file",
+    __pyx_k_BigBed_file, /* m_doc */
+    -1, /* m_size */
+    __pyx_methods /* m_methods */,
+    NULL, /* m_reload */
+    NULL, /* m_traverse */
+    NULL, /* m_clear */
+    NULL /* m_free */
+};
+#endif
+
+static __Pyx_StringTabEntry __pyx_string_tab[] = {
+  {&__pyx_kp_s_, __pyx_k_, sizeof(__pyx_k_), 0, 0, 1, 0},
+  {&__pyx_n_s_BinaryFileReader, __pyx_k_BinaryFileReader, sizeof(__pyx_k_BinaryFileReader), 0, 0, 1, 1},
+  {&__pyx_kp_u_Format_string_allocated_too_shor, __pyx_k_Format_string_allocated_too_shor, sizeof(__pyx_k_Format_string_allocated_too_shor), 0, 1, 0, 0},
+  {&__pyx_kp_u_Format_string_allocated_too_shor_2, __pyx_k_Format_string_allocated_too_shor_2, sizeof(__pyx_k_Format_string_allocated_too_shor_2), 0, 1, 0, 0},
+  {&__pyx_n_s_GenomicInterval, __pyx_k_GenomicInterval, sizeof(__pyx_k_GenomicInterval), 0, 0, 1, 1},
+  {&__pyx_n_s_LLL, __pyx_k_LLL, sizeof(__pyx_k_LLL), 0, 0, 1, 1},
+  {&__pyx_kp_u_Non_native_byte_order_not_suppor, __pyx_k_Non_native_byte_order_not_suppor, sizeof(__pyx_k_Non_native_byte_order_not_suppor), 0, 1, 0, 0},
+  {&__pyx_n_s_RuntimeError, __pyx_k_RuntimeError, sizeof(__pyx_k_RuntimeError), 0, 0, 1, 1},
+  {&__pyx_n_s_StringIO, __pyx_k_StringIO, sizeof(__pyx_k_StringIO), 0, 0, 1, 1},
+  {&__pyx_n_s_ValueError, __pyx_k_ValueError, sizeof(__pyx_k_ValueError), 0, 0, 1, 1},
+  {&__pyx_kp_s__3, __pyx_k__3, sizeof(__pyx_k__3), 0, 0, 1, 0},
+  {&__pyx_kp_s__5, __pyx_k__5, sizeof(__pyx_k__5), 0, 0, 1, 0},
+  {&__pyx_kp_s__7, __pyx_k__7, sizeof(__pyx_k__7), 0, 0, 1, 0},
+  {&__pyx_n_s_bigbed, __pyx_k_bigbed, sizeof(__pyx_k_bigbed), 0, 0, 1, 1},
+  {&__pyx_n_s_bx_intervals_io, __pyx_k_bx_intervals_io, sizeof(__pyx_k_bx_intervals_io), 0, 0, 1, 1},
+  {&__pyx_n_s_bx_misc_binary_file, __pyx_k_bx_misc_binary_file, sizeof(__pyx_k_bx_misc_binary_file), 0, 0, 1, 1},
+  {&__pyx_n_s_cStringIO, __pyx_k_cStringIO, sizeof(__pyx_k_cStringIO), 0, 0, 1, 1},
+  {&__pyx_n_s_chrom, __pyx_k_chrom, sizeof(__pyx_k_chrom), 0, 0, 1, 1},
+  {&__pyx_n_s_chrom_id, __pyx_k_chrom_id, sizeof(__pyx_k_chrom_id), 0, 0, 1, 1},
+  {&__pyx_n_s_end, __pyx_k_end, sizeof(__pyx_k_end), 0, 0, 1, 1},
+  {&__pyx_n_s_file, __pyx_k_file, sizeof(__pyx_k_file), 0, 0, 1, 1},
+  {&__pyx_n_s_find, __pyx_k_find, sizeof(__pyx_k_find), 0, 0, 1, 1},
+  {&__pyx_n_s_get, __pyx_k_get, sizeof(__pyx_k_get), 0, 0, 1, 1},
+  {&__pyx_n_s_import, __pyx_k_import, sizeof(__pyx_k_import), 0, 0, 1, 1},
+  {&__pyx_n_s_inf, __pyx_k_inf, sizeof(__pyx_k_inf), 0, 0, 1, 1},
+  {&__pyx_n_s_init, __pyx_k_init, sizeof(__pyx_k_init), 0, 0, 1, 1},
+  {&__pyx_n_s_is_little_endian, __pyx_k_is_little_endian, sizeof(__pyx_k_is_little_endian), 0, 0, 1, 1},
+  {&__pyx_n_s_join, __pyx_k_join, sizeof(__pyx_k_join), 0, 0, 1, 1},
+  {&__pyx_n_s_main, __pyx_k_main, sizeof(__pyx_k_main), 0, 0, 1, 1},
+  {&__pyx_kp_u_ndarray_is_not_C_contiguous, __pyx_k_ndarray_is_not_C_contiguous, sizeof(__pyx_k_ndarray_is_not_C_contiguous), 0, 1, 0, 0},
+  {&__pyx_kp_u_ndarray_is_not_Fortran_contiguou, __pyx_k_ndarray_is_not_Fortran_contiguou, sizeof(__pyx_k_ndarray_is_not_Fortran_contiguou), 0, 1, 0, 0},
+  {&__pyx_n_s_np, __pyx_k_np, sizeof(__pyx_k_np), 0, 0, 1, 1},
+  {&__pyx_n_s_numpy, __pyx_k_numpy, sizeof(__pyx_k_numpy), 0, 0, 1, 1},
+  {&__pyx_n_s_out, __pyx_k_out, sizeof(__pyx_k_out), 0, 0, 1, 1},
+  {&__pyx_n_s_pyx_vtable, __pyx_k_pyx_vtable, sizeof(__pyx_k_pyx_vtable), 0, 0, 1, 1},
+  {&__pyx_n_s_range, __pyx_k_range, sizeof(__pyx_k_range), 0, 0, 1, 1},
+  {&__pyx_n_s_read, __pyx_k_read, sizeof(__pyx_k_read), 0, 0, 1, 1},
+  {&__pyx_n_s_read_and_unpack, __pyx_k_read_and_unpack, sizeof(__pyx_k_read_and_unpack), 0, 0, 1, 1},
+  {&__pyx_n_s_round, __pyx_k_round, sizeof(__pyx_k_round), 0, 0, 1, 1},
+  {&__pyx_n_s_seek, __pyx_k_seek, sizeof(__pyx_k_seek), 0, 0, 1, 1},
+  {&__pyx_n_s_split, __pyx_k_split, sizeof(__pyx_k_split), 0, 0, 1, 1},
+  {&__pyx_n_s_start, __pyx_k_start, sizeof(__pyx_k_start), 0, 0, 1, 1},
+  {&__pyx_n_s_summary_size, __pyx_k_summary_size, sizeof(__pyx_k_summary_size), 0, 0, 1, 1},
+  {&__pyx_n_s_tell, __pyx_k_tell, sizeof(__pyx_k_tell), 0, 0, 1, 1},
+  {&__pyx_n_s_test, __pyx_k_test, sizeof(__pyx_k_test), 0, 0, 1, 1},
+  {&__pyx_kp_u_unknown_dtype_code_in_numpy_pxd, __pyx_k_unknown_dtype_code_in_numpy_pxd, sizeof(__pyx_k_unknown_dtype_code_in_numpy_pxd), 0, 1, 0, 0},
+  {&__pyx_n_s_zlib, __pyx_k_zlib, sizeof(__pyx_k_zlib), 0, 0, 1, 1},
+  {0, 0, 0, 0, 0, 0, 0}
+};
+static int __Pyx_InitCachedBuiltins(void) {
+  __pyx_builtin_range = __Pyx_GetBuiltinName(__pyx_n_s_range); if (!__pyx_builtin_range) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 85; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_builtin_ValueError = __Pyx_GetBuiltinName(__pyx_n_s_ValueError); if (!__pyx_builtin_ValueError) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 218; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_builtin_RuntimeError = __Pyx_GetBuiltinName(__pyx_n_s_RuntimeError); if (!__pyx_builtin_RuntimeError) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 802; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  return 0;
+  __pyx_L1_error:;
+  return -1;
+}
+
+static int __Pyx_InitCachedConstants(void) {
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0);
+
+  /* "bx/bbi/bigbed_file.pyx":35
+ *             break
+ * 
+ *     pos = read[-1].find('\0')             # <<<<<<<<<<<<<<
+ *     l = len(read[-1])
+ *     if l == chunksize:
+ */
+  __pyx_tuple__2 = PyTuple_Pack(1, __pyx_kp_s_); if (unlikely(!__pyx_tuple__2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 35; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__2);
+  __Pyx_GIVEREF(__pyx_tuple__2);
+
+  /* "bx/bbi/bigbed_file.pyx":66
+ *         length = len( block_data )
+ *         while string_io.tell() < length:
+ *             chrom_id, s, e = block_reader.read_and_unpack("LLL", 12)             # <<<<<<<<<<<<<<
+ *             rest = read_c_string(string_io)
+ * 
+ */
+  __pyx_tuple__4 = PyTuple_Pack(2, __pyx_n_s_LLL, __pyx_int_12); if (unlikely(!__pyx_tuple__4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 66; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__4);
+  __Pyx_GIVEREF(__pyx_tuple__4);
+
+  /* "bx/bbi/bigbed_file.pyx":138
+ *         # now.
+ *         for ( s, e, rest ) in v.intervals:
+ *             fields = [ chrom, str( s ), str( e ) ] + rest.split( "\t" )             # <<<<<<<<<<<<<<
+ *             rval.append( GenomicInterval( None, fields, 0, 1, 2, 5, "+" ) )
+ *         return rval
+ */
+  __pyx_tuple__6 = PyTuple_Pack(1, __pyx_kp_s__5); if (unlikely(!__pyx_tuple__6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 138; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__6);
+  __Pyx_GIVEREF(__pyx_tuple__6);
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":218
+ *             if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)
+ *                 and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)):
+ *                 raise ValueError(u"ndarray is not C contiguous")             # <<<<<<<<<<<<<<
+ * 
+ *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
+ */
+  __pyx_tuple__8 = PyTuple_Pack(1, __pyx_kp_u_ndarray_is_not_C_contiguous); if (unlikely(!__pyx_tuple__8)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 218; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__8);
+  __Pyx_GIVEREF(__pyx_tuple__8);
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":222
+ *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
+ *                 and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)):
+ *                 raise ValueError(u"ndarray is not Fortran contiguous")             # <<<<<<<<<<<<<<
+ * 
+ *             info.buf = PyArray_DATA(self)
+ */
+  __pyx_tuple__9 = PyTuple_Pack(1, __pyx_kp_u_ndarray_is_not_Fortran_contiguou); if (unlikely(!__pyx_tuple__9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 222; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__9);
+  __Pyx_GIVEREF(__pyx_tuple__9);
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":260
+ *                 if ((descr.byteorder == c'>' and little_endian) or
+ *                     (descr.byteorder == c'<' and not little_endian)):
+ *                     raise ValueError(u"Non-native byte order not supported")             # <<<<<<<<<<<<<<
+ *                 if   t == NPY_BYTE:        f = "b"
+ *                 elif t == NPY_UBYTE:       f = "B"
+ */
+  __pyx_tuple__10 = PyTuple_Pack(1, __pyx_kp_u_Non_native_byte_order_not_suppor); if (unlikely(!__pyx_tuple__10)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 260; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__10);
+  __Pyx_GIVEREF(__pyx_tuple__10);
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":802
+ * 
+ *         if (end - f) - <int>(new_offset - offset[0]) < 15:
+ *             raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd")             # <<<<<<<<<<<<<<
+ * 
+ *         if ((child.byteorder == c'>' and little_endian) or
+ */
+  __pyx_tuple__11 = PyTuple_Pack(1, __pyx_kp_u_Format_string_allocated_too_shor); if (unlikely(!__pyx_tuple__11)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 802; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__11);
+  __Pyx_GIVEREF(__pyx_tuple__11);
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":806
+ *         if ((child.byteorder == c'>' and little_endian) or
+ *             (child.byteorder == c'<' and not little_endian)):
+ *             raise ValueError(u"Non-native byte order not supported")             # <<<<<<<<<<<<<<
+ *             # One could encode it in the format string and have Cython
+ *             # complain instead, BUT: < and > in format strings also imply
+ */
+  __pyx_tuple__12 = PyTuple_Pack(1, __pyx_kp_u_Non_native_byte_order_not_suppor); if (unlikely(!__pyx_tuple__12)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 806; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__12);
+  __Pyx_GIVEREF(__pyx_tuple__12);
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":826
+ *             t = child.type_num
+ *             if end - f < 5:
+ *                 raise RuntimeError(u"Format string allocated too short.")             # <<<<<<<<<<<<<<
+ * 
+ *             # Until ticket #99 is fixed, use integers to avoid warnings
+ */
+  __pyx_tuple__13 = PyTuple_Pack(1, __pyx_kp_u_Format_string_allocated_too_shor_2); if (unlikely(!__pyx_tuple__13)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 826; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__13);
+  __Pyx_GIVEREF(__pyx_tuple__13);
+  __Pyx_RefNannyFinishContext();
+  return 0;
+  __pyx_L1_error:;
+  __Pyx_RefNannyFinishContext();
+  return -1;
+}
+
+static int __Pyx_InitGlobals(void) {
+  if (__Pyx_InitStrings(__pyx_string_tab) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  __pyx_int_0 = PyInt_FromLong(0); if (unlikely(!__pyx_int_0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_int_1 = PyInt_FromLong(1); if (unlikely(!__pyx_int_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_int_2 = PyInt_FromLong(2); if (unlikely(!__pyx_int_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_int_5 = PyInt_FromLong(5); if (unlikely(!__pyx_int_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_int_8 = PyInt_FromLong(8); if (unlikely(!__pyx_int_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_int_12 = PyInt_FromLong(12); if (unlikely(!__pyx_int_12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_int_2273964779 = PyInt_FromString((char *)"2273964779", 0, 0); if (unlikely(!__pyx_int_2273964779)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  return 0;
+  __pyx_L1_error:;
+  return -1;
+}
+
+#if PY_MAJOR_VERSION < 3
+PyMODINIT_FUNC initbigbed_file(void); /*proto*/
+PyMODINIT_FUNC initbigbed_file(void)
+#else
+PyMODINIT_FUNC PyInit_bigbed_file(void); /*proto*/
+PyMODINIT_FUNC PyInit_bigbed_file(void)
+#endif
+{
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannyDeclarations
+  #if CYTHON_REFNANNY
+  __Pyx_RefNanny = __Pyx_RefNannyImportAPI("refnanny");
+  if (!__Pyx_RefNanny) {
+      PyErr_Clear();
+      __Pyx_RefNanny = __Pyx_RefNannyImportAPI("Cython.Runtime.refnanny");
+      if (!__Pyx_RefNanny)
+          Py_FatalError("failed to import 'refnanny' module");
+  }
+  #endif
+  __Pyx_RefNannySetupContext("PyMODINIT_FUNC PyInit_bigbed_file(void)", 0);
+  if ( __Pyx_check_binary_version() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_bytes)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #ifdef __Pyx_CyFunction_USED
+  if (__Pyx_CyFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #endif
+  #ifdef __Pyx_FusedFunction_USED
+  if (__pyx_FusedFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #endif
+  #ifdef __Pyx_Generator_USED
+  if (__pyx_Generator_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #endif
+  /*--- Library function declarations ---*/
+  /*--- Threads initialization code ---*/
+  #if defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS
+  #ifdef WITH_THREAD /* Python build with threading support? */
+  PyEval_InitThreads();
+  #endif
+  #endif
+  /*--- Module creation code ---*/
+  #if PY_MAJOR_VERSION < 3
+  __pyx_m = Py_InitModule4("bigbed_file", __pyx_methods, __pyx_k_BigBed_file, 0, PYTHON_API_VERSION); Py_XINCREF(__pyx_m);
+  #else
+  __pyx_m = PyModule_Create(&__pyx_moduledef);
+  #endif
+  if (unlikely(!__pyx_m)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_d = PyModule_GetDict(__pyx_m); if (unlikely(!__pyx_d)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  Py_INCREF(__pyx_d);
+  __pyx_b = PyImport_AddModule(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_b)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #if CYTHON_COMPILING_IN_PYPY
+  Py_INCREF(__pyx_b);
+  #endif
+  if (PyObject_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  /*--- Initialize various global constants etc. ---*/
+  if (unlikely(__Pyx_InitGlobals() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #if PY_MAJOR_VERSION < 3 && (__PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT)
+  if (__Pyx_init_sys_getdefaultencoding_params() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #endif
+  if (__pyx_module_is_main_bx__bbi__bigbed_file) {
+    if (PyObject_SetAttrString(__pyx_m, "__name__", __pyx_n_s_main) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  }
+  #if PY_MAJOR_VERSION >= 3
+  {
+    PyObject *modules = PyImport_GetModuleDict(); if (unlikely(!modules)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (!PyDict_GetItemString(modules, "bx.bbi.bigbed_file")) {
+      if (unlikely(PyDict_SetItemString(modules, "bx.bbi.bigbed_file", __pyx_m) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+  }
+  #endif
+  /*--- Builtin init code ---*/
+  if (unlikely(__Pyx_InitCachedBuiltins() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  /*--- Constants init code ---*/
+  if (unlikely(__Pyx_InitCachedConstants() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  /*--- Global init code ---*/
+  /*--- Variable export code ---*/
+  /*--- Function export code ---*/
+  /*--- Type init code ---*/
+  __pyx_ptype_2bx_3bbi_8bbi_file_BlockHandler = __Pyx_ImportType("bx.bbi.bbi_file", "BlockHandler", sizeof(struct __pyx_obj_2bx_3bbi_8bbi_file_BlockHandler), 1); if (unlikely(!__pyx_ptype_2bx_3bbi_8bbi_file_BlockHandler)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_vtabptr_2bx_3bbi_8bbi_file_BlockHandler = (struct __pyx_vtabstruct_2bx_3bbi_8bbi_file_BlockHandler*)__Pyx_GetVtable(__pyx_ptype_2bx_3bbi_8bbi_file_BlockHandler->tp_dict); if (unlikely(!__pyx_vtabptr_2bx_3bbi_8bbi_file_BlockHandler)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_vtabptr_2bx_3bbi_11bigbed_file_BigBedBlockHandler = &__pyx_vtable_2bx_3bbi_11bigbed_file_BigBedBlockHandler;
+  __pyx_vtable_2bx_3bbi_11bigbed_file_BigBedBlockHandler.__pyx_base = *__pyx_vtabptr_2bx_3bbi_8bbi_file_BlockHandler;
+  __pyx_vtable_2bx_3bbi_11bigbed_file_BigBedBlockHandler.__pyx_base.handle_block = (PyObject *(*)(struct __pyx_obj_2bx_3bbi_8bbi_file_BlockHandler *, PyObject *, struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *))__pyx_f_2bx_3bbi_11bigbed_file_18BigBedBlockHandler_handle_block;
+  __pyx_vtable_2bx_3bbi_11bigbed_file_BigBedBlockHandler.handle_interval_value = (PyObject *(*)(struct __pyx_obj_2bx_3bbi_11bigbed_file_BigBedBlockHandler *, __pyx_t_2bx_3bbi_5types_bits32, __pyx_t_2bx_3bbi_5types_bits32, PyObject *))__pyx_f_2bx_3bbi_11bigbed_file_18BigBedBlockHandler_handle_interval_value;
+  __pyx_type_2bx_3bbi_11bigbed_file_BigBedBlockHandler.tp_base = __pyx_ptype_2bx_3bbi_8bbi_file_BlockHandler;
+  if (PyType_Ready(&__pyx_type_2bx_3bbi_11bigbed_file_BigBedBlockHandler) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 44; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_type_2bx_3bbi_11bigbed_file_BigBedBlockHandler.tp_print = 0;
+  if (__Pyx_SetVtable(__pyx_type_2bx_3bbi_11bigbed_file_BigBedBlockHandler.tp_dict, __pyx_vtabptr_2bx_3bbi_11bigbed_file_BigBedBlockHandler) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 44; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyObject_SetAttrString(__pyx_m, "BigBedBlockHandler", (PyObject *)&__pyx_type_2bx_3bbi_11bigbed_file_BigBedBlockHandler) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 44; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_2bx_3bbi_11bigbed_file_BigBedBlockHandler = &__pyx_type_2bx_3bbi_11bigbed_file_BigBedBlockHandler;
+  __pyx_vtabptr_2bx_3bbi_11bigbed_file_SummarizingBlockHandler = &__pyx_vtable_2bx_3bbi_11bigbed_file_SummarizingBlockHandler;
+  __pyx_vtable_2bx_3bbi_11bigbed_file_SummarizingBlockHandler.__pyx_base = *__pyx_vtabptr_2bx_3bbi_11bigbed_file_BigBedBlockHandler;
+  __pyx_vtable_2bx_3bbi_11bigbed_file_SummarizingBlockHandler.__pyx_base.handle_interval_value = (PyObject *(*)(struct __pyx_obj_2bx_3bbi_11bigbed_file_BigBedBlockHandler *, __pyx_t_2bx_3bbi_5types_bits32, __pyx_t_2bx_3bbi_5types_bits32, PyObject *))__pyx_f_2bx_3bbi_11bigbed_file_23SummarizingBlockHandler_handle_interval_value;
+  __pyx_type_2bx_3bbi_11bigbed_file_SummarizingBlockHandler.tp_base = __pyx_ptype_2bx_3bbi_11bigbed_file_BigBedBlockHandler;
+  if (PyType_Ready(&__pyx_type_2bx_3bbi_11bigbed_file_SummarizingBlockHandler) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 76; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_type_2bx_3bbi_11bigbed_file_SummarizingBlockHandler.tp_print = 0;
+  if (__Pyx_SetVtable(__pyx_type_2bx_3bbi_11bigbed_file_SummarizingBlockHandler.tp_dict, __pyx_vtabptr_2bx_3bbi_11bigbed_file_SummarizingBlockHandler) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 76; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyObject_SetAttrString(__pyx_m, "SummarizingBlockHandler", (PyObject *)&__pyx_type_2bx_3bbi_11bigbed_file_SummarizingBlockHandler) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 76; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_2bx_3bbi_11bigbed_file_SummarizingBlockHandler = &__pyx_type_2bx_3bbi_11bigbed_file_SummarizingBlockHandler;
+  __pyx_vtabptr_2bx_3bbi_11bigbed_file_IntervalAccumulatingBlockHandler = &__pyx_vtable_2bx_3bbi_11bigbed_file_IntervalAccumulatingBlockHandler;
+  __pyx_vtable_2bx_3bbi_11bigbed_file_IntervalAccumulatingBlockHandler.__pyx_base = *__pyx_vtabptr_2bx_3bbi_11bigbed_file_BigBedBlockHandler;
+  __pyx_vtable_2bx_3bbi_11bigbed_file_IntervalAccumulatingBlockHandler.__pyx_base.handle_interval_value = (PyObject *(*)(struct __pyx_obj_2bx_3bbi_11bigbed_file_BigBedBlockHandler *, __pyx_t_2bx_3bbi_5types_bits32, __pyx_t_2bx_3bbi_5types_bits32, PyObject *))__pyx_f_2bx_3bbi_11bigbed_file_32IntervalAccumulatingBlockHandler_handle_interval_value;
+  __pyx_type_2bx_3bbi_11bigbed_file_IntervalAccumulatingBlockHandler.tp_base = __pyx_ptype_2bx_3bbi_11bigbed_file_BigBedBlockHandler;
+  if (PyType_Ready(&__pyx_type_2bx_3bbi_11bigbed_file_IntervalAccumulatingBlockHandler) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 95; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_type_2bx_3bbi_11bigbed_file_IntervalAccumulatingBlockHandler.tp_print = 0;
+  if (__Pyx_SetVtable(__pyx_type_2bx_3bbi_11bigbed_file_IntervalAccumulatingBlockHandler.tp_dict, __pyx_vtabptr_2bx_3bbi_11bigbed_file_IntervalAccumulatingBlockHandler) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 95; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyObject_SetAttrString(__pyx_m, "IntervalAccumulatingBlockHandler", (PyObject *)&__pyx_type_2bx_3bbi_11bigbed_file_IntervalAccumulatingBlockHandler) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 95; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_2bx_3bbi_11bigbed_file_IntervalAccumulatingBlockHandler = &__pyx_type_2bx_3bbi_11bigbed_file_IntervalAccumulatingBlockHandler;
+  __pyx_ptype_2bx_3bbi_8bbi_file_BBIFile = __Pyx_ImportType("bx.bbi.bbi_file", "BBIFile", sizeof(struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile), 1); if (unlikely(!__pyx_ptype_2bx_3bbi_8bbi_file_BBIFile)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_vtabptr_2bx_3bbi_8bbi_file_BBIFile = (struct __pyx_vtabstruct_2bx_3bbi_8bbi_file_BBIFile*)__Pyx_GetVtable(__pyx_ptype_2bx_3bbi_8bbi_file_BBIFile->tp_dict); if (unlikely(!__pyx_vtabptr_2bx_3bbi_8bbi_file_BBIFile)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_vtabptr_2bx_3bbi_11bigbed_file_BigBedFile = &__pyx_vtable_2bx_3bbi_11bigbed_file_BigBedFile;
+  __pyx_vtable_2bx_3bbi_11bigbed_file_BigBedFile.__pyx_base = *__pyx_vtabptr_2bx_3bbi_8bbi_file_BBIFile;
+  __pyx_vtable_2bx_3bbi_11bigbed_file_BigBedFile.__pyx_base._summarize_from_full = (PyObject *(*)(struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *, __pyx_t_2bx_3bbi_5types_bits32, __pyx_t_2bx_3bbi_5types_bits32, __pyx_t_2bx_3bbi_5types_bits32, int))__pyx_f_2bx_3bbi_11bigbed_file_10BigBedFile__summarize_from_full;
+  __pyx_vtable_2bx_3bbi_11bigbed_file_BigBedFile.get = (PyObject *(*)(struct __pyx_obj_2bx_3bbi_11bigbed_file_BigBedFile *, char *, __pyx_t_2bx_3bbi_5types_bits32, __pyx_t_2bx_3bbi_5types_bits32, int __pyx_skip_dispatch))__pyx_f_2bx_3bbi_11bigbed_file_10BigBedFile_get;
+  __pyx_type_2bx_3bbi_11bigbed_file_BigBedFile.tp_base = __pyx_ptype_2bx_3bbi_8bbi_file_BBIFile;
+  if (PyType_Ready(&__pyx_type_2bx_3bbi_11bigbed_file_BigBedFile) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 107; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_type_2bx_3bbi_11bigbed_file_BigBedFile.tp_print = 0;
+  if (__Pyx_SetVtable(__pyx_type_2bx_3bbi_11bigbed_file_BigBedFile.tp_dict, __pyx_vtabptr_2bx_3bbi_11bigbed_file_BigBedFile) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 107; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyObject_SetAttrString(__pyx_m, "BigBedFile", (PyObject *)&__pyx_type_2bx_3bbi_11bigbed_file_BigBedFile) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 107; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_2bx_3bbi_11bigbed_file_BigBedFile = &__pyx_type_2bx_3bbi_11bigbed_file_BigBedFile;
+  /*--- Type import code ---*/
+  __pyx_ptype_2bx_3bbi_8bpt_file_BPTFile = __Pyx_ImportType("bx.bbi.bpt_file", "BPTFile", sizeof(struct __pyx_obj_2bx_3bbi_8bpt_file_BPTFile), 1); if (unlikely(!__pyx_ptype_2bx_3bbi_8bpt_file_BPTFile)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 5; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_2bx_3bbi_12cirtree_file_CIRTreeFile = __Pyx_ImportType("bx.bbi.cirtree_file", "CIRTreeFile", sizeof(struct __pyx_obj_2bx_3bbi_12cirtree_file_CIRTreeFile), 1); if (unlikely(!__pyx_ptype_2bx_3bbi_12cirtree_file_CIRTreeFile)) {__pyx_filename = __pyx_f[3]; __pyx_lineno = 3; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_7cpython_4type_type = __Pyx_ImportType(__Pyx_BUILTIN_MODULE_NAME, "type", 
+  #if CYTHON_COMPILING_IN_PYPY
+  sizeof(PyTypeObject),
+  #else
+  sizeof(PyHeapTypeObject),
+  #endif
+  0); if (unlikely(!__pyx_ptype_7cpython_4type_type)) {__pyx_filename = __pyx_f[4]; __pyx_lineno = 9; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_5numpy_dtype = __Pyx_ImportType("numpy", "dtype", sizeof(PyArray_Descr), 0); if (unlikely(!__pyx_ptype_5numpy_dtype)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 155; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_5numpy_flatiter = __Pyx_ImportType("numpy", "flatiter", sizeof(PyArrayIterObject), 0); if (unlikely(!__pyx_ptype_5numpy_flatiter)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 168; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_5numpy_broadcast = __Pyx_ImportType("numpy", "broadcast", sizeof(PyArrayMultiIterObject), 0); if (unlikely(!__pyx_ptype_5numpy_broadcast)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 172; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_5numpy_ndarray = __Pyx_ImportType("numpy", "ndarray", sizeof(PyArrayObject), 0); if (unlikely(!__pyx_ptype_5numpy_ndarray)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 181; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_5numpy_ufunc = __Pyx_ImportType("numpy", "ufunc", sizeof(PyUFuncObject), 0); if (unlikely(!__pyx_ptype_5numpy_ufunc)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 864; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_2bx_3bbi_8bbi_file_SummaryBlock = __Pyx_ImportType("bx.bbi.bbi_file", "SummaryBlock", sizeof(struct __pyx_obj_2bx_3bbi_8bbi_file_SummaryBlock), 1); if (unlikely(!__pyx_ptype_2bx_3bbi_8bbi_file_SummaryBlock)) {__pyx_filename = __pyx_f[5]; __pyx_lineno = 8; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_2bx_3bbi_8bbi_file_SummarizedData = __Pyx_ImportType("bx.bbi.bbi_file", "SummarizedData", sizeof(struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData), 1); if (unlikely(!__pyx_ptype_2bx_3bbi_8bbi_file_SummarizedData)) {__pyx_filename = __pyx_f[5]; __pyx_lineno = 21; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_vtabptr_2bx_3bbi_8bbi_file_SummarizedData = (struct __pyx_vtabstruct_2bx_3bbi_8bbi_file_SummarizedData*)__Pyx_GetVtable(__pyx_ptype_2bx_3bbi_8bbi_file_SummarizedData->tp_dict); if (unlikely(!__pyx_vtabptr_2bx_3bbi_8bbi_file_SummarizedData)) {__pyx_filename = __pyx_f[5]; __pyx_lineno = 21; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  /*--- Variable import code ---*/
+  /*--- Function import code ---*/
+  /*--- Execution code ---*/
+
+  /* "bx/bbi/bigbed_file.pyx":8
+ * from bbi_file cimport *
+ * from cirtree_file cimport CIRTreeFile
+ * import numpy as np             # <<<<<<<<<<<<<<
+ * cimport numpy as np
+ * from types cimport *
+ */
+  __pyx_t_1 = __Pyx_Import(__pyx_n_s_numpy, 0, -1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 8; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_np, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 8; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "bx/bbi/bigbed_file.pyx":11
+ * cimport numpy as np
+ * from types cimport *
+ * from bx.intervals.io import GenomicInterval             # <<<<<<<<<<<<<<
+ * from bx.misc.binary_file import BinaryFileReader
+ * from cStringIO import StringIO
+ */
+  __pyx_t_1 = PyList_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 11; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_INCREF(__pyx_n_s_GenomicInterval);
+  PyList_SET_ITEM(__pyx_t_1, 0, __pyx_n_s_GenomicInterval);
+  __Pyx_GIVEREF(__pyx_n_s_GenomicInterval);
+  __pyx_t_2 = __Pyx_Import(__pyx_n_s_bx_intervals_io, __pyx_t_1, -1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 11; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_1 = __Pyx_ImportFrom(__pyx_t_2, __pyx_n_s_GenomicInterval); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 11; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_GenomicInterval, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 11; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+  /* "bx/bbi/bigbed_file.pyx":12
+ * from types cimport *
+ * from bx.intervals.io import GenomicInterval
+ * from bx.misc.binary_file import BinaryFileReader             # <<<<<<<<<<<<<<
+ * from cStringIO import StringIO
+ * import zlib
+ */
+  __pyx_t_2 = PyList_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 12; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_INCREF(__pyx_n_s_BinaryFileReader);
+  PyList_SET_ITEM(__pyx_t_2, 0, __pyx_n_s_BinaryFileReader);
+  __Pyx_GIVEREF(__pyx_n_s_BinaryFileReader);
+  __pyx_t_1 = __Pyx_Import(__pyx_n_s_bx_misc_binary_file, __pyx_t_2, -1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 12; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_1, __pyx_n_s_BinaryFileReader); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 12; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_BinaryFileReader, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 12; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "bx/bbi/bigbed_file.pyx":13
+ * from bx.intervals.io import GenomicInterval
+ * from bx.misc.binary_file import BinaryFileReader
+ * from cStringIO import StringIO             # <<<<<<<<<<<<<<
+ * import zlib
+ * 
+ */
+  __pyx_t_1 = PyList_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 13; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_INCREF(__pyx_n_s_StringIO);
+  PyList_SET_ITEM(__pyx_t_1, 0, __pyx_n_s_StringIO);
+  __Pyx_GIVEREF(__pyx_n_s_StringIO);
+  __pyx_t_2 = __Pyx_Import(__pyx_n_s_cStringIO, __pyx_t_1, -1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 13; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_1 = __Pyx_ImportFrom(__pyx_t_2, __pyx_n_s_StringIO); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 13; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_StringIO, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 13; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+  /* "bx/bbi/bigbed_file.pyx":14
+ * from bx.misc.binary_file import BinaryFileReader
+ * from cStringIO import StringIO
+ * import zlib             # <<<<<<<<<<<<<<
+ * 
+ * DEF big_bed_sig = 0x8789F2EB
+ */
+  __pyx_t_2 = __Pyx_Import(__pyx_n_s_zlib, 0, -1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 14; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_zlib, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 14; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+  /* "bx/bbi/bigbed_file.pyx":1
+ * #cython: profile=False             # <<<<<<<<<<<<<<
+ * """
+ * BigBed file.
+ */
+  __pyx_t_2 = PyDict_New(); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":979
+ *      arr.base = baseptr
+ * 
+ * cdef inline object get_array_base(ndarray arr):             # <<<<<<<<<<<<<<
+ *     if arr.base is NULL:
+ *         return None
+ */
+
+  /*--- Wrapped vars code ---*/
+
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  if (__pyx_m) {
+    if (__pyx_d) {
+      __Pyx_AddTraceback("init bx.bbi.bigbed_file", __pyx_clineno, __pyx_lineno, __pyx_filename);
+    }
+    Py_DECREF(__pyx_m); __pyx_m = 0;
+  } else if (!PyErr_Occurred()) {
+    PyErr_SetString(PyExc_ImportError, "init bx.bbi.bigbed_file");
+  }
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  #if PY_MAJOR_VERSION < 3
+  return;
+  #else
+  return __pyx_m;
+  #endif
+}
+
+/* --- Runtime support code --- */
+#if CYTHON_REFNANNY
+static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) {
+    PyObject *m = NULL, *p = NULL;
+    void *r = NULL;
+    m = PyImport_ImportModule((char *)modname);
+    if (!m) goto end;
+    p = PyObject_GetAttrString(m, (char *)"RefNannyAPI");
+    if (!p) goto end;
+    r = PyLong_AsVoidPtr(p);
+end:
+    Py_XDECREF(p);
+    Py_XDECREF(m);
+    return (__Pyx_RefNannyAPIStruct *)r;
+}
+#endif
+
+static PyObject *__Pyx_GetBuiltinName(PyObject *name) {
+    PyObject* result = __Pyx_PyObject_GetAttrStr(__pyx_b, name);
+    if (unlikely(!result)) {
+        PyErr_Format(PyExc_NameError,
+#if PY_MAJOR_VERSION >= 3
+            "name '%U' is not defined", name);
+#else
+            "name '%.200s' is not defined", PyString_AS_STRING(name));
+#endif
+    }
+    return result;
+}
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw) {
+    PyObject *result;
+    ternaryfunc call = func->ob_type->tp_call;
+    if (unlikely(!call))
+        return PyObject_Call(func, arg, kw);
+    if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object")))
+        return NULL;
+    result = (*call)(func, arg, kw);
+    Py_LeaveRecursiveCall();
+    if (unlikely(!result) && unlikely(!PyErr_Occurred())) {
+        PyErr_SetString(
+            PyExc_SystemError,
+            "NULL result without error in PyObject_Call");
+    }
+    return result;
+}
+#endif
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg) {
+    PyObject *self, *result;
+    PyCFunction cfunc;
+    cfunc = PyCFunction_GET_FUNCTION(func);
+    self = PyCFunction_GET_SELF(func);
+    if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object")))
+        return NULL;
+    result = cfunc(self, arg);
+    Py_LeaveRecursiveCall();
+    if (unlikely(!result) && unlikely(!PyErr_Occurred())) {
+        PyErr_SetString(
+            PyExc_SystemError,
+            "NULL result without error in PyObject_Call");
+    }
+    return result;
+}
+#endif
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static PyObject* __Pyx__PyObject_CallOneArg(PyObject *func, PyObject *arg) {
+    PyObject *result;
+    PyObject *args = PyTuple_New(1);
+    if (unlikely(!args)) return NULL;
+    Py_INCREF(arg);
+    PyTuple_SET_ITEM(args, 0, arg);
+    result = __Pyx_PyObject_Call(func, args, NULL);
+    Py_DECREF(args);
+    return result;
+}
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) {
+#ifdef __Pyx_CyFunction_USED
+    if (likely(PyCFunction_Check(func) || PyObject_TypeCheck(func, __pyx_CyFunctionType))) {
+#else
+    if (likely(PyCFunction_Check(func))) {
+#endif
+        if (likely(PyCFunction_GET_FLAGS(func) & METH_O)) {
+            return __Pyx_PyObject_CallMethO(func, arg);
+        }
+    }
+    return __Pyx__PyObject_CallOneArg(func, arg);
+}
+#else
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) {
+    PyObject* args = PyTuple_Pack(1, arg);
+    return (likely(args)) ? __Pyx_PyObject_Call(func, args, NULL) : NULL;
+}
+#endif
+
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j) {
+    PyObject *r;
+    if (!j) return NULL;
+    r = PyObject_GetItem(o, j);
+    Py_DECREF(j);
+    return r;
+}
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i,
+                                                              int wraparound, int boundscheck) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    if (wraparound & unlikely(i < 0)) i += PyList_GET_SIZE(o);
+    if ((!boundscheck) || likely((0 <= i) & (i < PyList_GET_SIZE(o)))) {
+        PyObject *r = PyList_GET_ITEM(o, i);
+        Py_INCREF(r);
+        return r;
+    }
+    return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
+#else
+    return PySequence_GetItem(o, i);
+#endif
+}
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i,
+                                                              int wraparound, int boundscheck) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    if (wraparound & unlikely(i < 0)) i += PyTuple_GET_SIZE(o);
+    if ((!boundscheck) || likely((0 <= i) & (i < PyTuple_GET_SIZE(o)))) {
+        PyObject *r = PyTuple_GET_ITEM(o, i);
+        Py_INCREF(r);
+        return r;
+    }
+    return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
+#else
+    return PySequence_GetItem(o, i);
+#endif
+}
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i,
+                                                     int is_list, int wraparound, int boundscheck) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    if (is_list || PyList_CheckExact(o)) {
+        Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyList_GET_SIZE(o);
+        if ((!boundscheck) || (likely((n >= 0) & (n < PyList_GET_SIZE(o))))) {
+            PyObject *r = PyList_GET_ITEM(o, n);
+            Py_INCREF(r);
+            return r;
+        }
+    }
+    else if (PyTuple_CheckExact(o)) {
+        Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyTuple_GET_SIZE(o);
+        if ((!boundscheck) || likely((n >= 0) & (n < PyTuple_GET_SIZE(o)))) {
+            PyObject *r = PyTuple_GET_ITEM(o, n);
+            Py_INCREF(r);
+            return r;
+        }
+    } else {
+        PySequenceMethods *m = Py_TYPE(o)->tp_as_sequence;
+        if (likely(m && m->sq_item)) {
+            if (wraparound && unlikely(i < 0) && likely(m->sq_length)) {
+                Py_ssize_t l = m->sq_length(o);
+                if (likely(l >= 0)) {
+                    i += l;
+                } else {
+                    if (PyErr_ExceptionMatches(PyExc_OverflowError))
+                        PyErr_Clear();
+                    else
+                        return NULL;
+                }
+            }
+            return m->sq_item(o, i);
+        }
+    }
+#else
+    if (is_list || PySequence_Check(o)) {
+        return PySequence_GetItem(o, i);
+    }
+#endif
+    return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
+}
+
+static CYTHON_INLINE PyObject* __Pyx_PyObject_GetSlice(
+        PyObject* obj, Py_ssize_t cstart, Py_ssize_t cstop,
+        PyObject** _py_start, PyObject** _py_stop, PyObject** _py_slice,
+        int has_cstart, int has_cstop, CYTHON_UNUSED int wraparound) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    PyMappingMethods* mp;
+#if PY_MAJOR_VERSION < 3
+    PySequenceMethods* ms = Py_TYPE(obj)->tp_as_sequence;
+    if (likely(ms && ms->sq_slice)) {
+        if (!has_cstart) {
+            if (_py_start && (*_py_start != Py_None)) {
+                cstart = __Pyx_PyIndex_AsSsize_t(*_py_start);
+                if ((cstart == (Py_ssize_t)-1) && PyErr_Occurred()) goto bad;
+            } else
+                cstart = 0;
+        }
+        if (!has_cstop) {
+            if (_py_stop && (*_py_stop != Py_None)) {
+                cstop = __Pyx_PyIndex_AsSsize_t(*_py_stop);
+                if ((cstop == (Py_ssize_t)-1) && PyErr_Occurred()) goto bad;
+            } else
+                cstop = PY_SSIZE_T_MAX;
+        }
+        if (wraparound && unlikely((cstart < 0) | (cstop < 0)) && likely(ms->sq_length)) {
+            Py_ssize_t l = ms->sq_length(obj);
+            if (likely(l >= 0)) {
+                if (cstop < 0) {
+                    cstop += l;
+                    if (cstop < 0) cstop = 0;
+                }
+                if (cstart < 0) {
+                    cstart += l;
+                    if (cstart < 0) cstart = 0;
+                }
+            } else {
+                if (PyErr_ExceptionMatches(PyExc_OverflowError))
+                    PyErr_Clear();
+                else
+                    goto bad;
+            }
+        }
+        return ms->sq_slice(obj, cstart, cstop);
+    }
+#endif
+    mp = Py_TYPE(obj)->tp_as_mapping;
+    if (likely(mp && mp->mp_subscript))
+#endif
+    {
+        PyObject* result;
+        PyObject *py_slice, *py_start, *py_stop;
+        if (_py_slice) {
+            py_slice = *_py_slice;
+        } else {
+            PyObject* owned_start = NULL;
+            PyObject* owned_stop = NULL;
+            if (_py_start) {
+                py_start = *_py_start;
+            } else {
+                if (has_cstart) {
+                    owned_start = py_start = PyInt_FromSsize_t(cstart);
+                    if (unlikely(!py_start)) goto bad;
+                } else
+                    py_start = Py_None;
+            }
+            if (_py_stop) {
+                py_stop = *_py_stop;
+            } else {
+                if (has_cstop) {
+                    owned_stop = py_stop = PyInt_FromSsize_t(cstop);
+                    if (unlikely(!py_stop)) {
+                        Py_XDECREF(owned_start);
+                        goto bad;
+                    }
+                } else
+                    py_stop = Py_None;
+            }
+            py_slice = PySlice_New(py_start, py_stop, Py_None);
+            Py_XDECREF(owned_start);
+            Py_XDECREF(owned_stop);
+            if (unlikely(!py_slice)) goto bad;
+        }
+#if CYTHON_COMPILING_IN_CPYTHON
+        result = mp->mp_subscript(obj, py_slice);
+#else
+        result = PyObject_GetItem(obj, py_slice);
+#endif
+        if (!_py_slice) {
+            Py_DECREF(py_slice);
+        }
+        return result;
+    }
+    PyErr_Format(PyExc_TypeError,
+        "'%.200s' object is unsliceable", Py_TYPE(obj)->tp_name);
+bad:
+    return NULL;
+}
+
+static CYTHON_INLINE int __Pyx_SetItemInt_Generic(PyObject *o, PyObject *j, PyObject *v) {
+    int r;
+    if (!j) return -1;
+    r = PyObject_SetItem(o, j, v);
+    Py_DECREF(j);
+    return r;
+}
+static CYTHON_INLINE int __Pyx_SetItemInt_Fast(PyObject *o, Py_ssize_t i, PyObject *v,
+                                               int is_list, int wraparound, int boundscheck) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    if (is_list || PyList_CheckExact(o)) {
+        Py_ssize_t n = (!wraparound) ? i : ((likely(i >= 0)) ? i : i + PyList_GET_SIZE(o));
+        if ((!boundscheck) || likely((n >= 0) & (n < PyList_GET_SIZE(o)))) {
+            PyObject* old = PyList_GET_ITEM(o, n);
+            Py_INCREF(v);
+            PyList_SET_ITEM(o, n, v);
+            Py_DECREF(old);
+            return 1;
+        }
+    } else {
+        PySequenceMethods *m = Py_TYPE(o)->tp_as_sequence;
+        if (likely(m && m->sq_ass_item)) {
+            if (wraparound && unlikely(i < 0) && likely(m->sq_length)) {
+                Py_ssize_t l = m->sq_length(o);
+                if (likely(l >= 0)) {
+                    i += l;
+                } else {
+                    if (PyErr_ExceptionMatches(PyExc_OverflowError))
+                        PyErr_Clear();
+                    else
+                        return -1;
+                }
+            }
+            return m->sq_ass_item(o, i, v);
+        }
+    }
+#else
+#if CYTHON_COMPILING_IN_PYPY
+    if (is_list || (PySequence_Check(o) && !PyDict_Check(o))) {
+#else
+    if (is_list || PySequence_Check(o)) {
+#endif
+        return PySequence_SetItem(o, i, v);
+    }
+#endif
+    return __Pyx_SetItemInt_Generic(o, PyInt_FromSsize_t(i), v);
+}
+
+#if !CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyBytes_Join(PyObject* sep, PyObject* values) {
+    return PyObject_CallMethodObjArgs(sep, __pyx_n_s_join, values, NULL);
+}
+#endif
+
+static void __Pyx_RaiseArgtupleInvalid(
+    const char* func_name,
+    int exact,
+    Py_ssize_t num_min,
+    Py_ssize_t num_max,
+    Py_ssize_t num_found)
+{
+    Py_ssize_t num_expected;
+    const char *more_or_less;
+    if (num_found < num_min) {
+        num_expected = num_min;
+        more_or_less = "at least";
+    } else {
+        num_expected = num_max;
+        more_or_less = "at most";
+    }
+    if (exact) {
+        more_or_less = "exactly";
+    }
+    PyErr_Format(PyExc_TypeError,
+                 "%.200s() takes %.8s %" CYTHON_FORMAT_SSIZE_T "d positional argument%.1s (%" CYTHON_FORMAT_SSIZE_T "d given)",
+                 func_name, more_or_less, num_expected,
+                 (num_expected == 1) ? "" : "s", num_found);
+}
+
+static void __Pyx_RaiseDoubleKeywordsError(
+    const char* func_name,
+    PyObject* kw_name)
+{
+    PyErr_Format(PyExc_TypeError,
+        #if PY_MAJOR_VERSION >= 3
+        "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
+        #else
+        "%s() got multiple values for keyword argument '%s'", func_name,
+        PyString_AsString(kw_name));
+        #endif
+}
+
+static int __Pyx_ParseOptionalKeywords(
+    PyObject *kwds,
+    PyObject **argnames[],
+    PyObject *kwds2,
+    PyObject *values[],
+    Py_ssize_t num_pos_args,
+    const char* function_name)
+{
+    PyObject *key = 0, *value = 0;
+    Py_ssize_t pos = 0;
+    PyObject*** name;
+    PyObject*** first_kw_arg = argnames + num_pos_args;
+    while (PyDict_Next(kwds, &pos, &key, &value)) {
+        name = first_kw_arg;
+        while (*name && (**name != key)) name++;
+        if (*name) {
+            values[name-argnames] = value;
+            continue;
+        }
+        name = first_kw_arg;
+        #if PY_MAJOR_VERSION < 3
+        if (likely(PyString_CheckExact(key)) || likely(PyString_Check(key))) {
+            while (*name) {
+                if ((CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**name) == PyString_GET_SIZE(key))
+                        && _PyString_Eq(**name, key)) {
+                    values[name-argnames] = value;
+                    break;
+                }
+                name++;
+            }
+            if (*name) continue;
+            else {
+                PyObject*** argname = argnames;
+                while (argname != first_kw_arg) {
+                    if ((**argname == key) || (
+                            (CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**argname) == PyString_GET_SIZE(key))
+                             && _PyString_Eq(**argname, key))) {
+                        goto arg_passed_twice;
+                    }
+                    argname++;
+                }
+            }
+        } else
+        #endif
+        if (likely(PyUnicode_Check(key))) {
+            while (*name) {
+                int cmp = (**name == key) ? 0 :
+                #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3
+                    (PyUnicode_GET_SIZE(**name) != PyUnicode_GET_SIZE(key)) ? 1 :
+                #endif
+                    PyUnicode_Compare(**name, key);
+                if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad;
+                if (cmp == 0) {
+                    values[name-argnames] = value;
+                    break;
+                }
+                name++;
+            }
+            if (*name) continue;
+            else {
+                PyObject*** argname = argnames;
+                while (argname != first_kw_arg) {
+                    int cmp = (**argname == key) ? 0 :
+                    #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3
+                        (PyUnicode_GET_SIZE(**argname) != PyUnicode_GET_SIZE(key)) ? 1 :
+                    #endif
+                        PyUnicode_Compare(**argname, key);
+                    if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad;
+                    if (cmp == 0) goto arg_passed_twice;
+                    argname++;
+                }
+            }
+        } else
+            goto invalid_keyword_type;
+        if (kwds2) {
+            if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
+        } else {
+            goto invalid_keyword;
+        }
+    }
+    return 0;
+arg_passed_twice:
+    __Pyx_RaiseDoubleKeywordsError(function_name, key);
+    goto bad;
+invalid_keyword_type:
+    PyErr_Format(PyExc_TypeError,
+        "%.200s() keywords must be strings", function_name);
+    goto bad;
+invalid_keyword:
+    PyErr_Format(PyExc_TypeError,
+    #if PY_MAJOR_VERSION < 3
+        "%.200s() got an unexpected keyword argument '%.200s'",
+        function_name, PyString_AsString(key));
+    #else
+        "%s() got an unexpected keyword argument '%U'",
+        function_name, key);
+    #endif
+bad:
+    return -1;
+}
+
+static CYTHON_INLINE PyObject *__Pyx_GetModuleGlobalName(PyObject *name) {
+    PyObject *result;
+#if CYTHON_COMPILING_IN_CPYTHON
+    result = PyDict_GetItem(__pyx_d, name);
+    if (likely(result)) {
+        Py_INCREF(result);
+    } else {
+#else
+    result = PyObject_GetItem(__pyx_d, name);
+    if (!result) {
+        PyErr_Clear();
+#endif
+        result = __Pyx_GetBuiltinName(name);
+    }
+    return result;
+}
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func) {
+#ifdef __Pyx_CyFunction_USED
+    if (likely(PyCFunction_Check(func) || PyObject_TypeCheck(func, __pyx_CyFunctionType))) {
+#else
+    if (likely(PyCFunction_Check(func))) {
+#endif
+        if (likely(PyCFunction_GET_FLAGS(func) & METH_NOARGS)) {
+            return __Pyx_PyObject_CallMethO(func, NULL);
+        }
+    }
+    return __Pyx_PyObject_Call(func, __pyx_empty_tuple, NULL);
+}
+#endif
+
+static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected) {
+    PyErr_Format(PyExc_ValueError,
+                 "too many values to unpack (expected %" CYTHON_FORMAT_SSIZE_T "d)", expected);
+}
+
+static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index) {
+    PyErr_Format(PyExc_ValueError,
+                 "need more than %" CYTHON_FORMAT_SSIZE_T "d value%.1s to unpack",
+                 index, (index == 1) ? "" : "s");
+}
+
+static CYTHON_INLINE int __Pyx_IterFinish(void) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    PyThreadState *tstate = PyThreadState_GET();
+    PyObject* exc_type = tstate->curexc_type;
+    if (unlikely(exc_type)) {
+        if (likely(exc_type == PyExc_StopIteration) || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration)) {
+            PyObject *exc_value, *exc_tb;
+            exc_value = tstate->curexc_value;
+            exc_tb = tstate->curexc_traceback;
+            tstate->curexc_type = 0;
+            tstate->curexc_value = 0;
+            tstate->curexc_traceback = 0;
+            Py_DECREF(exc_type);
+            Py_XDECREF(exc_value);
+            Py_XDECREF(exc_tb);
+            return 0;
+        } else {
+            return -1;
+        }
+    }
+    return 0;
+#else
+    if (unlikely(PyErr_Occurred())) {
+        if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) {
+            PyErr_Clear();
+            return 0;
+        } else {
+            return -1;
+        }
+    }
+    return 0;
+#endif
+}
+
+static int __Pyx_IternextUnpackEndCheck(PyObject *retval, Py_ssize_t expected) {
+    if (unlikely(retval)) {
+        Py_DECREF(retval);
+        __Pyx_RaiseTooManyValuesError(expected);
+        return -1;
+    } else {
+        return __Pyx_IterFinish();
+    }
+    return 0;
+}
+
+static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    PyObject *tmp_type, *tmp_value, *tmp_tb;
+    PyThreadState *tstate = PyThreadState_GET();
+    tmp_type = tstate->curexc_type;
+    tmp_value = tstate->curexc_value;
+    tmp_tb = tstate->curexc_traceback;
+    tstate->curexc_type = type;
+    tstate->curexc_value = value;
+    tstate->curexc_traceback = tb;
+    Py_XDECREF(tmp_type);
+    Py_XDECREF(tmp_value);
+    Py_XDECREF(tmp_tb);
+#else
+    PyErr_Restore(type, value, tb);
+#endif
+}
+static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    PyThreadState *tstate = PyThreadState_GET();
+    *type = tstate->curexc_type;
+    *value = tstate->curexc_value;
+    *tb = tstate->curexc_traceback;
+    tstate->curexc_type = 0;
+    tstate->curexc_value = 0;
+    tstate->curexc_traceback = 0;
+#else
+    PyErr_Fetch(type, value, tb);
+#endif
+}
+
+#if PY_MAJOR_VERSION < 3
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb,
+                        CYTHON_UNUSED PyObject *cause) {
+    Py_XINCREF(type);
+    if (!value || value == Py_None)
+        value = NULL;
+    else
+        Py_INCREF(value);
+    if (!tb || tb == Py_None)
+        tb = NULL;
+    else {
+        Py_INCREF(tb);
+        if (!PyTraceBack_Check(tb)) {
+            PyErr_SetString(PyExc_TypeError,
+                "raise: arg 3 must be a traceback or None");
+            goto raise_error;
+        }
+    }
+    if (PyType_Check(type)) {
+#if CYTHON_COMPILING_IN_PYPY
+        if (!value) {
+            Py_INCREF(Py_None);
+            value = Py_None;
+        }
+#endif
+        PyErr_NormalizeException(&type, &value, &tb);
+    } else {
+        if (value) {
+            PyErr_SetString(PyExc_TypeError,
+                "instance exception may not have a separate value");
+            goto raise_error;
+        }
+        value = type;
+        type = (PyObject*) Py_TYPE(type);
+        Py_INCREF(type);
+        if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
+            PyErr_SetString(PyExc_TypeError,
+                "raise: exception class must be a subclass of BaseException");
+            goto raise_error;
+        }
+    }
+    __Pyx_ErrRestore(type, value, tb);
+    return;
+raise_error:
+    Py_XDECREF(value);
+    Py_XDECREF(type);
+    Py_XDECREF(tb);
+    return;
+}
+#else
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause) {
+    PyObject* owned_instance = NULL;
+    if (tb == Py_None) {
+        tb = 0;
+    } else if (tb && !PyTraceBack_Check(tb)) {
+        PyErr_SetString(PyExc_TypeError,
+            "raise: arg 3 must be a traceback or None");
+        goto bad;
+    }
+    if (value == Py_None)
+        value = 0;
+    if (PyExceptionInstance_Check(type)) {
+        if (value) {
+            PyErr_SetString(PyExc_TypeError,
+                "instance exception may not have a separate value");
+            goto bad;
+        }
+        value = type;
+        type = (PyObject*) Py_TYPE(value);
+    } else if (PyExceptionClass_Check(type)) {
+        PyObject *instance_class = NULL;
+        if (value && PyExceptionInstance_Check(value)) {
+            instance_class = (PyObject*) Py_TYPE(value);
+            if (instance_class != type) {
+                if (PyObject_IsSubclass(instance_class, type)) {
+                    type = instance_class;
+                } else {
+                    instance_class = NULL;
+                }
+            }
+        }
+        if (!instance_class) {
+            PyObject *args;
+            if (!value)
+                args = PyTuple_New(0);
+            else if (PyTuple_Check(value)) {
+                Py_INCREF(value);
+                args = value;
+            } else
+                args = PyTuple_Pack(1, value);
+            if (!args)
+                goto bad;
+            owned_instance = PyObject_Call(type, args, NULL);
+            Py_DECREF(args);
+            if (!owned_instance)
+                goto bad;
+            value = owned_instance;
+            if (!PyExceptionInstance_Check(value)) {
+                PyErr_Format(PyExc_TypeError,
+                             "calling %R should have returned an instance of "
+                             "BaseException, not %R",
+                             type, Py_TYPE(value));
+                goto bad;
+            }
+        }
+    } else {
+        PyErr_SetString(PyExc_TypeError,
+            "raise: exception class must be a subclass of BaseException");
+        goto bad;
+    }
+#if PY_VERSION_HEX >= 0x03030000
+    if (cause) {
+#else
+    if (cause && cause != Py_None) {
+#endif
+        PyObject *fixed_cause;
+        if (cause == Py_None) {
+            fixed_cause = NULL;
+        } else if (PyExceptionClass_Check(cause)) {
+            fixed_cause = PyObject_CallObject(cause, NULL);
+            if (fixed_cause == NULL)
+                goto bad;
+        } else if (PyExceptionInstance_Check(cause)) {
+            fixed_cause = cause;
+            Py_INCREF(fixed_cause);
+        } else {
+            PyErr_SetString(PyExc_TypeError,
+                            "exception causes must derive from "
+                            "BaseException");
+            goto bad;
+        }
+        PyException_SetCause(value, fixed_cause);
+    }
+    PyErr_SetObject(type, value);
+    if (tb) {
+#if CYTHON_COMPILING_IN_PYPY
+        PyObject *tmp_type, *tmp_value, *tmp_tb;
+        PyErr_Fetch(tmp_type, tmp_value, tmp_tb);
+        Py_INCREF(tb);
+        PyErr_Restore(tmp_type, tmp_value, tb);
+        Py_XDECREF(tmp_tb);
+#else
+        PyThreadState *tstate = PyThreadState_GET();
+        PyObject* tmp_tb = tstate->curexc_traceback;
+        if (tb != tmp_tb) {
+            Py_INCREF(tb);
+            tstate->curexc_traceback = tb;
+            Py_XDECREF(tmp_tb);
+        }
+#endif
+    }
+bad:
+    Py_XDECREF(owned_instance);
+    return;
+}
+#endif
+
+static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void) {
+    PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable");
+}
+
+static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type) {
+    if (unlikely(!type)) {
+        PyErr_SetString(PyExc_SystemError, "Missing type object");
+        return 0;
+    }
+    if (likely(PyObject_TypeCheck(obj, type)))
+        return 1;
+    PyErr_Format(PyExc_TypeError, "Cannot convert %.200s to %.200s",
+                 Py_TYPE(obj)->tp_name, type->tp_name);
+    return 0;
+}
+
+static void __Pyx_call_next_tp_dealloc(PyObject* obj, destructor current_tp_dealloc) {
+    PyTypeObject* type = Py_TYPE(obj);
+    while (type && type->tp_dealloc != current_tp_dealloc)
+        type = type->tp_base;
+    while (type && type->tp_dealloc == current_tp_dealloc)
+        type = type->tp_base;
+    if (type)
+        type->tp_dealloc(obj);
+}
+
+static int __Pyx_call_next_tp_traverse(PyObject* obj, visitproc v, void *a, traverseproc current_tp_traverse) {
+    PyTypeObject* type = Py_TYPE(obj);
+    while (type && type->tp_traverse != current_tp_traverse)
+        type = type->tp_base;
+    while (type && type->tp_traverse == current_tp_traverse)
+        type = type->tp_base;
+    if (type && type->tp_traverse)
+        return type->tp_traverse(obj, v, a);
+    return 0;
+}
+
+static void __Pyx_call_next_tp_clear(PyObject* obj, inquiry current_tp_clear) {
+    PyTypeObject* type = Py_TYPE(obj);
+    while (type && type->tp_clear != current_tp_clear)
+        type = type->tp_base;
+    while (type && type->tp_clear == current_tp_clear)
+        type = type->tp_base;
+    if (type && type->tp_clear)
+        type->tp_clear(obj);
+}
+
+static void* __Pyx_GetVtable(PyObject *dict) {
+    void* ptr;
+    PyObject *ob = PyObject_GetItem(dict, __pyx_n_s_pyx_vtable);
+    if (!ob)
+        goto bad;
+#if PY_VERSION_HEX >= 0x02070000
+    ptr = PyCapsule_GetPointer(ob, 0);
+#else
+    ptr = PyCObject_AsVoidPtr(ob);
+#endif
+    if (!ptr && !PyErr_Occurred())
+        PyErr_SetString(PyExc_RuntimeError, "invalid vtable found for imported type");
+    Py_DECREF(ob);
+    return ptr;
+bad:
+    Py_XDECREF(ob);
+    return NULL;
+}
+
+static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
+#if PY_VERSION_HEX >= 0x02070000
+    PyObject *ob = PyCapsule_New(vtable, 0, 0);
+#else
+    PyObject *ob = PyCObject_FromVoidPtr(vtable, 0);
+#endif
+    if (!ob)
+        goto bad;
+    if (PyDict_SetItem(dict, __pyx_n_s_pyx_vtable, ob) < 0)
+        goto bad;
+    Py_DECREF(ob);
+    return 0;
+bad:
+    Py_XDECREF(ob);
+    return -1;
+}
+
+static PyObject* __Pyx_ImportFrom(PyObject* module, PyObject* name) {
+    PyObject* value = __Pyx_PyObject_GetAttrStr(module, name);
+    if (unlikely(!value) && PyErr_ExceptionMatches(PyExc_AttributeError)) {
+        PyErr_Format(PyExc_ImportError,
+        #if PY_MAJOR_VERSION < 3
+            "cannot import name %.230s", PyString_AS_STRING(name));
+        #else
+            "cannot import name %S", name);
+        #endif
+    }
+    return value;
+}
+
+static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) {
+    int start = 0, mid = 0, end = count - 1;
+    if (end >= 0 && code_line > entries[end].code_line) {
+        return count;
+    }
+    while (start < end) {
+        mid = (start + end) / 2;
+        if (code_line < entries[mid].code_line) {
+            end = mid;
+        } else if (code_line > entries[mid].code_line) {
+             start = mid + 1;
+        } else {
+            return mid;
+        }
+    }
+    if (code_line <= entries[mid].code_line) {
+        return mid;
+    } else {
+        return mid + 1;
+    }
+}
+static PyCodeObject *__pyx_find_code_object(int code_line) {
+    PyCodeObject* code_object;
+    int pos;
+    if (unlikely(!code_line) || unlikely(!__pyx_code_cache.entries)) {
+        return NULL;
+    }
+    pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line);
+    if (unlikely(pos >= __pyx_code_cache.count) || unlikely(__pyx_code_cache.entries[pos].code_line != code_line)) {
+        return NULL;
+    }
+    code_object = __pyx_code_cache.entries[pos].code_object;
+    Py_INCREF(code_object);
+    return code_object;
+}
+static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) {
+    int pos, i;
+    __Pyx_CodeObjectCacheEntry* entries = __pyx_code_cache.entries;
+    if (unlikely(!code_line)) {
+        return;
+    }
+    if (unlikely(!entries)) {
+        entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Malloc(64*sizeof(__Pyx_CodeObjectCacheEntry));
+        if (likely(entries)) {
+            __pyx_code_cache.entries = entries;
+            __pyx_code_cache.max_count = 64;
+            __pyx_code_cache.count = 1;
+            entries[0].code_line = code_line;
+            entries[0].code_object = code_object;
+            Py_INCREF(code_object);
+        }
+        return;
+    }
+    pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line);
+    if ((pos < __pyx_code_cache.count) && unlikely(__pyx_code_cache.entries[pos].code_line == code_line)) {
+        PyCodeObject* tmp = entries[pos].code_object;
+        entries[pos].code_object = code_object;
+        Py_DECREF(tmp);
+        return;
+    }
+    if (__pyx_code_cache.count == __pyx_code_cache.max_count) {
+        int new_max = __pyx_code_cache.max_count + 64;
+        entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Realloc(
+            __pyx_code_cache.entries, (size_t)new_max*sizeof(__Pyx_CodeObjectCacheEntry));
+        if (unlikely(!entries)) {
+            return;
+        }
+        __pyx_code_cache.entries = entries;
+        __pyx_code_cache.max_count = new_max;
+    }
+    for (i=__pyx_code_cache.count; i>pos; i--) {
+        entries[i] = entries[i-1];
+    }
+    entries[pos].code_line = code_line;
+    entries[pos].code_object = code_object;
+    __pyx_code_cache.count++;
+    Py_INCREF(code_object);
+}
+
+#include "compile.h"
+#include "frameobject.h"
+#include "traceback.h"
+static PyCodeObject* __Pyx_CreateCodeObjectForTraceback(
+            const char *funcname, int c_line,
+            int py_line, const char *filename) {
+    PyCodeObject *py_code = 0;
+    PyObject *py_srcfile = 0;
+    PyObject *py_funcname = 0;
+    #if PY_MAJOR_VERSION < 3
+    py_srcfile = PyString_FromString(filename);
+    #else
+    py_srcfile = PyUnicode_FromString(filename);
+    #endif
+    if (!py_srcfile) goto bad;
+    if (c_line) {
+        #if PY_MAJOR_VERSION < 3
+        py_funcname = PyString_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line);
+        #else
+        py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line);
+        #endif
+    }
+    else {
+        #if PY_MAJOR_VERSION < 3
+        py_funcname = PyString_FromString(funcname);
+        #else
+        py_funcname = PyUnicode_FromString(funcname);
+        #endif
+    }
+    if (!py_funcname) goto bad;
+    py_code = __Pyx_PyCode_New(
+        0,
+        0,
+        0,
+        0,
+        0,
+        __pyx_empty_bytes, /*PyObject *code,*/
+        __pyx_empty_tuple, /*PyObject *consts,*/
+        __pyx_empty_tuple, /*PyObject *names,*/
+        __pyx_empty_tuple, /*PyObject *varnames,*/
+        __pyx_empty_tuple, /*PyObject *freevars,*/
+        __pyx_empty_tuple, /*PyObject *cellvars,*/
+        py_srcfile,   /*PyObject *filename,*/
+        py_funcname,  /*PyObject *name,*/
+        py_line,
+        __pyx_empty_bytes  /*PyObject *lnotab*/
+    );
+    Py_DECREF(py_srcfile);
+    Py_DECREF(py_funcname);
+    return py_code;
+bad:
+    Py_XDECREF(py_srcfile);
+    Py_XDECREF(py_funcname);
+    return NULL;
+}
+static void __Pyx_AddTraceback(const char *funcname, int c_line,
+                               int py_line, const char *filename) {
+    PyCodeObject *py_code = 0;
+    PyFrameObject *py_frame = 0;
+    py_code = __pyx_find_code_object(c_line ? c_line : py_line);
+    if (!py_code) {
+        py_code = __Pyx_CreateCodeObjectForTraceback(
+            funcname, c_line, py_line, filename);
+        if (!py_code) goto bad;
+        __pyx_insert_code_object(c_line ? c_line : py_line, py_code);
+    }
+    py_frame = PyFrame_New(
+        PyThreadState_GET(), /*PyThreadState *tstate,*/
+        py_code,             /*PyCodeObject *code,*/
+        __pyx_d,      /*PyObject *globals,*/
+        0                    /*PyObject *locals*/
+    );
+    if (!py_frame) goto bad;
+    py_frame->f_lineno = py_line;
+    PyTraceBack_Here(py_frame);
+bad:
+    Py_XDECREF(py_code);
+    Py_XDECREF(py_frame);
+}
+
+static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level) {
+    PyObject *empty_list = 0;
+    PyObject *module = 0;
+    PyObject *global_dict = 0;
+    PyObject *empty_dict = 0;
+    PyObject *list;
+    #if PY_VERSION_HEX < 0x03030000
+    PyObject *py_import;
+    py_import = __Pyx_PyObject_GetAttrStr(__pyx_b, __pyx_n_s_import);
+    if (!py_import)
+        goto bad;
+    #endif
+    if (from_list)
+        list = from_list;
+    else {
+        empty_list = PyList_New(0);
+        if (!empty_list)
+            goto bad;
+        list = empty_list;
+    }
+    global_dict = PyModule_GetDict(__pyx_m);
+    if (!global_dict)
+        goto bad;
+    empty_dict = PyDict_New();
+    if (!empty_dict)
+        goto bad;
+    {
+        #if PY_MAJOR_VERSION >= 3
+        if (level == -1) {
+            if (strchr(__Pyx_MODULE_NAME, '.')) {
+                #if PY_VERSION_HEX < 0x03030000
+                PyObject *py_level = PyInt_FromLong(1);
+                if (!py_level)
+                    goto bad;
+                module = PyObject_CallFunctionObjArgs(py_import,
+                    name, global_dict, empty_dict, list, py_level, NULL);
+                Py_DECREF(py_level);
+                #else
+                module = PyImport_ImportModuleLevelObject(
+                    name, global_dict, empty_dict, list, 1);
+                #endif
+                if (!module) {
+                    if (!PyErr_ExceptionMatches(PyExc_ImportError))
+                        goto bad;
+                    PyErr_Clear();
+                }
+            }
+            level = 0;
+        }
+        #endif
+        if (!module) {
+            #if PY_VERSION_HEX < 0x03030000
+            PyObject *py_level = PyInt_FromLong(level);
+            if (!py_level)
+                goto bad;
+            module = PyObject_CallFunctionObjArgs(py_import,
+                name, global_dict, empty_dict, list, py_level, NULL);
+            Py_DECREF(py_level);
+            #else
+            module = PyImport_ImportModuleLevelObject(
+                name, global_dict, empty_dict, list, level);
+            #endif
+        }
+    }
+bad:
+    #if PY_VERSION_HEX < 0x03030000
+    Py_XDECREF(py_import);
+    #endif
+    Py_XDECREF(empty_list);
+    Py_XDECREF(empty_dict);
+    return module;
+}
+
+#define __PYX_VERIFY_RETURN_INT(target_type, func_type, func_value)       \
+    {                                                                     \
+        func_type value = func_value;                                     \
+        if (sizeof(target_type) < sizeof(func_type)) {                    \
+            if (unlikely(value != (func_type) (target_type) value)) {     \
+                func_type zero = 0;                                       \
+                if (is_unsigned && unlikely(value < zero))                \
+                    goto raise_neg_overflow;                              \
+                else                                                      \
+                    goto raise_overflow;                                  \
+            }                                                             \
+        }                                                                 \
+        return (target_type) value;                                       \
+    }
+
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+  #include "longintrepr.h"
+ #endif
+#endif
+
+static CYTHON_INLINE unsigned int __Pyx_PyInt_As_unsigned_int(PyObject *x) {
+    const unsigned int neg_one = (unsigned int) -1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_MAJOR_VERSION < 3
+    if (likely(PyInt_Check(x))) {
+        if (sizeof(unsigned int) < sizeof(long)) {
+            __PYX_VERIFY_RETURN_INT(unsigned int, long, PyInt_AS_LONG(x))
+        } else {
+            long val = PyInt_AS_LONG(x);
+            if (is_unsigned && unlikely(val < 0)) {
+                goto raise_neg_overflow;
+            }
+            return (unsigned int) val;
+        }
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+            switch (Py_SIZE(x)) {
+                case  0: return 0;
+                case  1: __PYX_VERIFY_RETURN_INT(unsigned int, digit, ((PyLongObject*)x)->ob_digit[0]);
+            }
+ #endif
+#endif
+            if (unlikely(Py_SIZE(x) < 0)) {
+                goto raise_neg_overflow;
+            }
+            if (sizeof(unsigned int) <= sizeof(unsigned long)) {
+                __PYX_VERIFY_RETURN_INT(unsigned int, unsigned long, PyLong_AsUnsignedLong(x))
+            } else if (sizeof(unsigned int) <= sizeof(unsigned long long)) {
+                __PYX_VERIFY_RETURN_INT(unsigned int, unsigned long long, PyLong_AsUnsignedLongLong(x))
+            }
+        } else {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+            switch (Py_SIZE(x)) {
+                case  0: return 0;
+                case  1: __PYX_VERIFY_RETURN_INT(unsigned int,  digit, +(((PyLongObject*)x)->ob_digit[0]));
+                case -1: __PYX_VERIFY_RETURN_INT(unsigned int, sdigit, -(sdigit) ((PyLongObject*)x)->ob_digit[0]);
+            }
+ #endif
+#endif
+            if (sizeof(unsigned int) <= sizeof(long)) {
+                __PYX_VERIFY_RETURN_INT(unsigned int, long, PyLong_AsLong(x))
+            } else if (sizeof(unsigned int) <= sizeof(long long)) {
+                __PYX_VERIFY_RETURN_INT(unsigned int, long long, PyLong_AsLongLong(x))
+            }
+        }
+        {
+#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray)
+            PyErr_SetString(PyExc_RuntimeError,
+                            "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers");
+#else
+            unsigned int val;
+            PyObject *v = __Pyx_PyNumber_Int(x);
+ #if PY_MAJOR_VERSION < 3
+            if (likely(v) && !PyLong_Check(v)) {
+                PyObject *tmp = v;
+                v = PyNumber_Long(tmp);
+                Py_DECREF(tmp);
+            }
+ #endif
+            if (likely(v)) {
+                int one = 1; int is_little = (int)*(unsigned char *)&one;
+                unsigned char *bytes = (unsigned char *)&val;
+                int ret = _PyLong_AsByteArray((PyLongObject *)v,
+                                              bytes, sizeof(val),
+                                              is_little, !is_unsigned);
+                Py_DECREF(v);
+                if (likely(!ret))
+                    return val;
+            }
+#endif
+            return (unsigned int) -1;
+        }
+    } else {
+        unsigned int val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (unsigned int) -1;
+        val = __Pyx_PyInt_As_unsigned_int(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+raise_overflow:
+    PyErr_SetString(PyExc_OverflowError,
+        "value too large to convert to unsigned int");
+    return (unsigned int) -1;
+raise_neg_overflow:
+    PyErr_SetString(PyExc_OverflowError,
+        "can't convert negative value to unsigned int");
+    return (unsigned int) -1;
+}
+
+static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *x) {
+    const int neg_one = (int) -1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_MAJOR_VERSION < 3
+    if (likely(PyInt_Check(x))) {
+        if (sizeof(int) < sizeof(long)) {
+            __PYX_VERIFY_RETURN_INT(int, long, PyInt_AS_LONG(x))
+        } else {
+            long val = PyInt_AS_LONG(x);
+            if (is_unsigned && unlikely(val < 0)) {
+                goto raise_neg_overflow;
+            }
+            return (int) val;
+        }
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+            switch (Py_SIZE(x)) {
+                case  0: return 0;
+                case  1: __PYX_VERIFY_RETURN_INT(int, digit, ((PyLongObject*)x)->ob_digit[0]);
+            }
+ #endif
+#endif
+            if (unlikely(Py_SIZE(x) < 0)) {
+                goto raise_neg_overflow;
+            }
+            if (sizeof(int) <= sizeof(unsigned long)) {
+                __PYX_VERIFY_RETURN_INT(int, unsigned long, PyLong_AsUnsignedLong(x))
+            } else if (sizeof(int) <= sizeof(unsigned long long)) {
+                __PYX_VERIFY_RETURN_INT(int, unsigned long long, PyLong_AsUnsignedLongLong(x))
+            }
+        } else {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+            switch (Py_SIZE(x)) {
+                case  0: return 0;
+                case  1: __PYX_VERIFY_RETURN_INT(int,  digit, +(((PyLongObject*)x)->ob_digit[0]));
+                case -1: __PYX_VERIFY_RETURN_INT(int, sdigit, -(sdigit) ((PyLongObject*)x)->ob_digit[0]);
+            }
+ #endif
+#endif
+            if (sizeof(int) <= sizeof(long)) {
+                __PYX_VERIFY_RETURN_INT(int, long, PyLong_AsLong(x))
+            } else if (sizeof(int) <= sizeof(long long)) {
+                __PYX_VERIFY_RETURN_INT(int, long long, PyLong_AsLongLong(x))
+            }
+        }
+        {
+#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray)
+            PyErr_SetString(PyExc_RuntimeError,
+                            "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers");
+#else
+            int val;
+            PyObject *v = __Pyx_PyNumber_Int(x);
+ #if PY_MAJOR_VERSION < 3
+            if (likely(v) && !PyLong_Check(v)) {
+                PyObject *tmp = v;
+                v = PyNumber_Long(tmp);
+                Py_DECREF(tmp);
+            }
+ #endif
+            if (likely(v)) {
+                int one = 1; int is_little = (int)*(unsigned char *)&one;
+                unsigned char *bytes = (unsigned char *)&val;
+                int ret = _PyLong_AsByteArray((PyLongObject *)v,
+                                              bytes, sizeof(val),
+                                              is_little, !is_unsigned);
+                Py_DECREF(v);
+                if (likely(!ret))
+                    return val;
+            }
+#endif
+            return (int) -1;
+        }
+    } else {
+        int val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (int) -1;
+        val = __Pyx_PyInt_As_int(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+raise_overflow:
+    PyErr_SetString(PyExc_OverflowError,
+        "value too large to convert to int");
+    return (int) -1;
+raise_neg_overflow:
+    PyErr_SetString(PyExc_OverflowError,
+        "can't convert negative value to int");
+    return (int) -1;
+}
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value) {
+    const long neg_one = (long) -1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (is_unsigned) {
+        if (sizeof(long) < sizeof(long)) {
+            return PyInt_FromLong((long) value);
+        } else if (sizeof(long) <= sizeof(unsigned long)) {
+            return PyLong_FromUnsignedLong((unsigned long) value);
+        } else if (sizeof(long) <= sizeof(unsigned long long)) {
+            return PyLong_FromUnsignedLongLong((unsigned long long) value);
+        }
+    } else {
+        if (sizeof(long) <= sizeof(long)) {
+            return PyInt_FromLong((long) value);
+        } else if (sizeof(long) <= sizeof(long long)) {
+            return PyLong_FromLongLong((long long) value);
+        }
+    }
+    {
+        int one = 1; int little = (int)*(unsigned char *)&one;
+        unsigned char *bytes = (unsigned char *)&value;
+        return _PyLong_FromByteArray(bytes, sizeof(long),
+                                     little, !is_unsigned);
+    }
+}
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value) {
+    const int neg_one = (int) -1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (is_unsigned) {
+        if (sizeof(int) < sizeof(long)) {
+            return PyInt_FromLong((long) value);
+        } else if (sizeof(int) <= sizeof(unsigned long)) {
+            return PyLong_FromUnsignedLong((unsigned long) value);
+        } else if (sizeof(int) <= sizeof(unsigned long long)) {
+            return PyLong_FromUnsignedLongLong((unsigned long long) value);
+        }
+    } else {
+        if (sizeof(int) <= sizeof(long)) {
+            return PyInt_FromLong((long) value);
+        } else if (sizeof(int) <= sizeof(long long)) {
+            return PyLong_FromLongLong((long long) value);
+        }
+    }
+    {
+        int one = 1; int little = (int)*(unsigned char *)&one;
+        unsigned char *bytes = (unsigned char *)&value;
+        return _PyLong_FromByteArray(bytes, sizeof(int),
+                                     little, !is_unsigned);
+    }
+}
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_unsigned_int(unsigned int value) {
+    const unsigned int neg_one = (unsigned int) -1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (is_unsigned) {
+        if (sizeof(unsigned int) < sizeof(long)) {
+            return PyInt_FromLong((long) value);
+        } else if (sizeof(unsigned int) <= sizeof(unsigned long)) {
+            return PyLong_FromUnsignedLong((unsigned long) value);
+        } else if (sizeof(unsigned int) <= sizeof(unsigned long long)) {
+            return PyLong_FromUnsignedLongLong((unsigned long long) value);
+        }
+    } else {
+        if (sizeof(unsigned int) <= sizeof(long)) {
+            return PyInt_FromLong((long) value);
+        } else if (sizeof(unsigned int) <= sizeof(long long)) {
+            return PyLong_FromLongLong((long long) value);
+        }
+    }
+    {
+        int one = 1; int little = (int)*(unsigned char *)&one;
+        unsigned char *bytes = (unsigned char *)&value;
+        return _PyLong_FromByteArray(bytes, sizeof(unsigned int),
+                                     little, !is_unsigned);
+    }
+}
+
+#if CYTHON_CCOMPLEX
+  #ifdef __cplusplus
+    static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float x, float y) {
+      return ::std::complex< float >(x, y);
+    }
+  #else
+    static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float x, float y) {
+      return x + y*(__pyx_t_float_complex)_Complex_I;
+    }
+  #endif
+#else
+    static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float x, float y) {
+      __pyx_t_float_complex z;
+      z.real = x;
+      z.imag = y;
+      return z;
+    }
+#endif
+
+#if CYTHON_CCOMPLEX
+#else
+    static CYTHON_INLINE int __Pyx_c_eqf(__pyx_t_float_complex a, __pyx_t_float_complex b) {
+       return (a.real == b.real) && (a.imag == b.imag);
+    }
+    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_sumf(__pyx_t_float_complex a, __pyx_t_float_complex b) {
+        __pyx_t_float_complex z;
+        z.real = a.real + b.real;
+        z.imag = a.imag + b.imag;
+        return z;
+    }
+    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_difff(__pyx_t_float_complex a, __pyx_t_float_complex b) {
+        __pyx_t_float_complex z;
+        z.real = a.real - b.real;
+        z.imag = a.imag - b.imag;
+        return z;
+    }
+    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_prodf(__pyx_t_float_complex a, __pyx_t_float_complex b) {
+        __pyx_t_float_complex z;
+        z.real = a.real * b.real - a.imag * b.imag;
+        z.imag = a.real * b.imag + a.imag * b.real;
+        return z;
+    }
+    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_quotf(__pyx_t_float_complex a, __pyx_t_float_complex b) {
+        __pyx_t_float_complex z;
+        float denom = b.real * b.real + b.imag * b.imag;
+        z.real = (a.real * b.real + a.imag * b.imag) / denom;
+        z.imag = (a.imag * b.real - a.real * b.imag) / denom;
+        return z;
+    }
+    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_negf(__pyx_t_float_complex a) {
+        __pyx_t_float_complex z;
+        z.real = -a.real;
+        z.imag = -a.imag;
+        return z;
+    }
+    static CYTHON_INLINE int __Pyx_c_is_zerof(__pyx_t_float_complex a) {
+       return (a.real == 0) && (a.imag == 0);
+    }
+    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_conjf(__pyx_t_float_complex a) {
+        __pyx_t_float_complex z;
+        z.real =  a.real;
+        z.imag = -a.imag;
+        return z;
+    }
+    #if 1
+        static CYTHON_INLINE float __Pyx_c_absf(__pyx_t_float_complex z) {
+          #if !defined(HAVE_HYPOT) || defined(_MSC_VER)
+            return sqrtf(z.real*z.real + z.imag*z.imag);
+          #else
+            return hypotf(z.real, z.imag);
+          #endif
+        }
+        static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_powf(__pyx_t_float_complex a, __pyx_t_float_complex b) {
+            __pyx_t_float_complex z;
+            float r, lnr, theta, z_r, z_theta;
+            if (b.imag == 0 && b.real == (int)b.real) {
+                if (b.real < 0) {
+                    float denom = a.real * a.real + a.imag * a.imag;
+                    a.real = a.real / denom;
+                    a.imag = -a.imag / denom;
+                    b.real = -b.real;
+                }
+                switch ((int)b.real) {
+                    case 0:
+                        z.real = 1;
+                        z.imag = 0;
+                        return z;
+                    case 1:
+                        return a;
+                    case 2:
+                        z = __Pyx_c_prodf(a, a);
+                        return __Pyx_c_prodf(a, a);
+                    case 3:
+                        z = __Pyx_c_prodf(a, a);
+                        return __Pyx_c_prodf(z, a);
+                    case 4:
+                        z = __Pyx_c_prodf(a, a);
+                        return __Pyx_c_prodf(z, z);
+                }
+            }
+            if (a.imag == 0) {
+                if (a.real == 0) {
+                    return a;
+                }
+                r = a.real;
+                theta = 0;
+            } else {
+                r = __Pyx_c_absf(a);
+                theta = atan2f(a.imag, a.real);
+            }
+            lnr = logf(r);
+            z_r = expf(lnr * b.real - theta * b.imag);
+            z_theta = theta * b.real + lnr * b.imag;
+            z.real = z_r * cosf(z_theta);
+            z.imag = z_r * sinf(z_theta);
+            return z;
+        }
+    #endif
+#endif
+
+#if CYTHON_CCOMPLEX
+  #ifdef __cplusplus
+    static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) {
+      return ::std::complex< double >(x, y);
+    }
+  #else
+    static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) {
+      return x + y*(__pyx_t_double_complex)_Complex_I;
+    }
+  #endif
+#else
+    static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) {
+      __pyx_t_double_complex z;
+      z.real = x;
+      z.imag = y;
+      return z;
+    }
+#endif
+
+#if CYTHON_CCOMPLEX
+#else
+    static CYTHON_INLINE int __Pyx_c_eq(__pyx_t_double_complex a, __pyx_t_double_complex b) {
+       return (a.real == b.real) && (a.imag == b.imag);
+    }
+    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_sum(__pyx_t_double_complex a, __pyx_t_double_complex b) {
+        __pyx_t_double_complex z;
+        z.real = a.real + b.real;
+        z.imag = a.imag + b.imag;
+        return z;
+    }
+    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_diff(__pyx_t_double_complex a, __pyx_t_double_complex b) {
+        __pyx_t_double_complex z;
+        z.real = a.real - b.real;
+        z.imag = a.imag - b.imag;
+        return z;
+    }
+    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_prod(__pyx_t_double_complex a, __pyx_t_double_complex b) {
+        __pyx_t_double_complex z;
+        z.real = a.real * b.real - a.imag * b.imag;
+        z.imag = a.real * b.imag + a.imag * b.real;
+        return z;
+    }
+    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_quot(__pyx_t_double_complex a, __pyx_t_double_complex b) {
+        __pyx_t_double_complex z;
+        double denom = b.real * b.real + b.imag * b.imag;
+        z.real = (a.real * b.real + a.imag * b.imag) / denom;
+        z.imag = (a.imag * b.real - a.real * b.imag) / denom;
+        return z;
+    }
+    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_neg(__pyx_t_double_complex a) {
+        __pyx_t_double_complex z;
+        z.real = -a.real;
+        z.imag = -a.imag;
+        return z;
+    }
+    static CYTHON_INLINE int __Pyx_c_is_zero(__pyx_t_double_complex a) {
+       return (a.real == 0) && (a.imag == 0);
+    }
+    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_conj(__pyx_t_double_complex a) {
+        __pyx_t_double_complex z;
+        z.real =  a.real;
+        z.imag = -a.imag;
+        return z;
+    }
+    #if 1
+        static CYTHON_INLINE double __Pyx_c_abs(__pyx_t_double_complex z) {
+          #if !defined(HAVE_HYPOT) || defined(_MSC_VER)
+            return sqrt(z.real*z.real + z.imag*z.imag);
+          #else
+            return hypot(z.real, z.imag);
+          #endif
+        }
+        static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_pow(__pyx_t_double_complex a, __pyx_t_double_complex b) {
+            __pyx_t_double_complex z;
+            double r, lnr, theta, z_r, z_theta;
+            if (b.imag == 0 && b.real == (int)b.real) {
+                if (b.real < 0) {
+                    double denom = a.real * a.real + a.imag * a.imag;
+                    a.real = a.real / denom;
+                    a.imag = -a.imag / denom;
+                    b.real = -b.real;
+                }
+                switch ((int)b.real) {
+                    case 0:
+                        z.real = 1;
+                        z.imag = 0;
+                        return z;
+                    case 1:
+                        return a;
+                    case 2:
+                        z = __Pyx_c_prod(a, a);
+                        return __Pyx_c_prod(a, a);
+                    case 3:
+                        z = __Pyx_c_prod(a, a);
+                        return __Pyx_c_prod(z, a);
+                    case 4:
+                        z = __Pyx_c_prod(a, a);
+                        return __Pyx_c_prod(z, z);
+                }
+            }
+            if (a.imag == 0) {
+                if (a.real == 0) {
+                    return a;
+                }
+                r = a.real;
+                theta = 0;
+            } else {
+                r = __Pyx_c_abs(a);
+                theta = atan2(a.imag, a.real);
+            }
+            lnr = log(r);
+            z_r = exp(lnr * b.real - theta * b.imag);
+            z_theta = theta * b.real + lnr * b.imag;
+            z.real = z_r * cos(z_theta);
+            z.imag = z_r * sin(z_theta);
+            return z;
+        }
+    #endif
+#endif
+
+static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *x) {
+    const long neg_one = (long) -1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_MAJOR_VERSION < 3
+    if (likely(PyInt_Check(x))) {
+        if (sizeof(long) < sizeof(long)) {
+            __PYX_VERIFY_RETURN_INT(long, long, PyInt_AS_LONG(x))
+        } else {
+            long val = PyInt_AS_LONG(x);
+            if (is_unsigned && unlikely(val < 0)) {
+                goto raise_neg_overflow;
+            }
+            return (long) val;
+        }
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+            switch (Py_SIZE(x)) {
+                case  0: return 0;
+                case  1: __PYX_VERIFY_RETURN_INT(long, digit, ((PyLongObject*)x)->ob_digit[0]);
+            }
+ #endif
+#endif
+            if (unlikely(Py_SIZE(x) < 0)) {
+                goto raise_neg_overflow;
+            }
+            if (sizeof(long) <= sizeof(unsigned long)) {
+                __PYX_VERIFY_RETURN_INT(long, unsigned long, PyLong_AsUnsignedLong(x))
+            } else if (sizeof(long) <= sizeof(unsigned long long)) {
+                __PYX_VERIFY_RETURN_INT(long, unsigned long long, PyLong_AsUnsignedLongLong(x))
+            }
+        } else {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+            switch (Py_SIZE(x)) {
+                case  0: return 0;
+                case  1: __PYX_VERIFY_RETURN_INT(long,  digit, +(((PyLongObject*)x)->ob_digit[0]));
+                case -1: __PYX_VERIFY_RETURN_INT(long, sdigit, -(sdigit) ((PyLongObject*)x)->ob_digit[0]);
+            }
+ #endif
+#endif
+            if (sizeof(long) <= sizeof(long)) {
+                __PYX_VERIFY_RETURN_INT(long, long, PyLong_AsLong(x))
+            } else if (sizeof(long) <= sizeof(long long)) {
+                __PYX_VERIFY_RETURN_INT(long, long long, PyLong_AsLongLong(x))
+            }
+        }
+        {
+#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray)
+            PyErr_SetString(PyExc_RuntimeError,
+                            "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers");
+#else
+            long val;
+            PyObject *v = __Pyx_PyNumber_Int(x);
+ #if PY_MAJOR_VERSION < 3
+            if (likely(v) && !PyLong_Check(v)) {
+                PyObject *tmp = v;
+                v = PyNumber_Long(tmp);
+                Py_DECREF(tmp);
+            }
+ #endif
+            if (likely(v)) {
+                int one = 1; int is_little = (int)*(unsigned char *)&one;
+                unsigned char *bytes = (unsigned char *)&val;
+                int ret = _PyLong_AsByteArray((PyLongObject *)v,
+                                              bytes, sizeof(val),
+                                              is_little, !is_unsigned);
+                Py_DECREF(v);
+                if (likely(!ret))
+                    return val;
+            }
+#endif
+            return (long) -1;
+        }
+    } else {
+        long val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (long) -1;
+        val = __Pyx_PyInt_As_long(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+raise_overflow:
+    PyErr_SetString(PyExc_OverflowError,
+        "value too large to convert to long");
+    return (long) -1;
+raise_neg_overflow:
+    PyErr_SetString(PyExc_OverflowError,
+        "can't convert negative value to long");
+    return (long) -1;
+}
+
+static int __Pyx_check_binary_version(void) {
+    char ctversion[4], rtversion[4];
+    PyOS_snprintf(ctversion, 4, "%d.%d", PY_MAJOR_VERSION, PY_MINOR_VERSION);
+    PyOS_snprintf(rtversion, 4, "%s", Py_GetVersion());
+    if (ctversion[0] != rtversion[0] || ctversion[2] != rtversion[2]) {
+        char message[200];
+        PyOS_snprintf(message, sizeof(message),
+                      "compiletime version %s of module '%.100s' "
+                      "does not match runtime version %s",
+                      ctversion, __Pyx_MODULE_NAME, rtversion);
+        return PyErr_WarnEx(NULL, message, 1);
+    }
+    return 0;
+}
+
+#ifndef __PYX_HAVE_RT_ImportModule
+#define __PYX_HAVE_RT_ImportModule
+static PyObject *__Pyx_ImportModule(const char *name) {
+    PyObject *py_name = 0;
+    PyObject *py_module = 0;
+    py_name = __Pyx_PyIdentifier_FromString(name);
+    if (!py_name)
+        goto bad;
+    py_module = PyImport_Import(py_name);
+    Py_DECREF(py_name);
+    return py_module;
+bad:
+    Py_XDECREF(py_name);
+    return 0;
+}
+#endif
+
+#ifndef __PYX_HAVE_RT_ImportType
+#define __PYX_HAVE_RT_ImportType
+static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name,
+    size_t size, int strict)
+{
+    PyObject *py_module = 0;
+    PyObject *result = 0;
+    PyObject *py_name = 0;
+    char warning[200];
+    Py_ssize_t basicsize;
+#ifdef Py_LIMITED_API
+    PyObject *py_basicsize;
+#endif
+    py_module = __Pyx_ImportModule(module_name);
+    if (!py_module)
+        goto bad;
+    py_name = __Pyx_PyIdentifier_FromString(class_name);
+    if (!py_name)
+        goto bad;
+    result = PyObject_GetAttr(py_module, py_name);
+    Py_DECREF(py_name);
+    py_name = 0;
+    Py_DECREF(py_module);
+    py_module = 0;
+    if (!result)
+        goto bad;
+    if (!PyType_Check(result)) {
+        PyErr_Format(PyExc_TypeError,
+            "%.200s.%.200s is not a type object",
+            module_name, class_name);
+        goto bad;
+    }
+#ifndef Py_LIMITED_API
+    basicsize = ((PyTypeObject *)result)->tp_basicsize;
+#else
+    py_basicsize = PyObject_GetAttrString(result, "__basicsize__");
+    if (!py_basicsize)
+        goto bad;
+    basicsize = PyLong_AsSsize_t(py_basicsize);
+    Py_DECREF(py_basicsize);
+    py_basicsize = 0;
+    if (basicsize == (Py_ssize_t)-1 && PyErr_Occurred())
+        goto bad;
+#endif
+    if (!strict && (size_t)basicsize > size) {
+        PyOS_snprintf(warning, sizeof(warning),
+            "%s.%s size changed, may indicate binary incompatibility",
+            module_name, class_name);
+        if (PyErr_WarnEx(NULL, warning, 0) < 0) goto bad;
+    }
+    else if ((size_t)basicsize != size) {
+        PyErr_Format(PyExc_ValueError,
+            "%.200s.%.200s has the wrong size, try recompiling",
+            module_name, class_name);
+        goto bad;
+    }
+    return (PyTypeObject *)result;
+bad:
+    Py_XDECREF(py_module);
+    Py_XDECREF(result);
+    return NULL;
+}
+#endif
+
+static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
+    while (t->p) {
+        #if PY_MAJOR_VERSION < 3
+        if (t->is_unicode) {
+            *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
+        } else if (t->intern) {
+            *t->p = PyString_InternFromString(t->s);
+        } else {
+            *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
+        }
+        #else
+        if (t->is_unicode | t->is_str) {
+            if (t->intern) {
+                *t->p = PyUnicode_InternFromString(t->s);
+            } else if (t->encoding) {
+                *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL);
+            } else {
+                *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
+            }
+        } else {
+            *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
+        }
+        #endif
+        if (!*t->p)
+            return -1;
+        ++t;
+    }
+    return 0;
+}
+
+static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char* c_str) {
+    return __Pyx_PyUnicode_FromStringAndSize(c_str, (Py_ssize_t)strlen(c_str));
+}
+static CYTHON_INLINE char* __Pyx_PyObject_AsString(PyObject* o) {
+    Py_ssize_t ignore;
+    return __Pyx_PyObject_AsStringAndSize(o, &ignore);
+}
+static CYTHON_INLINE char* __Pyx_PyObject_AsStringAndSize(PyObject* o, Py_ssize_t *length) {
+#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT
+    if (
+#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII
+            __Pyx_sys_getdefaultencoding_not_ascii &&
+#endif
+            PyUnicode_Check(o)) {
+#if PY_VERSION_HEX < 0x03030000
+        char* defenc_c;
+        PyObject* defenc = _PyUnicode_AsDefaultEncodedString(o, NULL);
+        if (!defenc) return NULL;
+        defenc_c = PyBytes_AS_STRING(defenc);
+#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII
+        {
+            char* end = defenc_c + PyBytes_GET_SIZE(defenc);
+            char* c;
+            for (c = defenc_c; c < end; c++) {
+                if ((unsigned char) (*c) >= 128) {
+                    PyUnicode_AsASCIIString(o);
+                    return NULL;
+                }
+            }
+        }
+#endif
+        *length = PyBytes_GET_SIZE(defenc);
+        return defenc_c;
+#else
+        if (__Pyx_PyUnicode_READY(o) == -1) return NULL;
+#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII
+        if (PyUnicode_IS_ASCII(o)) {
+            *length = PyUnicode_GET_LENGTH(o);
+            return PyUnicode_AsUTF8(o);
+        } else {
+            PyUnicode_AsASCIIString(o);
+            return NULL;
+        }
+#else
+        return PyUnicode_AsUTF8AndSize(o, length);
+#endif
+#endif
+    } else
+#endif
+#if !CYTHON_COMPILING_IN_PYPY
+    if (PyByteArray_Check(o)) {
+        *length = PyByteArray_GET_SIZE(o);
+        return PyByteArray_AS_STRING(o);
+    } else
+#endif
+    {
+        char* result;
+        int r = PyBytes_AsStringAndSize(o, &result, length);
+        if (unlikely(r < 0)) {
+            return NULL;
+        } else {
+            return result;
+        }
+    }
+}
+static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) {
+   int is_true = x == Py_True;
+   if (is_true | (x == Py_False) | (x == Py_None)) return is_true;
+   else return PyObject_IsTrue(x);
+}
+static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x) {
+  PyNumberMethods *m;
+  const char *name = NULL;
+  PyObject *res = NULL;
+#if PY_MAJOR_VERSION < 3
+  if (PyInt_Check(x) || PyLong_Check(x))
+#else
+  if (PyLong_Check(x))
+#endif
+    return Py_INCREF(x), x;
+  m = Py_TYPE(x)->tp_as_number;
+#if PY_MAJOR_VERSION < 3
+  if (m && m->nb_int) {
+    name = "int";
+    res = PyNumber_Int(x);
+  }
+  else if (m && m->nb_long) {
+    name = "long";
+    res = PyNumber_Long(x);
+  }
+#else
+  if (m && m->nb_int) {
+    name = "int";
+    res = PyNumber_Long(x);
+  }
+#endif
+  if (res) {
+#if PY_MAJOR_VERSION < 3
+    if (!PyInt_Check(res) && !PyLong_Check(res)) {
+#else
+    if (!PyLong_Check(res)) {
+#endif
+      PyErr_Format(PyExc_TypeError,
+                   "__%.4s__ returned non-%.4s (type %.200s)",
+                   name, name, Py_TYPE(res)->tp_name);
+      Py_DECREF(res);
+      return NULL;
+    }
+  }
+  else if (!PyErr_Occurred()) {
+    PyErr_SetString(PyExc_TypeError,
+                    "an integer is required");
+  }
+  return res;
+}
+static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) {
+  Py_ssize_t ival;
+  PyObject *x;
+#if PY_MAJOR_VERSION < 3
+  if (likely(PyInt_CheckExact(b)))
+      return PyInt_AS_LONG(b);
+#endif
+  if (likely(PyLong_CheckExact(b))) {
+    #if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+     #if CYTHON_USE_PYLONG_INTERNALS
+       switch (Py_SIZE(b)) {
+       case -1: return -(sdigit)((PyLongObject*)b)->ob_digit[0];
+       case  0: return 0;
+       case  1: return ((PyLongObject*)b)->ob_digit[0];
+       }
+     #endif
+    #endif
+    return PyLong_AsSsize_t(b);
+  }
+  x = PyNumber_Index(b);
+  if (!x) return -1;
+  ival = PyInt_AsSsize_t(x);
+  Py_DECREF(x);
+  return ival;
+}
+static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) {
+    return PyInt_FromSize_t(ival);
+}
+
+
+#endif /* Py_PYTHON_H */
diff --git a/lib/bx/bbi/bigbed_file.pyx b/lib/bx/bbi/bigbed_file.pyx
new file mode 100644
index 0000000..9674770
--- /dev/null
+++ b/lib/bx/bbi/bigbed_file.pyx
@@ -0,0 +1,142 @@
+#cython: profile=False
+"""
+BigBed file.
+"""
+
+from bbi_file cimport *
+from cirtree_file cimport CIRTreeFile
+import numpy as np
+cimport numpy as np
+from types cimport *
+from bx.intervals.io import GenomicInterval
+from bx.misc.binary_file import BinaryFileReader
+from cStringIO import StringIO
+import zlib
+
+DEF big_bed_sig = 0x8789F2EB
+
+cdef inline int range_intersection( int start1, int end1, int start2, int end2 ):
+    return min( end1, end2 ) - max( start1, start2 )
+
+cdef str read_c_string(fh):
+    """
+    Read a zero terminated (C style) string
+    Read in chunks of 8 bytes to minimize calls to read.
+    If we read to much then seek back to the correct place.
+    """
+    chunksize = 8
+    read = [fh.read(chunksize)]
+    while not '\0' in read[-1]:
+        r = fh.read(chunksize)
+        read.append(r)
+        if len(r) != chunksize:
+            break
+
+    pos = read[-1].find('\0')
+    l = len(read[-1])
+    if l == chunksize:
+        fh.seek(-(chunksize - pos) + 1, 1)
+    if l != chunksize:
+        read[-1] = read[-1][:pos]
+
+    return "".join(read) if len(read) > 1 else read[0]
+
+cdef class BigBedBlockHandler( BlockHandler ):
+    """
+    BlockHandler that parses the block into a series of BED records
+    """
+    cdef bits32 chrom_id
+    cdef bits32 start
+    cdef bits32 end
+    def __init__( self, bits32 chrom_id, bits32 start, bits32 end ):
+        BlockHandler.__init__( self )
+        self.chrom_id = chrom_id
+        self.start = start
+        self.end = end
+    cdef handle_block( self, str block_data, BBIFile bbi_file ):
+        cdef object string_io
+        cdef int length
+        cdef bits32 chrom_id, s, e
+        cdef str rest
+        # Now we parse the block, which should just be a bunch of BED records
+        string_io = StringIO( block_data )
+        block_reader = BinaryFileReader( string_io, is_little_endian=bbi_file.reader.is_little_endian )
+        length = len( block_data )
+        while string_io.tell() < length:
+            chrom_id, s, e = block_reader.read_and_unpack("LLL", 12)
+            rest = read_c_string(string_io)
+
+            if chrom_id != self.chrom_id:
+                continue
+            if s < self.end and e > self.start:
+                self.handle_interval_value( s, e, rest )
+    cdef handle_interval_value( self, bits32 s, bits32 e, str rest ):
+        pass
+
+cdef class SummarizingBlockHandler( BigBedBlockHandler ):
+    """
+    Accumulates intervals into a SummarizedData
+    """
+    cdef SummarizedData sd
+    def __init__( self, bits32 chrom_id, bits32 start, bits32 end, int summary_size ):
+        BigBedBlockHandler.__init__( self, chrom_id, start, end )
+        # What we will load into
+        self.sd = SummarizedData( start, end, summary_size )
+        for i in range(summary_size):
+            self.sd.min_val[i] = +np.inf
+        for i in range(summary_size):
+            self.sd.max_val[i] = -np.inf
+
+    cdef handle_interval_value( self, bits32 s, bits32 e, str rest ):
+        # FIXME: Does this really obvious thing actually do what we want?
+        #        No... sum_data will end up being the coverage, but min/max/etc are wrong
+        self.sd.accumulate_interval_value( s, e, 1 )
+
+cdef class IntervalAccumulatingBlockHandler( BigBedBlockHandler ):
+    cdef list intervals
+    """
+    Accumulates intervals into a list of intervals with values
+    """
+    def __init__( self, bits32 chrom_id, bits32 start, bits32 end ):
+        BigBedBlockHandler.__init__( self, chrom_id, start, end )
+        self.intervals = []
+
+    cdef handle_interval_value( self, bits32 s, bits32 e, str rest ):
+        self.intervals.append( ( s, e, rest ) )
+
+cdef class BigBedFile( BBIFile ): 
+    """
+    A "big binary indexed" file whose raw data is in BED format.
+    """
+    def __init__( self, file=None ):
+        BBIFile.__init__( self, file, big_bed_sig, "bigbed" )
+
+    cdef _summarize_from_full( self, bits32 chrom_id, bits32 start, bits32 end, int summary_size ):
+        """
+        Create summary from full data.
+        """
+        v = SummarizingBlockHandler( chrom_id, start, end, summary_size )
+        self.visit_blocks_in_region( chrom_id, start, end, v )
+        np.round(v.sd.valid_count, out=v.sd.valid_count)
+        return v.sd
+        
+    cpdef get( self, char * chrom, bits32 start, bits32 end ):
+        """
+        Gets all data points over the regions `chrom`:`start`-`end`.
+        """
+        if start >= end:
+            return None
+        chrom_id, chrom_size = self._get_chrom_id_and_size( chrom )
+        if chrom_id is None:
+            return None
+        v = IntervalAccumulatingBlockHandler( chrom_id, start, end )
+        self.visit_blocks_in_region( chrom_id, start, end, v )
+        rval = []
+        # FIXME: Not sure the best way to return, will user GenomicInterval for
+        # now. 
+        for ( s, e, rest ) in v.intervals:
+            fields = [ chrom, str( s ), str( e ) ] + rest.split( "\t" )
+            rval.append( GenomicInterval( None, fields, 0, 1, 2, 5, "+" ) )
+        return rval
+
+
diff --git a/lib/bx/bbi/bigwig_file.c b/lib/bx/bbi/bigwig_file.c
new file mode 100644
index 0000000..832e80a
--- /dev/null
+++ b/lib/bx/bbi/bigwig_file.c
@@ -0,0 +1,10167 @@
+/* Generated by Cython 0.22 */
+
+#define PY_SSIZE_T_CLEAN
+#ifndef CYTHON_USE_PYLONG_INTERNALS
+#ifdef PYLONG_BITS_IN_DIGIT
+#define CYTHON_USE_PYLONG_INTERNALS 0
+#else
+#include "pyconfig.h"
+#ifdef PYLONG_BITS_IN_DIGIT
+#define CYTHON_USE_PYLONG_INTERNALS 1
+#else
+#define CYTHON_USE_PYLONG_INTERNALS 0
+#endif
+#endif
+#endif
+#include "Python.h"
+#ifndef Py_PYTHON_H
+    #error Python headers needed to compile C extensions, please install development version of Python.
+#elif PY_VERSION_HEX < 0x02060000 || (0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03020000)
+    #error Cython requires Python 2.6+ or Python 3.2+.
+#else
+#define CYTHON_ABI "0_22"
+#include <stddef.h>
+#ifndef offsetof
+#define offsetof(type, member) ( (size_t) & ((type*)0) -> member )
+#endif
+#if !defined(WIN32) && !defined(MS_WINDOWS)
+  #ifndef __stdcall
+    #define __stdcall
+  #endif
+  #ifndef __cdecl
+    #define __cdecl
+  #endif
+  #ifndef __fastcall
+    #define __fastcall
+  #endif
+#endif
+#ifndef DL_IMPORT
+  #define DL_IMPORT(t) t
+#endif
+#ifndef DL_EXPORT
+  #define DL_EXPORT(t) t
+#endif
+#ifndef PY_LONG_LONG
+  #define PY_LONG_LONG LONG_LONG
+#endif
+#ifndef Py_HUGE_VAL
+  #define Py_HUGE_VAL HUGE_VAL
+#endif
+#ifdef PYPY_VERSION
+#define CYTHON_COMPILING_IN_PYPY 1
+#define CYTHON_COMPILING_IN_CPYTHON 0
+#else
+#define CYTHON_COMPILING_IN_PYPY 0
+#define CYTHON_COMPILING_IN_CPYTHON 1
+#endif
+#if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX < 0x02070600 && !defined(Py_OptimizeFlag)
+#define Py_OptimizeFlag 0
+#endif
+#define __PYX_BUILD_PY_SSIZE_T "n"
+#define CYTHON_FORMAT_SSIZE_T "z"
+#if PY_MAJOR_VERSION < 3
+  #define __Pyx_BUILTIN_MODULE_NAME "__builtin__"
+  #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \
+          PyCode_New(a+k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
+  #define __Pyx_DefaultClassType PyClass_Type
+#else
+  #define __Pyx_BUILTIN_MODULE_NAME "builtins"
+  #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \
+          PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
+  #define __Pyx_DefaultClassType PyType_Type
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define Py_TPFLAGS_CHECKTYPES 0
+  #define Py_TPFLAGS_HAVE_INDEX 0
+  #define Py_TPFLAGS_HAVE_NEWBUFFER 0
+#endif
+#if PY_VERSION_HEX < 0x030400a1 && !defined(Py_TPFLAGS_HAVE_FINALIZE)
+  #define Py_TPFLAGS_HAVE_FINALIZE 0
+#endif
+#if PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND)
+  #define CYTHON_PEP393_ENABLED 1
+  #define __Pyx_PyUnicode_READY(op)       (likely(PyUnicode_IS_READY(op)) ? \
+                                              0 : _PyUnicode_Ready((PyObject *)(op)))
+  #define __Pyx_PyUnicode_GET_LENGTH(u)   PyUnicode_GET_LENGTH(u)
+  #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_READ_CHAR(u, i)
+  #define __Pyx_PyUnicode_KIND(u)         PyUnicode_KIND(u)
+  #define __Pyx_PyUnicode_DATA(u)         PyUnicode_DATA(u)
+  #define __Pyx_PyUnicode_READ(k, d, i)   PyUnicode_READ(k, d, i)
+#else
+  #define CYTHON_PEP393_ENABLED 0
+  #define __Pyx_PyUnicode_READY(op)       (0)
+  #define __Pyx_PyUnicode_GET_LENGTH(u)   PyUnicode_GET_SIZE(u)
+  #define __Pyx_PyUnicode_READ_CHAR(u, i) ((Py_UCS4)(PyUnicode_AS_UNICODE(u)[i]))
+  #define __Pyx_PyUnicode_KIND(u)         (sizeof(Py_UNICODE))
+  #define __Pyx_PyUnicode_DATA(u)         ((void*)PyUnicode_AS_UNICODE(u))
+  #define __Pyx_PyUnicode_READ(k, d, i)   ((void)(k), (Py_UCS4)(((Py_UNICODE*)d)[i]))
+#endif
+#if CYTHON_COMPILING_IN_PYPY
+  #define __Pyx_PyUnicode_Concat(a, b)      PyNumber_Add(a, b)
+  #define __Pyx_PyUnicode_ConcatSafe(a, b)  PyNumber_Add(a, b)
+  #define __Pyx_PyFrozenSet_Size(s)         PyObject_Size(s)
+#else
+  #define __Pyx_PyUnicode_Concat(a, b)      PyUnicode_Concat(a, b)
+  #define __Pyx_PyUnicode_ConcatSafe(a, b)  ((unlikely((a) == Py_None) || unlikely((b) == Py_None)) ? \
+      PyNumber_Add(a, b) : __Pyx_PyUnicode_Concat(a, b))
+  #define __Pyx_PyFrozenSet_Size(s)         PySet_Size(s)
+#endif
+#define __Pyx_PyString_FormatSafe(a, b)   ((unlikely((a) == Py_None)) ? PyNumber_Remainder(a, b) : __Pyx_PyString_Format(a, b))
+#define __Pyx_PyUnicode_FormatSafe(a, b)  ((unlikely((a) == Py_None)) ? PyNumber_Remainder(a, b) : PyUnicode_Format(a, b))
+#if PY_MAJOR_VERSION >= 3
+  #define __Pyx_PyString_Format(a, b)  PyUnicode_Format(a, b)
+#else
+  #define __Pyx_PyString_Format(a, b)  PyString_Format(a, b)
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define PyBaseString_Type            PyUnicode_Type
+  #define PyStringObject               PyUnicodeObject
+  #define PyString_Type                PyUnicode_Type
+  #define PyString_Check               PyUnicode_Check
+  #define PyString_CheckExact          PyUnicode_CheckExact
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define __Pyx_PyBaseString_Check(obj) PyUnicode_Check(obj)
+  #define __Pyx_PyBaseString_CheckExact(obj) PyUnicode_CheckExact(obj)
+#else
+  #define __Pyx_PyBaseString_Check(obj) (PyString_Check(obj) || PyUnicode_Check(obj))
+  #define __Pyx_PyBaseString_CheckExact(obj) (PyString_CheckExact(obj) || PyUnicode_CheckExact(obj))
+#endif
+#ifndef PySet_CheckExact
+  #define PySet_CheckExact(obj)        (Py_TYPE(obj) == &PySet_Type)
+#endif
+#define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type)
+#if PY_MAJOR_VERSION >= 3
+  #define PyIntObject                  PyLongObject
+  #define PyInt_Type                   PyLong_Type
+  #define PyInt_Check(op)              PyLong_Check(op)
+  #define PyInt_CheckExact(op)         PyLong_CheckExact(op)
+  #define PyInt_FromString             PyLong_FromString
+  #define PyInt_FromUnicode            PyLong_FromUnicode
+  #define PyInt_FromLong               PyLong_FromLong
+  #define PyInt_FromSize_t             PyLong_FromSize_t
+  #define PyInt_FromSsize_t            PyLong_FromSsize_t
+  #define PyInt_AsLong                 PyLong_AsLong
+  #define PyInt_AS_LONG                PyLong_AS_LONG
+  #define PyInt_AsSsize_t              PyLong_AsSsize_t
+  #define PyInt_AsUnsignedLongMask     PyLong_AsUnsignedLongMask
+  #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask
+  #define PyNumber_Int                 PyNumber_Long
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define PyBoolObject                 PyLongObject
+#endif
+#if PY_MAJOR_VERSION >= 3 && CYTHON_COMPILING_IN_PYPY
+  #ifndef PyUnicode_InternFromString
+    #define PyUnicode_InternFromString(s) PyUnicode_FromString(s)
+  #endif
+#endif
+#if PY_VERSION_HEX < 0x030200A4
+  typedef long Py_hash_t;
+  #define __Pyx_PyInt_FromHash_t PyInt_FromLong
+  #define __Pyx_PyInt_AsHash_t   PyInt_AsLong
+#else
+  #define __Pyx_PyInt_FromHash_t PyInt_FromSsize_t
+  #define __Pyx_PyInt_AsHash_t   PyInt_AsSsize_t
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define __Pyx_PyMethod_New(func, self, klass) ((self) ? PyMethod_New(func, self) : PyInstanceMethod_New(func))
+#else
+  #define __Pyx_PyMethod_New(func, self, klass) PyMethod_New(func, self, klass)
+#endif
+#ifndef CYTHON_INLINE
+  #if defined(__GNUC__)
+    #define CYTHON_INLINE __inline__
+  #elif defined(_MSC_VER)
+    #define CYTHON_INLINE __inline
+  #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+    #define CYTHON_INLINE inline
+  #else
+    #define CYTHON_INLINE
+  #endif
+#endif
+#ifndef CYTHON_RESTRICT
+  #if defined(__GNUC__)
+    #define CYTHON_RESTRICT __restrict__
+  #elif defined(_MSC_VER) && _MSC_VER >= 1400
+    #define CYTHON_RESTRICT __restrict
+  #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+    #define CYTHON_RESTRICT restrict
+  #else
+    #define CYTHON_RESTRICT
+  #endif
+#endif
+#ifdef NAN
+#define __PYX_NAN() ((float) NAN)
+#else
+static CYTHON_INLINE float __PYX_NAN() {
+  /* Initialize NaN. The sign is irrelevant, an exponent with all bits 1 and
+   a nonzero mantissa means NaN. If the first bit in the mantissa is 1, it is
+   a quiet NaN. */
+  float value;
+  memset(&value, 0xFF, sizeof(value));
+  return value;
+}
+#endif
+#define __Pyx_void_to_None(void_result) (void_result, Py_INCREF(Py_None), Py_None)
+#ifdef __cplusplus
+template<typename T>
+void __Pyx_call_destructor(T* x) {
+    x->~T();
+}
+template<typename T>
+class __Pyx_FakeReference {
+  public:
+    __Pyx_FakeReference() : ptr(NULL) { }
+    __Pyx_FakeReference(T& ref) : ptr(&ref) { }
+    T *operator->() { return ptr; }
+    operator T&() { return *ptr; }
+  private:
+    T *ptr;
+};
+#endif
+
+
+#if PY_MAJOR_VERSION >= 3
+  #define __Pyx_PyNumber_Divide(x,y)         PyNumber_TrueDivide(x,y)
+  #define __Pyx_PyNumber_InPlaceDivide(x,y)  PyNumber_InPlaceTrueDivide(x,y)
+#else
+  #define __Pyx_PyNumber_Divide(x,y)         PyNumber_Divide(x,y)
+  #define __Pyx_PyNumber_InPlaceDivide(x,y)  PyNumber_InPlaceDivide(x,y)
+#endif
+
+#ifndef __PYX_EXTERN_C
+  #ifdef __cplusplus
+    #define __PYX_EXTERN_C extern "C"
+  #else
+    #define __PYX_EXTERN_C extern
+  #endif
+#endif
+
+#if defined(WIN32) || defined(MS_WINDOWS)
+#define _USE_MATH_DEFINES
+#endif
+#include <math.h>
+#define __PYX_HAVE__bx__bbi__bigwig_file
+#define __PYX_HAVE_API__bx__bbi__bigwig_file
+#include "string.h"
+#include "stdio.h"
+#include "stdlib.h"
+#include "numpy/arrayobject.h"
+#include "numpy/ufuncobject.h"
+#ifdef _OPENMP
+#include <omp.h>
+#endif /* _OPENMP */
+
+#ifdef PYREX_WITHOUT_ASSERTIONS
+#define CYTHON_WITHOUT_ASSERTIONS
+#endif
+
+#ifndef CYTHON_UNUSED
+# if defined(__GNUC__)
+#   if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
+#     define CYTHON_UNUSED __attribute__ ((__unused__))
+#   else
+#     define CYTHON_UNUSED
+#   endif
+# elif defined(__ICC) || (defined(__INTEL_COMPILER) && !defined(_MSC_VER))
+#   define CYTHON_UNUSED __attribute__ ((__unused__))
+# else
+#   define CYTHON_UNUSED
+# endif
+#endif
+typedef struct {PyObject **p; char *s; const Py_ssize_t n; const char* encoding;
+                const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry;
+
+#define __PYX_DEFAULT_STRING_ENCODING_IS_ASCII 0
+#define __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT 0
+#define __PYX_DEFAULT_STRING_ENCODING ""
+#define __Pyx_PyObject_FromString __Pyx_PyBytes_FromString
+#define __Pyx_PyObject_FromStringAndSize __Pyx_PyBytes_FromStringAndSize
+#define __Pyx_fits_Py_ssize_t(v, type, is_signed)  (    \
+    (sizeof(type) < sizeof(Py_ssize_t))  ||             \
+    (sizeof(type) > sizeof(Py_ssize_t) &&               \
+          likely(v < (type)PY_SSIZE_T_MAX ||            \
+                 v == (type)PY_SSIZE_T_MAX)  &&         \
+          (!is_signed || likely(v > (type)PY_SSIZE_T_MIN ||       \
+                                v == (type)PY_SSIZE_T_MIN)))  ||  \
+    (sizeof(type) == sizeof(Py_ssize_t) &&              \
+          (is_signed || likely(v < (type)PY_SSIZE_T_MAX ||        \
+                               v == (type)PY_SSIZE_T_MAX)))  )
+static CYTHON_INLINE char* __Pyx_PyObject_AsString(PyObject*);
+static CYTHON_INLINE char* __Pyx_PyObject_AsStringAndSize(PyObject*, Py_ssize_t* length);
+#define __Pyx_PyByteArray_FromString(s) PyByteArray_FromStringAndSize((const char*)s, strlen((const char*)s))
+#define __Pyx_PyByteArray_FromStringAndSize(s, l) PyByteArray_FromStringAndSize((const char*)s, l)
+#define __Pyx_PyBytes_FromString        PyBytes_FromString
+#define __Pyx_PyBytes_FromStringAndSize PyBytes_FromStringAndSize
+static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char*);
+#if PY_MAJOR_VERSION < 3
+    #define __Pyx_PyStr_FromString        __Pyx_PyBytes_FromString
+    #define __Pyx_PyStr_FromStringAndSize __Pyx_PyBytes_FromStringAndSize
+#else
+    #define __Pyx_PyStr_FromString        __Pyx_PyUnicode_FromString
+    #define __Pyx_PyStr_FromStringAndSize __Pyx_PyUnicode_FromStringAndSize
+#endif
+#define __Pyx_PyObject_AsSString(s)    ((signed char*) __Pyx_PyObject_AsString(s))
+#define __Pyx_PyObject_AsUString(s)    ((unsigned char*) __Pyx_PyObject_AsString(s))
+#define __Pyx_PyObject_FromCString(s)  __Pyx_PyObject_FromString((const char*)s)
+#define __Pyx_PyBytes_FromCString(s)   __Pyx_PyBytes_FromString((const char*)s)
+#define __Pyx_PyByteArray_FromCString(s)   __Pyx_PyByteArray_FromString((const char*)s)
+#define __Pyx_PyStr_FromCString(s)     __Pyx_PyStr_FromString((const char*)s)
+#define __Pyx_PyUnicode_FromCString(s) __Pyx_PyUnicode_FromString((const char*)s)
+#if PY_MAJOR_VERSION < 3
+static CYTHON_INLINE size_t __Pyx_Py_UNICODE_strlen(const Py_UNICODE *u)
+{
+    const Py_UNICODE *u_end = u;
+    while (*u_end++) ;
+    return (size_t)(u_end - u - 1);
+}
+#else
+#define __Pyx_Py_UNICODE_strlen Py_UNICODE_strlen
+#endif
+#define __Pyx_PyUnicode_FromUnicode(u)       PyUnicode_FromUnicode(u, __Pyx_Py_UNICODE_strlen(u))
+#define __Pyx_PyUnicode_FromUnicodeAndLength PyUnicode_FromUnicode
+#define __Pyx_PyUnicode_AsUnicode            PyUnicode_AsUnicode
+#define __Pyx_Owned_Py_None(b) (Py_INCREF(Py_None), Py_None)
+#define __Pyx_PyBool_FromLong(b) ((b) ? (Py_INCREF(Py_True), Py_True) : (Py_INCREF(Py_False), Py_False))
+static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*);
+static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x);
+static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*);
+static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t);
+#if CYTHON_COMPILING_IN_CPYTHON
+#define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x))
+#else
+#define __pyx_PyFloat_AsDouble(x) PyFloat_AsDouble(x)
+#endif
+#define __pyx_PyFloat_AsFloat(x) ((float) __pyx_PyFloat_AsDouble(x))
+#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII
+static int __Pyx_sys_getdefaultencoding_not_ascii;
+static int __Pyx_init_sys_getdefaultencoding_params(void) {
+    PyObject* sys;
+    PyObject* default_encoding = NULL;
+    PyObject* ascii_chars_u = NULL;
+    PyObject* ascii_chars_b = NULL;
+    const char* default_encoding_c;
+    sys = PyImport_ImportModule("sys");
+    if (!sys) goto bad;
+    default_encoding = PyObject_CallMethod(sys, (char*) "getdefaultencoding", NULL);
+    Py_DECREF(sys);
+    if (!default_encoding) goto bad;
+    default_encoding_c = PyBytes_AsString(default_encoding);
+    if (!default_encoding_c) goto bad;
+    if (strcmp(default_encoding_c, "ascii") == 0) {
+        __Pyx_sys_getdefaultencoding_not_ascii = 0;
+    } else {
+        char ascii_chars[128];
+        int c;
+        for (c = 0; c < 128; c++) {
+            ascii_chars[c] = c;
+        }
+        __Pyx_sys_getdefaultencoding_not_ascii = 1;
+        ascii_chars_u = PyUnicode_DecodeASCII(ascii_chars, 128, NULL);
+        if (!ascii_chars_u) goto bad;
+        ascii_chars_b = PyUnicode_AsEncodedString(ascii_chars_u, default_encoding_c, NULL);
+        if (!ascii_chars_b || !PyBytes_Check(ascii_chars_b) || memcmp(ascii_chars, PyBytes_AS_STRING(ascii_chars_b), 128) != 0) {
+            PyErr_Format(
+                PyExc_ValueError,
+                "This module compiled with c_string_encoding=ascii, but default encoding '%.200s' is not a superset of ascii.",
+                default_encoding_c);
+            goto bad;
+        }
+        Py_DECREF(ascii_chars_u);
+        Py_DECREF(ascii_chars_b);
+    }
+    Py_DECREF(default_encoding);
+    return 0;
+bad:
+    Py_XDECREF(default_encoding);
+    Py_XDECREF(ascii_chars_u);
+    Py_XDECREF(ascii_chars_b);
+    return -1;
+}
+#endif
+#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT && PY_MAJOR_VERSION >= 3
+#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_DecodeUTF8(c_str, size, NULL)
+#else
+#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_Decode(c_str, size, __PYX_DEFAULT_STRING_ENCODING, NULL)
+#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT
+static char* __PYX_DEFAULT_STRING_ENCODING;
+static int __Pyx_init_sys_getdefaultencoding_params(void) {
+    PyObject* sys;
+    PyObject* default_encoding = NULL;
+    char* default_encoding_c;
+    sys = PyImport_ImportModule("sys");
+    if (!sys) goto bad;
+    default_encoding = PyObject_CallMethod(sys, (char*) (const char*) "getdefaultencoding", NULL);
+    Py_DECREF(sys);
+    if (!default_encoding) goto bad;
+    default_encoding_c = PyBytes_AsString(default_encoding);
+    if (!default_encoding_c) goto bad;
+    __PYX_DEFAULT_STRING_ENCODING = (char*) malloc(strlen(default_encoding_c));
+    if (!__PYX_DEFAULT_STRING_ENCODING) goto bad;
+    strcpy(__PYX_DEFAULT_STRING_ENCODING, default_encoding_c);
+    Py_DECREF(default_encoding);
+    return 0;
+bad:
+    Py_XDECREF(default_encoding);
+    return -1;
+}
+#endif
+#endif
+
+
+/* Test for GCC > 2.95 */
+#if defined(__GNUC__)     && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95)))
+  #define likely(x)   __builtin_expect(!!(x), 1)
+  #define unlikely(x) __builtin_expect(!!(x), 0)
+#else /* !__GNUC__ or GCC < 2.95 */
+  #define likely(x)   (x)
+  #define unlikely(x) (x)
+#endif /* __GNUC__ */
+
+static PyObject *__pyx_m;
+static PyObject *__pyx_d;
+static PyObject *__pyx_b;
+static PyObject *__pyx_empty_tuple;
+static PyObject *__pyx_empty_bytes;
+static int __pyx_lineno;
+static int __pyx_clineno = 0;
+static const char * __pyx_cfilenm= __FILE__;
+static const char *__pyx_filename;
+
+#if !defined(CYTHON_CCOMPLEX)
+  #if defined(__cplusplus)
+    #define CYTHON_CCOMPLEX 1
+  #elif defined(_Complex_I)
+    #define CYTHON_CCOMPLEX 1
+  #else
+    #define CYTHON_CCOMPLEX 0
+  #endif
+#endif
+#if CYTHON_CCOMPLEX
+  #ifdef __cplusplus
+    #include <complex>
+  #else
+    #include <complex.h>
+  #endif
+#endif
+#if CYTHON_CCOMPLEX && !defined(__cplusplus) && defined(__sun__) && defined(__GNUC__)
+  #undef _Complex_I
+  #define _Complex_I 1.0fj
+#endif
+
+
+static const char *__pyx_f[] = {
+  "bx/bbi/bigwig_file.pyx",
+  "__init__.pxd",
+  "bx/bbi/bpt_file.pxd",
+  "bx/bbi/cirtree_file.pxd",
+  "type.pxd",
+  "bx/bbi/bbi_file.pxd",
+};
+
+/* "types.pxd":1
+ * ctypedef unsigned char UBYTE             # <<<<<<<<<<<<<<
+ * ctypedef signed char BYTE
+ * ctypedef unsigned short UWORD
+ */
+typedef unsigned char __pyx_t_2bx_3bbi_5types_UBYTE;
+
+/* "types.pxd":2
+ * ctypedef unsigned char UBYTE
+ * ctypedef signed char BYTE             # <<<<<<<<<<<<<<
+ * ctypedef unsigned short UWORD
+ * ctypedef short WORD
+ */
+typedef signed char __pyx_t_2bx_3bbi_5types_BYTE;
+
+/* "types.pxd":3
+ * ctypedef unsigned char UBYTE
+ * ctypedef signed char BYTE
+ * ctypedef unsigned short UWORD             # <<<<<<<<<<<<<<
+ * ctypedef short WORD
+ * ctypedef unsigned long long bits64
+ */
+typedef unsigned short __pyx_t_2bx_3bbi_5types_UWORD;
+
+/* "types.pxd":4
+ * ctypedef signed char BYTE
+ * ctypedef unsigned short UWORD
+ * ctypedef short WORD             # <<<<<<<<<<<<<<
+ * ctypedef unsigned long long bits64
+ * ctypedef unsigned bits32
+ */
+typedef short __pyx_t_2bx_3bbi_5types_WORD;
+
+/* "types.pxd":5
+ * ctypedef unsigned short UWORD
+ * ctypedef short WORD
+ * ctypedef unsigned long long bits64             # <<<<<<<<<<<<<<
+ * ctypedef unsigned bits32
+ * ctypedef unsigned short bits16
+ */
+typedef unsigned PY_LONG_LONG __pyx_t_2bx_3bbi_5types_bits64;
+
+/* "types.pxd":6
+ * ctypedef short WORD
+ * ctypedef unsigned long long bits64
+ * ctypedef unsigned bits32             # <<<<<<<<<<<<<<
+ * ctypedef unsigned short bits16
+ * ctypedef unsigned char bits8
+ */
+typedef unsigned int __pyx_t_2bx_3bbi_5types_bits32;
+
+/* "types.pxd":7
+ * ctypedef unsigned long long bits64
+ * ctypedef unsigned bits32
+ * ctypedef unsigned short bits16             # <<<<<<<<<<<<<<
+ * ctypedef unsigned char bits8
+ * ctypedef int signed32
+ */
+typedef unsigned short __pyx_t_2bx_3bbi_5types_bits16;
+
+/* "types.pxd":8
+ * ctypedef unsigned bits32
+ * ctypedef unsigned short bits16
+ * ctypedef unsigned char bits8             # <<<<<<<<<<<<<<
+ * ctypedef int signed32
+ * 
+ */
+typedef unsigned char __pyx_t_2bx_3bbi_5types_bits8;
+
+/* "types.pxd":9
+ * ctypedef unsigned short bits16
+ * ctypedef unsigned char bits8
+ * ctypedef int signed32             # <<<<<<<<<<<<<<
+ * 
+ * ctypedef bint boolean
+ */
+typedef int __pyx_t_2bx_3bbi_5types_signed32;
+
+/* "types.pxd":11
+ * ctypedef int signed32
+ * 
+ * ctypedef bint boolean             # <<<<<<<<<<<<<<
+ * 
+ */
+typedef int __pyx_t_2bx_3bbi_5types_boolean;
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":726
+ * # in Cython to enable them only on the right systems.
+ * 
+ * ctypedef npy_int8       int8_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_int16      int16_t
+ * ctypedef npy_int32      int32_t
+ */
+typedef npy_int8 __pyx_t_5numpy_int8_t;
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":727
+ * 
+ * ctypedef npy_int8       int8_t
+ * ctypedef npy_int16      int16_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_int32      int32_t
+ * ctypedef npy_int64      int64_t
+ */
+typedef npy_int16 __pyx_t_5numpy_int16_t;
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":728
+ * ctypedef npy_int8       int8_t
+ * ctypedef npy_int16      int16_t
+ * ctypedef npy_int32      int32_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_int64      int64_t
+ * #ctypedef npy_int96      int96_t
+ */
+typedef npy_int32 __pyx_t_5numpy_int32_t;
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":729
+ * ctypedef npy_int16      int16_t
+ * ctypedef npy_int32      int32_t
+ * ctypedef npy_int64      int64_t             # <<<<<<<<<<<<<<
+ * #ctypedef npy_int96      int96_t
+ * #ctypedef npy_int128     int128_t
+ */
+typedef npy_int64 __pyx_t_5numpy_int64_t;
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":733
+ * #ctypedef npy_int128     int128_t
+ * 
+ * ctypedef npy_uint8      uint8_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_uint16     uint16_t
+ * ctypedef npy_uint32     uint32_t
+ */
+typedef npy_uint8 __pyx_t_5numpy_uint8_t;
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":734
+ * 
+ * ctypedef npy_uint8      uint8_t
+ * ctypedef npy_uint16     uint16_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_uint32     uint32_t
+ * ctypedef npy_uint64     uint64_t
+ */
+typedef npy_uint16 __pyx_t_5numpy_uint16_t;
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":735
+ * ctypedef npy_uint8      uint8_t
+ * ctypedef npy_uint16     uint16_t
+ * ctypedef npy_uint32     uint32_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_uint64     uint64_t
+ * #ctypedef npy_uint96     uint96_t
+ */
+typedef npy_uint32 __pyx_t_5numpy_uint32_t;
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":736
+ * ctypedef npy_uint16     uint16_t
+ * ctypedef npy_uint32     uint32_t
+ * ctypedef npy_uint64     uint64_t             # <<<<<<<<<<<<<<
+ * #ctypedef npy_uint96     uint96_t
+ * #ctypedef npy_uint128    uint128_t
+ */
+typedef npy_uint64 __pyx_t_5numpy_uint64_t;
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":740
+ * #ctypedef npy_uint128    uint128_t
+ * 
+ * ctypedef npy_float32    float32_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_float64    float64_t
+ * #ctypedef npy_float80    float80_t
+ */
+typedef npy_float32 __pyx_t_5numpy_float32_t;
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":741
+ * 
+ * ctypedef npy_float32    float32_t
+ * ctypedef npy_float64    float64_t             # <<<<<<<<<<<<<<
+ * #ctypedef npy_float80    float80_t
+ * #ctypedef npy_float128   float128_t
+ */
+typedef npy_float64 __pyx_t_5numpy_float64_t;
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":750
+ * # The int types are mapped a bit surprising --
+ * # numpy.int corresponds to 'l' and numpy.long to 'q'
+ * ctypedef npy_long       int_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_longlong   long_t
+ * ctypedef npy_longlong   longlong_t
+ */
+typedef npy_long __pyx_t_5numpy_int_t;
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":751
+ * # numpy.int corresponds to 'l' and numpy.long to 'q'
+ * ctypedef npy_long       int_t
+ * ctypedef npy_longlong   long_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_longlong   longlong_t
+ * 
+ */
+typedef npy_longlong __pyx_t_5numpy_long_t;
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":752
+ * ctypedef npy_long       int_t
+ * ctypedef npy_longlong   long_t
+ * ctypedef npy_longlong   longlong_t             # <<<<<<<<<<<<<<
+ * 
+ * ctypedef npy_ulong      uint_t
+ */
+typedef npy_longlong __pyx_t_5numpy_longlong_t;
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":754
+ * ctypedef npy_longlong   longlong_t
+ * 
+ * ctypedef npy_ulong      uint_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_ulonglong  ulong_t
+ * ctypedef npy_ulonglong  ulonglong_t
+ */
+typedef npy_ulong __pyx_t_5numpy_uint_t;
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":755
+ * 
+ * ctypedef npy_ulong      uint_t
+ * ctypedef npy_ulonglong  ulong_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_ulonglong  ulonglong_t
+ * 
+ */
+typedef npy_ulonglong __pyx_t_5numpy_ulong_t;
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":756
+ * ctypedef npy_ulong      uint_t
+ * ctypedef npy_ulonglong  ulong_t
+ * ctypedef npy_ulonglong  ulonglong_t             # <<<<<<<<<<<<<<
+ * 
+ * ctypedef npy_intp       intp_t
+ */
+typedef npy_ulonglong __pyx_t_5numpy_ulonglong_t;
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":758
+ * ctypedef npy_ulonglong  ulonglong_t
+ * 
+ * ctypedef npy_intp       intp_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_uintp      uintp_t
+ * 
+ */
+typedef npy_intp __pyx_t_5numpy_intp_t;
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":759
+ * 
+ * ctypedef npy_intp       intp_t
+ * ctypedef npy_uintp      uintp_t             # <<<<<<<<<<<<<<
+ * 
+ * ctypedef npy_double     float_t
+ */
+typedef npy_uintp __pyx_t_5numpy_uintp_t;
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":761
+ * ctypedef npy_uintp      uintp_t
+ * 
+ * ctypedef npy_double     float_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_double     double_t
+ * ctypedef npy_longdouble longdouble_t
+ */
+typedef npy_double __pyx_t_5numpy_float_t;
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":762
+ * 
+ * ctypedef npy_double     float_t
+ * ctypedef npy_double     double_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_longdouble longdouble_t
+ * 
+ */
+typedef npy_double __pyx_t_5numpy_double_t;
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":763
+ * ctypedef npy_double     float_t
+ * ctypedef npy_double     double_t
+ * ctypedef npy_longdouble longdouble_t             # <<<<<<<<<<<<<<
+ * 
+ * ctypedef npy_cfloat      cfloat_t
+ */
+typedef npy_longdouble __pyx_t_5numpy_longdouble_t;
+#if CYTHON_CCOMPLEX
+  #ifdef __cplusplus
+    typedef ::std::complex< float > __pyx_t_float_complex;
+  #else
+    typedef float _Complex __pyx_t_float_complex;
+  #endif
+#else
+    typedef struct { float real, imag; } __pyx_t_float_complex;
+#endif
+
+#if CYTHON_CCOMPLEX
+  #ifdef __cplusplus
+    typedef ::std::complex< double > __pyx_t_double_complex;
+  #else
+    typedef double _Complex __pyx_t_double_complex;
+  #endif
+#else
+    typedef struct { double real, imag; } __pyx_t_double_complex;
+#endif
+
+
+/*--- Type declarations ---*/
+struct __pyx_obj_2bx_3bbi_8bpt_file_BPTFile;
+struct __pyx_obj_2bx_3bbi_12cirtree_file_CIRTreeFile;
+struct __pyx_obj_2bx_3bbi_8bbi_file_SummaryBlock;
+struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData;
+struct __pyx_obj_2bx_3bbi_8bbi_file_BlockHandler;
+struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile;
+struct __pyx_obj_2bx_3bbi_11bigwig_file_BigWigBlockHandler;
+struct __pyx_obj_2bx_3bbi_11bigwig_file_SummarizingBlockHandler;
+struct __pyx_obj_2bx_3bbi_11bigwig_file_IntervalAccumulatingBlockHandler;
+struct __pyx_obj_2bx_3bbi_11bigwig_file_ArrayAccumulatingBlockHandler;
+struct __pyx_obj_2bx_3bbi_11bigwig_file_BigWigFile;
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":765
+ * ctypedef npy_longdouble longdouble_t
+ * 
+ * ctypedef npy_cfloat      cfloat_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_cdouble     cdouble_t
+ * ctypedef npy_clongdouble clongdouble_t
+ */
+typedef npy_cfloat __pyx_t_5numpy_cfloat_t;
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":766
+ * 
+ * ctypedef npy_cfloat      cfloat_t
+ * ctypedef npy_cdouble     cdouble_t             # <<<<<<<<<<<<<<
+ * ctypedef npy_clongdouble clongdouble_t
+ * 
+ */
+typedef npy_cdouble __pyx_t_5numpy_cdouble_t;
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":767
+ * ctypedef npy_cfloat      cfloat_t
+ * ctypedef npy_cdouble     cdouble_t
+ * ctypedef npy_clongdouble clongdouble_t             # <<<<<<<<<<<<<<
+ * 
+ * ctypedef npy_cdouble     complex_t
+ */
+typedef npy_clongdouble __pyx_t_5numpy_clongdouble_t;
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":769
+ * ctypedef npy_clongdouble clongdouble_t
+ * 
+ * ctypedef npy_cdouble     complex_t             # <<<<<<<<<<<<<<
+ * 
+ * cdef inline object PyArray_MultiIterNew1(a):
+ */
+typedef npy_cdouble __pyx_t_5numpy_complex_t;
+
+/* "bpt_file.pxd":5
+ * from types cimport *
+ * 
+ * cdef class BPTFile:             # <<<<<<<<<<<<<<
+ *     """
+ *     On disk B+ tree compatible with Jim Kent's bPlusTree.c
+ */
+struct __pyx_obj_2bx_3bbi_8bpt_file_BPTFile {
+  PyObject_HEAD
+  PyObject *file;
+  PyObject *reader;
+  __pyx_t_2bx_3bbi_5types_boolean is_byteswapped;
+  __pyx_t_2bx_3bbi_5types_bits32 block_size;
+  __pyx_t_2bx_3bbi_5types_bits32 key_size;
+  __pyx_t_2bx_3bbi_5types_bits32 value_size;
+  __pyx_t_2bx_3bbi_5types_bits64 item_count;
+  __pyx_t_2bx_3bbi_5types_bits64 root_offset;
+};
+
+
+/* "cirtree_file.pxd":3
+ * from types cimport *
+ * 
+ * cdef class CIRTreeFile:             # <<<<<<<<<<<<<<
+ *     cdef object file
+ *     cdef object reader
+ */
+struct __pyx_obj_2bx_3bbi_12cirtree_file_CIRTreeFile {
+  PyObject_HEAD
+  PyObject *file;
+  PyObject *reader;
+  __pyx_t_2bx_3bbi_5types_boolean is_byteswapped;
+  __pyx_t_2bx_3bbi_5types_bits64 root_offset;
+  __pyx_t_2bx_3bbi_5types_bits32 block_size;
+  __pyx_t_2bx_3bbi_5types_bits64 item_count;
+  __pyx_t_2bx_3bbi_5types_bits32 start_chrom_ix;
+  __pyx_t_2bx_3bbi_5types_bits32 start_base;
+  __pyx_t_2bx_3bbi_5types_bits32 end_chrom_ix;
+  __pyx_t_2bx_3bbi_5types_bits32 end_base;
+  __pyx_t_2bx_3bbi_5types_bits64 file_size;
+  __pyx_t_2bx_3bbi_5types_bits32 items_per_slot;
+};
+
+
+/* "bbi_file.pxd":8
+ * cimport numpy
+ * 
+ * cdef class SummaryBlock:             # <<<<<<<<<<<<<<
+ *     """
+ *     A block of summary data from disk
+ */
+struct __pyx_obj_2bx_3bbi_8bbi_file_SummaryBlock {
+  PyObject_HEAD
+  __pyx_t_2bx_3bbi_5types_bits32 chrom_id;
+  __pyx_t_2bx_3bbi_5types_bits32 start;
+  __pyx_t_2bx_3bbi_5types_bits32 end;
+  __pyx_t_2bx_3bbi_5types_bits32 valid_count;
+  double min_val;
+  double max_val;
+  double sum_data;
+  double sum_squares;
+};
+
+
+/* "bbi_file.pxd":21
+ *     cdef public double sum_squares
+ * 
+ * cdef class SummarizedData:             # <<<<<<<<<<<<<<
+ *     """
+ *     The result of using SummaryBlocks read from the file to produce a
+ */
+struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData {
+  PyObject_HEAD
+  struct __pyx_vtabstruct_2bx_3bbi_8bbi_file_SummarizedData *__pyx_vtab;
+  __pyx_t_2bx_3bbi_5types_bits32 start;
+  __pyx_t_2bx_3bbi_5types_bits32 end;
+  int size;
+  PyArrayObject *valid_count;
+  PyArrayObject *min_val;
+  PyArrayObject *max_val;
+  PyArrayObject *sum_data;
+  PyArrayObject *sum_squares;
+};
+
+
+/* "bbi_file.pxd":39
+ * cdef class BBIFile
+ * 
+ * cdef class BlockHandler:             # <<<<<<<<<<<<<<
+ *     """
+ *     Callback for `BBIFile.visit_blocks_in_region`
+ */
+struct __pyx_obj_2bx_3bbi_8bbi_file_BlockHandler {
+  PyObject_HEAD
+  struct __pyx_vtabstruct_2bx_3bbi_8bbi_file_BlockHandler *__pyx_vtab;
+};
+
+
+/* "bbi_file.pxd":37
+ *     cdef accumulate_interval_value( self, bits32 s, bits32 e, float val )
+ * 
+ * cdef class BBIFile             # <<<<<<<<<<<<<<
+ * 
+ * cdef class BlockHandler:
+ */
+struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile {
+  PyObject_HEAD
+  struct __pyx_vtabstruct_2bx_3bbi_8bbi_file_BBIFile *__pyx_vtab;
+  PyObject *file;
+  PyObject *reader;
+  __pyx_t_2bx_3bbi_5types_bits32 magic;
+  __pyx_t_2bx_3bbi_5types_boolean is_byteswapped;
+  struct __pyx_obj_2bx_3bbi_8bpt_file_BPTFile *chrom_bpt;
+  __pyx_t_2bx_3bbi_5types_bits16 version;
+  __pyx_t_2bx_3bbi_5types_bits16 zoom_levels;
+  __pyx_t_2bx_3bbi_5types_bits64 chrom_tree_offset;
+  __pyx_t_2bx_3bbi_5types_bits64 unzoomed_data_offset;
+  __pyx_t_2bx_3bbi_5types_bits64 unzoomed_index_offset;
+  __pyx_t_2bx_3bbi_5types_bits16 field_count;
+  __pyx_t_2bx_3bbi_5types_bits16 defined_field_count;
+  __pyx_t_2bx_3bbi_5types_bits64 as_offset;
+  __pyx_t_2bx_3bbi_5types_bits64 total_summary_offset;
+  __pyx_t_2bx_3bbi_5types_bits32 uncompress_buf_size;
+  PyObject *level_list;
+};
+
+
+/* "bx/bbi/bigwig_file.pyx":28
+ *     return [l[i:i + n] for i in range(0, len(l), n)]
+ * 
+ * cdef class BigWigBlockHandler( BlockHandler ):             # <<<<<<<<<<<<<<
+ *     """
+ *     BlockHandler that parses the block into a series of wiggle records, and calls `handle_interval_value` for each.
+ */
+struct __pyx_obj_2bx_3bbi_11bigwig_file_BigWigBlockHandler {
+  struct __pyx_obj_2bx_3bbi_8bbi_file_BlockHandler __pyx_base;
+  __pyx_t_2bx_3bbi_5types_bits32 start;
+  __pyx_t_2bx_3bbi_5types_bits32 end;
+};
+
+
+/* "bx/bbi/bigwig_file.pyx":74
+ *         pass
+ * 
+ * cdef class SummarizingBlockHandler( BigWigBlockHandler ):             # <<<<<<<<<<<<<<
+ *     """
+ *     Accumulates intervals into a SummarizedData
+ */
+struct __pyx_obj_2bx_3bbi_11bigwig_file_SummarizingBlockHandler {
+  struct __pyx_obj_2bx_3bbi_11bigwig_file_BigWigBlockHandler __pyx_base;
+  struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData *sd;
+};
+
+
+/* "bx/bbi/bigwig_file.pyx":89
+ *         self.sd.accumulate_interval_value( s, e, val )
+ * 
+ * cdef class IntervalAccumulatingBlockHandler( BigWigBlockHandler ):             # <<<<<<<<<<<<<<
+ *     cdef list intervals
+ *     """
+ */
+struct __pyx_obj_2bx_3bbi_11bigwig_file_IntervalAccumulatingBlockHandler {
+  struct __pyx_obj_2bx_3bbi_11bigwig_file_BigWigBlockHandler __pyx_base;
+  PyObject *intervals;
+};
+
+
+/* "bx/bbi/bigwig_file.pyx":101
+ *         self.intervals.append( ( s, e, val ) )
+ * 
+ * cdef class ArrayAccumulatingBlockHandler( BigWigBlockHandler ):             # <<<<<<<<<<<<<<
+ *     """
+ *     Accumulates intervals into a list of intervals with values
+ */
+struct __pyx_obj_2bx_3bbi_11bigwig_file_ArrayAccumulatingBlockHandler {
+  struct __pyx_obj_2bx_3bbi_11bigwig_file_BigWigBlockHandler __pyx_base;
+  PyArrayObject *array;
+};
+
+
+/* "bx/bbi/bigwig_file.pyx":116
+ *         self.array[s - self.start:e - self.start] = val
+ * 
+ * cdef class BigWigFile( BBIFile ):             # <<<<<<<<<<<<<<
+ *     """
+ *     A "big binary indexed" file whose raw data is in wiggle format.
+ */
+struct __pyx_obj_2bx_3bbi_11bigwig_file_BigWigFile {
+  struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile __pyx_base;
+};
+
+
+
+/* "bbi_file.pxd":21
+ *     cdef public double sum_squares
+ * 
+ * cdef class SummarizedData:             # <<<<<<<<<<<<<<
+ *     """
+ *     The result of using SummaryBlocks read from the file to produce a
+ */
+
+struct __pyx_vtabstruct_2bx_3bbi_8bbi_file_SummarizedData {
+  PyObject *(*accumulate_interval_value)(struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData *, __pyx_t_2bx_3bbi_5types_bits32, __pyx_t_2bx_3bbi_5types_bits32, float);
+};
+static struct __pyx_vtabstruct_2bx_3bbi_8bbi_file_SummarizedData *__pyx_vtabptr_2bx_3bbi_8bbi_file_SummarizedData;
+
+
+/* "bbi_file.pxd":37
+ *     cdef accumulate_interval_value( self, bits32 s, bits32 e, float val )
+ * 
+ * cdef class BBIFile             # <<<<<<<<<<<<<<
+ * 
+ * cdef class BlockHandler:
+ */
+
+struct __pyx_vtabstruct_2bx_3bbi_8bbi_file_BBIFile {
+  PyObject *(*visit_blocks_in_region)(struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *, __pyx_t_2bx_3bbi_5types_bits32, __pyx_t_2bx_3bbi_5types_bits32, __pyx_t_2bx_3bbi_5types_bits32, struct __pyx_obj_2bx_3bbi_8bbi_file_BlockHandler *);
+  PyObject *(*_get_chrom_id_and_size)(struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *, char *);
+  PyObject *(*_best_zoom_level)(struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *, int);
+  PyObject *(*summarize)(struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *, char *, __pyx_t_2bx_3bbi_5types_bits32, __pyx_t_2bx_3bbi_5types_bits32, int, int __pyx_skip_dispatch);
+  PyObject *(*summarize_from_full)(struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *, char *, __pyx_t_2bx_3bbi_5types_bits32, __pyx_t_2bx_3bbi_5types_bits32, int, int __pyx_skip_dispatch);
+  PyObject *(*query)(struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *, char *, __pyx_t_2bx_3bbi_5types_bits32, __pyx_t_2bx_3bbi_5types_bits32, int, int __pyx_skip_dispatch);
+  PyObject *(*_summarize_from_full)(struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *, __pyx_t_2bx_3bbi_5types_bits32, __pyx_t_2bx_3bbi_5types_bits32, __pyx_t_2bx_3bbi_5types_bits32, int);
+};
+static struct __pyx_vtabstruct_2bx_3bbi_8bbi_file_BBIFile *__pyx_vtabptr_2bx_3bbi_8bbi_file_BBIFile;
+
+
+/* "bbi_file.pxd":39
+ * cdef class BBIFile
+ * 
+ * cdef class BlockHandler:             # <<<<<<<<<<<<<<
+ *     """
+ *     Callback for `BBIFile.visit_blocks_in_region`
+ */
+
+struct __pyx_vtabstruct_2bx_3bbi_8bbi_file_BlockHandler {
+  PyObject *(*handle_block)(struct __pyx_obj_2bx_3bbi_8bbi_file_BlockHandler *, PyObject *, struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *);
+};
+static struct __pyx_vtabstruct_2bx_3bbi_8bbi_file_BlockHandler *__pyx_vtabptr_2bx_3bbi_8bbi_file_BlockHandler;
+
+
+/* "bx/bbi/bigwig_file.pyx":28
+ *     return [l[i:i + n] for i in range(0, len(l), n)]
+ * 
+ * cdef class BigWigBlockHandler( BlockHandler ):             # <<<<<<<<<<<<<<
+ *     """
+ *     BlockHandler that parses the block into a series of wiggle records, and calls `handle_interval_value` for each.
+ */
+
+struct __pyx_vtabstruct_2bx_3bbi_11bigwig_file_BigWigBlockHandler {
+  struct __pyx_vtabstruct_2bx_3bbi_8bbi_file_BlockHandler __pyx_base;
+  PyObject *(*handle_interval_value)(struct __pyx_obj_2bx_3bbi_11bigwig_file_BigWigBlockHandler *, __pyx_t_2bx_3bbi_5types_bits32, __pyx_t_2bx_3bbi_5types_bits32, float);
+};
+static struct __pyx_vtabstruct_2bx_3bbi_11bigwig_file_BigWigBlockHandler *__pyx_vtabptr_2bx_3bbi_11bigwig_file_BigWigBlockHandler;
+
+
+/* "bx/bbi/bigwig_file.pyx":74
+ *         pass
+ * 
+ * cdef class SummarizingBlockHandler( BigWigBlockHandler ):             # <<<<<<<<<<<<<<
+ *     """
+ *     Accumulates intervals into a SummarizedData
+ */
+
+struct __pyx_vtabstruct_2bx_3bbi_11bigwig_file_SummarizingBlockHandler {
+  struct __pyx_vtabstruct_2bx_3bbi_11bigwig_file_BigWigBlockHandler __pyx_base;
+};
+static struct __pyx_vtabstruct_2bx_3bbi_11bigwig_file_SummarizingBlockHandler *__pyx_vtabptr_2bx_3bbi_11bigwig_file_SummarizingBlockHandler;
+
+
+/* "bx/bbi/bigwig_file.pyx":89
+ *         self.sd.accumulate_interval_value( s, e, val )
+ * 
+ * cdef class IntervalAccumulatingBlockHandler( BigWigBlockHandler ):             # <<<<<<<<<<<<<<
+ *     cdef list intervals
+ *     """
+ */
+
+struct __pyx_vtabstruct_2bx_3bbi_11bigwig_file_IntervalAccumulatingBlockHandler {
+  struct __pyx_vtabstruct_2bx_3bbi_11bigwig_file_BigWigBlockHandler __pyx_base;
+};
+static struct __pyx_vtabstruct_2bx_3bbi_11bigwig_file_IntervalAccumulatingBlockHandler *__pyx_vtabptr_2bx_3bbi_11bigwig_file_IntervalAccumulatingBlockHandler;
+
+
+/* "bx/bbi/bigwig_file.pyx":101
+ *         self.intervals.append( ( s, e, val ) )
+ * 
+ * cdef class ArrayAccumulatingBlockHandler( BigWigBlockHandler ):             # <<<<<<<<<<<<<<
+ *     """
+ *     Accumulates intervals into a list of intervals with values
+ */
+
+struct __pyx_vtabstruct_2bx_3bbi_11bigwig_file_ArrayAccumulatingBlockHandler {
+  struct __pyx_vtabstruct_2bx_3bbi_11bigwig_file_BigWigBlockHandler __pyx_base;
+};
+static struct __pyx_vtabstruct_2bx_3bbi_11bigwig_file_ArrayAccumulatingBlockHandler *__pyx_vtabptr_2bx_3bbi_11bigwig_file_ArrayAccumulatingBlockHandler;
+
+
+/* "bx/bbi/bigwig_file.pyx":116
+ *         self.array[s - self.start:e - self.start] = val
+ * 
+ * cdef class BigWigFile( BBIFile ):             # <<<<<<<<<<<<<<
+ *     """
+ *     A "big binary indexed" file whose raw data is in wiggle format.
+ */
+
+struct __pyx_vtabstruct_2bx_3bbi_11bigwig_file_BigWigFile {
+  struct __pyx_vtabstruct_2bx_3bbi_8bbi_file_BBIFile __pyx_base;
+  PyObject *(*get)(struct __pyx_obj_2bx_3bbi_11bigwig_file_BigWigFile *, char *, __pyx_t_2bx_3bbi_5types_bits32, __pyx_t_2bx_3bbi_5types_bits32, int __pyx_skip_dispatch);
+  PyObject *(*get_as_array)(struct __pyx_obj_2bx_3bbi_11bigwig_file_BigWigFile *, char *, __pyx_t_2bx_3bbi_5types_bits32, __pyx_t_2bx_3bbi_5types_bits32, int __pyx_skip_dispatch);
+};
+static struct __pyx_vtabstruct_2bx_3bbi_11bigwig_file_BigWigFile *__pyx_vtabptr_2bx_3bbi_11bigwig_file_BigWigFile;
+
+/* --- Runtime support code (head) --- */
+#ifndef CYTHON_REFNANNY
+  #define CYTHON_REFNANNY 0
+#endif
+#if CYTHON_REFNANNY
+  typedef struct {
+    void (*INCREF)(void*, PyObject*, int);
+    void (*DECREF)(void*, PyObject*, int);
+    void (*GOTREF)(void*, PyObject*, int);
+    void (*GIVEREF)(void*, PyObject*, int);
+    void* (*SetupContext)(const char*, int, const char*);
+    void (*FinishContext)(void**);
+  } __Pyx_RefNannyAPIStruct;
+  static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL;
+  static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname);
+  #define __Pyx_RefNannyDeclarations void *__pyx_refnanny = NULL;
+#ifdef WITH_THREAD
+  #define __Pyx_RefNannySetupContext(name, acquire_gil) \
+          if (acquire_gil) { \
+              PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure(); \
+              __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__); \
+              PyGILState_Release(__pyx_gilstate_save); \
+          } else { \
+              __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__); \
+          }
+#else
+  #define __Pyx_RefNannySetupContext(name, acquire_gil) \
+          __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__)
+#endif
+  #define __Pyx_RefNannyFinishContext() \
+          __Pyx_RefNanny->FinishContext(&__pyx_refnanny)
+  #define __Pyx_INCREF(r)  __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_DECREF(r)  __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_GOTREF(r)  __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_XINCREF(r)  do { if((r) != NULL) {__Pyx_INCREF(r); }} while(0)
+  #define __Pyx_XDECREF(r)  do { if((r) != NULL) {__Pyx_DECREF(r); }} while(0)
+  #define __Pyx_XGOTREF(r)  do { if((r) != NULL) {__Pyx_GOTREF(r); }} while(0)
+  #define __Pyx_XGIVEREF(r) do { if((r) != NULL) {__Pyx_GIVEREF(r);}} while(0)
+#else
+  #define __Pyx_RefNannyDeclarations
+  #define __Pyx_RefNannySetupContext(name, acquire_gil)
+  #define __Pyx_RefNannyFinishContext()
+  #define __Pyx_INCREF(r) Py_INCREF(r)
+  #define __Pyx_DECREF(r) Py_DECREF(r)
+  #define __Pyx_GOTREF(r)
+  #define __Pyx_GIVEREF(r)
+  #define __Pyx_XINCREF(r) Py_XINCREF(r)
+  #define __Pyx_XDECREF(r) Py_XDECREF(r)
+  #define __Pyx_XGOTREF(r)
+  #define __Pyx_XGIVEREF(r)
+#endif
+#define __Pyx_XDECREF_SET(r, v) do {                            \
+        PyObject *tmp = (PyObject *) r;                         \
+        r = v; __Pyx_XDECREF(tmp);                              \
+    } while (0)
+#define __Pyx_DECREF_SET(r, v) do {                             \
+        PyObject *tmp = (PyObject *) r;                         \
+        r = v; __Pyx_DECREF(tmp);                               \
+    } while (0)
+#define __Pyx_CLEAR(r)    do { PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);} while(0)
+#define __Pyx_XCLEAR(r)   do { if((r) != NULL) {PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);}} while(0)
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name) {
+    PyTypeObject* tp = Py_TYPE(obj);
+    if (likely(tp->tp_getattro))
+        return tp->tp_getattro(obj, attr_name);
+#if PY_MAJOR_VERSION < 3
+    if (likely(tp->tp_getattr))
+        return tp->tp_getattr(obj, PyString_AS_STRING(attr_name));
+#endif
+    return PyObject_GetAttr(obj, attr_name);
+}
+#else
+#define __Pyx_PyObject_GetAttrStr(o,n) PyObject_GetAttr(o,n)
+#endif
+
+static PyObject *__Pyx_GetBuiltinName(PyObject *name);
+
+static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
+    Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found);
+
+static void __Pyx_RaiseDoubleKeywordsError(const char* func_name, PyObject* kw_name);
+
+static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
+    PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
+    const char* function_name);
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw);
+#else
+#define __Pyx_PyObject_Call(func, arg, kw) PyObject_Call(func, arg, kw)
+#endif
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE int __Pyx_ListComp_Append(PyObject* list, PyObject* x) {
+    PyListObject* L = (PyListObject*) list;
+    Py_ssize_t len = Py_SIZE(list);
+    if (likely(L->allocated > len)) {
+        Py_INCREF(x);
+        PyList_SET_ITEM(list, len, x);
+        Py_SIZE(list) = len+1;
+        return 0;
+    }
+    return PyList_Append(list, x);
+}
+#else
+#define __Pyx_ListComp_Append(L,x) PyList_Append(L,x)
+#endif
+
+static CYTHON_INLINE PyObject* __Pyx_PyObject_GetSlice(
+        PyObject* obj, Py_ssize_t cstart, Py_ssize_t cstop,
+        PyObject** py_start, PyObject** py_stop, PyObject** py_slice,
+        int has_cstart, int has_cstop, int wraparound);
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg);
+#endif
+
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg);
+
+static CYTHON_INLINE PyObject *__Pyx_GetModuleGlobalName(PyObject *name);
+
+static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected);
+
+static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index);
+
+static CYTHON_INLINE int __Pyx_IterFinish(void);
+
+static int __Pyx_IternextUnpackEndCheck(PyObject *retval, Py_ssize_t expected);
+
+static CYTHON_INLINE void __Pyx_RaiseUnboundLocalError(const char *varname);
+
+#define __Pyx_PyObject_DelSlice(obj, cstart, cstop, py_start, py_stop, py_slice, has_cstart, has_cstop, wraparound) \
+    __Pyx_PyObject_SetSlice(obj, (PyObject*)NULL, cstart, cstop, py_start, py_stop, py_slice, has_cstart, has_cstop, wraparound)
+static CYTHON_INLINE int __Pyx_PyObject_SetSlice(
+        PyObject* obj, PyObject* value, Py_ssize_t cstart, Py_ssize_t cstop,
+        PyObject** py_start, PyObject** py_stop, PyObject** py_slice,
+        int has_cstart, int has_cstop, int wraparound);
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE int __Pyx_PyList_Append(PyObject* list, PyObject* x) {
+    PyListObject* L = (PyListObject*) list;
+    Py_ssize_t len = Py_SIZE(list);
+    if (likely(L->allocated > len) & likely(len > (L->allocated >> 1))) {
+        Py_INCREF(x);
+        PyList_SET_ITEM(list, len, x);
+        Py_SIZE(list) = len+1;
+        return 0;
+    }
+    return PyList_Append(list, x);
+}
+#else
+#define __Pyx_PyList_Append(L,x) PyList_Append(L,x)
+#endif
+
+static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type);
+
+#define __Pyx_GetItemInt(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck) \
+    (__Pyx_fits_Py_ssize_t(i, type, is_signed) ? \
+    __Pyx_GetItemInt_Fast(o, (Py_ssize_t)i, is_list, wraparound, boundscheck) : \
+    (is_list ? (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL) : \
+               __Pyx_GetItemInt_Generic(o, to_py_func(i))))
+#define __Pyx_GetItemInt_List(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck) \
+    (__Pyx_fits_Py_ssize_t(i, type, is_signed) ? \
+    __Pyx_GetItemInt_List_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) : \
+    (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL))
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i,
+                                                              int wraparound, int boundscheck);
+#define __Pyx_GetItemInt_Tuple(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck) \
+    (__Pyx_fits_Py_ssize_t(i, type, is_signed) ? \
+    __Pyx_GetItemInt_Tuple_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) : \
+    (PyErr_SetString(PyExc_IndexError, "tuple index out of range"), (PyObject*)NULL))
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i,
+                                                              int wraparound, int boundscheck);
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j);
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i,
+                                                     int is_list, int wraparound, int boundscheck);
+
+#define __Pyx_SetItemInt(o, i, v, type, is_signed, to_py_func, is_list, wraparound, boundscheck) \
+    (__Pyx_fits_Py_ssize_t(i, type, is_signed) ? \
+    __Pyx_SetItemInt_Fast(o, (Py_ssize_t)i, v, is_list, wraparound, boundscheck) : \
+    (is_list ? (PyErr_SetString(PyExc_IndexError, "list assignment index out of range"), -1) : \
+               __Pyx_SetItemInt_Generic(o, to_py_func(i), v)))
+static CYTHON_INLINE int __Pyx_SetItemInt_Generic(PyObject *o, PyObject *j, PyObject *v);
+static CYTHON_INLINE int __Pyx_SetItemInt_Fast(PyObject *o, Py_ssize_t i, PyObject *v,
+                                               int is_list, int wraparound, int boundscheck);
+
+static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb);
+static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb);
+
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause);
+
+#if PY_MAJOR_VERSION >= 3
+static PyObject *__Pyx_PyDict_GetItem(PyObject *d, PyObject* key) {
+    PyObject *value;
+    value = PyDict_GetItemWithError(d, key);
+    if (unlikely(!value)) {
+        if (!PyErr_Occurred()) {
+            PyObject* args = PyTuple_Pack(1, key);
+            if (likely(args))
+                PyErr_SetObject(PyExc_KeyError, args);
+            Py_XDECREF(args);
+        }
+        return NULL;
+    }
+    Py_INCREF(value);
+    return value;
+}
+#else
+    #define __Pyx_PyDict_GetItem(d, key) PyObject_GetItem(d, key)
+#endif
+
+static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void);
+
+static void __Pyx_call_next_tp_dealloc(PyObject* obj, destructor current_tp_dealloc);
+
+static int __Pyx_call_next_tp_traverse(PyObject* obj, visitproc v, void *a, traverseproc current_tp_traverse);
+
+static void __Pyx_call_next_tp_clear(PyObject* obj, inquiry current_tp_dealloc);
+
+static void* __Pyx_GetVtable(PyObject *dict);
+
+static int __Pyx_SetVtable(PyObject *dict, void *vtable);
+
+static PyObject* __Pyx_ImportFrom(PyObject* module, PyObject* name);
+
+typedef struct {
+    int code_line;
+    PyCodeObject* code_object;
+} __Pyx_CodeObjectCacheEntry;
+struct __Pyx_CodeObjectCache {
+    int count;
+    int max_count;
+    __Pyx_CodeObjectCacheEntry* entries;
+};
+static struct __Pyx_CodeObjectCache __pyx_code_cache = {0,0,NULL};
+static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line);
+static PyCodeObject *__pyx_find_code_object(int code_line);
+static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object);
+
+static void __Pyx_AddTraceback(const char *funcname, int c_line,
+                               int py_line, const char *filename);
+
+static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level);
+
+static CYTHON_INLINE unsigned int __Pyx_PyInt_As_unsigned_int(PyObject *);
+
+static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *);
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value);
+
+static CYTHON_INLINE unsigned char __Pyx_PyInt_As_unsigned_char(PyObject *);
+
+static CYTHON_INLINE unsigned short __Pyx_PyInt_As_unsigned_short(PyObject *);
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_unsigned_short(unsigned short value);
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value);
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_unsigned_int(unsigned int value);
+
+#if CYTHON_CCOMPLEX
+  #ifdef __cplusplus
+    #define __Pyx_CREAL(z) ((z).real())
+    #define __Pyx_CIMAG(z) ((z).imag())
+  #else
+    #define __Pyx_CREAL(z) (__real__(z))
+    #define __Pyx_CIMAG(z) (__imag__(z))
+  #endif
+#else
+    #define __Pyx_CREAL(z) ((z).real)
+    #define __Pyx_CIMAG(z) ((z).imag)
+#endif
+#if (defined(_WIN32) || defined(__clang__)) && defined(__cplusplus) && CYTHON_CCOMPLEX
+    #define __Pyx_SET_CREAL(z,x) ((z).real(x))
+    #define __Pyx_SET_CIMAG(z,y) ((z).imag(y))
+#else
+    #define __Pyx_SET_CREAL(z,x) __Pyx_CREAL(z) = (x)
+    #define __Pyx_SET_CIMAG(z,y) __Pyx_CIMAG(z) = (y)
+#endif
+
+static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float, float);
+
+#if CYTHON_CCOMPLEX
+    #define __Pyx_c_eqf(a, b)   ((a)==(b))
+    #define __Pyx_c_sumf(a, b)  ((a)+(b))
+    #define __Pyx_c_difff(a, b) ((a)-(b))
+    #define __Pyx_c_prodf(a, b) ((a)*(b))
+    #define __Pyx_c_quotf(a, b) ((a)/(b))
+    #define __Pyx_c_negf(a)     (-(a))
+  #ifdef __cplusplus
+    #define __Pyx_c_is_zerof(z) ((z)==(float)0)
+    #define __Pyx_c_conjf(z)    (::std::conj(z))
+    #if 1
+        #define __Pyx_c_absf(z)     (::std::abs(z))
+        #define __Pyx_c_powf(a, b)  (::std::pow(a, b))
+    #endif
+  #else
+    #define __Pyx_c_is_zerof(z) ((z)==0)
+    #define __Pyx_c_conjf(z)    (conjf(z))
+    #if 1
+        #define __Pyx_c_absf(z)     (cabsf(z))
+        #define __Pyx_c_powf(a, b)  (cpowf(a, b))
+    #endif
+ #endif
+#else
+    static CYTHON_INLINE int __Pyx_c_eqf(__pyx_t_float_complex, __pyx_t_float_complex);
+    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_sumf(__pyx_t_float_complex, __pyx_t_float_complex);
+    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_difff(__pyx_t_float_complex, __pyx_t_float_complex);
+    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_prodf(__pyx_t_float_complex, __pyx_t_float_complex);
+    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_quotf(__pyx_t_float_complex, __pyx_t_float_complex);
+    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_negf(__pyx_t_float_complex);
+    static CYTHON_INLINE int __Pyx_c_is_zerof(__pyx_t_float_complex);
+    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_conjf(__pyx_t_float_complex);
+    #if 1
+        static CYTHON_INLINE float __Pyx_c_absf(__pyx_t_float_complex);
+        static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_powf(__pyx_t_float_complex, __pyx_t_float_complex);
+    #endif
+#endif
+
+static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double, double);
+
+#if CYTHON_CCOMPLEX
+    #define __Pyx_c_eq(a, b)   ((a)==(b))
+    #define __Pyx_c_sum(a, b)  ((a)+(b))
+    #define __Pyx_c_diff(a, b) ((a)-(b))
+    #define __Pyx_c_prod(a, b) ((a)*(b))
+    #define __Pyx_c_quot(a, b) ((a)/(b))
+    #define __Pyx_c_neg(a)     (-(a))
+  #ifdef __cplusplus
+    #define __Pyx_c_is_zero(z) ((z)==(double)0)
+    #define __Pyx_c_conj(z)    (::std::conj(z))
+    #if 1
+        #define __Pyx_c_abs(z)     (::std::abs(z))
+        #define __Pyx_c_pow(a, b)  (::std::pow(a, b))
+    #endif
+  #else
+    #define __Pyx_c_is_zero(z) ((z)==0)
+    #define __Pyx_c_conj(z)    (conj(z))
+    #if 1
+        #define __Pyx_c_abs(z)     (cabs(z))
+        #define __Pyx_c_pow(a, b)  (cpow(a, b))
+    #endif
+ #endif
+#else
+    static CYTHON_INLINE int __Pyx_c_eq(__pyx_t_double_complex, __pyx_t_double_complex);
+    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_sum(__pyx_t_double_complex, __pyx_t_double_complex);
+    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_diff(__pyx_t_double_complex, __pyx_t_double_complex);
+    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_prod(__pyx_t_double_complex, __pyx_t_double_complex);
+    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_quot(__pyx_t_double_complex, __pyx_t_double_complex);
+    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_neg(__pyx_t_double_complex);
+    static CYTHON_INLINE int __Pyx_c_is_zero(__pyx_t_double_complex);
+    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_conj(__pyx_t_double_complex);
+    #if 1
+        static CYTHON_INLINE double __Pyx_c_abs(__pyx_t_double_complex);
+        static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_pow(__pyx_t_double_complex, __pyx_t_double_complex);
+    #endif
+#endif
+
+static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *);
+
+static int __Pyx_check_binary_version(void);
+
+#if !defined(__Pyx_PyIdentifier_FromString)
+#if PY_MAJOR_VERSION < 3
+  #define __Pyx_PyIdentifier_FromString(s) PyString_FromString(s)
+#else
+  #define __Pyx_PyIdentifier_FromString(s) PyUnicode_FromString(s)
+#endif
+#endif
+
+static PyObject *__Pyx_ImportModule(const char *name);
+
+static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name, size_t size, int strict);
+
+static int __Pyx_InitStrings(__Pyx_StringTabEntry *t);
+
+static PyObject *__pyx_f_2bx_3bbi_11bigwig_file_18BigWigBlockHandler_handle_block(struct __pyx_obj_2bx_3bbi_11bigwig_file_BigWigBlockHandler *__pyx_v_self, PyObject *__pyx_v_block_data, struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *__pyx_v_bbi_file); /* proto*/
+static PyObject *__pyx_f_2bx_3bbi_11bigwig_file_18BigWigBlockHandler_handle_interval_value(CYTHON_UNUSED struct __pyx_obj_2bx_3bbi_11bigwig_file_BigWigBlockHandler *__pyx_v_self, CYTHON_UNUSED __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_s, CYTHON_UNUSED __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_e, CYTHON_UNUSED float __pyx_v_val); /* proto*/
+static PyObject *__pyx_f_2bx_3bbi_11bigwig_file_23SummarizingBlockHandler_handle_interval_value(struct __pyx_obj_2bx_3bbi_11bigwig_file_SummarizingBlockHandler *__pyx_v_self, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_s, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_e, float __pyx_v_val); /* proto*/
+static PyObject *__pyx_f_2bx_3bbi_11bigwig_file_32IntervalAccumulatingBlockHandler_handle_interval_value(struct __pyx_obj_2bx_3bbi_11bigwig_file_IntervalAccumulatingBlockHandler *__pyx_v_self, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_s, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_e, float __pyx_v_val); /* proto*/
+static PyObject *__pyx_f_2bx_3bbi_11bigwig_file_29ArrayAccumulatingBlockHandler_handle_interval_value(struct __pyx_obj_2bx_3bbi_11bigwig_file_ArrayAccumulatingBlockHandler *__pyx_v_self, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_s, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_e, float __pyx_v_val); /* proto*/
+static PyObject *__pyx_f_2bx_3bbi_11bigwig_file_10BigWigFile__summarize_from_full(struct __pyx_obj_2bx_3bbi_11bigwig_file_BigWigFile *__pyx_v_self, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_chrom_id, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_start, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_end, int __pyx_v_summary_size); /* proto*/
+static PyObject *__pyx_f_2bx_3bbi_11bigwig_file_10BigWigFile_get(struct __pyx_obj_2bx_3bbi_11bigwig_file_BigWigFile *__pyx_v_self, char *__pyx_v_chrom, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_start, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_end, int __pyx_skip_dispatch); /* proto*/
+static PyObject *__pyx_f_2bx_3bbi_11bigwig_file_10BigWigFile_get_as_array(struct __pyx_obj_2bx_3bbi_11bigwig_file_BigWigFile *__pyx_v_self, char *__pyx_v_chrom, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_start, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_end, int __pyx_skip_dispatch); /* proto*/
+
+/* Module declarations from 'bx.bbi.types' */
+
+/* Module declarations from 'bx.bbi.bpt_file' */
+static PyTypeObject *__pyx_ptype_2bx_3bbi_8bpt_file_BPTFile = 0;
+
+/* Module declarations from 'bx.bbi.cirtree_file' */
+static PyTypeObject *__pyx_ptype_2bx_3bbi_12cirtree_file_CIRTreeFile = 0;
+
+/* Module declarations from 'cpython.buffer' */
+
+/* Module declarations from 'cpython.ref' */
+
+/* Module declarations from 'libc.string' */
+
+/* Module declarations from 'libc.stdio' */
+
+/* Module declarations from 'cpython.object' */
+
+/* Module declarations from '__builtin__' */
+
+/* Module declarations from 'cpython.type' */
+static PyTypeObject *__pyx_ptype_7cpython_4type_type = 0;
+
+/* Module declarations from 'libc.stdlib' */
+
+/* Module declarations from 'numpy' */
+
+/* Module declarations from 'numpy' */
+static PyTypeObject *__pyx_ptype_5numpy_dtype = 0;
+static PyTypeObject *__pyx_ptype_5numpy_flatiter = 0;
+static PyTypeObject *__pyx_ptype_5numpy_broadcast = 0;
+static PyTypeObject *__pyx_ptype_5numpy_ndarray = 0;
+static PyTypeObject *__pyx_ptype_5numpy_ufunc = 0;
+static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *, char *, char *, int *); /*proto*/
+
+/* Module declarations from 'bx.bbi.bbi_file' */
+static PyTypeObject *__pyx_ptype_2bx_3bbi_8bbi_file_SummaryBlock = 0;
+static PyTypeObject *__pyx_ptype_2bx_3bbi_8bbi_file_SummarizedData = 0;
+static PyTypeObject *__pyx_ptype_2bx_3bbi_8bbi_file_BBIFile = 0;
+static PyTypeObject *__pyx_ptype_2bx_3bbi_8bbi_file_BlockHandler = 0;
+
+/* Module declarations from 'bx.bbi.bigwig_file' */
+static PyTypeObject *__pyx_ptype_2bx_3bbi_11bigwig_file_BigWigBlockHandler = 0;
+static PyTypeObject *__pyx_ptype_2bx_3bbi_11bigwig_file_SummarizingBlockHandler = 0;
+static PyTypeObject *__pyx_ptype_2bx_3bbi_11bigwig_file_IntervalAccumulatingBlockHandler = 0;
+static PyTypeObject *__pyx_ptype_2bx_3bbi_11bigwig_file_ArrayAccumulatingBlockHandler = 0;
+static PyTypeObject *__pyx_ptype_2bx_3bbi_11bigwig_file_BigWigFile = 0;
+#define __Pyx_MODULE_NAME "bx.bbi.bigwig_file"
+int __pyx_module_is_main_bx__bbi__bigwig_file = 0;
+
+/* Implementation of 'bx.bbi.bigwig_file' */
+static PyObject *__pyx_builtin_range;
+static PyObject *__pyx_builtin_enumerate;
+static PyObject *__pyx_builtin_round;
+static PyObject *__pyx_builtin_ValueError;
+static PyObject *__pyx_builtin_RuntimeError;
+static PyObject *__pyx_pf_2bx_3bbi_11bigwig_file_chunks(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_l, PyObject *__pyx_v_n); /* proto */
+static int __pyx_pf_2bx_3bbi_11bigwig_file_18BigWigBlockHandler___init__(struct __pyx_obj_2bx_3bbi_11bigwig_file_BigWigBlockHandler *__pyx_v_self, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_start, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_end); /* proto */
+static int __pyx_pf_2bx_3bbi_11bigwig_file_23SummarizingBlockHandler___init__(struct __pyx_obj_2bx_3bbi_11bigwig_file_SummarizingBlockHandler *__pyx_v_self, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_start, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_end, int __pyx_v_summary_size); /* proto */
+static int __pyx_pf_2bx_3bbi_11bigwig_file_32IntervalAccumulatingBlockHandler___init__(struct __pyx_obj_2bx_3bbi_11bigwig_file_IntervalAccumulatingBlockHandler *__pyx_v_self, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_start, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_end); /* proto */
+static int __pyx_pf_2bx_3bbi_11bigwig_file_29ArrayAccumulatingBlockHandler___init__(struct __pyx_obj_2bx_3bbi_11bigwig_file_ArrayAccumulatingBlockHandler *__pyx_v_self, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_start, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_end); /* proto */
+static int __pyx_pf_2bx_3bbi_11bigwig_file_10BigWigFile___init__(struct __pyx_obj_2bx_3bbi_11bigwig_file_BigWigFile *__pyx_v_self, PyObject *__pyx_v_file); /* proto */
+static PyObject *__pyx_pf_2bx_3bbi_11bigwig_file_10BigWigFile_2get(struct __pyx_obj_2bx_3bbi_11bigwig_file_BigWigFile *__pyx_v_self, char *__pyx_v_chrom, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_start, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_end); /* proto */
+static PyObject *__pyx_pf_2bx_3bbi_11bigwig_file_10BigWigFile_4get_as_array(struct __pyx_obj_2bx_3bbi_11bigwig_file_BigWigFile *__pyx_v_self, char *__pyx_v_chrom, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_start, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_end); /* proto */
+static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /* proto */
+static void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info); /* proto */
+static PyObject *__pyx_tp_new_2bx_3bbi_11bigwig_file_BigWigBlockHandler(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
+static PyObject *__pyx_tp_new_2bx_3bbi_11bigwig_file_SummarizingBlockHandler(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
+static PyObject *__pyx_tp_new_2bx_3bbi_11bigwig_file_IntervalAccumulatingBlockHandler(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
+static PyObject *__pyx_tp_new_2bx_3bbi_11bigwig_file_ArrayAccumulatingBlockHandler(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
+static PyObject *__pyx_tp_new_2bx_3bbi_11bigwig_file_BigWigFile(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
+static char __pyx_k_B[] = "B";
+static char __pyx_k_H[] = "H";
+static char __pyx_k_I[] = "I";
+static char __pyx_k_L[] = "L";
+static char __pyx_k_O[] = "O";
+static char __pyx_k_Q[] = "Q";
+static char __pyx_k_b[] = "b";
+static char __pyx_k_d[] = "d";
+static char __pyx_k_f[] = "f";
+static char __pyx_k_g[] = "g";
+static char __pyx_k_h[] = "h";
+static char __pyx_k_i[] = "i";
+static char __pyx_k_l[] = "l";
+static char __pyx_k_n[] = "n";
+static char __pyx_k_q[] = "q";
+static char __pyx_k_Lf[] = "Lf";
+static char __pyx_k_Zd[] = "Zd";
+static char __pyx_k_Zf[] = "Zf";
+static char __pyx_k_Zg[] = "Zg";
+static char __pyx_k_LLf[] = "LLf";
+static char __pyx_k_end[] = "end";
+static char __pyx_k_get[] = "get";
+static char __pyx_k_inf[] = "inf";
+static char __pyx_k_nan[] = "nan";
+static char __pyx_k_file[] = "file";
+static char __pyx_k_init[] = "__init__";
+static char __pyx_k_main[] = "__main__";
+static char __pyx_k_test[] = "__test__";
+static char __pyx_k_zlib[] = "zlib";
+static char __pyx_k_chrom[] = "chrom";
+static char __pyx_k_deque[] = "deque";
+static char __pyx_k_dtype[] = "dtype";
+static char __pyx_k_numpy[] = "numpy";
+static char __pyx_k_range[] = "range";
+static char __pyx_k_round[] = "round";
+static char __pyx_k_start[] = "start";
+static char __pyx_k_zeros[] = "zeros";
+static char __pyx_k_bigwig[] = "bigwig";
+static char __pyx_k_chunks[] = "chunks";
+static char __pyx_k_import[] = "__import__";
+static char __pyx_k_float32[] = "float32";
+static char __pyx_k_LLLLLBBH[] = "LLLLLBBH";
+static char __pyx_k_StringIO[] = "StringIO";
+static char __pyx_k_cStringIO[] = "cStringIO";
+static char __pyx_k_enumerate[] = "enumerate";
+static char __pyx_k_ValueError[] = "ValueError";
+static char __pyx_k_pyx_vtable[] = "__pyx_vtable__";
+static char __pyx_k_BigWig_file[] = "\nBigWig file.\n";
+static char __pyx_k_collections[] = "collections";
+static char __pyx_k_RuntimeError[] = "RuntimeError";
+static char __pyx_k_get_as_array[] = "get_as_array";
+static char __pyx_k_summary_size[] = "summary_size";
+static char __pyx_k_read_and_unpack[] = "read_and_unpack";
+static char __pyx_k_BinaryFileReader[] = "BinaryFileReader";
+static char __pyx_k_is_little_endian[] = "is_little_endian";
+static char __pyx_k_bx_bbi_bigwig_file[] = "bx.bbi.bigwig_file";
+static char __pyx_k_bx_misc_binary_file[] = "bx.misc.binary_file";
+static char __pyx_k_ndarray_is_not_C_contiguous[] = "ndarray is not C contiguous";
+static char __pyx_k_unknown_dtype_code_in_numpy_pxd[] = "unknown dtype code in numpy.pxd (%d)";
+static char __pyx_k_usr_local_src_bx_python_mod_lib[] = "/usr/local/src/bx-python-mod/lib/bx/bbi/bigwig_file.pyx";
+static char __pyx_k_Format_string_allocated_too_shor[] = "Format string allocated too short, see comment in numpy.pxd";
+static char __pyx_k_Non_native_byte_order_not_suppor[] = "Non-native byte order not supported";
+static char __pyx_k_ndarray_is_not_Fortran_contiguou[] = "ndarray is not Fortran contiguous";
+static char __pyx_k_Format_string_allocated_too_shor_2[] = "Format string allocated too short.";
+static PyObject *__pyx_n_s_BinaryFileReader;
+static PyObject *__pyx_kp_u_Format_string_allocated_too_shor;
+static PyObject *__pyx_kp_u_Format_string_allocated_too_shor_2;
+static PyObject *__pyx_n_s_LLLLLBBH;
+static PyObject *__pyx_n_s_LLf;
+static PyObject *__pyx_n_s_Lf;
+static PyObject *__pyx_kp_u_Non_native_byte_order_not_suppor;
+static PyObject *__pyx_n_s_RuntimeError;
+static PyObject *__pyx_n_s_StringIO;
+static PyObject *__pyx_n_s_ValueError;
+static PyObject *__pyx_n_s_bigwig;
+static PyObject *__pyx_n_s_bx_bbi_bigwig_file;
+static PyObject *__pyx_n_s_bx_misc_binary_file;
+static PyObject *__pyx_n_s_cStringIO;
+static PyObject *__pyx_n_s_chrom;
+static PyObject *__pyx_n_s_chunks;
+static PyObject *__pyx_n_s_collections;
+static PyObject *__pyx_n_s_deque;
+static PyObject *__pyx_n_s_dtype;
+static PyObject *__pyx_n_s_end;
+static PyObject *__pyx_n_s_enumerate;
+static PyObject *__pyx_n_s_f;
+static PyObject *__pyx_n_s_file;
+static PyObject *__pyx_n_s_float32;
+static PyObject *__pyx_n_s_get;
+static PyObject *__pyx_n_s_get_as_array;
+static PyObject *__pyx_n_s_i;
+static PyObject *__pyx_n_s_import;
+static PyObject *__pyx_n_s_inf;
+static PyObject *__pyx_n_s_init;
+static PyObject *__pyx_n_s_is_little_endian;
+static PyObject *__pyx_n_s_l;
+static PyObject *__pyx_n_s_main;
+static PyObject *__pyx_n_s_n;
+static PyObject *__pyx_n_s_nan;
+static PyObject *__pyx_kp_u_ndarray_is_not_C_contiguous;
+static PyObject *__pyx_kp_u_ndarray_is_not_Fortran_contiguou;
+static PyObject *__pyx_n_s_numpy;
+static PyObject *__pyx_n_s_pyx_vtable;
+static PyObject *__pyx_n_s_range;
+static PyObject *__pyx_n_s_read_and_unpack;
+static PyObject *__pyx_n_s_round;
+static PyObject *__pyx_n_s_start;
+static PyObject *__pyx_n_s_summary_size;
+static PyObject *__pyx_n_s_test;
+static PyObject *__pyx_kp_u_unknown_dtype_code_in_numpy_pxd;
+static PyObject *__pyx_kp_s_usr_local_src_bx_python_mod_lib;
+static PyObject *__pyx_n_s_zeros;
+static PyObject *__pyx_n_s_zlib;
+static PyObject *__pyx_int_0;
+static PyObject *__pyx_int_1;
+static PyObject *__pyx_int_2;
+static PyObject *__pyx_int_3;
+static PyObject *__pyx_int_24;
+static PyObject *__pyx_int_2291137574;
+static PyObject *__pyx_tuple_;
+static PyObject *__pyx_slice__2;
+static PyObject *__pyx_slice__3;
+static PyObject *__pyx_tuple__4;
+static PyObject *__pyx_tuple__5;
+static PyObject *__pyx_tuple__6;
+static PyObject *__pyx_tuple__7;
+static PyObject *__pyx_tuple__8;
+static PyObject *__pyx_tuple__9;
+static PyObject *__pyx_tuple__10;
+static PyObject *__pyx_codeobj__11;
+
+/* "bx/bbi/bigwig_file.pyx":21
+ * DEF bwg_fixed_step = 3
+ * 
+ * cdef inline int range_intersection( int start1, int end1, int start2, int end2 ):             # <<<<<<<<<<<<<<
+ *     return min( end1, end2 ) - max( start1, start2 )
+ * 
+ */
+
+static CYTHON_INLINE int __pyx_f_2bx_3bbi_11bigwig_file_range_intersection(int __pyx_v_start1, int __pyx_v_end1, int __pyx_v_start2, int __pyx_v_end2) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  int __pyx_t_2;
+  int __pyx_t_3;
+  int __pyx_t_4;
+  __Pyx_RefNannySetupContext("range_intersection", 0);
+
+  /* "bx/bbi/bigwig_file.pyx":22
+ * 
+ * cdef inline int range_intersection( int start1, int end1, int start2, int end2 ):
+ *     return min( end1, end2 ) - max( start1, start2 )             # <<<<<<<<<<<<<<
+ * 
+ * def chunks(l, n):
+ */
+  __pyx_t_1 = __pyx_v_end2;
+  __pyx_t_2 = __pyx_v_end1;
+  if (((__pyx_t_1 < __pyx_t_2) != 0)) {
+    __pyx_t_3 = __pyx_t_1;
+  } else {
+    __pyx_t_3 = __pyx_t_2;
+  }
+  __pyx_t_1 = __pyx_v_start2;
+  __pyx_t_2 = __pyx_v_start1;
+  if (((__pyx_t_1 > __pyx_t_2) != 0)) {
+    __pyx_t_4 = __pyx_t_1;
+  } else {
+    __pyx_t_4 = __pyx_t_2;
+  }
+  __pyx_r = (__pyx_t_3 - __pyx_t_4);
+  goto __pyx_L0;
+
+  /* "bx/bbi/bigwig_file.pyx":21
+ * DEF bwg_fixed_step = 3
+ * 
+ * cdef inline int range_intersection( int start1, int end1, int start2, int end2 ):             # <<<<<<<<<<<<<<
+ *     return min( end1, end2 ) - max( start1, start2 )
+ * 
+ */
+
+  /* function exit code */
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bbi/bigwig_file.pyx":24
+ *     return min( end1, end2 ) - max( start1, start2 )
+ * 
+ * def chunks(l, n):             # <<<<<<<<<<<<<<
+ *     n = max(1, n)
+ *     return [l[i:i + n] for i in range(0, len(l), n)]
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_3bbi_11bigwig_file_1chunks(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_mdef_2bx_3bbi_11bigwig_file_1chunks = {"chunks", (PyCFunction)__pyx_pw_2bx_3bbi_11bigwig_file_1chunks, METH_VARARGS|METH_KEYWORDS, 0};
+static PyObject *__pyx_pw_2bx_3bbi_11bigwig_file_1chunks(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_l = 0;
+  PyObject *__pyx_v_n = 0;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("chunks (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_l,&__pyx_n_s_n,0};
+    PyObject* values[2] = {0,0};
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_l)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_n)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("chunks", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 24; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "chunks") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 24; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
+      goto __pyx_L5_argtuple_error;
+    } else {
+      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+    }
+    __pyx_v_l = values[0];
+    __pyx_v_n = values[1];
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("chunks", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 24; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.bbi.bigwig_file.chunks", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_3bbi_11bigwig_file_chunks(__pyx_self, __pyx_v_l, __pyx_v_n);
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_2bx_3bbi_11bigwig_file_chunks(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_l, PyObject *__pyx_v_n) {
+  PyObject *__pyx_v_i = NULL;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  long __pyx_t_2;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  PyObject *__pyx_t_5 = NULL;
+  int __pyx_t_6;
+  Py_ssize_t __pyx_t_7;
+  PyObject *(*__pyx_t_8)(PyObject *);
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("chunks", 0);
+  __Pyx_INCREF(__pyx_v_n);
+
+  /* "bx/bbi/bigwig_file.pyx":25
+ * 
+ * def chunks(l, n):
+ *     n = max(1, n)             # <<<<<<<<<<<<<<
+ *     return [l[i:i + n] for i in range(0, len(l), n)]
+ * 
+ */
+  __Pyx_INCREF(__pyx_v_n);
+  __pyx_t_1 = __pyx_v_n;
+  __pyx_t_2 = 1;
+  __pyx_t_4 = __Pyx_PyInt_From_long(__pyx_t_2); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 25; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __pyx_t_5 = PyObject_RichCompare(__pyx_t_1, __pyx_t_4, Py_GT); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 25; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 25; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+  if (__pyx_t_6) {
+    __Pyx_INCREF(__pyx_t_1);
+    __pyx_t_3 = __pyx_t_1;
+  } else {
+    __pyx_t_5 = __Pyx_PyInt_From_long(__pyx_t_2); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 25; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_5);
+    __pyx_t_3 = __pyx_t_5;
+    __pyx_t_5 = 0;
+  }
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_1 = __pyx_t_3;
+  __Pyx_INCREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __Pyx_DECREF_SET(__pyx_v_n, __pyx_t_1);
+  __pyx_t_1 = 0;
+
+  /* "bx/bbi/bigwig_file.pyx":26
+ * def chunks(l, n):
+ *     n = max(1, n)
+ *     return [l[i:i + n] for i in range(0, len(l), n)]             # <<<<<<<<<<<<<<
+ * 
+ * cdef class BigWigBlockHandler( BlockHandler ):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 26; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_7 = PyObject_Length(__pyx_v_l); if (unlikely(__pyx_t_7 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 26; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = PyInt_FromSsize_t(__pyx_t_7); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 26; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_5 = PyTuple_New(3); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 26; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __Pyx_INCREF(__pyx_int_0);
+  PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_int_0);
+  __Pyx_GIVEREF(__pyx_int_0);
+  PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_t_3);
+  __Pyx_GIVEREF(__pyx_t_3);
+  __Pyx_INCREF(__pyx_v_n);
+  PyTuple_SET_ITEM(__pyx_t_5, 2, __pyx_v_n);
+  __Pyx_GIVEREF(__pyx_v_n);
+  __pyx_t_3 = 0;
+  __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_range, __pyx_t_5, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 26; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+  if (likely(PyList_CheckExact(__pyx_t_3)) || PyTuple_CheckExact(__pyx_t_3)) {
+    __pyx_t_5 = __pyx_t_3; __Pyx_INCREF(__pyx_t_5); __pyx_t_7 = 0;
+    __pyx_t_8 = NULL;
+  } else {
+    __pyx_t_7 = -1; __pyx_t_5 = PyObject_GetIter(__pyx_t_3); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 26; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_5);
+    __pyx_t_8 = Py_TYPE(__pyx_t_5)->tp_iternext; if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 26; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  for (;;) {
+    if (likely(!__pyx_t_8)) {
+      if (likely(PyList_CheckExact(__pyx_t_5))) {
+        if (__pyx_t_7 >= PyList_GET_SIZE(__pyx_t_5)) break;
+        #if CYTHON_COMPILING_IN_CPYTHON
+        __pyx_t_3 = PyList_GET_ITEM(__pyx_t_5, __pyx_t_7); __Pyx_INCREF(__pyx_t_3); __pyx_t_7++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 26; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #else
+        __pyx_t_3 = PySequence_ITEM(__pyx_t_5, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 26; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #endif
+      } else {
+        if (__pyx_t_7 >= PyTuple_GET_SIZE(__pyx_t_5)) break;
+        #if CYTHON_COMPILING_IN_CPYTHON
+        __pyx_t_3 = PyTuple_GET_ITEM(__pyx_t_5, __pyx_t_7); __Pyx_INCREF(__pyx_t_3); __pyx_t_7++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 26; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #else
+        __pyx_t_3 = PySequence_ITEM(__pyx_t_5, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 26; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #endif
+      }
+    } else {
+      __pyx_t_3 = __pyx_t_8(__pyx_t_5);
+      if (unlikely(!__pyx_t_3)) {
+        PyObject* exc_type = PyErr_Occurred();
+        if (exc_type) {
+          if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+          else {__pyx_filename = __pyx_f[0]; __pyx_lineno = 26; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        }
+        break;
+      }
+      __Pyx_GOTREF(__pyx_t_3);
+    }
+    __Pyx_XDECREF_SET(__pyx_v_i, __pyx_t_3);
+    __pyx_t_3 = 0;
+    __pyx_t_3 = PyNumber_Add(__pyx_v_i, __pyx_v_n); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 26; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __pyx_t_4 = __Pyx_PyObject_GetSlice(__pyx_v_l, 0, 0, &__pyx_v_i, &__pyx_t_3, NULL, 0, 0, 1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 26; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    if (unlikely(__Pyx_ListComp_Append(__pyx_t_1, (PyObject*)__pyx_t_4))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 26; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  }
+  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  /* "bx/bbi/bigwig_file.pyx":24
+ *     return min( end1, end2 ) - max( start1, start2 )
+ * 
+ * def chunks(l, n):             # <<<<<<<<<<<<<<
+ *     n = max(1, n)
+ *     return [l[i:i + n] for i in range(0, len(l), n)]
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_XDECREF(__pyx_t_5);
+  __Pyx_AddTraceback("bx.bbi.bigwig_file.chunks", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_i);
+  __Pyx_XDECREF(__pyx_v_n);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bbi/bigwig_file.pyx":34
+ *     cdef bits32 start
+ *     cdef bits32 end
+ *     def __init__( self, bits32 start, bits32 end ):             # <<<<<<<<<<<<<<
+ *         BlockHandler.__init__( self )
+ *         self.start = start
+ */
+
+/* Python wrapper */
+static int __pyx_pw_2bx_3bbi_11bigwig_file_18BigWigBlockHandler_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static int __pyx_pw_2bx_3bbi_11bigwig_file_18BigWigBlockHandler_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_start;
+  __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_end;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__init__ (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_start,&__pyx_n_s_end,0};
+    PyObject* values[2] = {0,0};
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_start)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_end)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("__init__", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 34; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 34; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
+      goto __pyx_L5_argtuple_error;
+    } else {
+      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+    }
+    __pyx_v_start = __Pyx_PyInt_As_unsigned_int(values[0]); if (unlikely((__pyx_v_start == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 34; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_end = __Pyx_PyInt_As_unsigned_int(values[1]); if (unlikely((__pyx_v_end == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 34; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("__init__", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 34; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.bbi.bigwig_file.BigWigBlockHandler.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return -1;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_3bbi_11bigwig_file_18BigWigBlockHandler___init__(((struct __pyx_obj_2bx_3bbi_11bigwig_file_BigWigBlockHandler *)__pyx_v_self), __pyx_v_start, __pyx_v_end);
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_2bx_3bbi_11bigwig_file_18BigWigBlockHandler___init__(struct __pyx_obj_2bx_3bbi_11bigwig_file_BigWigBlockHandler *__pyx_v_self, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_start, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_end) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__init__", 0);
+
+  /* "bx/bbi/bigwig_file.pyx":35
+ *     cdef bits32 end
+ *     def __init__( self, bits32 start, bits32 end ):
+ *         BlockHandler.__init__( self )             # <<<<<<<<<<<<<<
+ *         self.start = start
+ *         self.end = end
+ */
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(((PyObject *)((PyObject*)__pyx_ptype_2bx_3bbi_8bbi_file_BlockHandler)), __pyx_n_s_init); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 35; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = NULL;
+  if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_2))) {
+    __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2);
+    if (likely(__pyx_t_3)) {
+      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+      __Pyx_INCREF(__pyx_t_3);
+      __Pyx_INCREF(function);
+      __Pyx_DECREF_SET(__pyx_t_2, function);
+    }
+  }
+  if (!__pyx_t_3) {
+    __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 35; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+  } else {
+    __pyx_t_4 = PyTuple_New(1+1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 35; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3); __Pyx_GIVEREF(__pyx_t_3); __pyx_t_3 = NULL;
+    __Pyx_INCREF(((PyObject *)__pyx_v_self));
+    PyTuple_SET_ITEM(__pyx_t_4, 0+1, ((PyObject *)__pyx_v_self));
+    __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
+    __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_4, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 35; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  }
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "bx/bbi/bigwig_file.pyx":36
+ *     def __init__( self, bits32 start, bits32 end ):
+ *         BlockHandler.__init__( self )
+ *         self.start = start             # <<<<<<<<<<<<<<
+ *         self.end = end
+ *     cdef handle_block( self, str block_data, BBIFile bbi_file ):
+ */
+  __pyx_v_self->start = __pyx_v_start;
+
+  /* "bx/bbi/bigwig_file.pyx":37
+ *         BlockHandler.__init__( self )
+ *         self.start = start
+ *         self.end = end             # <<<<<<<<<<<<<<
+ *     cdef handle_block( self, str block_data, BBIFile bbi_file ):
+ *         cdef bits32 b_chrom_id, b_start, b_end, b_valid_count
+ */
+  __pyx_v_self->end = __pyx_v_end;
+
+  /* "bx/bbi/bigwig_file.pyx":34
+ *     cdef bits32 start
+ *     cdef bits32 end
+ *     def __init__( self, bits32 start, bits32 end ):             # <<<<<<<<<<<<<<
+ *         BlockHandler.__init__( self )
+ *         self.start = start
+ */
+
+  /* function exit code */
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_AddTraceback("bx.bbi.bigwig_file.BigWigBlockHandler.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = -1;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bbi/bigwig_file.pyx":38
+ *         self.start = start
+ *         self.end = end
+ *     cdef handle_block( self, str block_data, BBIFile bbi_file ):             # <<<<<<<<<<<<<<
+ *         cdef bits32 b_chrom_id, b_start, b_end, b_valid_count
+ *         cdef bits32 b_item_step, b_item_span
+ */
+
+static PyObject *__pyx_f_2bx_3bbi_11bigwig_file_18BigWigBlockHandler_handle_block(struct __pyx_obj_2bx_3bbi_11bigwig_file_BigWigBlockHandler *__pyx_v_self, PyObject *__pyx_v_block_data, struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *__pyx_v_bbi_file) {
+  CYTHON_UNUSED __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_b_chrom_id;
+  __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_b_start;
+  CYTHON_UNUSED __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_b_end;
+  CYTHON_UNUSED __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_b_item_step;
+  __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_b_item_span;
+  __pyx_t_2bx_3bbi_5types_bits16 __pyx_v_b_item_count;
+  __pyx_t_2bx_3bbi_5types_UBYTE __pyx_v_b_type;
+  int __pyx_v_s;
+  int __pyx_v_e;
+  float __pyx_v_val;
+  PyObject *__pyx_v_block_reader = NULL;
+  CYTHON_UNUSED PyObject *__pyx_v__ = NULL;
+  PyObject *__pyx_v_sevs = NULL;
+  PyObject *__pyx_v_svs = NULL;
+  PyObject *__pyx_v_vs = NULL;
+  PyObject *__pyx_v_v = NULL;
+  PyObject *__pyx_v_i = NULL;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  PyObject *__pyx_t_5 = NULL;
+  PyObject *__pyx_t_6 = NULL;
+  PyObject *__pyx_t_7 = NULL;
+  PyObject *__pyx_t_8 = NULL;
+  PyObject *__pyx_t_9 = NULL;
+  PyObject *__pyx_t_10 = NULL;
+  PyObject *(*__pyx_t_11)(PyObject *);
+  __pyx_t_2bx_3bbi_5types_bits32 __pyx_t_12;
+  __pyx_t_2bx_3bbi_5types_bits32 __pyx_t_13;
+  __pyx_t_2bx_3bbi_5types_bits32 __pyx_t_14;
+  __pyx_t_2bx_3bbi_5types_bits32 __pyx_t_15;
+  __pyx_t_2bx_3bbi_5types_bits32 __pyx_t_16;
+  __pyx_t_2bx_3bbi_5types_UBYTE __pyx_t_17;
+  __pyx_t_2bx_3bbi_5types_bits16 __pyx_t_18;
+  Py_ssize_t __pyx_t_19;
+  PyObject *(*__pyx_t_20)(PyObject *);
+  int __pyx_t_21;
+  int __pyx_t_22;
+  float __pyx_t_23;
+  int __pyx_t_24;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("handle_block", 0);
+
+  /* "bx/bbi/bigwig_file.pyx":46
+ *         cdef float val
+ *         # Now we parse the block, first the header
+ *         block_reader = BinaryFileReader( StringIO( block_data ), is_little_endian=bbi_file.reader.is_little_endian )             # <<<<<<<<<<<<<<
+ *         # _ is skipped byte
+ *         b_chrom_id, b_start, b_end, b_item_step, b_item_span, b_type, _, b_item_count = block_reader.read_and_unpack("LLLLLBBH", 5*4+1+1+2)
+ */
+  __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_BinaryFileReader); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 46; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_StringIO); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 46; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_4 = NULL;
+  if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_3))) {
+    __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_3);
+    if (likely(__pyx_t_4)) {
+      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+      __Pyx_INCREF(__pyx_t_4);
+      __Pyx_INCREF(function);
+      __Pyx_DECREF_SET(__pyx_t_3, function);
+    }
+  }
+  if (!__pyx_t_4) {
+    __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_v_block_data); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 46; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+  } else {
+    __pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 46; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_5);
+    PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_4); __Pyx_GIVEREF(__pyx_t_4); __pyx_t_4 = NULL;
+    __Pyx_INCREF(__pyx_v_block_data);
+    PyTuple_SET_ITEM(__pyx_t_5, 0+1, __pyx_v_block_data);
+    __Pyx_GIVEREF(__pyx_v_block_data);
+    __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_5, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 46; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+  }
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 46; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_2);
+  __Pyx_GIVEREF(__pyx_t_2);
+  __pyx_t_2 = 0;
+  __pyx_t_2 = PyDict_New(); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 46; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_bbi_file->reader, __pyx_n_s_is_little_endian); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 46; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_is_little_endian, __pyx_t_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 46; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+  __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_3, __pyx_t_2); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 46; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_v_block_reader = __pyx_t_5;
+  __pyx_t_5 = 0;
+
+  /* "bx/bbi/bigwig_file.pyx":48
+ *         block_reader = BinaryFileReader( StringIO( block_data ), is_little_endian=bbi_file.reader.is_little_endian )
+ *         # _ is skipped byte
+ *         b_chrom_id, b_start, b_end, b_item_step, b_item_span, b_type, _, b_item_count = block_reader.read_and_unpack("LLLLLBBH", 5*4+1+1+2)             # <<<<<<<<<<<<<<
+ * 
+ *         if b_type == bwg_bed_graph:
+ */
+  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_block_reader, __pyx_n_s_read_and_unpack); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 48; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_tuple_, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 48; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+  if ((likely(PyTuple_CheckExact(__pyx_t_2))) || (PyList_CheckExact(__pyx_t_2))) {
+    PyObject* sequence = __pyx_t_2;
+    #if CYTHON_COMPILING_IN_CPYTHON
+    Py_ssize_t size = Py_SIZE(sequence);
+    #else
+    Py_ssize_t size = PySequence_Size(sequence);
+    #endif
+    if (unlikely(size != 8)) {
+      if (size > 8) __Pyx_RaiseTooManyValuesError(8);
+      else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
+      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 48; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+    #if CYTHON_COMPILING_IN_CPYTHON
+    if (likely(PyTuple_CheckExact(sequence))) {
+      __pyx_t_5 = PyTuple_GET_ITEM(sequence, 0); 
+      __pyx_t_3 = PyTuple_GET_ITEM(sequence, 1); 
+      __pyx_t_1 = PyTuple_GET_ITEM(sequence, 2); 
+      __pyx_t_4 = PyTuple_GET_ITEM(sequence, 3); 
+      __pyx_t_6 = PyTuple_GET_ITEM(sequence, 4); 
+      __pyx_t_7 = PyTuple_GET_ITEM(sequence, 5); 
+      __pyx_t_8 = PyTuple_GET_ITEM(sequence, 6); 
+      __pyx_t_9 = PyTuple_GET_ITEM(sequence, 7); 
+    } else {
+      __pyx_t_5 = PyList_GET_ITEM(sequence, 0); 
+      __pyx_t_3 = PyList_GET_ITEM(sequence, 1); 
+      __pyx_t_1 = PyList_GET_ITEM(sequence, 2); 
+      __pyx_t_4 = PyList_GET_ITEM(sequence, 3); 
+      __pyx_t_6 = PyList_GET_ITEM(sequence, 4); 
+      __pyx_t_7 = PyList_GET_ITEM(sequence, 5); 
+      __pyx_t_8 = PyList_GET_ITEM(sequence, 6); 
+      __pyx_t_9 = PyList_GET_ITEM(sequence, 7); 
+    }
+    __Pyx_INCREF(__pyx_t_5);
+    __Pyx_INCREF(__pyx_t_3);
+    __Pyx_INCREF(__pyx_t_1);
+    __Pyx_INCREF(__pyx_t_4);
+    __Pyx_INCREF(__pyx_t_6);
+    __Pyx_INCREF(__pyx_t_7);
+    __Pyx_INCREF(__pyx_t_8);
+    __Pyx_INCREF(__pyx_t_9);
+    #else
+    {
+      Py_ssize_t i;
+      PyObject** temps[8] = {&__pyx_t_5,&__pyx_t_3,&__pyx_t_1,&__pyx_t_4,&__pyx_t_6,&__pyx_t_7,&__pyx_t_8,&__pyx_t_9};
+      for (i=0; i < 8; i++) {
+        PyObject* item = PySequence_ITEM(sequence, i); if (unlikely(!item)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 48; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(item);
+        *(temps[i]) = item;
+      }
+    }
+    #endif
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  } else {
+    Py_ssize_t index = -1;
+    PyObject** temps[8] = {&__pyx_t_5,&__pyx_t_3,&__pyx_t_1,&__pyx_t_4,&__pyx_t_6,&__pyx_t_7,&__pyx_t_8,&__pyx_t_9};
+    __pyx_t_10 = PyObject_GetIter(__pyx_t_2); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 48; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_10);
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    __pyx_t_11 = Py_TYPE(__pyx_t_10)->tp_iternext;
+    for (index=0; index < 8; index++) {
+      PyObject* item = __pyx_t_11(__pyx_t_10); if (unlikely(!item)) goto __pyx_L3_unpacking_failed;
+      __Pyx_GOTREF(item);
+      *(temps[index]) = item;
+    }
+    if (__Pyx_IternextUnpackEndCheck(__pyx_t_11(__pyx_t_10), 8) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 48; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_11 = NULL;
+    __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+    goto __pyx_L4_unpacking_done;
+    __pyx_L3_unpacking_failed:;
+    __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+    __pyx_t_11 = NULL;
+    if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 48; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_L4_unpacking_done:;
+  }
+  __pyx_t_12 = __Pyx_PyInt_As_unsigned_int(__pyx_t_5); if (unlikely((__pyx_t_12 == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 48; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+  __pyx_t_13 = __Pyx_PyInt_As_unsigned_int(__pyx_t_3); if (unlikely((__pyx_t_13 == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 48; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __pyx_t_14 = __Pyx_PyInt_As_unsigned_int(__pyx_t_1); if (unlikely((__pyx_t_14 == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 48; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_15 = __Pyx_PyInt_As_unsigned_int(__pyx_t_4); if (unlikely((__pyx_t_15 == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 48; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  __pyx_t_16 = __Pyx_PyInt_As_unsigned_int(__pyx_t_6); if (unlikely((__pyx_t_16 == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 48; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+  __pyx_t_17 = __Pyx_PyInt_As_unsigned_char(__pyx_t_7); if (unlikely((__pyx_t_17 == (unsigned char)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 48; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+  __pyx_t_18 = __Pyx_PyInt_As_unsigned_short(__pyx_t_9); if (unlikely((__pyx_t_18 == (unsigned short)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 48; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+  __pyx_v_b_chrom_id = __pyx_t_12;
+  __pyx_v_b_start = __pyx_t_13;
+  __pyx_v_b_end = __pyx_t_14;
+  __pyx_v_b_item_step = __pyx_t_15;
+  __pyx_v_b_item_span = __pyx_t_16;
+  __pyx_v_b_type = __pyx_t_17;
+  __pyx_v__ = __pyx_t_8;
+  __pyx_t_8 = 0;
+  __pyx_v_b_item_count = __pyx_t_18;
+
+  /* "bx/bbi/bigwig_file.pyx":56
+ *             svs = chunks(block_reader.read_and_unpack("Lf" * b_item_count, (4 + 4) * b_item_count), 2)
+ *             sevs = [(s, s + b_item_span, v) for s, v in svs]
+ *         elif b_type == bwg_fixed_step:             # <<<<<<<<<<<<<<
+ *             vs = block_reader.read_and_unpack("f" * b_item_count, 4 * b_item_count)
+ *             sevs = [(b_start + (i * b_item_span), b_start + (i * b_item_span) + b_item_span, v) for i, v in enumerate(vs)]
+ */
+  switch (__pyx_v_b_type) {
+
+    /* "bx/bbi/bigwig_file.pyx":50
+ *         b_chrom_id, b_start, b_end, b_item_step, b_item_span, b_type, _, b_item_count = block_reader.read_and_unpack("LLLLLBBH", 5*4+1+1+2)
+ * 
+ *         if b_type == bwg_bed_graph:             # <<<<<<<<<<<<<<
+ *             # [(start, end, val), ...]
+ *             sevs = chunks(block_reader.read_and_unpack("LLf" * b_item_count, (2 * 4 + 4) * b_item_count), 3)
+ */
+    case 1:
+
+    /* "bx/bbi/bigwig_file.pyx":52
+ *         if b_type == bwg_bed_graph:
+ *             # [(start, end, val), ...]
+ *             sevs = chunks(block_reader.read_and_unpack("LLf" * b_item_count, (2 * 4 + 4) * b_item_count), 3)             # <<<<<<<<<<<<<<
+ *         elif b_type == bwg_variable_step:
+ *             svs = chunks(block_reader.read_and_unpack("Lf" * b_item_count, (4 + 4) * b_item_count), 2)
+ */
+    __pyx_t_9 = __Pyx_GetModuleGlobalName(__pyx_n_s_chunks); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 52; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_9);
+    __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_block_reader, __pyx_n_s_read_and_unpack); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 52; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_7);
+    __pyx_t_6 = __Pyx_PyInt_From_unsigned_short(__pyx_v_b_item_count); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 52; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_6);
+    __pyx_t_4 = PyNumber_Multiply(__pyx_n_s_LLf, __pyx_t_6); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 52; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+    __pyx_t_6 = __Pyx_PyInt_From_long((12 * __pyx_v_b_item_count)); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 52; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_6);
+    __pyx_t_1 = NULL;
+    __pyx_t_19 = 0;
+    if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_7))) {
+      __pyx_t_1 = PyMethod_GET_SELF(__pyx_t_7);
+      if (likely(__pyx_t_1)) {
+        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_7);
+        __Pyx_INCREF(__pyx_t_1);
+        __Pyx_INCREF(function);
+        __Pyx_DECREF_SET(__pyx_t_7, function);
+        __pyx_t_19 = 1;
+      }
+    }
+    __pyx_t_3 = PyTuple_New(2+__pyx_t_19); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 52; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    if (__pyx_t_1) {
+      PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1); __Pyx_GIVEREF(__pyx_t_1); __pyx_t_1 = NULL;
+    }
+    PyTuple_SET_ITEM(__pyx_t_3, 0+__pyx_t_19, __pyx_t_4);
+    __Pyx_GIVEREF(__pyx_t_4);
+    PyTuple_SET_ITEM(__pyx_t_3, 1+__pyx_t_19, __pyx_t_6);
+    __Pyx_GIVEREF(__pyx_t_6);
+    __pyx_t_4 = 0;
+    __pyx_t_6 = 0;
+    __pyx_t_8 = __Pyx_PyObject_Call(__pyx_t_7, __pyx_t_3, NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 52; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_8);
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+    __pyx_t_7 = NULL;
+    __pyx_t_19 = 0;
+    if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_9))) {
+      __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_9);
+      if (likely(__pyx_t_7)) {
+        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_9);
+        __Pyx_INCREF(__pyx_t_7);
+        __Pyx_INCREF(function);
+        __Pyx_DECREF_SET(__pyx_t_9, function);
+        __pyx_t_19 = 1;
+      }
+    }
+    __pyx_t_3 = PyTuple_New(2+__pyx_t_19); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 52; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    if (__pyx_t_7) {
+      PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_7); __Pyx_GIVEREF(__pyx_t_7); __pyx_t_7 = NULL;
+    }
+    PyTuple_SET_ITEM(__pyx_t_3, 0+__pyx_t_19, __pyx_t_8);
+    __Pyx_GIVEREF(__pyx_t_8);
+    __Pyx_INCREF(__pyx_int_3);
+    PyTuple_SET_ITEM(__pyx_t_3, 1+__pyx_t_19, __pyx_int_3);
+    __Pyx_GIVEREF(__pyx_int_3);
+    __pyx_t_8 = 0;
+    __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_9, __pyx_t_3, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 52; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+    __pyx_v_sevs = __pyx_t_2;
+    __pyx_t_2 = 0;
+    break;
+
+    /* "bx/bbi/bigwig_file.pyx":53
+ *             # [(start, end, val), ...]
+ *             sevs = chunks(block_reader.read_and_unpack("LLf" * b_item_count, (2 * 4 + 4) * b_item_count), 3)
+ *         elif b_type == bwg_variable_step:             # <<<<<<<<<<<<<<
+ *             svs = chunks(block_reader.read_and_unpack("Lf" * b_item_count, (4 + 4) * b_item_count), 2)
+ *             sevs = [(s, s + b_item_span, v) for s, v in svs]
+ */
+    case 2:
+
+    /* "bx/bbi/bigwig_file.pyx":54
+ *             sevs = chunks(block_reader.read_and_unpack("LLf" * b_item_count, (2 * 4 + 4) * b_item_count), 3)
+ *         elif b_type == bwg_variable_step:
+ *             svs = chunks(block_reader.read_and_unpack("Lf" * b_item_count, (4 + 4) * b_item_count), 2)             # <<<<<<<<<<<<<<
+ *             sevs = [(s, s + b_item_span, v) for s, v in svs]
+ *         elif b_type == bwg_fixed_step:
+ */
+    __pyx_t_9 = __Pyx_GetModuleGlobalName(__pyx_n_s_chunks); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 54; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_9);
+    __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_v_block_reader, __pyx_n_s_read_and_unpack); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 54; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_8);
+    __pyx_t_7 = __Pyx_PyInt_From_unsigned_short(__pyx_v_b_item_count); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 54; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_7);
+    __pyx_t_6 = PyNumber_Multiply(__pyx_n_s_Lf, __pyx_t_7); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 54; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_6);
+    __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+    __pyx_t_7 = __Pyx_PyInt_From_long((8 * __pyx_v_b_item_count)); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 54; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_7);
+    __pyx_t_4 = NULL;
+    __pyx_t_19 = 0;
+    if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_8))) {
+      __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_8);
+      if (likely(__pyx_t_4)) {
+        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_8);
+        __Pyx_INCREF(__pyx_t_4);
+        __Pyx_INCREF(function);
+        __Pyx_DECREF_SET(__pyx_t_8, function);
+        __pyx_t_19 = 1;
+      }
+    }
+    __pyx_t_1 = PyTuple_New(2+__pyx_t_19); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 54; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    if (__pyx_t_4) {
+      PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_4); __Pyx_GIVEREF(__pyx_t_4); __pyx_t_4 = NULL;
+    }
+    PyTuple_SET_ITEM(__pyx_t_1, 0+__pyx_t_19, __pyx_t_6);
+    __Pyx_GIVEREF(__pyx_t_6);
+    PyTuple_SET_ITEM(__pyx_t_1, 1+__pyx_t_19, __pyx_t_7);
+    __Pyx_GIVEREF(__pyx_t_7);
+    __pyx_t_6 = 0;
+    __pyx_t_7 = 0;
+    __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_8, __pyx_t_1, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 54; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+    __pyx_t_8 = NULL;
+    __pyx_t_19 = 0;
+    if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_9))) {
+      __pyx_t_8 = PyMethod_GET_SELF(__pyx_t_9);
+      if (likely(__pyx_t_8)) {
+        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_9);
+        __Pyx_INCREF(__pyx_t_8);
+        __Pyx_INCREF(function);
+        __Pyx_DECREF_SET(__pyx_t_9, function);
+        __pyx_t_19 = 1;
+      }
+    }
+    __pyx_t_1 = PyTuple_New(2+__pyx_t_19); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 54; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    if (__pyx_t_8) {
+      PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_8); __Pyx_GIVEREF(__pyx_t_8); __pyx_t_8 = NULL;
+    }
+    PyTuple_SET_ITEM(__pyx_t_1, 0+__pyx_t_19, __pyx_t_3);
+    __Pyx_GIVEREF(__pyx_t_3);
+    __Pyx_INCREF(__pyx_int_2);
+    PyTuple_SET_ITEM(__pyx_t_1, 1+__pyx_t_19, __pyx_int_2);
+    __Pyx_GIVEREF(__pyx_int_2);
+    __pyx_t_3 = 0;
+    __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_9, __pyx_t_1, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 54; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+    __pyx_v_svs = __pyx_t_2;
+    __pyx_t_2 = 0;
+
+    /* "bx/bbi/bigwig_file.pyx":55
+ *         elif b_type == bwg_variable_step:
+ *             svs = chunks(block_reader.read_and_unpack("Lf" * b_item_count, (4 + 4) * b_item_count), 2)
+ *             sevs = [(s, s + b_item_span, v) for s, v in svs]             # <<<<<<<<<<<<<<
+ *         elif b_type == bwg_fixed_step:
+ *             vs = block_reader.read_and_unpack("f" * b_item_count, 4 * b_item_count)
+ */
+    __pyx_t_2 = PyList_New(0); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 55; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    if (likely(PyList_CheckExact(__pyx_v_svs)) || PyTuple_CheckExact(__pyx_v_svs)) {
+      __pyx_t_9 = __pyx_v_svs; __Pyx_INCREF(__pyx_t_9); __pyx_t_19 = 0;
+      __pyx_t_20 = NULL;
+    } else {
+      __pyx_t_19 = -1; __pyx_t_9 = PyObject_GetIter(__pyx_v_svs); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 55; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_9);
+      __pyx_t_20 = Py_TYPE(__pyx_t_9)->tp_iternext; if (unlikely(!__pyx_t_20)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 55; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+    for (;;) {
+      if (likely(!__pyx_t_20)) {
+        if (likely(PyList_CheckExact(__pyx_t_9))) {
+          if (__pyx_t_19 >= PyList_GET_SIZE(__pyx_t_9)) break;
+          #if CYTHON_COMPILING_IN_CPYTHON
+          __pyx_t_1 = PyList_GET_ITEM(__pyx_t_9, __pyx_t_19); __Pyx_INCREF(__pyx_t_1); __pyx_t_19++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 55; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          #else
+          __pyx_t_1 = PySequence_ITEM(__pyx_t_9, __pyx_t_19); __pyx_t_19++; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 55; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          #endif
+        } else {
+          if (__pyx_t_19 >= PyTuple_GET_SIZE(__pyx_t_9)) break;
+          #if CYTHON_COMPILING_IN_CPYTHON
+          __pyx_t_1 = PyTuple_GET_ITEM(__pyx_t_9, __pyx_t_19); __Pyx_INCREF(__pyx_t_1); __pyx_t_19++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 55; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          #else
+          __pyx_t_1 = PySequence_ITEM(__pyx_t_9, __pyx_t_19); __pyx_t_19++; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 55; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          #endif
+        }
+      } else {
+        __pyx_t_1 = __pyx_t_20(__pyx_t_9);
+        if (unlikely(!__pyx_t_1)) {
+          PyObject* exc_type = PyErr_Occurred();
+          if (exc_type) {
+            if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+            else {__pyx_filename = __pyx_f[0]; __pyx_lineno = 55; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          }
+          break;
+        }
+        __Pyx_GOTREF(__pyx_t_1);
+      }
+      if ((likely(PyTuple_CheckExact(__pyx_t_1))) || (PyList_CheckExact(__pyx_t_1))) {
+        PyObject* sequence = __pyx_t_1;
+        #if CYTHON_COMPILING_IN_CPYTHON
+        Py_ssize_t size = Py_SIZE(sequence);
+        #else
+        Py_ssize_t size = PySequence_Size(sequence);
+        #endif
+        if (unlikely(size != 2)) {
+          if (size > 2) __Pyx_RaiseTooManyValuesError(2);
+          else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
+          {__pyx_filename = __pyx_f[0]; __pyx_lineno = 55; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        }
+        #if CYTHON_COMPILING_IN_CPYTHON
+        if (likely(PyTuple_CheckExact(sequence))) {
+          __pyx_t_3 = PyTuple_GET_ITEM(sequence, 0); 
+          __pyx_t_8 = PyTuple_GET_ITEM(sequence, 1); 
+        } else {
+          __pyx_t_3 = PyList_GET_ITEM(sequence, 0); 
+          __pyx_t_8 = PyList_GET_ITEM(sequence, 1); 
+        }
+        __Pyx_INCREF(__pyx_t_3);
+        __Pyx_INCREF(__pyx_t_8);
+        #else
+        __pyx_t_3 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 55; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_3);
+        __pyx_t_8 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 55; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_8);
+        #endif
+        __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+      } else {
+        Py_ssize_t index = -1;
+        __pyx_t_7 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 55; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_7);
+        __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+        __pyx_t_11 = Py_TYPE(__pyx_t_7)->tp_iternext;
+        index = 0; __pyx_t_3 = __pyx_t_11(__pyx_t_7); if (unlikely(!__pyx_t_3)) goto __pyx_L7_unpacking_failed;
+        __Pyx_GOTREF(__pyx_t_3);
+        index = 1; __pyx_t_8 = __pyx_t_11(__pyx_t_7); if (unlikely(!__pyx_t_8)) goto __pyx_L7_unpacking_failed;
+        __Pyx_GOTREF(__pyx_t_8);
+        if (__Pyx_IternextUnpackEndCheck(__pyx_t_11(__pyx_t_7), 2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 55; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_11 = NULL;
+        __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+        goto __pyx_L8_unpacking_done;
+        __pyx_L7_unpacking_failed:;
+        __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+        __pyx_t_11 = NULL;
+        if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
+        {__pyx_filename = __pyx_f[0]; __pyx_lineno = 55; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_L8_unpacking_done:;
+      }
+      __pyx_t_21 = __Pyx_PyInt_As_int(__pyx_t_3); if (unlikely((__pyx_t_21 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 55; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_v_s = __pyx_t_21;
+      __Pyx_XDECREF_SET(__pyx_v_v, __pyx_t_8);
+      __pyx_t_8 = 0;
+      __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_s); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 55; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_1);
+      __pyx_t_8 = __Pyx_PyInt_From_unsigned_int((__pyx_v_s + __pyx_v_b_item_span)); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 55; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_8);
+      __pyx_t_3 = PyTuple_New(3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 55; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1);
+      __Pyx_GIVEREF(__pyx_t_1);
+      PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_8);
+      __Pyx_GIVEREF(__pyx_t_8);
+      __Pyx_INCREF(__pyx_v_v);
+      PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_v_v);
+      __Pyx_GIVEREF(__pyx_v_v);
+      __pyx_t_1 = 0;
+      __pyx_t_8 = 0;
+      if (unlikely(__Pyx_ListComp_Append(__pyx_t_2, (PyObject*)__pyx_t_3))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 55; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    }
+    __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+    __pyx_v_sevs = __pyx_t_2;
+    __pyx_t_2 = 0;
+    break;
+
+    /* "bx/bbi/bigwig_file.pyx":56
+ *             svs = chunks(block_reader.read_and_unpack("Lf" * b_item_count, (4 + 4) * b_item_count), 2)
+ *             sevs = [(s, s + b_item_span, v) for s, v in svs]
+ *         elif b_type == bwg_fixed_step:             # <<<<<<<<<<<<<<
+ *             vs = block_reader.read_and_unpack("f" * b_item_count, 4 * b_item_count)
+ *             sevs = [(b_start + (i * b_item_span), b_start + (i * b_item_span) + b_item_span, v) for i, v in enumerate(vs)]
+ */
+    case 3:
+
+    /* "bx/bbi/bigwig_file.pyx":57
+ *             sevs = [(s, s + b_item_span, v) for s, v in svs]
+ *         elif b_type == bwg_fixed_step:
+ *             vs = block_reader.read_and_unpack("f" * b_item_count, 4 * b_item_count)             # <<<<<<<<<<<<<<
+ *             sevs = [(b_start + (i * b_item_span), b_start + (i * b_item_span) + b_item_span, v) for i, v in enumerate(vs)]
+ * 
+ */
+    __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_block_reader, __pyx_n_s_read_and_unpack); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 57; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_9);
+    __pyx_t_3 = __Pyx_PyInt_From_unsigned_short(__pyx_v_b_item_count); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 57; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __pyx_t_8 = PyNumber_Multiply(__pyx_n_s_f, __pyx_t_3); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 57; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_8);
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __pyx_t_3 = __Pyx_PyInt_From_long((4 * __pyx_v_b_item_count)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 57; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __pyx_t_1 = NULL;
+    __pyx_t_19 = 0;
+    if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_9))) {
+      __pyx_t_1 = PyMethod_GET_SELF(__pyx_t_9);
+      if (likely(__pyx_t_1)) {
+        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_9);
+        __Pyx_INCREF(__pyx_t_1);
+        __Pyx_INCREF(function);
+        __Pyx_DECREF_SET(__pyx_t_9, function);
+        __pyx_t_19 = 1;
+      }
+    }
+    __pyx_t_7 = PyTuple_New(2+__pyx_t_19); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 57; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_7);
+    if (__pyx_t_1) {
+      PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_1); __Pyx_GIVEREF(__pyx_t_1); __pyx_t_1 = NULL;
+    }
+    PyTuple_SET_ITEM(__pyx_t_7, 0+__pyx_t_19, __pyx_t_8);
+    __Pyx_GIVEREF(__pyx_t_8);
+    PyTuple_SET_ITEM(__pyx_t_7, 1+__pyx_t_19, __pyx_t_3);
+    __Pyx_GIVEREF(__pyx_t_3);
+    __pyx_t_8 = 0;
+    __pyx_t_3 = 0;
+    __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_9, __pyx_t_7, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 57; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+    __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+    __pyx_v_vs = __pyx_t_2;
+    __pyx_t_2 = 0;
+
+    /* "bx/bbi/bigwig_file.pyx":58
+ *         elif b_type == bwg_fixed_step:
+ *             vs = block_reader.read_and_unpack("f" * b_item_count, 4 * b_item_count)
+ *             sevs = [(b_start + (i * b_item_span), b_start + (i * b_item_span) + b_item_span, v) for i, v in enumerate(vs)]             # <<<<<<<<<<<<<<
+ * 
+ *         # TODO: change handle_interval to take a numpy array and this will be
+ */
+    __pyx_t_2 = PyList_New(0); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 58; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __Pyx_INCREF(__pyx_int_0);
+    __pyx_t_9 = __pyx_int_0;
+    if (likely(PyList_CheckExact(__pyx_v_vs)) || PyTuple_CheckExact(__pyx_v_vs)) {
+      __pyx_t_7 = __pyx_v_vs; __Pyx_INCREF(__pyx_t_7); __pyx_t_19 = 0;
+      __pyx_t_20 = NULL;
+    } else {
+      __pyx_t_19 = -1; __pyx_t_7 = PyObject_GetIter(__pyx_v_vs); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 58; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_7);
+      __pyx_t_20 = Py_TYPE(__pyx_t_7)->tp_iternext; if (unlikely(!__pyx_t_20)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 58; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+    for (;;) {
+      if (likely(!__pyx_t_20)) {
+        if (likely(PyList_CheckExact(__pyx_t_7))) {
+          if (__pyx_t_19 >= PyList_GET_SIZE(__pyx_t_7)) break;
+          #if CYTHON_COMPILING_IN_CPYTHON
+          __pyx_t_3 = PyList_GET_ITEM(__pyx_t_7, __pyx_t_19); __Pyx_INCREF(__pyx_t_3); __pyx_t_19++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 58; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          #else
+          __pyx_t_3 = PySequence_ITEM(__pyx_t_7, __pyx_t_19); __pyx_t_19++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 58; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          #endif
+        } else {
+          if (__pyx_t_19 >= PyTuple_GET_SIZE(__pyx_t_7)) break;
+          #if CYTHON_COMPILING_IN_CPYTHON
+          __pyx_t_3 = PyTuple_GET_ITEM(__pyx_t_7, __pyx_t_19); __Pyx_INCREF(__pyx_t_3); __pyx_t_19++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 58; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          #else
+          __pyx_t_3 = PySequence_ITEM(__pyx_t_7, __pyx_t_19); __pyx_t_19++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 58; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          #endif
+        }
+      } else {
+        __pyx_t_3 = __pyx_t_20(__pyx_t_7);
+        if (unlikely(!__pyx_t_3)) {
+          PyObject* exc_type = PyErr_Occurred();
+          if (exc_type) {
+            if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+            else {__pyx_filename = __pyx_f[0]; __pyx_lineno = 58; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          }
+          break;
+        }
+        __Pyx_GOTREF(__pyx_t_3);
+      }
+      __Pyx_XDECREF_SET(__pyx_v_v, __pyx_t_3);
+      __pyx_t_3 = 0;
+      __Pyx_INCREF(__pyx_t_9);
+      __Pyx_XDECREF_SET(__pyx_v_i, __pyx_t_9);
+      __pyx_t_3 = PyNumber_Add(__pyx_t_9, __pyx_int_1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 58; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __Pyx_DECREF(__pyx_t_9);
+      __pyx_t_9 = __pyx_t_3;
+      __pyx_t_3 = 0;
+      __pyx_t_3 = __Pyx_PyInt_From_unsigned_int(__pyx_v_b_start); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 58; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_8 = __Pyx_PyInt_From_unsigned_int(__pyx_v_b_item_span); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 58; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_8);
+      __pyx_t_1 = PyNumber_Multiply(__pyx_v_i, __pyx_t_8); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 58; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_1);
+      __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+      __pyx_t_8 = PyNumber_Add(__pyx_t_3, __pyx_t_1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 58; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_8);
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+      __pyx_t_1 = __Pyx_PyInt_From_unsigned_int(__pyx_v_b_start); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 58; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_1);
+      __pyx_t_3 = __Pyx_PyInt_From_unsigned_int(__pyx_v_b_item_span); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 58; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_6 = PyNumber_Multiply(__pyx_v_i, __pyx_t_3); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 58; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_6);
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_t_3 = PyNumber_Add(__pyx_t_1, __pyx_t_6); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 58; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+      __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+      __pyx_t_6 = __Pyx_PyInt_From_unsigned_int(__pyx_v_b_item_span); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 58; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_6);
+      __pyx_t_1 = PyNumber_Add(__pyx_t_3, __pyx_t_6); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 58; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_1);
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+      __pyx_t_6 = PyTuple_New(3); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 58; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_6);
+      PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_8);
+      __Pyx_GIVEREF(__pyx_t_8);
+      PyTuple_SET_ITEM(__pyx_t_6, 1, __pyx_t_1);
+      __Pyx_GIVEREF(__pyx_t_1);
+      __Pyx_INCREF(__pyx_v_v);
+      PyTuple_SET_ITEM(__pyx_t_6, 2, __pyx_v_v);
+      __Pyx_GIVEREF(__pyx_v_v);
+      __pyx_t_8 = 0;
+      __pyx_t_1 = 0;
+      if (unlikely(__Pyx_ListComp_Append(__pyx_t_2, (PyObject*)__pyx_t_6))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 58; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+    }
+    __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+    __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+    __pyx_v_sevs = __pyx_t_2;
+    __pyx_t_2 = 0;
+    break;
+    default: break;
+  }
+
+  /* "bx/bbi/bigwig_file.pyx":62
+ *         # TODO: change handle_interval to take a numpy array and this will be
+ *         # much faster.
+ *         for s, e, val in sevs:             # <<<<<<<<<<<<<<
+ *             if s < self.start:
+ *                 s = self.start
+ */
+  if (unlikely(!__pyx_v_sevs)) { __Pyx_RaiseUnboundLocalError("sevs"); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 62; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+  if (likely(PyList_CheckExact(__pyx_v_sevs)) || PyTuple_CheckExact(__pyx_v_sevs)) {
+    __pyx_t_2 = __pyx_v_sevs; __Pyx_INCREF(__pyx_t_2); __pyx_t_19 = 0;
+    __pyx_t_20 = NULL;
+  } else {
+    __pyx_t_19 = -1; __pyx_t_2 = PyObject_GetIter(__pyx_v_sevs); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 62; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_t_20 = Py_TYPE(__pyx_t_2)->tp_iternext; if (unlikely(!__pyx_t_20)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 62; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  for (;;) {
+    if (likely(!__pyx_t_20)) {
+      if (likely(PyList_CheckExact(__pyx_t_2))) {
+        if (__pyx_t_19 >= PyList_GET_SIZE(__pyx_t_2)) break;
+        #if CYTHON_COMPILING_IN_CPYTHON
+        __pyx_t_9 = PyList_GET_ITEM(__pyx_t_2, __pyx_t_19); __Pyx_INCREF(__pyx_t_9); __pyx_t_19++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 62; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #else
+        __pyx_t_9 = PySequence_ITEM(__pyx_t_2, __pyx_t_19); __pyx_t_19++; if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 62; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #endif
+      } else {
+        if (__pyx_t_19 >= PyTuple_GET_SIZE(__pyx_t_2)) break;
+        #if CYTHON_COMPILING_IN_CPYTHON
+        __pyx_t_9 = PyTuple_GET_ITEM(__pyx_t_2, __pyx_t_19); __Pyx_INCREF(__pyx_t_9); __pyx_t_19++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 62; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #else
+        __pyx_t_9 = PySequence_ITEM(__pyx_t_2, __pyx_t_19); __pyx_t_19++; if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 62; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #endif
+      }
+    } else {
+      __pyx_t_9 = __pyx_t_20(__pyx_t_2);
+      if (unlikely(!__pyx_t_9)) {
+        PyObject* exc_type = PyErr_Occurred();
+        if (exc_type) {
+          if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+          else {__pyx_filename = __pyx_f[0]; __pyx_lineno = 62; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        }
+        break;
+      }
+      __Pyx_GOTREF(__pyx_t_9);
+    }
+    if ((likely(PyTuple_CheckExact(__pyx_t_9))) || (PyList_CheckExact(__pyx_t_9))) {
+      PyObject* sequence = __pyx_t_9;
+      #if CYTHON_COMPILING_IN_CPYTHON
+      Py_ssize_t size = Py_SIZE(sequence);
+      #else
+      Py_ssize_t size = PySequence_Size(sequence);
+      #endif
+      if (unlikely(size != 3)) {
+        if (size > 3) __Pyx_RaiseTooManyValuesError(3);
+        else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
+        {__pyx_filename = __pyx_f[0]; __pyx_lineno = 62; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      }
+      #if CYTHON_COMPILING_IN_CPYTHON
+      if (likely(PyTuple_CheckExact(sequence))) {
+        __pyx_t_7 = PyTuple_GET_ITEM(sequence, 0); 
+        __pyx_t_6 = PyTuple_GET_ITEM(sequence, 1); 
+        __pyx_t_1 = PyTuple_GET_ITEM(sequence, 2); 
+      } else {
+        __pyx_t_7 = PyList_GET_ITEM(sequence, 0); 
+        __pyx_t_6 = PyList_GET_ITEM(sequence, 1); 
+        __pyx_t_1 = PyList_GET_ITEM(sequence, 2); 
+      }
+      __Pyx_INCREF(__pyx_t_7);
+      __Pyx_INCREF(__pyx_t_6);
+      __Pyx_INCREF(__pyx_t_1);
+      #else
+      __pyx_t_7 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 62; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_7);
+      __pyx_t_6 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 62; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_6);
+      __pyx_t_1 = PySequence_ITEM(sequence, 2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 62; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_1);
+      #endif
+      __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+    } else {
+      Py_ssize_t index = -1;
+      __pyx_t_8 = PyObject_GetIter(__pyx_t_9); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 62; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_8);
+      __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+      __pyx_t_11 = Py_TYPE(__pyx_t_8)->tp_iternext;
+      index = 0; __pyx_t_7 = __pyx_t_11(__pyx_t_8); if (unlikely(!__pyx_t_7)) goto __pyx_L13_unpacking_failed;
+      __Pyx_GOTREF(__pyx_t_7);
+      index = 1; __pyx_t_6 = __pyx_t_11(__pyx_t_8); if (unlikely(!__pyx_t_6)) goto __pyx_L13_unpacking_failed;
+      __Pyx_GOTREF(__pyx_t_6);
+      index = 2; __pyx_t_1 = __pyx_t_11(__pyx_t_8); if (unlikely(!__pyx_t_1)) goto __pyx_L13_unpacking_failed;
+      __Pyx_GOTREF(__pyx_t_1);
+      if (__Pyx_IternextUnpackEndCheck(__pyx_t_11(__pyx_t_8), 3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 62; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_11 = NULL;
+      __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+      goto __pyx_L14_unpacking_done;
+      __pyx_L13_unpacking_failed:;
+      __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+      __pyx_t_11 = NULL;
+      if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
+      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 62; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_L14_unpacking_done:;
+    }
+    __pyx_t_21 = __Pyx_PyInt_As_int(__pyx_t_7); if (unlikely((__pyx_t_21 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 62; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+    __pyx_t_22 = __Pyx_PyInt_As_int(__pyx_t_6); if (unlikely((__pyx_t_22 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 62; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+    __pyx_t_23 = __pyx_PyFloat_AsFloat(__pyx_t_1); if (unlikely((__pyx_t_23 == (float)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 62; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    __pyx_v_s = __pyx_t_21;
+    __pyx_v_e = __pyx_t_22;
+    __pyx_v_val = __pyx_t_23;
+
+    /* "bx/bbi/bigwig_file.pyx":63
+ *         # much faster.
+ *         for s, e, val in sevs:
+ *             if s < self.start:             # <<<<<<<<<<<<<<
+ *                 s = self.start
+ *             if e > self.end:
+ */
+    __pyx_t_24 = ((__pyx_v_s < __pyx_v_self->start) != 0);
+    if (__pyx_t_24) {
+
+      /* "bx/bbi/bigwig_file.pyx":64
+ *         for s, e, val in sevs:
+ *             if s < self.start:
+ *                 s = self.start             # <<<<<<<<<<<<<<
+ *             if e > self.end:
+ *                 e = self.end
+ */
+      __pyx_t_16 = __pyx_v_self->start;
+      __pyx_v_s = __pyx_t_16;
+      goto __pyx_L15;
+    }
+    __pyx_L15:;
+
+    /* "bx/bbi/bigwig_file.pyx":65
+ *             if s < self.start:
+ *                 s = self.start
+ *             if e > self.end:             # <<<<<<<<<<<<<<
+ *                 e = self.end
+ *             if s >= e:
+ */
+    __pyx_t_24 = ((__pyx_v_e > __pyx_v_self->end) != 0);
+    if (__pyx_t_24) {
+
+      /* "bx/bbi/bigwig_file.pyx":66
+ *                 s = self.start
+ *             if e > self.end:
+ *                 e = self.end             # <<<<<<<<<<<<<<
+ *             if s >= e:
+ *                 continue
+ */
+      __pyx_t_16 = __pyx_v_self->end;
+      __pyx_v_e = __pyx_t_16;
+      goto __pyx_L16;
+    }
+    __pyx_L16:;
+
+    /* "bx/bbi/bigwig_file.pyx":67
+ *             if e > self.end:
+ *                 e = self.end
+ *             if s >= e:             # <<<<<<<<<<<<<<
+ *                 continue
+ *             self.handle_interval_value( s, e, val )
+ */
+    __pyx_t_24 = ((__pyx_v_s >= __pyx_v_e) != 0);
+    if (__pyx_t_24) {
+
+      /* "bx/bbi/bigwig_file.pyx":68
+ *                 e = self.end
+ *             if s >= e:
+ *                 continue             # <<<<<<<<<<<<<<
+ *             self.handle_interval_value( s, e, val )
+ * 
+ */
+      goto __pyx_L11_continue;
+    }
+
+    /* "bx/bbi/bigwig_file.pyx":69
+ *             if s >= e:
+ *                 continue
+ *             self.handle_interval_value( s, e, val )             # <<<<<<<<<<<<<<
+ * 
+ *     cdef handle_interval_value( self, bits32 s, bits32 e, float val ):
+ */
+    __pyx_t_9 = ((struct __pyx_vtabstruct_2bx_3bbi_11bigwig_file_BigWigBlockHandler *)__pyx_v_self->__pyx_base.__pyx_vtab)->handle_interval_value(__pyx_v_self, __pyx_v_s, __pyx_v_e, __pyx_v_val); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 69; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_9);
+    __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+
+    /* "bx/bbi/bigwig_file.pyx":62
+ *         # TODO: change handle_interval to take a numpy array and this will be
+ *         # much faster.
+ *         for s, e, val in sevs:             # <<<<<<<<<<<<<<
+ *             if s < self.start:
+ *                 s = self.start
+ */
+    __pyx_L11_continue:;
+  }
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+  /* "bx/bbi/bigwig_file.pyx":38
+ *         self.start = start
+ *         self.end = end
+ *     cdef handle_block( self, str block_data, BBIFile bbi_file ):             # <<<<<<<<<<<<<<
+ *         cdef bits32 b_chrom_id, b_start, b_end, b_valid_count
+ *         cdef bits32 b_item_step, b_item_span
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_XDECREF(__pyx_t_5);
+  __Pyx_XDECREF(__pyx_t_6);
+  __Pyx_XDECREF(__pyx_t_7);
+  __Pyx_XDECREF(__pyx_t_8);
+  __Pyx_XDECREF(__pyx_t_9);
+  __Pyx_XDECREF(__pyx_t_10);
+  __Pyx_AddTraceback("bx.bbi.bigwig_file.BigWigBlockHandler.handle_block", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_block_reader);
+  __Pyx_XDECREF(__pyx_v__);
+  __Pyx_XDECREF(__pyx_v_sevs);
+  __Pyx_XDECREF(__pyx_v_svs);
+  __Pyx_XDECREF(__pyx_v_vs);
+  __Pyx_XDECREF(__pyx_v_v);
+  __Pyx_XDECREF(__pyx_v_i);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bbi/bigwig_file.pyx":71
+ *             self.handle_interval_value( s, e, val )
+ * 
+ *     cdef handle_interval_value( self, bits32 s, bits32 e, float val ):             # <<<<<<<<<<<<<<
+ *         pass
+ * 
+ */
+
+static PyObject *__pyx_f_2bx_3bbi_11bigwig_file_18BigWigBlockHandler_handle_interval_value(CYTHON_UNUSED struct __pyx_obj_2bx_3bbi_11bigwig_file_BigWigBlockHandler *__pyx_v_self, CYTHON_UNUSED __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_s, CYTHON_UNUSED __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_e, CYTHON_UNUSED float __pyx_v_val) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("handle_interval_value", 0);
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bbi/bigwig_file.pyx":79
+ *     """
+ *     cdef SummarizedData sd
+ *     def __init__( self, bits32 start, bits32 end, int summary_size ):             # <<<<<<<<<<<<<<
+ *         BigWigBlockHandler.__init__( self, start, end )
+ *         # What we will load into
+ */
+
+/* Python wrapper */
+static int __pyx_pw_2bx_3bbi_11bigwig_file_23SummarizingBlockHandler_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static int __pyx_pw_2bx_3bbi_11bigwig_file_23SummarizingBlockHandler_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_start;
+  __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_end;
+  int __pyx_v_summary_size;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__init__ (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_start,&__pyx_n_s_end,&__pyx_n_s_summary_size,0};
+    PyObject* values[3] = {0,0,0};
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_start)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_end)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("__init__", 1, 3, 3, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 79; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+        case  2:
+        if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_summary_size)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("__init__", 1, 3, 3, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 79; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 79; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else if (PyTuple_GET_SIZE(__pyx_args) != 3) {
+      goto __pyx_L5_argtuple_error;
+    } else {
+      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+      values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+    }
+    __pyx_v_start = __Pyx_PyInt_As_unsigned_int(values[0]); if (unlikely((__pyx_v_start == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 79; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_end = __Pyx_PyInt_As_unsigned_int(values[1]); if (unlikely((__pyx_v_end == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 79; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_summary_size = __Pyx_PyInt_As_int(values[2]); if (unlikely((__pyx_v_summary_size == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 79; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("__init__", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 79; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.bbi.bigwig_file.SummarizingBlockHandler.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return -1;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_3bbi_11bigwig_file_23SummarizingBlockHandler___init__(((struct __pyx_obj_2bx_3bbi_11bigwig_file_SummarizingBlockHandler *)__pyx_v_self), __pyx_v_start, __pyx_v_end, __pyx_v_summary_size);
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_2bx_3bbi_11bigwig_file_23SummarizingBlockHandler___init__(struct __pyx_obj_2bx_3bbi_11bigwig_file_SummarizingBlockHandler *__pyx_v_self, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_start, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_end, int __pyx_v_summary_size) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  PyObject *__pyx_t_5 = NULL;
+  Py_ssize_t __pyx_t_6;
+  PyObject *__pyx_t_7 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__init__", 0);
+
+  /* "bx/bbi/bigwig_file.pyx":80
+ *     cdef SummarizedData sd
+ *     def __init__( self, bits32 start, bits32 end, int summary_size ):
+ *         BigWigBlockHandler.__init__( self, start, end )             # <<<<<<<<<<<<<<
+ *         # What we will load into
+ *         self.sd = SummarizedData( start, end, summary_size )
+ */
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(((PyObject *)((PyObject*)__pyx_ptype_2bx_3bbi_11bigwig_file_BigWigBlockHandler)), __pyx_n_s_init); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 80; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = __Pyx_PyInt_From_unsigned_int(__pyx_v_start); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 80; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_4 = __Pyx_PyInt_From_unsigned_int(__pyx_v_end); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 80; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __pyx_t_5 = NULL;
+  __pyx_t_6 = 0;
+  if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_2))) {
+    __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_2);
+    if (likely(__pyx_t_5)) {
+      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+      __Pyx_INCREF(__pyx_t_5);
+      __Pyx_INCREF(function);
+      __Pyx_DECREF_SET(__pyx_t_2, function);
+      __pyx_t_6 = 1;
+    }
+  }
+  __pyx_t_7 = PyTuple_New(3+__pyx_t_6); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 80; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_7);
+  if (__pyx_t_5) {
+    PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_5); __Pyx_GIVEREF(__pyx_t_5); __pyx_t_5 = NULL;
+  }
+  __Pyx_INCREF(((PyObject *)__pyx_v_self));
+  PyTuple_SET_ITEM(__pyx_t_7, 0+__pyx_t_6, ((PyObject *)__pyx_v_self));
+  __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
+  PyTuple_SET_ITEM(__pyx_t_7, 1+__pyx_t_6, __pyx_t_3);
+  __Pyx_GIVEREF(__pyx_t_3);
+  PyTuple_SET_ITEM(__pyx_t_7, 2+__pyx_t_6, __pyx_t_4);
+  __Pyx_GIVEREF(__pyx_t_4);
+  __pyx_t_3 = 0;
+  __pyx_t_4 = 0;
+  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_7, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 80; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "bx/bbi/bigwig_file.pyx":82
+ *         BigWigBlockHandler.__init__( self, start, end )
+ *         # What we will load into
+ *         self.sd = SummarizedData( start, end, summary_size )             # <<<<<<<<<<<<<<
+ *         self.sd.min_val[:] = numpy.inf
+ *         self.sd.max_val[:] = -numpy.inf
+ */
+  __pyx_t_1 = __Pyx_PyInt_From_unsigned_int(__pyx_v_start); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 82; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = __Pyx_PyInt_From_unsigned_int(__pyx_v_end); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 82; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_7 = __Pyx_PyInt_From_int(__pyx_v_summary_size); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 82; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_7);
+  __pyx_t_4 = PyTuple_New(3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 82; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_1);
+  __Pyx_GIVEREF(__pyx_t_1);
+  PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_2);
+  __Pyx_GIVEREF(__pyx_t_2);
+  PyTuple_SET_ITEM(__pyx_t_4, 2, __pyx_t_7);
+  __Pyx_GIVEREF(__pyx_t_7);
+  __pyx_t_1 = 0;
+  __pyx_t_2 = 0;
+  __pyx_t_7 = 0;
+  __pyx_t_7 = __Pyx_PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_2bx_3bbi_8bbi_file_SummarizedData)), __pyx_t_4, NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 82; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_7);
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  __Pyx_GIVEREF(__pyx_t_7);
+  __Pyx_GOTREF(__pyx_v_self->sd);
+  __Pyx_DECREF(((PyObject *)__pyx_v_self->sd));
+  __pyx_v_self->sd = ((struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData *)__pyx_t_7);
+  __pyx_t_7 = 0;
+
+  /* "bx/bbi/bigwig_file.pyx":83
+ *         # What we will load into
+ *         self.sd = SummarizedData( start, end, summary_size )
+ *         self.sd.min_val[:] = numpy.inf             # <<<<<<<<<<<<<<
+ *         self.sd.max_val[:] = -numpy.inf
+ * 
+ */
+  __pyx_t_7 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 83; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_7);
+  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_inf); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 83; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+  if (__Pyx_PyObject_SetSlice(((PyObject *)__pyx_v_self->sd->min_val), __pyx_t_4, 0, 0, NULL, NULL, &__pyx_slice__2, 0, 0, 1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 83; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+
+  /* "bx/bbi/bigwig_file.pyx":84
+ *         self.sd = SummarizedData( start, end, summary_size )
+ *         self.sd.min_val[:] = numpy.inf
+ *         self.sd.max_val[:] = -numpy.inf             # <<<<<<<<<<<<<<
+ * 
+ *     cdef inline handle_interval_value( self, bits32 s, bits32 e, float val ):
+ */
+  __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 84; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_inf); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 84; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_7);
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  __pyx_t_4 = PyNumber_Negative(__pyx_t_7); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 84; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+  if (__Pyx_PyObject_SetSlice(((PyObject *)__pyx_v_self->sd->max_val), __pyx_t_4, 0, 0, NULL, NULL, &__pyx_slice__3, 0, 0, 1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 84; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+
+  /* "bx/bbi/bigwig_file.pyx":79
+ *     """
+ *     cdef SummarizedData sd
+ *     def __init__( self, bits32 start, bits32 end, int summary_size ):             # <<<<<<<<<<<<<<
+ *         BigWigBlockHandler.__init__( self, start, end )
+ *         # What we will load into
+ */
+
+  /* function exit code */
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_XDECREF(__pyx_t_5);
+  __Pyx_XDECREF(__pyx_t_7);
+  __Pyx_AddTraceback("bx.bbi.bigwig_file.SummarizingBlockHandler.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = -1;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bbi/bigwig_file.pyx":86
+ *         self.sd.max_val[:] = -numpy.inf
+ * 
+ *     cdef inline handle_interval_value( self, bits32 s, bits32 e, float val ):             # <<<<<<<<<<<<<<
+ *         self.sd.accumulate_interval_value( s, e, val )
+ * 
+ */
+
+static PyObject *__pyx_f_2bx_3bbi_11bigwig_file_23SummarizingBlockHandler_handle_interval_value(struct __pyx_obj_2bx_3bbi_11bigwig_file_SummarizingBlockHandler *__pyx_v_self, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_s, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_e, float __pyx_v_val) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("handle_interval_value", 0);
+
+  /* "bx/bbi/bigwig_file.pyx":87
+ * 
+ *     cdef inline handle_interval_value( self, bits32 s, bits32 e, float val ):
+ *         self.sd.accumulate_interval_value( s, e, val )             # <<<<<<<<<<<<<<
+ * 
+ * cdef class IntervalAccumulatingBlockHandler( BigWigBlockHandler ):
+ */
+  __pyx_t_1 = ((struct __pyx_vtabstruct_2bx_3bbi_8bbi_file_SummarizedData *)__pyx_v_self->sd->__pyx_vtab)->accumulate_interval_value(__pyx_v_self->sd, __pyx_v_s, __pyx_v_e, __pyx_v_val); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 87; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "bx/bbi/bigwig_file.pyx":86
+ *         self.sd.max_val[:] = -numpy.inf
+ * 
+ *     cdef inline handle_interval_value( self, bits32 s, bits32 e, float val ):             # <<<<<<<<<<<<<<
+ *         self.sd.accumulate_interval_value( s, e, val )
+ * 
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("bx.bbi.bigwig_file.SummarizingBlockHandler.handle_interval_value", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bbi/bigwig_file.pyx":94
+ *     Accumulates intervals into a list of intervals with values
+ *     """
+ *     def __init__( self, bits32 start, bits32 end ):             # <<<<<<<<<<<<<<
+ *         BigWigBlockHandler.__init__( self, start, end )
+ *         self.intervals = []
+ */
+
+/* Python wrapper */
+static int __pyx_pw_2bx_3bbi_11bigwig_file_32IntervalAccumulatingBlockHandler_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static int __pyx_pw_2bx_3bbi_11bigwig_file_32IntervalAccumulatingBlockHandler_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_start;
+  __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_end;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__init__ (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_start,&__pyx_n_s_end,0};
+    PyObject* values[2] = {0,0};
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_start)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_end)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("__init__", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 94; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 94; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
+      goto __pyx_L5_argtuple_error;
+    } else {
+      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+    }
+    __pyx_v_start = __Pyx_PyInt_As_unsigned_int(values[0]); if (unlikely((__pyx_v_start == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 94; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_end = __Pyx_PyInt_As_unsigned_int(values[1]); if (unlikely((__pyx_v_end == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 94; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("__init__", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 94; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.bbi.bigwig_file.IntervalAccumulatingBlockHandler.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return -1;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_3bbi_11bigwig_file_32IntervalAccumulatingBlockHandler___init__(((struct __pyx_obj_2bx_3bbi_11bigwig_file_IntervalAccumulatingBlockHandler *)__pyx_v_self), __pyx_v_start, __pyx_v_end);
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_2bx_3bbi_11bigwig_file_32IntervalAccumulatingBlockHandler___init__(struct __pyx_obj_2bx_3bbi_11bigwig_file_IntervalAccumulatingBlockHandler *__pyx_v_self, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_start, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_end) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  PyObject *__pyx_t_5 = NULL;
+  Py_ssize_t __pyx_t_6;
+  PyObject *__pyx_t_7 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__init__", 0);
+
+  /* "bx/bbi/bigwig_file.pyx":95
+ *     """
+ *     def __init__( self, bits32 start, bits32 end ):
+ *         BigWigBlockHandler.__init__( self, start, end )             # <<<<<<<<<<<<<<
+ *         self.intervals = []
+ * 
+ */
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(((PyObject *)((PyObject*)__pyx_ptype_2bx_3bbi_11bigwig_file_BigWigBlockHandler)), __pyx_n_s_init); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 95; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = __Pyx_PyInt_From_unsigned_int(__pyx_v_start); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 95; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_4 = __Pyx_PyInt_From_unsigned_int(__pyx_v_end); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 95; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __pyx_t_5 = NULL;
+  __pyx_t_6 = 0;
+  if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_2))) {
+    __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_2);
+    if (likely(__pyx_t_5)) {
+      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+      __Pyx_INCREF(__pyx_t_5);
+      __Pyx_INCREF(function);
+      __Pyx_DECREF_SET(__pyx_t_2, function);
+      __pyx_t_6 = 1;
+    }
+  }
+  __pyx_t_7 = PyTuple_New(3+__pyx_t_6); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 95; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_7);
+  if (__pyx_t_5) {
+    PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_5); __Pyx_GIVEREF(__pyx_t_5); __pyx_t_5 = NULL;
+  }
+  __Pyx_INCREF(((PyObject *)__pyx_v_self));
+  PyTuple_SET_ITEM(__pyx_t_7, 0+__pyx_t_6, ((PyObject *)__pyx_v_self));
+  __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
+  PyTuple_SET_ITEM(__pyx_t_7, 1+__pyx_t_6, __pyx_t_3);
+  __Pyx_GIVEREF(__pyx_t_3);
+  PyTuple_SET_ITEM(__pyx_t_7, 2+__pyx_t_6, __pyx_t_4);
+  __Pyx_GIVEREF(__pyx_t_4);
+  __pyx_t_3 = 0;
+  __pyx_t_4 = 0;
+  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_7, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 95; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "bx/bbi/bigwig_file.pyx":96
+ *     def __init__( self, bits32 start, bits32 end ):
+ *         BigWigBlockHandler.__init__( self, start, end )
+ *         self.intervals = []             # <<<<<<<<<<<<<<
+ * 
+ *     cdef handle_interval_value( self, bits32 s, bits32 e, float val ):
+ */
+  __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 96; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_GIVEREF(__pyx_t_1);
+  __Pyx_GOTREF(__pyx_v_self->intervals);
+  __Pyx_DECREF(__pyx_v_self->intervals);
+  __pyx_v_self->intervals = ((PyObject*)__pyx_t_1);
+  __pyx_t_1 = 0;
+
+  /* "bx/bbi/bigwig_file.pyx":94
+ *     Accumulates intervals into a list of intervals with values
+ *     """
+ *     def __init__( self, bits32 start, bits32 end ):             # <<<<<<<<<<<<<<
+ *         BigWigBlockHandler.__init__( self, start, end )
+ *         self.intervals = []
+ */
+
+  /* function exit code */
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_XDECREF(__pyx_t_5);
+  __Pyx_XDECREF(__pyx_t_7);
+  __Pyx_AddTraceback("bx.bbi.bigwig_file.IntervalAccumulatingBlockHandler.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = -1;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bbi/bigwig_file.pyx":98
+ *         self.intervals = []
+ * 
+ *     cdef handle_interval_value( self, bits32 s, bits32 e, float val ):             # <<<<<<<<<<<<<<
+ *         self.intervals.append( ( s, e, val ) )
+ * 
+ */
+
+static PyObject *__pyx_f_2bx_3bbi_11bigwig_file_32IntervalAccumulatingBlockHandler_handle_interval_value(struct __pyx_obj_2bx_3bbi_11bigwig_file_IntervalAccumulatingBlockHandler *__pyx_v_self, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_s, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_e, float __pyx_v_val) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  int __pyx_t_5;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("handle_interval_value", 0);
+
+  /* "bx/bbi/bigwig_file.pyx":99
+ * 
+ *     cdef handle_interval_value( self, bits32 s, bits32 e, float val ):
+ *         self.intervals.append( ( s, e, val ) )             # <<<<<<<<<<<<<<
+ * 
+ * cdef class ArrayAccumulatingBlockHandler( BigWigBlockHandler ):
+ */
+  if (unlikely(__pyx_v_self->intervals == Py_None)) {
+    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "append");
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 99; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  __pyx_t_1 = __Pyx_PyInt_From_unsigned_int(__pyx_v_s); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 99; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = __Pyx_PyInt_From_unsigned_int(__pyx_v_e); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 99; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = PyFloat_FromDouble(__pyx_v_val); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 99; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_4 = PyTuple_New(3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 99; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_1);
+  __Pyx_GIVEREF(__pyx_t_1);
+  PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_2);
+  __Pyx_GIVEREF(__pyx_t_2);
+  PyTuple_SET_ITEM(__pyx_t_4, 2, __pyx_t_3);
+  __Pyx_GIVEREF(__pyx_t_3);
+  __pyx_t_1 = 0;
+  __pyx_t_2 = 0;
+  __pyx_t_3 = 0;
+  __pyx_t_5 = __Pyx_PyList_Append(__pyx_v_self->intervals, __pyx_t_4); if (unlikely(__pyx_t_5 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 99; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+
+  /* "bx/bbi/bigwig_file.pyx":98
+ *         self.intervals = []
+ * 
+ *     cdef handle_interval_value( self, bits32 s, bits32 e, float val ):             # <<<<<<<<<<<<<<
+ *         self.intervals.append( ( s, e, val ) )
+ * 
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_AddTraceback("bx.bbi.bigwig_file.IntervalAccumulatingBlockHandler.handle_interval_value", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bbi/bigwig_file.pyx":106
+ *     """
+ *     cdef numpy.ndarray array
+ *     def __init__( self, bits32 start, bits32 end ):             # <<<<<<<<<<<<<<
+ *         BigWigBlockHandler.__init__( self, start, end )
+ *         self.array = numpy.zeros( end - start, dtype=numpy.float32 )
+ */
+
+/* Python wrapper */
+static int __pyx_pw_2bx_3bbi_11bigwig_file_29ArrayAccumulatingBlockHandler_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static int __pyx_pw_2bx_3bbi_11bigwig_file_29ArrayAccumulatingBlockHandler_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_start;
+  __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_end;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__init__ (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_start,&__pyx_n_s_end,0};
+    PyObject* values[2] = {0,0};
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_start)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_end)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("__init__", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 106; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 106; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
+      goto __pyx_L5_argtuple_error;
+    } else {
+      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+    }
+    __pyx_v_start = __Pyx_PyInt_As_unsigned_int(values[0]); if (unlikely((__pyx_v_start == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 106; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_end = __Pyx_PyInt_As_unsigned_int(values[1]); if (unlikely((__pyx_v_end == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 106; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("__init__", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 106; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.bbi.bigwig_file.ArrayAccumulatingBlockHandler.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return -1;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_3bbi_11bigwig_file_29ArrayAccumulatingBlockHandler___init__(((struct __pyx_obj_2bx_3bbi_11bigwig_file_ArrayAccumulatingBlockHandler *)__pyx_v_self), __pyx_v_start, __pyx_v_end);
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_2bx_3bbi_11bigwig_file_29ArrayAccumulatingBlockHandler___init__(struct __pyx_obj_2bx_3bbi_11bigwig_file_ArrayAccumulatingBlockHandler *__pyx_v_self, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_start, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_end) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  PyObject *__pyx_t_5 = NULL;
+  Py_ssize_t __pyx_t_6;
+  PyObject *__pyx_t_7 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__init__", 0);
+
+  /* "bx/bbi/bigwig_file.pyx":107
+ *     cdef numpy.ndarray array
+ *     def __init__( self, bits32 start, bits32 end ):
+ *         BigWigBlockHandler.__init__( self, start, end )             # <<<<<<<<<<<<<<
+ *         self.array = numpy.zeros( end - start, dtype=numpy.float32 )
+ *         self.array[...] = numpy.nan
+ */
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(((PyObject *)((PyObject*)__pyx_ptype_2bx_3bbi_11bigwig_file_BigWigBlockHandler)), __pyx_n_s_init); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 107; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = __Pyx_PyInt_From_unsigned_int(__pyx_v_start); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 107; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_4 = __Pyx_PyInt_From_unsigned_int(__pyx_v_end); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 107; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __pyx_t_5 = NULL;
+  __pyx_t_6 = 0;
+  if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_2))) {
+    __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_2);
+    if (likely(__pyx_t_5)) {
+      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+      __Pyx_INCREF(__pyx_t_5);
+      __Pyx_INCREF(function);
+      __Pyx_DECREF_SET(__pyx_t_2, function);
+      __pyx_t_6 = 1;
+    }
+  }
+  __pyx_t_7 = PyTuple_New(3+__pyx_t_6); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 107; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_7);
+  if (__pyx_t_5) {
+    PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_5); __Pyx_GIVEREF(__pyx_t_5); __pyx_t_5 = NULL;
+  }
+  __Pyx_INCREF(((PyObject *)__pyx_v_self));
+  PyTuple_SET_ITEM(__pyx_t_7, 0+__pyx_t_6, ((PyObject *)__pyx_v_self));
+  __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
+  PyTuple_SET_ITEM(__pyx_t_7, 1+__pyx_t_6, __pyx_t_3);
+  __Pyx_GIVEREF(__pyx_t_3);
+  PyTuple_SET_ITEM(__pyx_t_7, 2+__pyx_t_6, __pyx_t_4);
+  __Pyx_GIVEREF(__pyx_t_4);
+  __pyx_t_3 = 0;
+  __pyx_t_4 = 0;
+  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_7, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 107; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "bx/bbi/bigwig_file.pyx":108
+ *     def __init__( self, bits32 start, bits32 end ):
+ *         BigWigBlockHandler.__init__( self, start, end )
+ *         self.array = numpy.zeros( end - start, dtype=numpy.float32 )             # <<<<<<<<<<<<<<
+ *         self.array[...] = numpy.nan
+ * 
+ */
+  __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_zeros); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_1 = __Pyx_PyInt_From_unsigned_int((__pyx_v_end - __pyx_v_start)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_7 = PyTuple_New(1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_7);
+  PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_1);
+  __Pyx_GIVEREF(__pyx_t_1);
+  __pyx_t_1 = 0;
+  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_float32); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_dtype, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_7, __pyx_t_1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GIVEREF(__pyx_t_3);
+  __Pyx_GOTREF(__pyx_v_self->array);
+  __Pyx_DECREF(((PyObject *)__pyx_v_self->array));
+  __pyx_v_self->array = ((PyArrayObject *)__pyx_t_3);
+  __pyx_t_3 = 0;
+
+  /* "bx/bbi/bigwig_file.pyx":109
+ *         BigWigBlockHandler.__init__( self, start, end )
+ *         self.array = numpy.zeros( end - start, dtype=numpy.float32 )
+ *         self.array[...] = numpy.nan             # <<<<<<<<<<<<<<
+ * 
+ *     cdef handle_interval_value( self, bits32 s, bits32 e, float val ):
+ */
+  __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 109; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_nan); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 109; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  if (unlikely(PyObject_SetItem(((PyObject *)__pyx_v_self->array), Py_Ellipsis, __pyx_t_1) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 109; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "bx/bbi/bigwig_file.pyx":106
+ *     """
+ *     cdef numpy.ndarray array
+ *     def __init__( self, bits32 start, bits32 end ):             # <<<<<<<<<<<<<<
+ *         BigWigBlockHandler.__init__( self, start, end )
+ *         self.array = numpy.zeros( end - start, dtype=numpy.float32 )
+ */
+
+  /* function exit code */
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_XDECREF(__pyx_t_5);
+  __Pyx_XDECREF(__pyx_t_7);
+  __Pyx_AddTraceback("bx.bbi.bigwig_file.ArrayAccumulatingBlockHandler.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = -1;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bbi/bigwig_file.pyx":111
+ *         self.array[...] = numpy.nan
+ * 
+ *     cdef handle_interval_value( self, bits32 s, bits32 e, float val ):             # <<<<<<<<<<<<<<
+ *         #cdef numpy.ndarray[ numpy.float32_t, ndim=1 ] array = self.array
+ *         # Slicing is optimized by Cython
+ */
+
+static PyObject *__pyx_f_2bx_3bbi_11bigwig_file_29ArrayAccumulatingBlockHandler_handle_interval_value(struct __pyx_obj_2bx_3bbi_11bigwig_file_ArrayAccumulatingBlockHandler *__pyx_v_self, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_s, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_e, float __pyx_v_val) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("handle_interval_value", 0);
+
+  /* "bx/bbi/bigwig_file.pyx":114
+ *         #cdef numpy.ndarray[ numpy.float32_t, ndim=1 ] array = self.array
+ *         # Slicing is optimized by Cython
+ *         self.array[s - self.start:e - self.start] = val             # <<<<<<<<<<<<<<
+ * 
+ * cdef class BigWigFile( BBIFile ):
+ */
+  __pyx_t_1 = PyFloat_FromDouble(__pyx_v_val); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 114; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (__Pyx_PyObject_SetSlice(((PyObject *)__pyx_v_self->array), __pyx_t_1, (__pyx_v_s - __pyx_v_self->__pyx_base.start), (__pyx_v_e - __pyx_v_self->__pyx_base.start), NULL, NULL, NULL, 1, 1, 1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 114; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "bx/bbi/bigwig_file.pyx":111
+ *         self.array[...] = numpy.nan
+ * 
+ *     cdef handle_interval_value( self, bits32 s, bits32 e, float val ):             # <<<<<<<<<<<<<<
+ *         #cdef numpy.ndarray[ numpy.float32_t, ndim=1 ] array = self.array
+ *         # Slicing is optimized by Cython
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("bx.bbi.bigwig_file.ArrayAccumulatingBlockHandler.handle_interval_value", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bbi/bigwig_file.pyx":120
+ *     A "big binary indexed" file whose raw data is in wiggle format.
+ *     """
+ *     def __init__( self, file=None ):             # <<<<<<<<<<<<<<
+ *         BBIFile.__init__( self, file, big_wig_sig, "bigwig" )
+ * 
+ */
+
+/* Python wrapper */
+static int __pyx_pw_2bx_3bbi_11bigwig_file_10BigWigFile_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static int __pyx_pw_2bx_3bbi_11bigwig_file_10BigWigFile_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_file = 0;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__init__ (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_file,0};
+    PyObject* values[1] = {0};
+    values[0] = ((PyObject *)Py_None);
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_file);
+          if (value) { values[0] = value; kw_args--; }
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 120; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else {
+      switch (PyTuple_GET_SIZE(__pyx_args)) {
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+    }
+    __pyx_v_file = values[0];
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("__init__", 0, 0, 1, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 120; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.bbi.bigwig_file.BigWigFile.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return -1;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_3bbi_11bigwig_file_10BigWigFile___init__(((struct __pyx_obj_2bx_3bbi_11bigwig_file_BigWigFile *)__pyx_v_self), __pyx_v_file);
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_2bx_3bbi_11bigwig_file_10BigWigFile___init__(struct __pyx_obj_2bx_3bbi_11bigwig_file_BigWigFile *__pyx_v_self, PyObject *__pyx_v_file) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  Py_ssize_t __pyx_t_4;
+  PyObject *__pyx_t_5 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__init__", 0);
+
+  /* "bx/bbi/bigwig_file.pyx":121
+ *     """
+ *     def __init__( self, file=None ):
+ *         BBIFile.__init__( self, file, big_wig_sig, "bigwig" )             # <<<<<<<<<<<<<<
+ * 
+ *     cdef _summarize_from_full( self, bits32 chrom_id, bits32 start, bits32 end, int summary_size ):
+ */
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(((PyObject *)((PyObject*)__pyx_ptype_2bx_3bbi_8bbi_file_BBIFile)), __pyx_n_s_init); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 121; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = NULL;
+  __pyx_t_4 = 0;
+  if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_2))) {
+    __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2);
+    if (likely(__pyx_t_3)) {
+      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+      __Pyx_INCREF(__pyx_t_3);
+      __Pyx_INCREF(function);
+      __Pyx_DECREF_SET(__pyx_t_2, function);
+      __pyx_t_4 = 1;
+    }
+  }
+  __pyx_t_5 = PyTuple_New(4+__pyx_t_4); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 121; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  if (__pyx_t_3) {
+    PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_3); __Pyx_GIVEREF(__pyx_t_3); __pyx_t_3 = NULL;
+  }
+  __Pyx_INCREF(((PyObject *)__pyx_v_self));
+  PyTuple_SET_ITEM(__pyx_t_5, 0+__pyx_t_4, ((PyObject *)__pyx_v_self));
+  __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
+  __Pyx_INCREF(__pyx_v_file);
+  PyTuple_SET_ITEM(__pyx_t_5, 1+__pyx_t_4, __pyx_v_file);
+  __Pyx_GIVEREF(__pyx_v_file);
+  __Pyx_INCREF(__pyx_int_2291137574);
+  PyTuple_SET_ITEM(__pyx_t_5, 2+__pyx_t_4, __pyx_int_2291137574);
+  __Pyx_GIVEREF(__pyx_int_2291137574);
+  __Pyx_INCREF(__pyx_n_s_bigwig);
+  PyTuple_SET_ITEM(__pyx_t_5, 3+__pyx_t_4, __pyx_n_s_bigwig);
+  __Pyx_GIVEREF(__pyx_n_s_bigwig);
+  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_5, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 121; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "bx/bbi/bigwig_file.pyx":120
+ *     A "big binary indexed" file whose raw data is in wiggle format.
+ *     """
+ *     def __init__( self, file=None ):             # <<<<<<<<<<<<<<
+ *         BBIFile.__init__( self, file, big_wig_sig, "bigwig" )
+ * 
+ */
+
+  /* function exit code */
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_5);
+  __Pyx_AddTraceback("bx.bbi.bigwig_file.BigWigFile.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = -1;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bbi/bigwig_file.pyx":123
+ *         BBIFile.__init__( self, file, big_wig_sig, "bigwig" )
+ * 
+ *     cdef _summarize_from_full( self, bits32 chrom_id, bits32 start, bits32 end, int summary_size ):             # <<<<<<<<<<<<<<
+ *         """
+ *         Create summary from full data.
+ */
+
+static PyObject *__pyx_f_2bx_3bbi_11bigwig_file_10BigWigFile__summarize_from_full(struct __pyx_obj_2bx_3bbi_11bigwig_file_BigWigFile *__pyx_v_self, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_chrom_id, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_start, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_end, int __pyx_v_summary_size) {
+  struct __pyx_obj_2bx_3bbi_11bigwig_file_SummarizingBlockHandler *__pyx_v_v = NULL;
+  long __pyx_v_i;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  int __pyx_t_5;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("_summarize_from_full", 0);
+
+  /* "bx/bbi/bigwig_file.pyx":127
+ *         Create summary from full data.
+ *         """
+ *         v = SummarizingBlockHandler( start, end, summary_size )             # <<<<<<<<<<<<<<
+ *         self.visit_blocks_in_region( chrom_id, start, end, v )
+ *         # Round valid count, in place
+ */
+  __pyx_t_1 = __Pyx_PyInt_From_unsigned_int(__pyx_v_start); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = __Pyx_PyInt_From_unsigned_int(__pyx_v_end); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_summary_size); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_4 = PyTuple_New(3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_1);
+  __Pyx_GIVEREF(__pyx_t_1);
+  PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_2);
+  __Pyx_GIVEREF(__pyx_t_2);
+  PyTuple_SET_ITEM(__pyx_t_4, 2, __pyx_t_3);
+  __Pyx_GIVEREF(__pyx_t_3);
+  __pyx_t_1 = 0;
+  __pyx_t_2 = 0;
+  __pyx_t_3 = 0;
+  __pyx_t_3 = __Pyx_PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_2bx_3bbi_11bigwig_file_SummarizingBlockHandler)), __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  __pyx_v_v = ((struct __pyx_obj_2bx_3bbi_11bigwig_file_SummarizingBlockHandler *)__pyx_t_3);
+  __pyx_t_3 = 0;
+
+  /* "bx/bbi/bigwig_file.pyx":128
+ *         """
+ *         v = SummarizingBlockHandler( start, end, summary_size )
+ *         self.visit_blocks_in_region( chrom_id, start, end, v )             # <<<<<<<<<<<<<<
+ *         # Round valid count, in place
+ *         for i from 0 <= i < summary_size:
+ */
+  __pyx_t_3 = ((struct __pyx_vtabstruct_2bx_3bbi_11bigwig_file_BigWigFile *)__pyx_v_self->__pyx_base.__pyx_vtab)->__pyx_base.visit_blocks_in_region(((struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *)__pyx_v_self), __pyx_v_chrom_id, __pyx_v_start, __pyx_v_end, ((struct __pyx_obj_2bx_3bbi_8bbi_file_BlockHandler *)__pyx_v_v)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 128; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+  /* "bx/bbi/bigwig_file.pyx":130
+ *         self.visit_blocks_in_region( chrom_id, start, end, v )
+ *         # Round valid count, in place
+ *         for i from 0 <= i < summary_size:             # <<<<<<<<<<<<<<
+ *             v.sd.valid_count[i] = round( v.sd.valid_count[i] )
+ *         return v.sd
+ */
+  __pyx_t_5 = __pyx_v_summary_size;
+  for (__pyx_v_i = 0; __pyx_v_i < __pyx_t_5; __pyx_v_i++) {
+
+    /* "bx/bbi/bigwig_file.pyx":131
+ *         # Round valid count, in place
+ *         for i from 0 <= i < summary_size:
+ *             v.sd.valid_count[i] = round( v.sd.valid_count[i] )             # <<<<<<<<<<<<<<
+ *         return v.sd
+ * 
+ */
+    __pyx_t_3 = __Pyx_GetItemInt(((PyObject *)__pyx_v_v->sd->valid_count), __pyx_v_i, long, 1, __Pyx_PyInt_From_long, 0, 1, 1); if (unlikely(__pyx_t_3 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 131; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+    __Pyx_GOTREF(__pyx_t_3);
+    __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 131; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
+    __Pyx_GIVEREF(__pyx_t_3);
+    __pyx_t_3 = 0;
+    __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_round, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 131; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    if (unlikely(__Pyx_SetItemInt(((PyObject *)__pyx_v_v->sd->valid_count), __pyx_v_i, __pyx_t_3, long, 1, __Pyx_PyInt_From_long, 0, 1, 1) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 131; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  }
+
+  /* "bx/bbi/bigwig_file.pyx":132
+ *         for i from 0 <= i < summary_size:
+ *             v.sd.valid_count[i] = round( v.sd.valid_count[i] )
+ *         return v.sd             # <<<<<<<<<<<<<<
+ * 
+ *     cpdef get( self, char * chrom, bits32 start, bits32 end ):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __Pyx_INCREF(((PyObject *)__pyx_v_v->sd));
+  __pyx_r = ((PyObject *)__pyx_v_v->sd);
+  goto __pyx_L0;
+
+  /* "bx/bbi/bigwig_file.pyx":123
+ *         BBIFile.__init__( self, file, big_wig_sig, "bigwig" )
+ * 
+ *     cdef _summarize_from_full( self, bits32 chrom_id, bits32 start, bits32 end, int summary_size ):             # <<<<<<<<<<<<<<
+ *         """
+ *         Create summary from full data.
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_AddTraceback("bx.bbi.bigwig_file.BigWigFile._summarize_from_full", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XDECREF((PyObject *)__pyx_v_v);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bbi/bigwig_file.pyx":134
+ *         return v.sd
+ * 
+ *     cpdef get( self, char * chrom, bits32 start, bits32 end ):             # <<<<<<<<<<<<<<
+ *         """
+ *         Gets all data points over the regions `chrom`:`start`-`end`.
+ */
+
+static PyObject *__pyx_pw_2bx_3bbi_11bigwig_file_10BigWigFile_3get(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyObject *__pyx_f_2bx_3bbi_11bigwig_file_10BigWigFile_get(struct __pyx_obj_2bx_3bbi_11bigwig_file_BigWigFile *__pyx_v_self, char *__pyx_v_chrom, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_start, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_end, int __pyx_skip_dispatch) {
+  PyObject *__pyx_v_chrom_id = NULL;
+  CYTHON_UNUSED PyObject *__pyx_v_chrom_size = NULL;
+  struct __pyx_obj_2bx_3bbi_11bigwig_file_IntervalAccumulatingBlockHandler *__pyx_v_v = NULL;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  PyObject *__pyx_t_5 = NULL;
+  PyObject *__pyx_t_6 = NULL;
+  PyObject *__pyx_t_7 = NULL;
+  Py_ssize_t __pyx_t_8;
+  PyObject *__pyx_t_9 = NULL;
+  int __pyx_t_10;
+  PyObject *(*__pyx_t_11)(PyObject *);
+  int __pyx_t_12;
+  __pyx_t_2bx_3bbi_5types_bits32 __pyx_t_13;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("get", 0);
+  /* Check if called by wrapper */
+  if (unlikely(__pyx_skip_dispatch)) ;
+  /* Check if overridden in Python */
+  else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
+    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_get); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 134; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_2bx_3bbi_11bigwig_file_10BigWigFile_3get)) {
+      __Pyx_XDECREF(__pyx_r);
+      __pyx_t_3 = __Pyx_PyBytes_FromString(__pyx_v_chrom); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 134; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_4 = __Pyx_PyInt_From_unsigned_int(__pyx_v_start); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 134; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __pyx_t_5 = __Pyx_PyInt_From_unsigned_int(__pyx_v_end); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 134; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_5);
+      __Pyx_INCREF(__pyx_t_1);
+      __pyx_t_6 = __pyx_t_1; __pyx_t_7 = NULL;
+      __pyx_t_8 = 0;
+      if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_6))) {
+        __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_6);
+        if (likely(__pyx_t_7)) {
+          PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6);
+          __Pyx_INCREF(__pyx_t_7);
+          __Pyx_INCREF(function);
+          __Pyx_DECREF_SET(__pyx_t_6, function);
+          __pyx_t_8 = 1;
+        }
+      }
+      __pyx_t_9 = PyTuple_New(3+__pyx_t_8); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 134; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_9);
+      if (__pyx_t_7) {
+        PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_7); __Pyx_GIVEREF(__pyx_t_7); __pyx_t_7 = NULL;
+      }
+      PyTuple_SET_ITEM(__pyx_t_9, 0+__pyx_t_8, __pyx_t_3);
+      __Pyx_GIVEREF(__pyx_t_3);
+      PyTuple_SET_ITEM(__pyx_t_9, 1+__pyx_t_8, __pyx_t_4);
+      __Pyx_GIVEREF(__pyx_t_4);
+      PyTuple_SET_ITEM(__pyx_t_9, 2+__pyx_t_8, __pyx_t_5);
+      __Pyx_GIVEREF(__pyx_t_5);
+      __pyx_t_3 = 0;
+      __pyx_t_4 = 0;
+      __pyx_t_5 = 0;
+      __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_t_9, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 134; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_2);
+      __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+      __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+      __pyx_r = __pyx_t_2;
+      __pyx_t_2 = 0;
+      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+      goto __pyx_L0;
+    }
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  }
+
+  /* "bx/bbi/bigwig_file.pyx":138
+ *         Gets all data points over the regions `chrom`:`start`-`end`.
+ *         """
+ *         if start >= end:             # <<<<<<<<<<<<<<
+ *             return None
+ *         chrom_id, chrom_size = self._get_chrom_id_and_size( chrom )
+ */
+  __pyx_t_10 = ((__pyx_v_start >= __pyx_v_end) != 0);
+  if (__pyx_t_10) {
+
+    /* "bx/bbi/bigwig_file.pyx":139
+ *         """
+ *         if start >= end:
+ *             return None             # <<<<<<<<<<<<<<
+ *         chrom_id, chrom_size = self._get_chrom_id_and_size( chrom )
+ *         if chrom_id is None:
+ */
+    __Pyx_XDECREF(__pyx_r);
+    __Pyx_INCREF(Py_None);
+    __pyx_r = Py_None;
+    goto __pyx_L0;
+  }
+
+  /* "bx/bbi/bigwig_file.pyx":140
+ *         if start >= end:
+ *             return None
+ *         chrom_id, chrom_size = self._get_chrom_id_and_size( chrom )             # <<<<<<<<<<<<<<
+ *         if chrom_id is None:
+ *             return None
+ */
+  __pyx_t_1 = ((struct __pyx_vtabstruct_2bx_3bbi_11bigwig_file_BigWigFile *)__pyx_v_self->__pyx_base.__pyx_vtab)->__pyx_base._get_chrom_id_and_size(((struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *)__pyx_v_self), __pyx_v_chrom); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 140; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if ((likely(PyTuple_CheckExact(__pyx_t_1))) || (PyList_CheckExact(__pyx_t_1))) {
+    PyObject* sequence = __pyx_t_1;
+    #if CYTHON_COMPILING_IN_CPYTHON
+    Py_ssize_t size = Py_SIZE(sequence);
+    #else
+    Py_ssize_t size = PySequence_Size(sequence);
+    #endif
+    if (unlikely(size != 2)) {
+      if (size > 2) __Pyx_RaiseTooManyValuesError(2);
+      else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
+      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 140; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+    #if CYTHON_COMPILING_IN_CPYTHON
+    if (likely(PyTuple_CheckExact(sequence))) {
+      __pyx_t_2 = PyTuple_GET_ITEM(sequence, 0); 
+      __pyx_t_6 = PyTuple_GET_ITEM(sequence, 1); 
+    } else {
+      __pyx_t_2 = PyList_GET_ITEM(sequence, 0); 
+      __pyx_t_6 = PyList_GET_ITEM(sequence, 1); 
+    }
+    __Pyx_INCREF(__pyx_t_2);
+    __Pyx_INCREF(__pyx_t_6);
+    #else
+    __pyx_t_2 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 140; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_t_6 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 140; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_6);
+    #endif
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  } else {
+    Py_ssize_t index = -1;
+    __pyx_t_9 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 140; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_9);
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    __pyx_t_11 = Py_TYPE(__pyx_t_9)->tp_iternext;
+    index = 0; __pyx_t_2 = __pyx_t_11(__pyx_t_9); if (unlikely(!__pyx_t_2)) goto __pyx_L4_unpacking_failed;
+    __Pyx_GOTREF(__pyx_t_2);
+    index = 1; __pyx_t_6 = __pyx_t_11(__pyx_t_9); if (unlikely(!__pyx_t_6)) goto __pyx_L4_unpacking_failed;
+    __Pyx_GOTREF(__pyx_t_6);
+    if (__Pyx_IternextUnpackEndCheck(__pyx_t_11(__pyx_t_9), 2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 140; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_11 = NULL;
+    __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+    goto __pyx_L5_unpacking_done;
+    __pyx_L4_unpacking_failed:;
+    __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+    __pyx_t_11 = NULL;
+    if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 140; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_L5_unpacking_done:;
+  }
+  __pyx_v_chrom_id = __pyx_t_2;
+  __pyx_t_2 = 0;
+  __pyx_v_chrom_size = __pyx_t_6;
+  __pyx_t_6 = 0;
+
+  /* "bx/bbi/bigwig_file.pyx":141
+ *             return None
+ *         chrom_id, chrom_size = self._get_chrom_id_and_size( chrom )
+ *         if chrom_id is None:             # <<<<<<<<<<<<<<
+ *             return None
+ *         v = IntervalAccumulatingBlockHandler( start, end )
+ */
+  __pyx_t_10 = (__pyx_v_chrom_id == Py_None);
+  __pyx_t_12 = (__pyx_t_10 != 0);
+  if (__pyx_t_12) {
+
+    /* "bx/bbi/bigwig_file.pyx":142
+ *         chrom_id, chrom_size = self._get_chrom_id_and_size( chrom )
+ *         if chrom_id is None:
+ *             return None             # <<<<<<<<<<<<<<
+ *         v = IntervalAccumulatingBlockHandler( start, end )
+ *         self.visit_blocks_in_region( chrom_id, start, end, v )
+ */
+    __Pyx_XDECREF(__pyx_r);
+    __Pyx_INCREF(Py_None);
+    __pyx_r = Py_None;
+    goto __pyx_L0;
+  }
+
+  /* "bx/bbi/bigwig_file.pyx":143
+ *         if chrom_id is None:
+ *             return None
+ *         v = IntervalAccumulatingBlockHandler( start, end )             # <<<<<<<<<<<<<<
+ *         self.visit_blocks_in_region( chrom_id, start, end, v )
+ *         return v.intervals
+ */
+  __pyx_t_1 = __Pyx_PyInt_From_unsigned_int(__pyx_v_start); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_6 = __Pyx_PyInt_From_unsigned_int(__pyx_v_end); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_6);
+  __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
+  __Pyx_GIVEREF(__pyx_t_1);
+  PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_6);
+  __Pyx_GIVEREF(__pyx_t_6);
+  __pyx_t_1 = 0;
+  __pyx_t_6 = 0;
+  __pyx_t_6 = __Pyx_PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_2bx_3bbi_11bigwig_file_IntervalAccumulatingBlockHandler)), __pyx_t_2, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_6);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_v_v = ((struct __pyx_obj_2bx_3bbi_11bigwig_file_IntervalAccumulatingBlockHandler *)__pyx_t_6);
+  __pyx_t_6 = 0;
+
+  /* "bx/bbi/bigwig_file.pyx":144
+ *             return None
+ *         v = IntervalAccumulatingBlockHandler( start, end )
+ *         self.visit_blocks_in_region( chrom_id, start, end, v )             # <<<<<<<<<<<<<<
+ *         return v.intervals
+ * 
+ */
+  __pyx_t_13 = __Pyx_PyInt_As_unsigned_int(__pyx_v_chrom_id); if (unlikely((__pyx_t_13 == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 144; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_6 = ((struct __pyx_vtabstruct_2bx_3bbi_11bigwig_file_BigWigFile *)__pyx_v_self->__pyx_base.__pyx_vtab)->__pyx_base.visit_blocks_in_region(((struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *)__pyx_v_self), __pyx_t_13, __pyx_v_start, __pyx_v_end, ((struct __pyx_obj_2bx_3bbi_8bbi_file_BlockHandler *)__pyx_v_v)); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 144; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_6);
+  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+
+  /* "bx/bbi/bigwig_file.pyx":145
+ *         v = IntervalAccumulatingBlockHandler( start, end )
+ *         self.visit_blocks_in_region( chrom_id, start, end, v )
+ *         return v.intervals             # <<<<<<<<<<<<<<
+ * 
+ *     cpdef get_as_array( self, char * chrom, bits32 start, bits32 end ):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __Pyx_INCREF(__pyx_v_v->intervals);
+  __pyx_r = __pyx_v_v->intervals;
+  goto __pyx_L0;
+
+  /* "bx/bbi/bigwig_file.pyx":134
+ *         return v.sd
+ * 
+ *     cpdef get( self, char * chrom, bits32 start, bits32 end ):             # <<<<<<<<<<<<<<
+ *         """
+ *         Gets all data points over the regions `chrom`:`start`-`end`.
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_XDECREF(__pyx_t_5);
+  __Pyx_XDECREF(__pyx_t_6);
+  __Pyx_XDECREF(__pyx_t_7);
+  __Pyx_XDECREF(__pyx_t_9);
+  __Pyx_AddTraceback("bx.bbi.bigwig_file.BigWigFile.get", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_chrom_id);
+  __Pyx_XDECREF(__pyx_v_chrom_size);
+  __Pyx_XDECREF((PyObject *)__pyx_v_v);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_3bbi_11bigwig_file_10BigWigFile_3get(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_2bx_3bbi_11bigwig_file_10BigWigFile_2get[] = "\n        Gets all data points over the regions `chrom`:`start`-`end`.\n        ";
+static PyObject *__pyx_pw_2bx_3bbi_11bigwig_file_10BigWigFile_3get(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  char *__pyx_v_chrom;
+  __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_start;
+  __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_end;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("get (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_chrom,&__pyx_n_s_start,&__pyx_n_s_end,0};
+    PyObject* values[3] = {0,0,0};
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_chrom)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_start)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("get", 1, 3, 3, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 134; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+        case  2:
+        if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_end)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("get", 1, 3, 3, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 134; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "get") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 134; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else if (PyTuple_GET_SIZE(__pyx_args) != 3) {
+      goto __pyx_L5_argtuple_error;
+    } else {
+      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+      values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+    }
+    __pyx_v_chrom = __Pyx_PyObject_AsString(values[0]); if (unlikely((!__pyx_v_chrom) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 134; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_start = __Pyx_PyInt_As_unsigned_int(values[1]); if (unlikely((__pyx_v_start == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 134; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_end = __Pyx_PyInt_As_unsigned_int(values[2]); if (unlikely((__pyx_v_end == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 134; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("get", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 134; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.bbi.bigwig_file.BigWigFile.get", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_3bbi_11bigwig_file_10BigWigFile_2get(((struct __pyx_obj_2bx_3bbi_11bigwig_file_BigWigFile *)__pyx_v_self), __pyx_v_chrom, __pyx_v_start, __pyx_v_end);
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_2bx_3bbi_11bigwig_file_10BigWigFile_2get(struct __pyx_obj_2bx_3bbi_11bigwig_file_BigWigFile *__pyx_v_self, char *__pyx_v_chrom, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_start, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_end) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("get", 0);
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = __pyx_f_2bx_3bbi_11bigwig_file_10BigWigFile_get(__pyx_v_self, __pyx_v_chrom, __pyx_v_start, __pyx_v_end, 1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 134; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("bx.bbi.bigwig_file.BigWigFile.get", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bbi/bigwig_file.pyx":147
+ *         return v.intervals
+ * 
+ *     cpdef get_as_array( self, char * chrom, bits32 start, bits32 end ):             # <<<<<<<<<<<<<<
+ *         """
+ *         Gets all data points over the regions `chrom`:`start`-`end`.
+ */
+
+static PyObject *__pyx_pw_2bx_3bbi_11bigwig_file_10BigWigFile_5get_as_array(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyObject *__pyx_f_2bx_3bbi_11bigwig_file_10BigWigFile_get_as_array(struct __pyx_obj_2bx_3bbi_11bigwig_file_BigWigFile *__pyx_v_self, char *__pyx_v_chrom, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_start, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_end, int __pyx_skip_dispatch) {
+  PyObject *__pyx_v_chrom_id = NULL;
+  CYTHON_UNUSED PyObject *__pyx_v_chrom_size = NULL;
+  struct __pyx_obj_2bx_3bbi_11bigwig_file_ArrayAccumulatingBlockHandler *__pyx_v_v = NULL;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  PyObject *__pyx_t_5 = NULL;
+  PyObject *__pyx_t_6 = NULL;
+  PyObject *__pyx_t_7 = NULL;
+  Py_ssize_t __pyx_t_8;
+  PyObject *__pyx_t_9 = NULL;
+  int __pyx_t_10;
+  PyObject *(*__pyx_t_11)(PyObject *);
+  int __pyx_t_12;
+  __pyx_t_2bx_3bbi_5types_bits32 __pyx_t_13;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("get_as_array", 0);
+  /* Check if called by wrapper */
+  if (unlikely(__pyx_skip_dispatch)) ;
+  /* Check if overridden in Python */
+  else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
+    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_get_as_array); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_2bx_3bbi_11bigwig_file_10BigWigFile_5get_as_array)) {
+      __Pyx_XDECREF(__pyx_r);
+      __pyx_t_3 = __Pyx_PyBytes_FromString(__pyx_v_chrom); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_4 = __Pyx_PyInt_From_unsigned_int(__pyx_v_start); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __pyx_t_5 = __Pyx_PyInt_From_unsigned_int(__pyx_v_end); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_5);
+      __Pyx_INCREF(__pyx_t_1);
+      __pyx_t_6 = __pyx_t_1; __pyx_t_7 = NULL;
+      __pyx_t_8 = 0;
+      if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_6))) {
+        __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_6);
+        if (likely(__pyx_t_7)) {
+          PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6);
+          __Pyx_INCREF(__pyx_t_7);
+          __Pyx_INCREF(function);
+          __Pyx_DECREF_SET(__pyx_t_6, function);
+          __pyx_t_8 = 1;
+        }
+      }
+      __pyx_t_9 = PyTuple_New(3+__pyx_t_8); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_9);
+      if (__pyx_t_7) {
+        PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_7); __Pyx_GIVEREF(__pyx_t_7); __pyx_t_7 = NULL;
+      }
+      PyTuple_SET_ITEM(__pyx_t_9, 0+__pyx_t_8, __pyx_t_3);
+      __Pyx_GIVEREF(__pyx_t_3);
+      PyTuple_SET_ITEM(__pyx_t_9, 1+__pyx_t_8, __pyx_t_4);
+      __Pyx_GIVEREF(__pyx_t_4);
+      PyTuple_SET_ITEM(__pyx_t_9, 2+__pyx_t_8, __pyx_t_5);
+      __Pyx_GIVEREF(__pyx_t_5);
+      __pyx_t_3 = 0;
+      __pyx_t_4 = 0;
+      __pyx_t_5 = 0;
+      __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_t_9, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_2);
+      __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+      __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+      __pyx_r = __pyx_t_2;
+      __pyx_t_2 = 0;
+      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+      goto __pyx_L0;
+    }
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  }
+
+  /* "bx/bbi/bigwig_file.pyx":151
+ *         Gets all data points over the regions `chrom`:`start`-`end`.
+ *         """
+ *         if start >= end:             # <<<<<<<<<<<<<<
+ *             return None
+ *         chrom_id, chrom_size = self._get_chrom_id_and_size( chrom )
+ */
+  __pyx_t_10 = ((__pyx_v_start >= __pyx_v_end) != 0);
+  if (__pyx_t_10) {
+
+    /* "bx/bbi/bigwig_file.pyx":152
+ *         """
+ *         if start >= end:
+ *             return None             # <<<<<<<<<<<<<<
+ *         chrom_id, chrom_size = self._get_chrom_id_and_size( chrom )
+ *         if chrom_id is None:
+ */
+    __Pyx_XDECREF(__pyx_r);
+    __Pyx_INCREF(Py_None);
+    __pyx_r = Py_None;
+    goto __pyx_L0;
+  }
+
+  /* "bx/bbi/bigwig_file.pyx":153
+ *         if start >= end:
+ *             return None
+ *         chrom_id, chrom_size = self._get_chrom_id_and_size( chrom )             # <<<<<<<<<<<<<<
+ *         if chrom_id is None:
+ *             return None
+ */
+  __pyx_t_1 = ((struct __pyx_vtabstruct_2bx_3bbi_11bigwig_file_BigWigFile *)__pyx_v_self->__pyx_base.__pyx_vtab)->__pyx_base._get_chrom_id_and_size(((struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *)__pyx_v_self), __pyx_v_chrom); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 153; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if ((likely(PyTuple_CheckExact(__pyx_t_1))) || (PyList_CheckExact(__pyx_t_1))) {
+    PyObject* sequence = __pyx_t_1;
+    #if CYTHON_COMPILING_IN_CPYTHON
+    Py_ssize_t size = Py_SIZE(sequence);
+    #else
+    Py_ssize_t size = PySequence_Size(sequence);
+    #endif
+    if (unlikely(size != 2)) {
+      if (size > 2) __Pyx_RaiseTooManyValuesError(2);
+      else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
+      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 153; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+    #if CYTHON_COMPILING_IN_CPYTHON
+    if (likely(PyTuple_CheckExact(sequence))) {
+      __pyx_t_2 = PyTuple_GET_ITEM(sequence, 0); 
+      __pyx_t_6 = PyTuple_GET_ITEM(sequence, 1); 
+    } else {
+      __pyx_t_2 = PyList_GET_ITEM(sequence, 0); 
+      __pyx_t_6 = PyList_GET_ITEM(sequence, 1); 
+    }
+    __Pyx_INCREF(__pyx_t_2);
+    __Pyx_INCREF(__pyx_t_6);
+    #else
+    __pyx_t_2 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 153; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_t_6 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 153; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_6);
+    #endif
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  } else {
+    Py_ssize_t index = -1;
+    __pyx_t_9 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 153; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_9);
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    __pyx_t_11 = Py_TYPE(__pyx_t_9)->tp_iternext;
+    index = 0; __pyx_t_2 = __pyx_t_11(__pyx_t_9); if (unlikely(!__pyx_t_2)) goto __pyx_L4_unpacking_failed;
+    __Pyx_GOTREF(__pyx_t_2);
+    index = 1; __pyx_t_6 = __pyx_t_11(__pyx_t_9); if (unlikely(!__pyx_t_6)) goto __pyx_L4_unpacking_failed;
+    __Pyx_GOTREF(__pyx_t_6);
+    if (__Pyx_IternextUnpackEndCheck(__pyx_t_11(__pyx_t_9), 2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 153; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_11 = NULL;
+    __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+    goto __pyx_L5_unpacking_done;
+    __pyx_L4_unpacking_failed:;
+    __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+    __pyx_t_11 = NULL;
+    if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 153; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_L5_unpacking_done:;
+  }
+  __pyx_v_chrom_id = __pyx_t_2;
+  __pyx_t_2 = 0;
+  __pyx_v_chrom_size = __pyx_t_6;
+  __pyx_t_6 = 0;
+
+  /* "bx/bbi/bigwig_file.pyx":154
+ *             return None
+ *         chrom_id, chrom_size = self._get_chrom_id_and_size( chrom )
+ *         if chrom_id is None:             # <<<<<<<<<<<<<<
+ *             return None
+ *         v = ArrayAccumulatingBlockHandler( start, end )
+ */
+  __pyx_t_10 = (__pyx_v_chrom_id == Py_None);
+  __pyx_t_12 = (__pyx_t_10 != 0);
+  if (__pyx_t_12) {
+
+    /* "bx/bbi/bigwig_file.pyx":155
+ *         chrom_id, chrom_size = self._get_chrom_id_and_size( chrom )
+ *         if chrom_id is None:
+ *             return None             # <<<<<<<<<<<<<<
+ *         v = ArrayAccumulatingBlockHandler( start, end )
+ *         self.visit_blocks_in_region( chrom_id, start, end, v )
+ */
+    __Pyx_XDECREF(__pyx_r);
+    __Pyx_INCREF(Py_None);
+    __pyx_r = Py_None;
+    goto __pyx_L0;
+  }
+
+  /* "bx/bbi/bigwig_file.pyx":156
+ *         if chrom_id is None:
+ *             return None
+ *         v = ArrayAccumulatingBlockHandler( start, end )             # <<<<<<<<<<<<<<
+ *         self.visit_blocks_in_region( chrom_id, start, end, v )
+ *         return v.array
+ */
+  __pyx_t_1 = __Pyx_PyInt_From_unsigned_int(__pyx_v_start); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_6 = __Pyx_PyInt_From_unsigned_int(__pyx_v_end); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_6);
+  __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
+  __Pyx_GIVEREF(__pyx_t_1);
+  PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_6);
+  __Pyx_GIVEREF(__pyx_t_6);
+  __pyx_t_1 = 0;
+  __pyx_t_6 = 0;
+  __pyx_t_6 = __Pyx_PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_2bx_3bbi_11bigwig_file_ArrayAccumulatingBlockHandler)), __pyx_t_2, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_6);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_v_v = ((struct __pyx_obj_2bx_3bbi_11bigwig_file_ArrayAccumulatingBlockHandler *)__pyx_t_6);
+  __pyx_t_6 = 0;
+
+  /* "bx/bbi/bigwig_file.pyx":157
+ *             return None
+ *         v = ArrayAccumulatingBlockHandler( start, end )
+ *         self.visit_blocks_in_region( chrom_id, start, end, v )             # <<<<<<<<<<<<<<
+ *         return v.array
+ * 
+ */
+  __pyx_t_13 = __Pyx_PyInt_As_unsigned_int(__pyx_v_chrom_id); if (unlikely((__pyx_t_13 == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 157; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_6 = ((struct __pyx_vtabstruct_2bx_3bbi_11bigwig_file_BigWigFile *)__pyx_v_self->__pyx_base.__pyx_vtab)->__pyx_base.visit_blocks_in_region(((struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *)__pyx_v_self), __pyx_t_13, __pyx_v_start, __pyx_v_end, ((struct __pyx_obj_2bx_3bbi_8bbi_file_BlockHandler *)__pyx_v_v)); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 157; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_6);
+  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+
+  /* "bx/bbi/bigwig_file.pyx":158
+ *         v = ArrayAccumulatingBlockHandler( start, end )
+ *         self.visit_blocks_in_region( chrom_id, start, end, v )
+ *         return v.array             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __Pyx_INCREF(((PyObject *)__pyx_v_v->array));
+  __pyx_r = ((PyObject *)__pyx_v_v->array);
+  goto __pyx_L0;
+
+  /* "bx/bbi/bigwig_file.pyx":147
+ *         return v.intervals
+ * 
+ *     cpdef get_as_array( self, char * chrom, bits32 start, bits32 end ):             # <<<<<<<<<<<<<<
+ *         """
+ *         Gets all data points over the regions `chrom`:`start`-`end`.
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_XDECREF(__pyx_t_5);
+  __Pyx_XDECREF(__pyx_t_6);
+  __Pyx_XDECREF(__pyx_t_7);
+  __Pyx_XDECREF(__pyx_t_9);
+  __Pyx_AddTraceback("bx.bbi.bigwig_file.BigWigFile.get_as_array", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_chrom_id);
+  __Pyx_XDECREF(__pyx_v_chrom_size);
+  __Pyx_XDECREF((PyObject *)__pyx_v_v);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_3bbi_11bigwig_file_10BigWigFile_5get_as_array(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_2bx_3bbi_11bigwig_file_10BigWigFile_4get_as_array[] = "\n        Gets all data points over the regions `chrom`:`start`-`end`.\n        ";
+static PyObject *__pyx_pw_2bx_3bbi_11bigwig_file_10BigWigFile_5get_as_array(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  char *__pyx_v_chrom;
+  __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_start;
+  __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_end;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("get_as_array (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_chrom,&__pyx_n_s_start,&__pyx_n_s_end,0};
+    PyObject* values[3] = {0,0,0};
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_chrom)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_start)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("get_as_array", 1, 3, 3, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+        case  2:
+        if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_end)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("get_as_array", 1, 3, 3, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "get_as_array") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else if (PyTuple_GET_SIZE(__pyx_args) != 3) {
+      goto __pyx_L5_argtuple_error;
+    } else {
+      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+      values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+    }
+    __pyx_v_chrom = __Pyx_PyObject_AsString(values[0]); if (unlikely((!__pyx_v_chrom) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_start = __Pyx_PyInt_As_unsigned_int(values[1]); if (unlikely((__pyx_v_start == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_end = __Pyx_PyInt_As_unsigned_int(values[2]); if (unlikely((__pyx_v_end == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("get_as_array", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.bbi.bigwig_file.BigWigFile.get_as_array", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_3bbi_11bigwig_file_10BigWigFile_4get_as_array(((struct __pyx_obj_2bx_3bbi_11bigwig_file_BigWigFile *)__pyx_v_self), __pyx_v_chrom, __pyx_v_start, __pyx_v_end);
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_2bx_3bbi_11bigwig_file_10BigWigFile_4get_as_array(struct __pyx_obj_2bx_3bbi_11bigwig_file_BigWigFile *__pyx_v_self, char *__pyx_v_chrom, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_start, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_end) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("get_as_array", 0);
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = __pyx_f_2bx_3bbi_11bigwig_file_10BigWigFile_get_as_array(__pyx_v_self, __pyx_v_chrom, __pyx_v_start, __pyx_v_end, 1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("bx.bbi.bigwig_file.BigWigFile.get_as_array", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":197
+ *         # experimental exception made for __getbuffer__ and __releasebuffer__
+ *         # -- the details of this may change.
+ *         def __getbuffer__(ndarray self, Py_buffer* info, int flags):             # <<<<<<<<<<<<<<
+ *             # This implementation of getbuffer is geared towards Cython
+ *             # requirements, and does not yet fullfill the PEP.
+ */
+
+/* Python wrapper */
+static CYTHON_UNUSED int __pyx_pw_5numpy_7ndarray_1__getbuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /*proto*/
+static CYTHON_UNUSED int __pyx_pw_5numpy_7ndarray_1__getbuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__getbuffer__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_5numpy_7ndarray___getbuffer__(((PyArrayObject *)__pyx_v_self), ((Py_buffer *)__pyx_v_info), ((int)__pyx_v_flags));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) {
+  int __pyx_v_copy_shape;
+  int __pyx_v_i;
+  int __pyx_v_ndim;
+  int __pyx_v_endian_detector;
+  int __pyx_v_little_endian;
+  int __pyx_v_t;
+  char *__pyx_v_f;
+  PyArray_Descr *__pyx_v_descr = 0;
+  int __pyx_v_offset;
+  int __pyx_v_hasfields;
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  int __pyx_t_2;
+  PyObject *__pyx_t_3 = NULL;
+  int __pyx_t_4;
+  int __pyx_t_5;
+  PyObject *__pyx_t_6 = NULL;
+  char *__pyx_t_7;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__getbuffer__", 0);
+  if (__pyx_v_info != NULL) {
+    __pyx_v_info->obj = Py_None; __Pyx_INCREF(Py_None);
+    __Pyx_GIVEREF(__pyx_v_info->obj);
+  }
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":203
+ *             # of flags
+ * 
+ *             if info == NULL: return             # <<<<<<<<<<<<<<
+ * 
+ *             cdef int copy_shape, i, ndim
+ */
+  __pyx_t_1 = ((__pyx_v_info == NULL) != 0);
+  if (__pyx_t_1) {
+    __pyx_r = 0;
+    goto __pyx_L0;
+  }
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":206
+ * 
+ *             cdef int copy_shape, i, ndim
+ *             cdef int endian_detector = 1             # <<<<<<<<<<<<<<
+ *             cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)
+ * 
+ */
+  __pyx_v_endian_detector = 1;
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":207
+ *             cdef int copy_shape, i, ndim
+ *             cdef int endian_detector = 1
+ *             cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)             # <<<<<<<<<<<<<<
+ * 
+ *             ndim = PyArray_NDIM(self)
+ */
+  __pyx_v_little_endian = ((((char *)(&__pyx_v_endian_detector))[0]) != 0);
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":209
+ *             cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)
+ * 
+ *             ndim = PyArray_NDIM(self)             # <<<<<<<<<<<<<<
+ * 
+ *             if sizeof(npy_intp) != sizeof(Py_ssize_t):
+ */
+  __pyx_v_ndim = PyArray_NDIM(__pyx_v_self);
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":211
+ *             ndim = PyArray_NDIM(self)
+ * 
+ *             if sizeof(npy_intp) != sizeof(Py_ssize_t):             # <<<<<<<<<<<<<<
+ *                 copy_shape = 1
+ *             else:
+ */
+  __pyx_t_1 = (((sizeof(npy_intp)) != (sizeof(Py_ssize_t))) != 0);
+  if (__pyx_t_1) {
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":212
+ * 
+ *             if sizeof(npy_intp) != sizeof(Py_ssize_t):
+ *                 copy_shape = 1             # <<<<<<<<<<<<<<
+ *             else:
+ *                 copy_shape = 0
+ */
+    __pyx_v_copy_shape = 1;
+    goto __pyx_L4;
+  }
+  /*else*/ {
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":214
+ *                 copy_shape = 1
+ *             else:
+ *                 copy_shape = 0             # <<<<<<<<<<<<<<
+ * 
+ *             if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)
+ */
+    __pyx_v_copy_shape = 0;
+  }
+  __pyx_L4:;
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":216
+ *                 copy_shape = 0
+ * 
+ *             if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)             # <<<<<<<<<<<<<<
+ *                 and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)):
+ *                 raise ValueError(u"ndarray is not C contiguous")
+ */
+  __pyx_t_2 = (((__pyx_v_flags & PyBUF_C_CONTIGUOUS) == PyBUF_C_CONTIGUOUS) != 0);
+  if (__pyx_t_2) {
+  } else {
+    __pyx_t_1 = __pyx_t_2;
+    goto __pyx_L6_bool_binop_done;
+  }
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":217
+ * 
+ *             if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)
+ *                 and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)):             # <<<<<<<<<<<<<<
+ *                 raise ValueError(u"ndarray is not C contiguous")
+ * 
+ */
+  __pyx_t_2 = ((!(PyArray_CHKFLAGS(__pyx_v_self, NPY_C_CONTIGUOUS) != 0)) != 0);
+  __pyx_t_1 = __pyx_t_2;
+  __pyx_L6_bool_binop_done:;
+  if (__pyx_t_1) {
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":218
+ *             if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)
+ *                 and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)):
+ *                 raise ValueError(u"ndarray is not C contiguous")             # <<<<<<<<<<<<<<
+ * 
+ *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
+ */
+    __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 218; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    {__pyx_filename = __pyx_f[1]; __pyx_lineno = 218; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":220
+ *                 raise ValueError(u"ndarray is not C contiguous")
+ * 
+ *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)             # <<<<<<<<<<<<<<
+ *                 and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)):
+ *                 raise ValueError(u"ndarray is not Fortran contiguous")
+ */
+  __pyx_t_2 = (((__pyx_v_flags & PyBUF_F_CONTIGUOUS) == PyBUF_F_CONTIGUOUS) != 0);
+  if (__pyx_t_2) {
+  } else {
+    __pyx_t_1 = __pyx_t_2;
+    goto __pyx_L9_bool_binop_done;
+  }
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":221
+ * 
+ *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
+ *                 and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)):             # <<<<<<<<<<<<<<
+ *                 raise ValueError(u"ndarray is not Fortran contiguous")
+ * 
+ */
+  __pyx_t_2 = ((!(PyArray_CHKFLAGS(__pyx_v_self, NPY_F_CONTIGUOUS) != 0)) != 0);
+  __pyx_t_1 = __pyx_t_2;
+  __pyx_L9_bool_binop_done:;
+  if (__pyx_t_1) {
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":222
+ *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
+ *                 and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)):
+ *                 raise ValueError(u"ndarray is not Fortran contiguous")             # <<<<<<<<<<<<<<
+ * 
+ *             info.buf = PyArray_DATA(self)
+ */
+    __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__5, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 222; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    {__pyx_filename = __pyx_f[1]; __pyx_lineno = 222; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":224
+ *                 raise ValueError(u"ndarray is not Fortran contiguous")
+ * 
+ *             info.buf = PyArray_DATA(self)             # <<<<<<<<<<<<<<
+ *             info.ndim = ndim
+ *             if copy_shape:
+ */
+  __pyx_v_info->buf = PyArray_DATA(__pyx_v_self);
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":225
+ * 
+ *             info.buf = PyArray_DATA(self)
+ *             info.ndim = ndim             # <<<<<<<<<<<<<<
+ *             if copy_shape:
+ *                 # Allocate new buffer for strides and shape info.
+ */
+  __pyx_v_info->ndim = __pyx_v_ndim;
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":226
+ *             info.buf = PyArray_DATA(self)
+ *             info.ndim = ndim
+ *             if copy_shape:             # <<<<<<<<<<<<<<
+ *                 # Allocate new buffer for strides and shape info.
+ *                 # This is allocated as one block, strides first.
+ */
+  __pyx_t_1 = (__pyx_v_copy_shape != 0);
+  if (__pyx_t_1) {
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":229
+ *                 # Allocate new buffer for strides and shape info.
+ *                 # This is allocated as one block, strides first.
+ *                 info.strides = <Py_ssize_t*>stdlib.malloc(sizeof(Py_ssize_t) * <size_t>ndim * 2)             # <<<<<<<<<<<<<<
+ *                 info.shape = info.strides + ndim
+ *                 for i in range(ndim):
+ */
+    __pyx_v_info->strides = ((Py_ssize_t *)malloc((((sizeof(Py_ssize_t)) * ((size_t)__pyx_v_ndim)) * 2)));
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":230
+ *                 # This is allocated as one block, strides first.
+ *                 info.strides = <Py_ssize_t*>stdlib.malloc(sizeof(Py_ssize_t) * <size_t>ndim * 2)
+ *                 info.shape = info.strides + ndim             # <<<<<<<<<<<<<<
+ *                 for i in range(ndim):
+ *                     info.strides[i] = PyArray_STRIDES(self)[i]
+ */
+    __pyx_v_info->shape = (__pyx_v_info->strides + __pyx_v_ndim);
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":231
+ *                 info.strides = <Py_ssize_t*>stdlib.malloc(sizeof(Py_ssize_t) * <size_t>ndim * 2)
+ *                 info.shape = info.strides + ndim
+ *                 for i in range(ndim):             # <<<<<<<<<<<<<<
+ *                     info.strides[i] = PyArray_STRIDES(self)[i]
+ *                     info.shape[i] = PyArray_DIMS(self)[i]
+ */
+    __pyx_t_4 = __pyx_v_ndim;
+    for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_4; __pyx_t_5+=1) {
+      __pyx_v_i = __pyx_t_5;
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":232
+ *                 info.shape = info.strides + ndim
+ *                 for i in range(ndim):
+ *                     info.strides[i] = PyArray_STRIDES(self)[i]             # <<<<<<<<<<<<<<
+ *                     info.shape[i] = PyArray_DIMS(self)[i]
+ *             else:
+ */
+      (__pyx_v_info->strides[__pyx_v_i]) = (PyArray_STRIDES(__pyx_v_self)[__pyx_v_i]);
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":233
+ *                 for i in range(ndim):
+ *                     info.strides[i] = PyArray_STRIDES(self)[i]
+ *                     info.shape[i] = PyArray_DIMS(self)[i]             # <<<<<<<<<<<<<<
+ *             else:
+ *                 info.strides = <Py_ssize_t*>PyArray_STRIDES(self)
+ */
+      (__pyx_v_info->shape[__pyx_v_i]) = (PyArray_DIMS(__pyx_v_self)[__pyx_v_i]);
+    }
+    goto __pyx_L11;
+  }
+  /*else*/ {
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":235
+ *                     info.shape[i] = PyArray_DIMS(self)[i]
+ *             else:
+ *                 info.strides = <Py_ssize_t*>PyArray_STRIDES(self)             # <<<<<<<<<<<<<<
+ *                 info.shape = <Py_ssize_t*>PyArray_DIMS(self)
+ *             info.suboffsets = NULL
+ */
+    __pyx_v_info->strides = ((Py_ssize_t *)PyArray_STRIDES(__pyx_v_self));
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":236
+ *             else:
+ *                 info.strides = <Py_ssize_t*>PyArray_STRIDES(self)
+ *                 info.shape = <Py_ssize_t*>PyArray_DIMS(self)             # <<<<<<<<<<<<<<
+ *             info.suboffsets = NULL
+ *             info.itemsize = PyArray_ITEMSIZE(self)
+ */
+    __pyx_v_info->shape = ((Py_ssize_t *)PyArray_DIMS(__pyx_v_self));
+  }
+  __pyx_L11:;
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":237
+ *                 info.strides = <Py_ssize_t*>PyArray_STRIDES(self)
+ *                 info.shape = <Py_ssize_t*>PyArray_DIMS(self)
+ *             info.suboffsets = NULL             # <<<<<<<<<<<<<<
+ *             info.itemsize = PyArray_ITEMSIZE(self)
+ *             info.readonly = not PyArray_ISWRITEABLE(self)
+ */
+  __pyx_v_info->suboffsets = NULL;
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":238
+ *                 info.shape = <Py_ssize_t*>PyArray_DIMS(self)
+ *             info.suboffsets = NULL
+ *             info.itemsize = PyArray_ITEMSIZE(self)             # <<<<<<<<<<<<<<
+ *             info.readonly = not PyArray_ISWRITEABLE(self)
+ * 
+ */
+  __pyx_v_info->itemsize = PyArray_ITEMSIZE(__pyx_v_self);
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":239
+ *             info.suboffsets = NULL
+ *             info.itemsize = PyArray_ITEMSIZE(self)
+ *             info.readonly = not PyArray_ISWRITEABLE(self)             # <<<<<<<<<<<<<<
+ * 
+ *             cdef int t
+ */
+  __pyx_v_info->readonly = (!(PyArray_ISWRITEABLE(__pyx_v_self) != 0));
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":242
+ * 
+ *             cdef int t
+ *             cdef char* f = NULL             # <<<<<<<<<<<<<<
+ *             cdef dtype descr = self.descr
+ *             cdef list stack
+ */
+  __pyx_v_f = NULL;
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":243
+ *             cdef int t
+ *             cdef char* f = NULL
+ *             cdef dtype descr = self.descr             # <<<<<<<<<<<<<<
+ *             cdef list stack
+ *             cdef int offset
+ */
+  __pyx_t_3 = ((PyObject *)__pyx_v_self->descr);
+  __Pyx_INCREF(__pyx_t_3);
+  __pyx_v_descr = ((PyArray_Descr *)__pyx_t_3);
+  __pyx_t_3 = 0;
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":247
+ *             cdef int offset
+ * 
+ *             cdef bint hasfields = PyDataType_HASFIELDS(descr)             # <<<<<<<<<<<<<<
+ * 
+ *             if not hasfields and not copy_shape:
+ */
+  __pyx_v_hasfields = PyDataType_HASFIELDS(__pyx_v_descr);
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":249
+ *             cdef bint hasfields = PyDataType_HASFIELDS(descr)
+ * 
+ *             if not hasfields and not copy_shape:             # <<<<<<<<<<<<<<
+ *                 # do not call releasebuffer
+ *                 info.obj = None
+ */
+  __pyx_t_2 = ((!(__pyx_v_hasfields != 0)) != 0);
+  if (__pyx_t_2) {
+  } else {
+    __pyx_t_1 = __pyx_t_2;
+    goto __pyx_L15_bool_binop_done;
+  }
+  __pyx_t_2 = ((!(__pyx_v_copy_shape != 0)) != 0);
+  __pyx_t_1 = __pyx_t_2;
+  __pyx_L15_bool_binop_done:;
+  if (__pyx_t_1) {
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":251
+ *             if not hasfields and not copy_shape:
+ *                 # do not call releasebuffer
+ *                 info.obj = None             # <<<<<<<<<<<<<<
+ *             else:
+ *                 # need to call releasebuffer
+ */
+    __Pyx_INCREF(Py_None);
+    __Pyx_GIVEREF(Py_None);
+    __Pyx_GOTREF(__pyx_v_info->obj);
+    __Pyx_DECREF(__pyx_v_info->obj);
+    __pyx_v_info->obj = Py_None;
+    goto __pyx_L14;
+  }
+  /*else*/ {
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":254
+ *             else:
+ *                 # need to call releasebuffer
+ *                 info.obj = self             # <<<<<<<<<<<<<<
+ * 
+ *             if not hasfields:
+ */
+    __Pyx_INCREF(((PyObject *)__pyx_v_self));
+    __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
+    __Pyx_GOTREF(__pyx_v_info->obj);
+    __Pyx_DECREF(__pyx_v_info->obj);
+    __pyx_v_info->obj = ((PyObject *)__pyx_v_self);
+  }
+  __pyx_L14:;
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":256
+ *                 info.obj = self
+ * 
+ *             if not hasfields:             # <<<<<<<<<<<<<<
+ *                 t = descr.type_num
+ *                 if ((descr.byteorder == c'>' and little_endian) or
+ */
+  __pyx_t_1 = ((!(__pyx_v_hasfields != 0)) != 0);
+  if (__pyx_t_1) {
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":257
+ * 
+ *             if not hasfields:
+ *                 t = descr.type_num             # <<<<<<<<<<<<<<
+ *                 if ((descr.byteorder == c'>' and little_endian) or
+ *                     (descr.byteorder == c'<' and not little_endian)):
+ */
+    __pyx_t_4 = __pyx_v_descr->type_num;
+    __pyx_v_t = __pyx_t_4;
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":258
+ *             if not hasfields:
+ *                 t = descr.type_num
+ *                 if ((descr.byteorder == c'>' and little_endian) or             # <<<<<<<<<<<<<<
+ *                     (descr.byteorder == c'<' and not little_endian)):
+ *                     raise ValueError(u"Non-native byte order not supported")
+ */
+    __pyx_t_2 = ((__pyx_v_descr->byteorder == '>') != 0);
+    if (!__pyx_t_2) {
+      goto __pyx_L20_next_or;
+    } else {
+    }
+    __pyx_t_2 = (__pyx_v_little_endian != 0);
+    if (!__pyx_t_2) {
+    } else {
+      __pyx_t_1 = __pyx_t_2;
+      goto __pyx_L19_bool_binop_done;
+    }
+    __pyx_L20_next_or:;
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":259
+ *                 t = descr.type_num
+ *                 if ((descr.byteorder == c'>' and little_endian) or
+ *                     (descr.byteorder == c'<' and not little_endian)):             # <<<<<<<<<<<<<<
+ *                     raise ValueError(u"Non-native byte order not supported")
+ *                 if   t == NPY_BYTE:        f = "b"
+ */
+    __pyx_t_2 = ((__pyx_v_descr->byteorder == '<') != 0);
+    if (__pyx_t_2) {
+    } else {
+      __pyx_t_1 = __pyx_t_2;
+      goto __pyx_L19_bool_binop_done;
+    }
+    __pyx_t_2 = ((!(__pyx_v_little_endian != 0)) != 0);
+    __pyx_t_1 = __pyx_t_2;
+    __pyx_L19_bool_binop_done:;
+    if (__pyx_t_1) {
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":260
+ *                 if ((descr.byteorder == c'>' and little_endian) or
+ *                     (descr.byteorder == c'<' and not little_endian)):
+ *                     raise ValueError(u"Non-native byte order not supported")             # <<<<<<<<<<<<<<
+ *                 if   t == NPY_BYTE:        f = "b"
+ *                 elif t == NPY_UBYTE:       f = "B"
+ */
+      __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__6, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 260; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      {__pyx_filename = __pyx_f[1]; __pyx_lineno = 260; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":277
+ *                 elif t == NPY_CDOUBLE:     f = "Zd"
+ *                 elif t == NPY_CLONGDOUBLE: f = "Zg"
+ *                 elif t == NPY_OBJECT:      f = "O"             # <<<<<<<<<<<<<<
+ *                 else:
+ *                     raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
+ */
+    switch (__pyx_v_t) {
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":261
+ *                     (descr.byteorder == c'<' and not little_endian)):
+ *                     raise ValueError(u"Non-native byte order not supported")
+ *                 if   t == NPY_BYTE:        f = "b"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_UBYTE:       f = "B"
+ *                 elif t == NPY_SHORT:       f = "h"
+ */
+      case NPY_BYTE:
+      __pyx_v_f = __pyx_k_b;
+      break;
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":262
+ *                     raise ValueError(u"Non-native byte order not supported")
+ *                 if   t == NPY_BYTE:        f = "b"
+ *                 elif t == NPY_UBYTE:       f = "B"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_SHORT:       f = "h"
+ *                 elif t == NPY_USHORT:      f = "H"
+ */
+      case NPY_UBYTE:
+      __pyx_v_f = __pyx_k_B;
+      break;
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":263
+ *                 if   t == NPY_BYTE:        f = "b"
+ *                 elif t == NPY_UBYTE:       f = "B"
+ *                 elif t == NPY_SHORT:       f = "h"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_USHORT:      f = "H"
+ *                 elif t == NPY_INT:         f = "i"
+ */
+      case NPY_SHORT:
+      __pyx_v_f = __pyx_k_h;
+      break;
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":264
+ *                 elif t == NPY_UBYTE:       f = "B"
+ *                 elif t == NPY_SHORT:       f = "h"
+ *                 elif t == NPY_USHORT:      f = "H"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_INT:         f = "i"
+ *                 elif t == NPY_UINT:        f = "I"
+ */
+      case NPY_USHORT:
+      __pyx_v_f = __pyx_k_H;
+      break;
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":265
+ *                 elif t == NPY_SHORT:       f = "h"
+ *                 elif t == NPY_USHORT:      f = "H"
+ *                 elif t == NPY_INT:         f = "i"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_UINT:        f = "I"
+ *                 elif t == NPY_LONG:        f = "l"
+ */
+      case NPY_INT:
+      __pyx_v_f = __pyx_k_i;
+      break;
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":266
+ *                 elif t == NPY_USHORT:      f = "H"
+ *                 elif t == NPY_INT:         f = "i"
+ *                 elif t == NPY_UINT:        f = "I"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_LONG:        f = "l"
+ *                 elif t == NPY_ULONG:       f = "L"
+ */
+      case NPY_UINT:
+      __pyx_v_f = __pyx_k_I;
+      break;
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":267
+ *                 elif t == NPY_INT:         f = "i"
+ *                 elif t == NPY_UINT:        f = "I"
+ *                 elif t == NPY_LONG:        f = "l"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_ULONG:       f = "L"
+ *                 elif t == NPY_LONGLONG:    f = "q"
+ */
+      case NPY_LONG:
+      __pyx_v_f = __pyx_k_l;
+      break;
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":268
+ *                 elif t == NPY_UINT:        f = "I"
+ *                 elif t == NPY_LONG:        f = "l"
+ *                 elif t == NPY_ULONG:       f = "L"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_LONGLONG:    f = "q"
+ *                 elif t == NPY_ULONGLONG:   f = "Q"
+ */
+      case NPY_ULONG:
+      __pyx_v_f = __pyx_k_L;
+      break;
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":269
+ *                 elif t == NPY_LONG:        f = "l"
+ *                 elif t == NPY_ULONG:       f = "L"
+ *                 elif t == NPY_LONGLONG:    f = "q"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_ULONGLONG:   f = "Q"
+ *                 elif t == NPY_FLOAT:       f = "f"
+ */
+      case NPY_LONGLONG:
+      __pyx_v_f = __pyx_k_q;
+      break;
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":270
+ *                 elif t == NPY_ULONG:       f = "L"
+ *                 elif t == NPY_LONGLONG:    f = "q"
+ *                 elif t == NPY_ULONGLONG:   f = "Q"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_FLOAT:       f = "f"
+ *                 elif t == NPY_DOUBLE:      f = "d"
+ */
+      case NPY_ULONGLONG:
+      __pyx_v_f = __pyx_k_Q;
+      break;
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":271
+ *                 elif t == NPY_LONGLONG:    f = "q"
+ *                 elif t == NPY_ULONGLONG:   f = "Q"
+ *                 elif t == NPY_FLOAT:       f = "f"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_DOUBLE:      f = "d"
+ *                 elif t == NPY_LONGDOUBLE:  f = "g"
+ */
+      case NPY_FLOAT:
+      __pyx_v_f = __pyx_k_f;
+      break;
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":272
+ *                 elif t == NPY_ULONGLONG:   f = "Q"
+ *                 elif t == NPY_FLOAT:       f = "f"
+ *                 elif t == NPY_DOUBLE:      f = "d"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_LONGDOUBLE:  f = "g"
+ *                 elif t == NPY_CFLOAT:      f = "Zf"
+ */
+      case NPY_DOUBLE:
+      __pyx_v_f = __pyx_k_d;
+      break;
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":273
+ *                 elif t == NPY_FLOAT:       f = "f"
+ *                 elif t == NPY_DOUBLE:      f = "d"
+ *                 elif t == NPY_LONGDOUBLE:  f = "g"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_CFLOAT:      f = "Zf"
+ *                 elif t == NPY_CDOUBLE:     f = "Zd"
+ */
+      case NPY_LONGDOUBLE:
+      __pyx_v_f = __pyx_k_g;
+      break;
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":274
+ *                 elif t == NPY_DOUBLE:      f = "d"
+ *                 elif t == NPY_LONGDOUBLE:  f = "g"
+ *                 elif t == NPY_CFLOAT:      f = "Zf"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_CDOUBLE:     f = "Zd"
+ *                 elif t == NPY_CLONGDOUBLE: f = "Zg"
+ */
+      case NPY_CFLOAT:
+      __pyx_v_f = __pyx_k_Zf;
+      break;
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":275
+ *                 elif t == NPY_LONGDOUBLE:  f = "g"
+ *                 elif t == NPY_CFLOAT:      f = "Zf"
+ *                 elif t == NPY_CDOUBLE:     f = "Zd"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_CLONGDOUBLE: f = "Zg"
+ *                 elif t == NPY_OBJECT:      f = "O"
+ */
+      case NPY_CDOUBLE:
+      __pyx_v_f = __pyx_k_Zd;
+      break;
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":276
+ *                 elif t == NPY_CFLOAT:      f = "Zf"
+ *                 elif t == NPY_CDOUBLE:     f = "Zd"
+ *                 elif t == NPY_CLONGDOUBLE: f = "Zg"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_OBJECT:      f = "O"
+ *                 else:
+ */
+      case NPY_CLONGDOUBLE:
+      __pyx_v_f = __pyx_k_Zg;
+      break;
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":277
+ *                 elif t == NPY_CDOUBLE:     f = "Zd"
+ *                 elif t == NPY_CLONGDOUBLE: f = "Zg"
+ *                 elif t == NPY_OBJECT:      f = "O"             # <<<<<<<<<<<<<<
+ *                 else:
+ *                     raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
+ */
+      case NPY_OBJECT:
+      __pyx_v_f = __pyx_k_O;
+      break;
+      default:
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":279
+ *                 elif t == NPY_OBJECT:      f = "O"
+ *                 else:
+ *                     raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)             # <<<<<<<<<<<<<<
+ *                 info.format = f
+ *                 return
+ */
+      __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_t); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 279; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_6 = PyUnicode_Format(__pyx_kp_u_unknown_dtype_code_in_numpy_pxd, __pyx_t_3); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 279; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_6);
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 279; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_6);
+      __Pyx_GIVEREF(__pyx_t_6);
+      __pyx_t_6 = 0;
+      __pyx_t_6 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_3, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 279; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_6);
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __Pyx_Raise(__pyx_t_6, 0, 0, 0);
+      __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+      {__pyx_filename = __pyx_f[1]; __pyx_lineno = 279; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      break;
+    }
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":280
+ *                 else:
+ *                     raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
+ *                 info.format = f             # <<<<<<<<<<<<<<
+ *                 return
+ *             else:
+ */
+    __pyx_v_info->format = __pyx_v_f;
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":281
+ *                     raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
+ *                 info.format = f
+ *                 return             # <<<<<<<<<<<<<<
+ *             else:
+ *                 info.format = <char*>stdlib.malloc(_buffer_format_string_len)
+ */
+    __pyx_r = 0;
+    goto __pyx_L0;
+  }
+  /*else*/ {
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":283
+ *                 return
+ *             else:
+ *                 info.format = <char*>stdlib.malloc(_buffer_format_string_len)             # <<<<<<<<<<<<<<
+ *                 info.format[0] = c'^' # Native data types, manual alignment
+ *                 offset = 0
+ */
+    __pyx_v_info->format = ((char *)malloc(255));
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":284
+ *             else:
+ *                 info.format = <char*>stdlib.malloc(_buffer_format_string_len)
+ *                 info.format[0] = c'^' # Native data types, manual alignment             # <<<<<<<<<<<<<<
+ *                 offset = 0
+ *                 f = _util_dtypestring(descr, info.format + 1,
+ */
+    (__pyx_v_info->format[0]) = '^';
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":285
+ *                 info.format = <char*>stdlib.malloc(_buffer_format_string_len)
+ *                 info.format[0] = c'^' # Native data types, manual alignment
+ *                 offset = 0             # <<<<<<<<<<<<<<
+ *                 f = _util_dtypestring(descr, info.format + 1,
+ *                                       info.format + _buffer_format_string_len,
+ */
+    __pyx_v_offset = 0;
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":286
+ *                 info.format[0] = c'^' # Native data types, manual alignment
+ *                 offset = 0
+ *                 f = _util_dtypestring(descr, info.format + 1,             # <<<<<<<<<<<<<<
+ *                                       info.format + _buffer_format_string_len,
+ *                                       &offset)
+ */
+    __pyx_t_7 = __pyx_f_5numpy__util_dtypestring(__pyx_v_descr, (__pyx_v_info->format + 1), (__pyx_v_info->format + 255), (&__pyx_v_offset)); if (unlikely(__pyx_t_7 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 286; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_v_f = __pyx_t_7;
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":289
+ *                                       info.format + _buffer_format_string_len,
+ *                                       &offset)
+ *                 f[0] = c'\0' # Terminate format string             # <<<<<<<<<<<<<<
+ * 
+ *         def __releasebuffer__(ndarray self, Py_buffer* info):
+ */
+    (__pyx_v_f[0]) = '\x00';
+  }
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":197
+ *         # experimental exception made for __getbuffer__ and __releasebuffer__
+ *         # -- the details of this may change.
+ *         def __getbuffer__(ndarray self, Py_buffer* info, int flags):             # <<<<<<<<<<<<<<
+ *             # This implementation of getbuffer is geared towards Cython
+ *             # requirements, and does not yet fullfill the PEP.
+ */
+
+  /* function exit code */
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_6);
+  __Pyx_AddTraceback("numpy.ndarray.__getbuffer__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = -1;
+  if (__pyx_v_info != NULL && __pyx_v_info->obj != NULL) {
+    __Pyx_GOTREF(__pyx_v_info->obj);
+    __Pyx_DECREF(__pyx_v_info->obj); __pyx_v_info->obj = NULL;
+  }
+  goto __pyx_L2;
+  __pyx_L0:;
+  if (__pyx_v_info != NULL && __pyx_v_info->obj == Py_None) {
+    __Pyx_GOTREF(Py_None);
+    __Pyx_DECREF(Py_None); __pyx_v_info->obj = NULL;
+  }
+  __pyx_L2:;
+  __Pyx_XDECREF((PyObject *)__pyx_v_descr);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":291
+ *                 f[0] = c'\0' # Terminate format string
+ * 
+ *         def __releasebuffer__(ndarray self, Py_buffer* info):             # <<<<<<<<<<<<<<
+ *             if PyArray_HASFIELDS(self):
+ *                 stdlib.free(info.format)
+ */
+
+/* Python wrapper */
+static CYTHON_UNUSED void __pyx_pw_5numpy_7ndarray_3__releasebuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info); /*proto*/
+static CYTHON_UNUSED void __pyx_pw_5numpy_7ndarray_3__releasebuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info) {
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__releasebuffer__ (wrapper)", 0);
+  __pyx_pf_5numpy_7ndarray_2__releasebuffer__(((PyArrayObject *)__pyx_v_self), ((Py_buffer *)__pyx_v_info));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+}
+
+static void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info) {
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("__releasebuffer__", 0);
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":292
+ * 
+ *         def __releasebuffer__(ndarray self, Py_buffer* info):
+ *             if PyArray_HASFIELDS(self):             # <<<<<<<<<<<<<<
+ *                 stdlib.free(info.format)
+ *             if sizeof(npy_intp) != sizeof(Py_ssize_t):
+ */
+  __pyx_t_1 = (PyArray_HASFIELDS(__pyx_v_self) != 0);
+  if (__pyx_t_1) {
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":293
+ *         def __releasebuffer__(ndarray self, Py_buffer* info):
+ *             if PyArray_HASFIELDS(self):
+ *                 stdlib.free(info.format)             # <<<<<<<<<<<<<<
+ *             if sizeof(npy_intp) != sizeof(Py_ssize_t):
+ *                 stdlib.free(info.strides)
+ */
+    free(__pyx_v_info->format);
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":294
+ *             if PyArray_HASFIELDS(self):
+ *                 stdlib.free(info.format)
+ *             if sizeof(npy_intp) != sizeof(Py_ssize_t):             # <<<<<<<<<<<<<<
+ *                 stdlib.free(info.strides)
+ *                 # info.shape was stored after info.strides in the same block
+ */
+  __pyx_t_1 = (((sizeof(npy_intp)) != (sizeof(Py_ssize_t))) != 0);
+  if (__pyx_t_1) {
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":295
+ *                 stdlib.free(info.format)
+ *             if sizeof(npy_intp) != sizeof(Py_ssize_t):
+ *                 stdlib.free(info.strides)             # <<<<<<<<<<<<<<
+ *                 # info.shape was stored after info.strides in the same block
+ * 
+ */
+    free(__pyx_v_info->strides);
+    goto __pyx_L4;
+  }
+  __pyx_L4:;
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":291
+ *                 f[0] = c'\0' # Terminate format string
+ * 
+ *         def __releasebuffer__(ndarray self, Py_buffer* info):             # <<<<<<<<<<<<<<
+ *             if PyArray_HASFIELDS(self):
+ *                 stdlib.free(info.format)
+ */
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+}
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":771
+ * ctypedef npy_cdouble     complex_t
+ * 
+ * cdef inline object PyArray_MultiIterNew1(a):             # <<<<<<<<<<<<<<
+ *     return PyArray_MultiIterNew(1, <void*>a)
+ * 
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew1(PyObject *__pyx_v_a) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("PyArray_MultiIterNew1", 0);
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":772
+ * 
+ * cdef inline object PyArray_MultiIterNew1(a):
+ *     return PyArray_MultiIterNew(1, <void*>a)             # <<<<<<<<<<<<<<
+ * 
+ * cdef inline object PyArray_MultiIterNew2(a, b):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = PyArray_MultiIterNew(1, ((void *)__pyx_v_a)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 772; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":771
+ * ctypedef npy_cdouble     complex_t
+ * 
+ * cdef inline object PyArray_MultiIterNew1(a):             # <<<<<<<<<<<<<<
+ *     return PyArray_MultiIterNew(1, <void*>a)
+ * 
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("numpy.PyArray_MultiIterNew1", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":774
+ *     return PyArray_MultiIterNew(1, <void*>a)
+ * 
+ * cdef inline object PyArray_MultiIterNew2(a, b):             # <<<<<<<<<<<<<<
+ *     return PyArray_MultiIterNew(2, <void*>a, <void*>b)
+ * 
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew2(PyObject *__pyx_v_a, PyObject *__pyx_v_b) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("PyArray_MultiIterNew2", 0);
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":775
+ * 
+ * cdef inline object PyArray_MultiIterNew2(a, b):
+ *     return PyArray_MultiIterNew(2, <void*>a, <void*>b)             # <<<<<<<<<<<<<<
+ * 
+ * cdef inline object PyArray_MultiIterNew3(a, b, c):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = PyArray_MultiIterNew(2, ((void *)__pyx_v_a), ((void *)__pyx_v_b)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 775; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":774
+ *     return PyArray_MultiIterNew(1, <void*>a)
+ * 
+ * cdef inline object PyArray_MultiIterNew2(a, b):             # <<<<<<<<<<<<<<
+ *     return PyArray_MultiIterNew(2, <void*>a, <void*>b)
+ * 
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("numpy.PyArray_MultiIterNew2", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":777
+ *     return PyArray_MultiIterNew(2, <void*>a, <void*>b)
+ * 
+ * cdef inline object PyArray_MultiIterNew3(a, b, c):             # <<<<<<<<<<<<<<
+ *     return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)
+ * 
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew3(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("PyArray_MultiIterNew3", 0);
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":778
+ * 
+ * cdef inline object PyArray_MultiIterNew3(a, b, c):
+ *     return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)             # <<<<<<<<<<<<<<
+ * 
+ * cdef inline object PyArray_MultiIterNew4(a, b, c, d):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = PyArray_MultiIterNew(3, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 778; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":777
+ *     return PyArray_MultiIterNew(2, <void*>a, <void*>b)
+ * 
+ * cdef inline object PyArray_MultiIterNew3(a, b, c):             # <<<<<<<<<<<<<<
+ *     return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)
+ * 
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("numpy.PyArray_MultiIterNew3", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":780
+ *     return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)
+ * 
+ * cdef inline object PyArray_MultiIterNew4(a, b, c, d):             # <<<<<<<<<<<<<<
+ *     return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)
+ * 
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew4(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c, PyObject *__pyx_v_d) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("PyArray_MultiIterNew4", 0);
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":781
+ * 
+ * cdef inline object PyArray_MultiIterNew4(a, b, c, d):
+ *     return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)             # <<<<<<<<<<<<<<
+ * 
+ * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = PyArray_MultiIterNew(4, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c), ((void *)__pyx_v_d)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 781; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":780
+ *     return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)
+ * 
+ * cdef inline object PyArray_MultiIterNew4(a, b, c, d):             # <<<<<<<<<<<<<<
+ *     return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)
+ * 
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("numpy.PyArray_MultiIterNew4", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":783
+ *     return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)
+ * 
+ * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e):             # <<<<<<<<<<<<<<
+ *     return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)
+ * 
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew5(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c, PyObject *__pyx_v_d, PyObject *__pyx_v_e) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("PyArray_MultiIterNew5", 0);
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":784
+ * 
+ * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e):
+ *     return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)             # <<<<<<<<<<<<<<
+ * 
+ * cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL:
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = PyArray_MultiIterNew(5, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c), ((void *)__pyx_v_d), ((void *)__pyx_v_e)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 784; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":783
+ *     return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)
+ * 
+ * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e):             # <<<<<<<<<<<<<<
+ *     return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)
+ * 
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("numpy.PyArray_MultiIterNew5", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":786
+ *     return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)
+ * 
+ * cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL:             # <<<<<<<<<<<<<<
+ *     # Recursive utility function used in __getbuffer__ to get format
+ *     # string. The new location in the format string is returned.
+ */
+
+static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx_v_descr, char *__pyx_v_f, char *__pyx_v_end, int *__pyx_v_offset) {
+  PyArray_Descr *__pyx_v_child = 0;
+  int __pyx_v_endian_detector;
+  int __pyx_v_little_endian;
+  PyObject *__pyx_v_fields = 0;
+  PyObject *__pyx_v_childname = NULL;
+  PyObject *__pyx_v_new_offset = NULL;
+  PyObject *__pyx_v_t = NULL;
+  char *__pyx_r;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  Py_ssize_t __pyx_t_2;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  int __pyx_t_5;
+  int __pyx_t_6;
+  int __pyx_t_7;
+  long __pyx_t_8;
+  char *__pyx_t_9;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("_util_dtypestring", 0);
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":793
+ *     cdef int delta_offset
+ *     cdef tuple i
+ *     cdef int endian_detector = 1             # <<<<<<<<<<<<<<
+ *     cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)
+ *     cdef tuple fields
+ */
+  __pyx_v_endian_detector = 1;
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":794
+ *     cdef tuple i
+ *     cdef int endian_detector = 1
+ *     cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)             # <<<<<<<<<<<<<<
+ *     cdef tuple fields
+ * 
+ */
+  __pyx_v_little_endian = ((((char *)(&__pyx_v_endian_detector))[0]) != 0);
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":797
+ *     cdef tuple fields
+ * 
+ *     for childname in descr.names:             # <<<<<<<<<<<<<<
+ *         fields = descr.fields[childname]
+ *         child, new_offset = fields
+ */
+  if (unlikely(__pyx_v_descr->names == Py_None)) {
+    PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable");
+    {__pyx_filename = __pyx_f[1]; __pyx_lineno = 797; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  __pyx_t_1 = __pyx_v_descr->names; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0;
+  for (;;) {
+    if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
+    #if CYTHON_COMPILING_IN_CPYTHON
+    __pyx_t_3 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_3); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 797; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    #else
+    __pyx_t_3 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 797; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    #endif
+    __Pyx_XDECREF_SET(__pyx_v_childname, __pyx_t_3);
+    __pyx_t_3 = 0;
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":798
+ * 
+ *     for childname in descr.names:
+ *         fields = descr.fields[childname]             # <<<<<<<<<<<<<<
+ *         child, new_offset = fields
+ * 
+ */
+    if (unlikely(__pyx_v_descr->fields == Py_None)) {
+      PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable");
+      {__pyx_filename = __pyx_f[1]; __pyx_lineno = 798; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+    __pyx_t_3 = __Pyx_PyDict_GetItem(__pyx_v_descr->fields, __pyx_v_childname); if (unlikely(__pyx_t_3 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 798; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+    __Pyx_GOTREF(__pyx_t_3);
+    if (!(likely(PyTuple_CheckExact(__pyx_t_3))||((__pyx_t_3) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "tuple", Py_TYPE(__pyx_t_3)->tp_name), 0))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 798; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_XDECREF_SET(__pyx_v_fields, ((PyObject*)__pyx_t_3));
+    __pyx_t_3 = 0;
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":799
+ *     for childname in descr.names:
+ *         fields = descr.fields[childname]
+ *         child, new_offset = fields             # <<<<<<<<<<<<<<
+ * 
+ *         if (end - f) - <int>(new_offset - offset[0]) < 15:
+ */
+    if (likely(__pyx_v_fields != Py_None)) {
+      PyObject* sequence = __pyx_v_fields;
+      #if CYTHON_COMPILING_IN_CPYTHON
+      Py_ssize_t size = Py_SIZE(sequence);
+      #else
+      Py_ssize_t size = PySequence_Size(sequence);
+      #endif
+      if (unlikely(size != 2)) {
+        if (size > 2) __Pyx_RaiseTooManyValuesError(2);
+        else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
+        {__pyx_filename = __pyx_f[1]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      }
+      #if CYTHON_COMPILING_IN_CPYTHON
+      __pyx_t_3 = PyTuple_GET_ITEM(sequence, 0); 
+      __pyx_t_4 = PyTuple_GET_ITEM(sequence, 1); 
+      __Pyx_INCREF(__pyx_t_3);
+      __Pyx_INCREF(__pyx_t_4);
+      #else
+      __pyx_t_3 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_4 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      #endif
+    } else {
+      __Pyx_RaiseNoneNotIterableError(); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+    if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_ptype_5numpy_dtype))))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_XDECREF_SET(__pyx_v_child, ((PyArray_Descr *)__pyx_t_3));
+    __pyx_t_3 = 0;
+    __Pyx_XDECREF_SET(__pyx_v_new_offset, __pyx_t_4);
+    __pyx_t_4 = 0;
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":801
+ *         child, new_offset = fields
+ * 
+ *         if (end - f) - <int>(new_offset - offset[0]) < 15:             # <<<<<<<<<<<<<<
+ *             raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd")
+ * 
+ */
+    __pyx_t_4 = __Pyx_PyInt_From_int((__pyx_v_offset[0])); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 801; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    __pyx_t_3 = PyNumber_Subtract(__pyx_v_new_offset, __pyx_t_4); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 801; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    __pyx_t_5 = __Pyx_PyInt_As_int(__pyx_t_3); if (unlikely((__pyx_t_5 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 801; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __pyx_t_6 = ((((__pyx_v_end - __pyx_v_f) - ((int)__pyx_t_5)) < 15) != 0);
+    if (__pyx_t_6) {
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":802
+ * 
+ *         if (end - f) - <int>(new_offset - offset[0]) < 15:
+ *             raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd")             # <<<<<<<<<<<<<<
+ * 
+ *         if ((child.byteorder == c'>' and little_endian) or
+ */
+      __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_RuntimeError, __pyx_tuple__7, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 802; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      {__pyx_filename = __pyx_f[1]; __pyx_lineno = 802; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":804
+ *             raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd")
+ * 
+ *         if ((child.byteorder == c'>' and little_endian) or             # <<<<<<<<<<<<<<
+ *             (child.byteorder == c'<' and not little_endian)):
+ *             raise ValueError(u"Non-native byte order not supported")
+ */
+    __pyx_t_7 = ((__pyx_v_child->byteorder == '>') != 0);
+    if (!__pyx_t_7) {
+      goto __pyx_L8_next_or;
+    } else {
+    }
+    __pyx_t_7 = (__pyx_v_little_endian != 0);
+    if (!__pyx_t_7) {
+    } else {
+      __pyx_t_6 = __pyx_t_7;
+      goto __pyx_L7_bool_binop_done;
+    }
+    __pyx_L8_next_or:;
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":805
+ * 
+ *         if ((child.byteorder == c'>' and little_endian) or
+ *             (child.byteorder == c'<' and not little_endian)):             # <<<<<<<<<<<<<<
+ *             raise ValueError(u"Non-native byte order not supported")
+ *             # One could encode it in the format string and have Cython
+ */
+    __pyx_t_7 = ((__pyx_v_child->byteorder == '<') != 0);
+    if (__pyx_t_7) {
+    } else {
+      __pyx_t_6 = __pyx_t_7;
+      goto __pyx_L7_bool_binop_done;
+    }
+    __pyx_t_7 = ((!(__pyx_v_little_endian != 0)) != 0);
+    __pyx_t_6 = __pyx_t_7;
+    __pyx_L7_bool_binop_done:;
+    if (__pyx_t_6) {
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":806
+ *         if ((child.byteorder == c'>' and little_endian) or
+ *             (child.byteorder == c'<' and not little_endian)):
+ *             raise ValueError(u"Non-native byte order not supported")             # <<<<<<<<<<<<<<
+ *             # One could encode it in the format string and have Cython
+ *             # complain instead, BUT: < and > in format strings also imply
+ */
+      __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__8, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 806; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      {__pyx_filename = __pyx_f[1]; __pyx_lineno = 806; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":816
+ * 
+ *         # Output padding bytes
+ *         while offset[0] < new_offset:             # <<<<<<<<<<<<<<
+ *             f[0] = 120 # "x"; pad byte
+ *             f += 1
+ */
+    while (1) {
+      __pyx_t_3 = __Pyx_PyInt_From_int((__pyx_v_offset[0])); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 816; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_4 = PyObject_RichCompare(__pyx_t_3, __pyx_v_new_offset, Py_LT); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 816; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 816; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      if (!__pyx_t_6) break;
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":817
+ *         # Output padding bytes
+ *         while offset[0] < new_offset:
+ *             f[0] = 120 # "x"; pad byte             # <<<<<<<<<<<<<<
+ *             f += 1
+ *             offset[0] += 1
+ */
+      (__pyx_v_f[0]) = 120;
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":818
+ *         while offset[0] < new_offset:
+ *             f[0] = 120 # "x"; pad byte
+ *             f += 1             # <<<<<<<<<<<<<<
+ *             offset[0] += 1
+ * 
+ */
+      __pyx_v_f = (__pyx_v_f + 1);
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":819
+ *             f[0] = 120 # "x"; pad byte
+ *             f += 1
+ *             offset[0] += 1             # <<<<<<<<<<<<<<
+ * 
+ *         offset[0] += child.itemsize
+ */
+      __pyx_t_8 = 0;
+      (__pyx_v_offset[__pyx_t_8]) = ((__pyx_v_offset[__pyx_t_8]) + 1);
+    }
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":821
+ *             offset[0] += 1
+ * 
+ *         offset[0] += child.itemsize             # <<<<<<<<<<<<<<
+ * 
+ *         if not PyDataType_HASFIELDS(child):
+ */
+    __pyx_t_8 = 0;
+    (__pyx_v_offset[__pyx_t_8]) = ((__pyx_v_offset[__pyx_t_8]) + __pyx_v_child->elsize);
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":823
+ *         offset[0] += child.itemsize
+ * 
+ *         if not PyDataType_HASFIELDS(child):             # <<<<<<<<<<<<<<
+ *             t = child.type_num
+ *             if end - f < 5:
+ */
+    __pyx_t_6 = ((!(PyDataType_HASFIELDS(__pyx_v_child) != 0)) != 0);
+    if (__pyx_t_6) {
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":824
+ * 
+ *         if not PyDataType_HASFIELDS(child):
+ *             t = child.type_num             # <<<<<<<<<<<<<<
+ *             if end - f < 5:
+ *                 raise RuntimeError(u"Format string allocated too short.")
+ */
+      __pyx_t_4 = __Pyx_PyInt_From_int(__pyx_v_child->type_num); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 824; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __Pyx_XDECREF_SET(__pyx_v_t, __pyx_t_4);
+      __pyx_t_4 = 0;
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":825
+ *         if not PyDataType_HASFIELDS(child):
+ *             t = child.type_num
+ *             if end - f < 5:             # <<<<<<<<<<<<<<
+ *                 raise RuntimeError(u"Format string allocated too short.")
+ * 
+ */
+      __pyx_t_6 = (((__pyx_v_end - __pyx_v_f) < 5) != 0);
+      if (__pyx_t_6) {
+
+        /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":826
+ *             t = child.type_num
+ *             if end - f < 5:
+ *                 raise RuntimeError(u"Format string allocated too short.")             # <<<<<<<<<<<<<<
+ * 
+ *             # Until ticket #99 is fixed, use integers to avoid warnings
+ */
+        __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_RuntimeError, __pyx_tuple__9, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 826; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_4);
+        __Pyx_Raise(__pyx_t_4, 0, 0, 0);
+        __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+        {__pyx_filename = __pyx_f[1]; __pyx_lineno = 826; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      }
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":829
+ * 
+ *             # Until ticket #99 is fixed, use integers to avoid warnings
+ *             if   t == NPY_BYTE:        f[0] =  98 #"b"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_UBYTE:       f[0] =  66 #"B"
+ *             elif t == NPY_SHORT:       f[0] = 104 #"h"
+ */
+      __pyx_t_4 = PyInt_FromLong(NPY_BYTE); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 829; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 829; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 829; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 98;
+        goto __pyx_L15;
+      }
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":830
+ *             # Until ticket #99 is fixed, use integers to avoid warnings
+ *             if   t == NPY_BYTE:        f[0] =  98 #"b"
+ *             elif t == NPY_UBYTE:       f[0] =  66 #"B"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_SHORT:       f[0] = 104 #"h"
+ *             elif t == NPY_USHORT:      f[0] =  72 #"H"
+ */
+      __pyx_t_3 = PyInt_FromLong(NPY_UBYTE); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 830; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 830; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 830; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 66;
+        goto __pyx_L15;
+      }
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":831
+ *             if   t == NPY_BYTE:        f[0] =  98 #"b"
+ *             elif t == NPY_UBYTE:       f[0] =  66 #"B"
+ *             elif t == NPY_SHORT:       f[0] = 104 #"h"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_USHORT:      f[0] =  72 #"H"
+ *             elif t == NPY_INT:         f[0] = 105 #"i"
+ */
+      __pyx_t_4 = PyInt_FromLong(NPY_SHORT); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 831; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 831; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 831; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 104;
+        goto __pyx_L15;
+      }
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":832
+ *             elif t == NPY_UBYTE:       f[0] =  66 #"B"
+ *             elif t == NPY_SHORT:       f[0] = 104 #"h"
+ *             elif t == NPY_USHORT:      f[0] =  72 #"H"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_INT:         f[0] = 105 #"i"
+ *             elif t == NPY_UINT:        f[0] =  73 #"I"
+ */
+      __pyx_t_3 = PyInt_FromLong(NPY_USHORT); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 832; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 832; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 832; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 72;
+        goto __pyx_L15;
+      }
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":833
+ *             elif t == NPY_SHORT:       f[0] = 104 #"h"
+ *             elif t == NPY_USHORT:      f[0] =  72 #"H"
+ *             elif t == NPY_INT:         f[0] = 105 #"i"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_UINT:        f[0] =  73 #"I"
+ *             elif t == NPY_LONG:        f[0] = 108 #"l"
+ */
+      __pyx_t_4 = PyInt_FromLong(NPY_INT); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 833; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 833; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 833; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 105;
+        goto __pyx_L15;
+      }
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":834
+ *             elif t == NPY_USHORT:      f[0] =  72 #"H"
+ *             elif t == NPY_INT:         f[0] = 105 #"i"
+ *             elif t == NPY_UINT:        f[0] =  73 #"I"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_LONG:        f[0] = 108 #"l"
+ *             elif t == NPY_ULONG:       f[0] = 76  #"L"
+ */
+      __pyx_t_3 = PyInt_FromLong(NPY_UINT); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 834; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 834; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 834; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 73;
+        goto __pyx_L15;
+      }
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":835
+ *             elif t == NPY_INT:         f[0] = 105 #"i"
+ *             elif t == NPY_UINT:        f[0] =  73 #"I"
+ *             elif t == NPY_LONG:        f[0] = 108 #"l"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_ULONG:       f[0] = 76  #"L"
+ *             elif t == NPY_LONGLONG:    f[0] = 113 #"q"
+ */
+      __pyx_t_4 = PyInt_FromLong(NPY_LONG); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 835; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 835; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 835; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 108;
+        goto __pyx_L15;
+      }
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":836
+ *             elif t == NPY_UINT:        f[0] =  73 #"I"
+ *             elif t == NPY_LONG:        f[0] = 108 #"l"
+ *             elif t == NPY_ULONG:       f[0] = 76  #"L"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_LONGLONG:    f[0] = 113 #"q"
+ *             elif t == NPY_ULONGLONG:   f[0] = 81  #"Q"
+ */
+      __pyx_t_3 = PyInt_FromLong(NPY_ULONG); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 836; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 836; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 836; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 76;
+        goto __pyx_L15;
+      }
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":837
+ *             elif t == NPY_LONG:        f[0] = 108 #"l"
+ *             elif t == NPY_ULONG:       f[0] = 76  #"L"
+ *             elif t == NPY_LONGLONG:    f[0] = 113 #"q"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_ULONGLONG:   f[0] = 81  #"Q"
+ *             elif t == NPY_FLOAT:       f[0] = 102 #"f"
+ */
+      __pyx_t_4 = PyInt_FromLong(NPY_LONGLONG); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 837; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 837; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 837; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 113;
+        goto __pyx_L15;
+      }
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":838
+ *             elif t == NPY_ULONG:       f[0] = 76  #"L"
+ *             elif t == NPY_LONGLONG:    f[0] = 113 #"q"
+ *             elif t == NPY_ULONGLONG:   f[0] = 81  #"Q"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_FLOAT:       f[0] = 102 #"f"
+ *             elif t == NPY_DOUBLE:      f[0] = 100 #"d"
+ */
+      __pyx_t_3 = PyInt_FromLong(NPY_ULONGLONG); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 838; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 838; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 838; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 81;
+        goto __pyx_L15;
+      }
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":839
+ *             elif t == NPY_LONGLONG:    f[0] = 113 #"q"
+ *             elif t == NPY_ULONGLONG:   f[0] = 81  #"Q"
+ *             elif t == NPY_FLOAT:       f[0] = 102 #"f"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_DOUBLE:      f[0] = 100 #"d"
+ *             elif t == NPY_LONGDOUBLE:  f[0] = 103 #"g"
+ */
+      __pyx_t_4 = PyInt_FromLong(NPY_FLOAT); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 839; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 839; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 839; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 102;
+        goto __pyx_L15;
+      }
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":840
+ *             elif t == NPY_ULONGLONG:   f[0] = 81  #"Q"
+ *             elif t == NPY_FLOAT:       f[0] = 102 #"f"
+ *             elif t == NPY_DOUBLE:      f[0] = 100 #"d"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_LONGDOUBLE:  f[0] = 103 #"g"
+ *             elif t == NPY_CFLOAT:      f[0] = 90; f[1] = 102; f += 1 # Zf
+ */
+      __pyx_t_3 = PyInt_FromLong(NPY_DOUBLE); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 840; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 840; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 840; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 100;
+        goto __pyx_L15;
+      }
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":841
+ *             elif t == NPY_FLOAT:       f[0] = 102 #"f"
+ *             elif t == NPY_DOUBLE:      f[0] = 100 #"d"
+ *             elif t == NPY_LONGDOUBLE:  f[0] = 103 #"g"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_CFLOAT:      f[0] = 90; f[1] = 102; f += 1 # Zf
+ *             elif t == NPY_CDOUBLE:     f[0] = 90; f[1] = 100; f += 1 # Zd
+ */
+      __pyx_t_4 = PyInt_FromLong(NPY_LONGDOUBLE); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 841; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 841; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 841; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 103;
+        goto __pyx_L15;
+      }
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":842
+ *             elif t == NPY_DOUBLE:      f[0] = 100 #"d"
+ *             elif t == NPY_LONGDOUBLE:  f[0] = 103 #"g"
+ *             elif t == NPY_CFLOAT:      f[0] = 90; f[1] = 102; f += 1 # Zf             # <<<<<<<<<<<<<<
+ *             elif t == NPY_CDOUBLE:     f[0] = 90; f[1] = 100; f += 1 # Zd
+ *             elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg
+ */
+      __pyx_t_3 = PyInt_FromLong(NPY_CFLOAT); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 842; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 842; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 842; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 90;
+        (__pyx_v_f[1]) = 102;
+        __pyx_v_f = (__pyx_v_f + 1);
+        goto __pyx_L15;
+      }
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":843
+ *             elif t == NPY_LONGDOUBLE:  f[0] = 103 #"g"
+ *             elif t == NPY_CFLOAT:      f[0] = 90; f[1] = 102; f += 1 # Zf
+ *             elif t == NPY_CDOUBLE:     f[0] = 90; f[1] = 100; f += 1 # Zd             # <<<<<<<<<<<<<<
+ *             elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg
+ *             elif t == NPY_OBJECT:      f[0] = 79 #"O"
+ */
+      __pyx_t_4 = PyInt_FromLong(NPY_CDOUBLE); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 843; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 843; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 843; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 90;
+        (__pyx_v_f[1]) = 100;
+        __pyx_v_f = (__pyx_v_f + 1);
+        goto __pyx_L15;
+      }
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":844
+ *             elif t == NPY_CFLOAT:      f[0] = 90; f[1] = 102; f += 1 # Zf
+ *             elif t == NPY_CDOUBLE:     f[0] = 90; f[1] = 100; f += 1 # Zd
+ *             elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg             # <<<<<<<<<<<<<<
+ *             elif t == NPY_OBJECT:      f[0] = 79 #"O"
+ *             else:
+ */
+      __pyx_t_3 = PyInt_FromLong(NPY_CLONGDOUBLE); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 844; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 844; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 844; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 90;
+        (__pyx_v_f[1]) = 103;
+        __pyx_v_f = (__pyx_v_f + 1);
+        goto __pyx_L15;
+      }
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":845
+ *             elif t == NPY_CDOUBLE:     f[0] = 90; f[1] = 100; f += 1 # Zd
+ *             elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg
+ *             elif t == NPY_OBJECT:      f[0] = 79 #"O"             # <<<<<<<<<<<<<<
+ *             else:
+ *                 raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
+ */
+      __pyx_t_4 = PyInt_FromLong(NPY_OBJECT); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 845; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 845; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 845; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 79;
+        goto __pyx_L15;
+      }
+      /*else*/ {
+
+        /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":847
+ *             elif t == NPY_OBJECT:      f[0] = 79 #"O"
+ *             else:
+ *                 raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)             # <<<<<<<<<<<<<<
+ *             f += 1
+ *         else:
+ */
+        __pyx_t_3 = PyUnicode_Format(__pyx_kp_u_unknown_dtype_code_in_numpy_pxd, __pyx_v_t); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 847; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_3);
+        __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 847; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_4);
+        PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
+        __Pyx_GIVEREF(__pyx_t_3);
+        __pyx_t_3 = 0;
+        __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 847; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_3);
+        __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+        __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+        __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+        {__pyx_filename = __pyx_f[1]; __pyx_lineno = 847; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      }
+      __pyx_L15:;
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":848
+ *             else:
+ *                 raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
+ *             f += 1             # <<<<<<<<<<<<<<
+ *         else:
+ *             # Cython ignores struct boundary information ("T{...}"),
+ */
+      __pyx_v_f = (__pyx_v_f + 1);
+      goto __pyx_L13;
+    }
+    /*else*/ {
+
+      /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":852
+ *             # Cython ignores struct boundary information ("T{...}"),
+ *             # so don't output it
+ *             f = _util_dtypestring(child, f, end, offset)             # <<<<<<<<<<<<<<
+ *     return f
+ * 
+ */
+      __pyx_t_9 = __pyx_f_5numpy__util_dtypestring(__pyx_v_child, __pyx_v_f, __pyx_v_end, __pyx_v_offset); if (unlikely(__pyx_t_9 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 852; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_v_f = __pyx_t_9;
+    }
+    __pyx_L13:;
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":797
+ *     cdef tuple fields
+ * 
+ *     for childname in descr.names:             # <<<<<<<<<<<<<<
+ *         fields = descr.fields[childname]
+ *         child, new_offset = fields
+ */
+  }
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":853
+ *             # so don't output it
+ *             f = _util_dtypestring(child, f, end, offset)
+ *     return f             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+  __pyx_r = __pyx_v_f;
+  goto __pyx_L0;
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":786
+ *     return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)
+ * 
+ * cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL:             # <<<<<<<<<<<<<<
+ *     # Recursive utility function used in __getbuffer__ to get format
+ *     # string. The new location in the format string is returned.
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_AddTraceback("numpy._util_dtypestring", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XDECREF((PyObject *)__pyx_v_child);
+  __Pyx_XDECREF(__pyx_v_fields);
+  __Pyx_XDECREF(__pyx_v_childname);
+  __Pyx_XDECREF(__pyx_v_new_offset);
+  __Pyx_XDECREF(__pyx_v_t);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":969
+ * 
+ * 
+ * cdef inline void set_array_base(ndarray arr, object base):             # <<<<<<<<<<<<<<
+ *      cdef PyObject* baseptr
+ *      if base is None:
+ */
+
+static CYTHON_INLINE void __pyx_f_5numpy_set_array_base(PyArrayObject *__pyx_v_arr, PyObject *__pyx_v_base) {
+  PyObject *__pyx_v_baseptr;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  int __pyx_t_2;
+  __Pyx_RefNannySetupContext("set_array_base", 0);
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":971
+ * cdef inline void set_array_base(ndarray arr, object base):
+ *      cdef PyObject* baseptr
+ *      if base is None:             # <<<<<<<<<<<<<<
+ *          baseptr = NULL
+ *      else:
+ */
+  __pyx_t_1 = (__pyx_v_base == Py_None);
+  __pyx_t_2 = (__pyx_t_1 != 0);
+  if (__pyx_t_2) {
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":972
+ *      cdef PyObject* baseptr
+ *      if base is None:
+ *          baseptr = NULL             # <<<<<<<<<<<<<<
+ *      else:
+ *          Py_INCREF(base) # important to do this before decref below!
+ */
+    __pyx_v_baseptr = NULL;
+    goto __pyx_L3;
+  }
+  /*else*/ {
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":974
+ *          baseptr = NULL
+ *      else:
+ *          Py_INCREF(base) # important to do this before decref below!             # <<<<<<<<<<<<<<
+ *          baseptr = <PyObject*>base
+ *      Py_XDECREF(arr.base)
+ */
+    Py_INCREF(__pyx_v_base);
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":975
+ *      else:
+ *          Py_INCREF(base) # important to do this before decref below!
+ *          baseptr = <PyObject*>base             # <<<<<<<<<<<<<<
+ *      Py_XDECREF(arr.base)
+ *      arr.base = baseptr
+ */
+    __pyx_v_baseptr = ((PyObject *)__pyx_v_base);
+  }
+  __pyx_L3:;
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":976
+ *          Py_INCREF(base) # important to do this before decref below!
+ *          baseptr = <PyObject*>base
+ *      Py_XDECREF(arr.base)             # <<<<<<<<<<<<<<
+ *      arr.base = baseptr
+ * 
+ */
+  Py_XDECREF(__pyx_v_arr->base);
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":977
+ *          baseptr = <PyObject*>base
+ *      Py_XDECREF(arr.base)
+ *      arr.base = baseptr             # <<<<<<<<<<<<<<
+ * 
+ * cdef inline object get_array_base(ndarray arr):
+ */
+  __pyx_v_arr->base = __pyx_v_baseptr;
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":969
+ * 
+ * 
+ * cdef inline void set_array_base(ndarray arr, object base):             # <<<<<<<<<<<<<<
+ *      cdef PyObject* baseptr
+ *      if base is None:
+ */
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+}
+
+/* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":979
+ *      arr.base = baseptr
+ * 
+ * cdef inline object get_array_base(ndarray arr):             # <<<<<<<<<<<<<<
+ *     if arr.base is NULL:
+ *         return None
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_5numpy_get_array_base(PyArrayObject *__pyx_v_arr) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("get_array_base", 0);
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":980
+ * 
+ * cdef inline object get_array_base(ndarray arr):
+ *     if arr.base is NULL:             # <<<<<<<<<<<<<<
+ *         return None
+ *     else:
+ */
+  __pyx_t_1 = ((__pyx_v_arr->base == NULL) != 0);
+  if (__pyx_t_1) {
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":981
+ * cdef inline object get_array_base(ndarray arr):
+ *     if arr.base is NULL:
+ *         return None             # <<<<<<<<<<<<<<
+ *     else:
+ *         return <object>arr.base
+ */
+    __Pyx_XDECREF(__pyx_r);
+    __Pyx_INCREF(Py_None);
+    __pyx_r = Py_None;
+    goto __pyx_L0;
+  }
+  /*else*/ {
+
+    /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":983
+ *         return None
+ *     else:
+ *         return <object>arr.base             # <<<<<<<<<<<<<<
+ */
+    __Pyx_XDECREF(__pyx_r);
+    __Pyx_INCREF(((PyObject *)__pyx_v_arr->base));
+    __pyx_r = ((PyObject *)__pyx_v_arr->base);
+    goto __pyx_L0;
+  }
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":979
+ *      arr.base = baseptr
+ * 
+ * cdef inline object get_array_base(ndarray arr):             # <<<<<<<<<<<<<<
+ *     if arr.base is NULL:
+ *         return None
+ */
+
+  /* function exit code */
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+static struct __pyx_vtabstruct_2bx_3bbi_11bigwig_file_BigWigBlockHandler __pyx_vtable_2bx_3bbi_11bigwig_file_BigWigBlockHandler;
+
+static PyObject *__pyx_tp_new_2bx_3bbi_11bigwig_file_BigWigBlockHandler(PyTypeObject *t, PyObject *a, PyObject *k) {
+  struct __pyx_obj_2bx_3bbi_11bigwig_file_BigWigBlockHandler *p;
+  PyObject *o = __pyx_ptype_2bx_3bbi_8bbi_file_BlockHandler->tp_new(t, a, k);
+  if (unlikely(!o)) return 0;
+  p = ((struct __pyx_obj_2bx_3bbi_11bigwig_file_BigWigBlockHandler *)o);
+  p->__pyx_base.__pyx_vtab = (struct __pyx_vtabstruct_2bx_3bbi_8bbi_file_BlockHandler*)__pyx_vtabptr_2bx_3bbi_11bigwig_file_BigWigBlockHandler;
+  return o;
+}
+
+static void __pyx_tp_dealloc_2bx_3bbi_11bigwig_file_BigWigBlockHandler(PyObject *o) {
+  #if PY_VERSION_HEX >= 0x030400a1
+  if (unlikely(Py_TYPE(o)->tp_finalize) && (!PyType_IS_GC(Py_TYPE(o)) || !_PyGC_FINALIZED(o))) {
+    if (PyObject_CallFinalizerFromDealloc(o)) return;
+  }
+  #endif
+  if (likely(__pyx_ptype_2bx_3bbi_8bbi_file_BlockHandler)) __pyx_ptype_2bx_3bbi_8bbi_file_BlockHandler->tp_dealloc(o); else __Pyx_call_next_tp_dealloc(o, __pyx_tp_dealloc_2bx_3bbi_11bigwig_file_BigWigBlockHandler);
+}
+
+static PyMethodDef __pyx_methods_2bx_3bbi_11bigwig_file_BigWigBlockHandler[] = {
+  {0, 0, 0, 0}
+};
+
+static PyTypeObject __pyx_type_2bx_3bbi_11bigwig_file_BigWigBlockHandler = {
+  PyVarObject_HEAD_INIT(0, 0)
+  "bx.bbi.bigwig_file.BigWigBlockHandler", /*tp_name*/
+  sizeof(struct __pyx_obj_2bx_3bbi_11bigwig_file_BigWigBlockHandler), /*tp_basicsize*/
+  0, /*tp_itemsize*/
+  __pyx_tp_dealloc_2bx_3bbi_11bigwig_file_BigWigBlockHandler, /*tp_dealloc*/
+  0, /*tp_print*/
+  0, /*tp_getattr*/
+  0, /*tp_setattr*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*tp_compare*/
+  #else
+  0, /*reserved*/
+  #endif
+  0, /*tp_repr*/
+  0, /*tp_as_number*/
+  0, /*tp_as_sequence*/
+  0, /*tp_as_mapping*/
+  0, /*tp_hash*/
+  0, /*tp_call*/
+  0, /*tp_str*/
+  0, /*tp_getattro*/
+  0, /*tp_setattro*/
+  0, /*tp_as_buffer*/
+  Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE, /*tp_flags*/
+  "\n    BlockHandler that parses the block into a series of wiggle records, and calls `handle_interval_value` for each.\n    ", /*tp_doc*/
+  0, /*tp_traverse*/
+  0, /*tp_clear*/
+  0, /*tp_richcompare*/
+  0, /*tp_weaklistoffset*/
+  0, /*tp_iter*/
+  0, /*tp_iternext*/
+  __pyx_methods_2bx_3bbi_11bigwig_file_BigWigBlockHandler, /*tp_methods*/
+  0, /*tp_members*/
+  0, /*tp_getset*/
+  0, /*tp_base*/
+  0, /*tp_dict*/
+  0, /*tp_descr_get*/
+  0, /*tp_descr_set*/
+  0, /*tp_dictoffset*/
+  __pyx_pw_2bx_3bbi_11bigwig_file_18BigWigBlockHandler_1__init__, /*tp_init*/
+  0, /*tp_alloc*/
+  __pyx_tp_new_2bx_3bbi_11bigwig_file_BigWigBlockHandler, /*tp_new*/
+  0, /*tp_free*/
+  0, /*tp_is_gc*/
+  0, /*tp_bases*/
+  0, /*tp_mro*/
+  0, /*tp_cache*/
+  0, /*tp_subclasses*/
+  0, /*tp_weaklist*/
+  0, /*tp_del*/
+  0, /*tp_version_tag*/
+  #if PY_VERSION_HEX >= 0x030400a1
+  0, /*tp_finalize*/
+  #endif
+};
+static struct __pyx_vtabstruct_2bx_3bbi_11bigwig_file_SummarizingBlockHandler __pyx_vtable_2bx_3bbi_11bigwig_file_SummarizingBlockHandler;
+
+static PyObject *__pyx_tp_new_2bx_3bbi_11bigwig_file_SummarizingBlockHandler(PyTypeObject *t, PyObject *a, PyObject *k) {
+  struct __pyx_obj_2bx_3bbi_11bigwig_file_SummarizingBlockHandler *p;
+  PyObject *o = __pyx_tp_new_2bx_3bbi_11bigwig_file_BigWigBlockHandler(t, a, k);
+  if (unlikely(!o)) return 0;
+  p = ((struct __pyx_obj_2bx_3bbi_11bigwig_file_SummarizingBlockHandler *)o);
+  p->__pyx_base.__pyx_base.__pyx_vtab = (struct __pyx_vtabstruct_2bx_3bbi_8bbi_file_BlockHandler*)__pyx_vtabptr_2bx_3bbi_11bigwig_file_SummarizingBlockHandler;
+  p->sd = ((struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData *)Py_None); Py_INCREF(Py_None);
+  return o;
+}
+
+static void __pyx_tp_dealloc_2bx_3bbi_11bigwig_file_SummarizingBlockHandler(PyObject *o) {
+  struct __pyx_obj_2bx_3bbi_11bigwig_file_SummarizingBlockHandler *p = (struct __pyx_obj_2bx_3bbi_11bigwig_file_SummarizingBlockHandler *)o;
+  #if PY_VERSION_HEX >= 0x030400a1
+  if (unlikely(Py_TYPE(o)->tp_finalize) && !_PyGC_FINALIZED(o)) {
+    if (PyObject_CallFinalizerFromDealloc(o)) return;
+  }
+  #endif
+  PyObject_GC_UnTrack(o);
+  Py_CLEAR(p->sd);
+  #if CYTHON_COMPILING_IN_CPYTHON
+  if (PyType_IS_GC(Py_TYPE(o)->tp_base))
+  #endif
+  PyObject_GC_Track(o);
+  __pyx_tp_dealloc_2bx_3bbi_11bigwig_file_BigWigBlockHandler(o);
+}
+
+static int __pyx_tp_traverse_2bx_3bbi_11bigwig_file_SummarizingBlockHandler(PyObject *o, visitproc v, void *a) {
+  int e;
+  struct __pyx_obj_2bx_3bbi_11bigwig_file_SummarizingBlockHandler *p = (struct __pyx_obj_2bx_3bbi_11bigwig_file_SummarizingBlockHandler *)o;
+  e = ((likely(__pyx_ptype_2bx_3bbi_11bigwig_file_BigWigBlockHandler)) ? ((__pyx_ptype_2bx_3bbi_11bigwig_file_BigWigBlockHandler->tp_traverse) ? __pyx_ptype_2bx_3bbi_11bigwig_file_BigWigBlockHandler->tp_traverse(o, v, a) : 0) : __Pyx_call_next_tp_traverse(o, v, a, __pyx_tp_traverse_2bx_3bbi_11bigwig_file_SummarizingBlockHandler)); if (e) return e;
+  if (p->sd) {
+    e = (*v)(((PyObject*)p->sd), a); if (e) return e;
+  }
+  return 0;
+}
+
+static int __pyx_tp_clear_2bx_3bbi_11bigwig_file_SummarizingBlockHandler(PyObject *o) {
+  PyObject* tmp;
+  struct __pyx_obj_2bx_3bbi_11bigwig_file_SummarizingBlockHandler *p = (struct __pyx_obj_2bx_3bbi_11bigwig_file_SummarizingBlockHandler *)o;
+  if (likely(__pyx_ptype_2bx_3bbi_11bigwig_file_BigWigBlockHandler)) { if (__pyx_ptype_2bx_3bbi_11bigwig_file_BigWigBlockHandler->tp_clear) __pyx_ptype_2bx_3bbi_11bigwig_file_BigWigBlockHandler->tp_clear(o); } else __Pyx_call_next_tp_clear(o, __pyx_tp_clear_2bx_3bbi_11bigwig_file_SummarizingBlockHandler);
+  tmp = ((PyObject*)p->sd);
+  p->sd = ((struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData *)Py_None); Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  return 0;
+}
+
+static PyMethodDef __pyx_methods_2bx_3bbi_11bigwig_file_SummarizingBlockHandler[] = {
+  {0, 0, 0, 0}
+};
+
+static PyTypeObject __pyx_type_2bx_3bbi_11bigwig_file_SummarizingBlockHandler = {
+  PyVarObject_HEAD_INIT(0, 0)
+  "bx.bbi.bigwig_file.SummarizingBlockHandler", /*tp_name*/
+  sizeof(struct __pyx_obj_2bx_3bbi_11bigwig_file_SummarizingBlockHandler), /*tp_basicsize*/
+  0, /*tp_itemsize*/
+  __pyx_tp_dealloc_2bx_3bbi_11bigwig_file_SummarizingBlockHandler, /*tp_dealloc*/
+  0, /*tp_print*/
+  0, /*tp_getattr*/
+  0, /*tp_setattr*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*tp_compare*/
+  #else
+  0, /*reserved*/
+  #endif
+  0, /*tp_repr*/
+  0, /*tp_as_number*/
+  0, /*tp_as_sequence*/
+  0, /*tp_as_mapping*/
+  0, /*tp_hash*/
+  0, /*tp_call*/
+  0, /*tp_str*/
+  0, /*tp_getattro*/
+  0, /*tp_setattro*/
+  0, /*tp_as_buffer*/
+  Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+  "\n    Accumulates intervals into a SummarizedData\n    ", /*tp_doc*/
+  __pyx_tp_traverse_2bx_3bbi_11bigwig_file_SummarizingBlockHandler, /*tp_traverse*/
+  __pyx_tp_clear_2bx_3bbi_11bigwig_file_SummarizingBlockHandler, /*tp_clear*/
+  0, /*tp_richcompare*/
+  0, /*tp_weaklistoffset*/
+  0, /*tp_iter*/
+  0, /*tp_iternext*/
+  __pyx_methods_2bx_3bbi_11bigwig_file_SummarizingBlockHandler, /*tp_methods*/
+  0, /*tp_members*/
+  0, /*tp_getset*/
+  0, /*tp_base*/
+  0, /*tp_dict*/
+  0, /*tp_descr_get*/
+  0, /*tp_descr_set*/
+  0, /*tp_dictoffset*/
+  __pyx_pw_2bx_3bbi_11bigwig_file_23SummarizingBlockHandler_1__init__, /*tp_init*/
+  0, /*tp_alloc*/
+  __pyx_tp_new_2bx_3bbi_11bigwig_file_SummarizingBlockHandler, /*tp_new*/
+  0, /*tp_free*/
+  0, /*tp_is_gc*/
+  0, /*tp_bases*/
+  0, /*tp_mro*/
+  0, /*tp_cache*/
+  0, /*tp_subclasses*/
+  0, /*tp_weaklist*/
+  0, /*tp_del*/
+  0, /*tp_version_tag*/
+  #if PY_VERSION_HEX >= 0x030400a1
+  0, /*tp_finalize*/
+  #endif
+};
+static struct __pyx_vtabstruct_2bx_3bbi_11bigwig_file_IntervalAccumulatingBlockHandler __pyx_vtable_2bx_3bbi_11bigwig_file_IntervalAccumulatingBlockHandler;
+
+static PyObject *__pyx_tp_new_2bx_3bbi_11bigwig_file_IntervalAccumulatingBlockHandler(PyTypeObject *t, PyObject *a, PyObject *k) {
+  struct __pyx_obj_2bx_3bbi_11bigwig_file_IntervalAccumulatingBlockHandler *p;
+  PyObject *o = __pyx_tp_new_2bx_3bbi_11bigwig_file_BigWigBlockHandler(t, a, k);
+  if (unlikely(!o)) return 0;
+  p = ((struct __pyx_obj_2bx_3bbi_11bigwig_file_IntervalAccumulatingBlockHandler *)o);
+  p->__pyx_base.__pyx_base.__pyx_vtab = (struct __pyx_vtabstruct_2bx_3bbi_8bbi_file_BlockHandler*)__pyx_vtabptr_2bx_3bbi_11bigwig_file_IntervalAccumulatingBlockHandler;
+  p->intervals = ((PyObject*)Py_None); Py_INCREF(Py_None);
+  return o;
+}
+
+static void __pyx_tp_dealloc_2bx_3bbi_11bigwig_file_IntervalAccumulatingBlockHandler(PyObject *o) {
+  struct __pyx_obj_2bx_3bbi_11bigwig_file_IntervalAccumulatingBlockHandler *p = (struct __pyx_obj_2bx_3bbi_11bigwig_file_IntervalAccumulatingBlockHandler *)o;
+  #if PY_VERSION_HEX >= 0x030400a1
+  if (unlikely(Py_TYPE(o)->tp_finalize) && !_PyGC_FINALIZED(o)) {
+    if (PyObject_CallFinalizerFromDealloc(o)) return;
+  }
+  #endif
+  PyObject_GC_UnTrack(o);
+  Py_CLEAR(p->intervals);
+  #if CYTHON_COMPILING_IN_CPYTHON
+  if (PyType_IS_GC(Py_TYPE(o)->tp_base))
+  #endif
+  PyObject_GC_Track(o);
+  __pyx_tp_dealloc_2bx_3bbi_11bigwig_file_BigWigBlockHandler(o);
+}
+
+static int __pyx_tp_traverse_2bx_3bbi_11bigwig_file_IntervalAccumulatingBlockHandler(PyObject *o, visitproc v, void *a) {
+  int e;
+  struct __pyx_obj_2bx_3bbi_11bigwig_file_IntervalAccumulatingBlockHandler *p = (struct __pyx_obj_2bx_3bbi_11bigwig_file_IntervalAccumulatingBlockHandler *)o;
+  e = ((likely(__pyx_ptype_2bx_3bbi_11bigwig_file_BigWigBlockHandler)) ? ((__pyx_ptype_2bx_3bbi_11bigwig_file_BigWigBlockHandler->tp_traverse) ? __pyx_ptype_2bx_3bbi_11bigwig_file_BigWigBlockHandler->tp_traverse(o, v, a) : 0) : __Pyx_call_next_tp_traverse(o, v, a, __pyx_tp_traverse_2bx_3bbi_11bigwig_file_IntervalAccumulatingBlockHandler)); if (e) return e;
+  if (p->intervals) {
+    e = (*v)(p->intervals, a); if (e) return e;
+  }
+  return 0;
+}
+
+static int __pyx_tp_clear_2bx_3bbi_11bigwig_file_IntervalAccumulatingBlockHandler(PyObject *o) {
+  PyObject* tmp;
+  struct __pyx_obj_2bx_3bbi_11bigwig_file_IntervalAccumulatingBlockHandler *p = (struct __pyx_obj_2bx_3bbi_11bigwig_file_IntervalAccumulatingBlockHandler *)o;
+  if (likely(__pyx_ptype_2bx_3bbi_11bigwig_file_BigWigBlockHandler)) { if (__pyx_ptype_2bx_3bbi_11bigwig_file_BigWigBlockHandler->tp_clear) __pyx_ptype_2bx_3bbi_11bigwig_file_BigWigBlockHandler->tp_clear(o); } else __Pyx_call_next_tp_clear(o, __pyx_tp_clear_2bx_3bbi_11bigwig_file_IntervalAccumulatingBlockHandler);
+  tmp = ((PyObject*)p->intervals);
+  p->intervals = ((PyObject*)Py_None); Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  return 0;
+}
+
+static PyMethodDef __pyx_methods_2bx_3bbi_11bigwig_file_IntervalAccumulatingBlockHandler[] = {
+  {0, 0, 0, 0}
+};
+
+static PyTypeObject __pyx_type_2bx_3bbi_11bigwig_file_IntervalAccumulatingBlockHandler = {
+  PyVarObject_HEAD_INIT(0, 0)
+  "bx.bbi.bigwig_file.IntervalAccumulatingBlockHandler", /*tp_name*/
+  sizeof(struct __pyx_obj_2bx_3bbi_11bigwig_file_IntervalAccumulatingBlockHandler), /*tp_basicsize*/
+  0, /*tp_itemsize*/
+  __pyx_tp_dealloc_2bx_3bbi_11bigwig_file_IntervalAccumulatingBlockHandler, /*tp_dealloc*/
+  0, /*tp_print*/
+  0, /*tp_getattr*/
+  0, /*tp_setattr*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*tp_compare*/
+  #else
+  0, /*reserved*/
+  #endif
+  0, /*tp_repr*/
+  0, /*tp_as_number*/
+  0, /*tp_as_sequence*/
+  0, /*tp_as_mapping*/
+  0, /*tp_hash*/
+  0, /*tp_call*/
+  0, /*tp_str*/
+  0, /*tp_getattro*/
+  0, /*tp_setattro*/
+  0, /*tp_as_buffer*/
+  Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+  0, /*tp_doc*/
+  __pyx_tp_traverse_2bx_3bbi_11bigwig_file_IntervalAccumulatingBlockHandler, /*tp_traverse*/
+  __pyx_tp_clear_2bx_3bbi_11bigwig_file_IntervalAccumulatingBlockHandler, /*tp_clear*/
+  0, /*tp_richcompare*/
+  0, /*tp_weaklistoffset*/
+  0, /*tp_iter*/
+  0, /*tp_iternext*/
+  __pyx_methods_2bx_3bbi_11bigwig_file_IntervalAccumulatingBlockHandler, /*tp_methods*/
+  0, /*tp_members*/
+  0, /*tp_getset*/
+  0, /*tp_base*/
+  0, /*tp_dict*/
+  0, /*tp_descr_get*/
+  0, /*tp_descr_set*/
+  0, /*tp_dictoffset*/
+  __pyx_pw_2bx_3bbi_11bigwig_file_32IntervalAccumulatingBlockHandler_1__init__, /*tp_init*/
+  0, /*tp_alloc*/
+  __pyx_tp_new_2bx_3bbi_11bigwig_file_IntervalAccumulatingBlockHandler, /*tp_new*/
+  0, /*tp_free*/
+  0, /*tp_is_gc*/
+  0, /*tp_bases*/
+  0, /*tp_mro*/
+  0, /*tp_cache*/
+  0, /*tp_subclasses*/
+  0, /*tp_weaklist*/
+  0, /*tp_del*/
+  0, /*tp_version_tag*/
+  #if PY_VERSION_HEX >= 0x030400a1
+  0, /*tp_finalize*/
+  #endif
+};
+static struct __pyx_vtabstruct_2bx_3bbi_11bigwig_file_ArrayAccumulatingBlockHandler __pyx_vtable_2bx_3bbi_11bigwig_file_ArrayAccumulatingBlockHandler;
+
+static PyObject *__pyx_tp_new_2bx_3bbi_11bigwig_file_ArrayAccumulatingBlockHandler(PyTypeObject *t, PyObject *a, PyObject *k) {
+  struct __pyx_obj_2bx_3bbi_11bigwig_file_ArrayAccumulatingBlockHandler *p;
+  PyObject *o = __pyx_tp_new_2bx_3bbi_11bigwig_file_BigWigBlockHandler(t, a, k);
+  if (unlikely(!o)) return 0;
+  p = ((struct __pyx_obj_2bx_3bbi_11bigwig_file_ArrayAccumulatingBlockHandler *)o);
+  p->__pyx_base.__pyx_base.__pyx_vtab = (struct __pyx_vtabstruct_2bx_3bbi_8bbi_file_BlockHandler*)__pyx_vtabptr_2bx_3bbi_11bigwig_file_ArrayAccumulatingBlockHandler;
+  p->array = ((PyArrayObject *)Py_None); Py_INCREF(Py_None);
+  return o;
+}
+
+static void __pyx_tp_dealloc_2bx_3bbi_11bigwig_file_ArrayAccumulatingBlockHandler(PyObject *o) {
+  struct __pyx_obj_2bx_3bbi_11bigwig_file_ArrayAccumulatingBlockHandler *p = (struct __pyx_obj_2bx_3bbi_11bigwig_file_ArrayAccumulatingBlockHandler *)o;
+  #if PY_VERSION_HEX >= 0x030400a1
+  if (unlikely(Py_TYPE(o)->tp_finalize) && !_PyGC_FINALIZED(o)) {
+    if (PyObject_CallFinalizerFromDealloc(o)) return;
+  }
+  #endif
+  PyObject_GC_UnTrack(o);
+  Py_CLEAR(p->array);
+  #if CYTHON_COMPILING_IN_CPYTHON
+  if (PyType_IS_GC(Py_TYPE(o)->tp_base))
+  #endif
+  PyObject_GC_Track(o);
+  __pyx_tp_dealloc_2bx_3bbi_11bigwig_file_BigWigBlockHandler(o);
+}
+
+static int __pyx_tp_traverse_2bx_3bbi_11bigwig_file_ArrayAccumulatingBlockHandler(PyObject *o, visitproc v, void *a) {
+  int e;
+  struct __pyx_obj_2bx_3bbi_11bigwig_file_ArrayAccumulatingBlockHandler *p = (struct __pyx_obj_2bx_3bbi_11bigwig_file_ArrayAccumulatingBlockHandler *)o;
+  e = ((likely(__pyx_ptype_2bx_3bbi_11bigwig_file_BigWigBlockHandler)) ? ((__pyx_ptype_2bx_3bbi_11bigwig_file_BigWigBlockHandler->tp_traverse) ? __pyx_ptype_2bx_3bbi_11bigwig_file_BigWigBlockHandler->tp_traverse(o, v, a) : 0) : __Pyx_call_next_tp_traverse(o, v, a, __pyx_tp_traverse_2bx_3bbi_11bigwig_file_ArrayAccumulatingBlockHandler)); if (e) return e;
+  if (p->array) {
+    e = (*v)(((PyObject*)p->array), a); if (e) return e;
+  }
+  return 0;
+}
+
+static int __pyx_tp_clear_2bx_3bbi_11bigwig_file_ArrayAccumulatingBlockHandler(PyObject *o) {
+  PyObject* tmp;
+  struct __pyx_obj_2bx_3bbi_11bigwig_file_ArrayAccumulatingBlockHandler *p = (struct __pyx_obj_2bx_3bbi_11bigwig_file_ArrayAccumulatingBlockHandler *)o;
+  if (likely(__pyx_ptype_2bx_3bbi_11bigwig_file_BigWigBlockHandler)) { if (__pyx_ptype_2bx_3bbi_11bigwig_file_BigWigBlockHandler->tp_clear) __pyx_ptype_2bx_3bbi_11bigwig_file_BigWigBlockHandler->tp_clear(o); } else __Pyx_call_next_tp_clear(o, __pyx_tp_clear_2bx_3bbi_11bigwig_file_ArrayAccumulatingBlockHandler);
+  tmp = ((PyObject*)p->array);
+  p->array = ((PyArrayObject *)Py_None); Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  return 0;
+}
+
+static PyMethodDef __pyx_methods_2bx_3bbi_11bigwig_file_ArrayAccumulatingBlockHandler[] = {
+  {0, 0, 0, 0}
+};
+
+static PyTypeObject __pyx_type_2bx_3bbi_11bigwig_file_ArrayAccumulatingBlockHandler = {
+  PyVarObject_HEAD_INIT(0, 0)
+  "bx.bbi.bigwig_file.ArrayAccumulatingBlockHandler", /*tp_name*/
+  sizeof(struct __pyx_obj_2bx_3bbi_11bigwig_file_ArrayAccumulatingBlockHandler), /*tp_basicsize*/
+  0, /*tp_itemsize*/
+  __pyx_tp_dealloc_2bx_3bbi_11bigwig_file_ArrayAccumulatingBlockHandler, /*tp_dealloc*/
+  0, /*tp_print*/
+  0, /*tp_getattr*/
+  0, /*tp_setattr*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*tp_compare*/
+  #else
+  0, /*reserved*/
+  #endif
+  0, /*tp_repr*/
+  0, /*tp_as_number*/
+  0, /*tp_as_sequence*/
+  0, /*tp_as_mapping*/
+  0, /*tp_hash*/
+  0, /*tp_call*/
+  0, /*tp_str*/
+  0, /*tp_getattro*/
+  0, /*tp_setattro*/
+  0, /*tp_as_buffer*/
+  Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+  "\n    Accumulates intervals into a list of intervals with values\n    ", /*tp_doc*/
+  __pyx_tp_traverse_2bx_3bbi_11bigwig_file_ArrayAccumulatingBlockHandler, /*tp_traverse*/
+  __pyx_tp_clear_2bx_3bbi_11bigwig_file_ArrayAccumulatingBlockHandler, /*tp_clear*/
+  0, /*tp_richcompare*/
+  0, /*tp_weaklistoffset*/
+  0, /*tp_iter*/
+  0, /*tp_iternext*/
+  __pyx_methods_2bx_3bbi_11bigwig_file_ArrayAccumulatingBlockHandler, /*tp_methods*/
+  0, /*tp_members*/
+  0, /*tp_getset*/
+  0, /*tp_base*/
+  0, /*tp_dict*/
+  0, /*tp_descr_get*/
+  0, /*tp_descr_set*/
+  0, /*tp_dictoffset*/
+  __pyx_pw_2bx_3bbi_11bigwig_file_29ArrayAccumulatingBlockHandler_1__init__, /*tp_init*/
+  0, /*tp_alloc*/
+  __pyx_tp_new_2bx_3bbi_11bigwig_file_ArrayAccumulatingBlockHandler, /*tp_new*/
+  0, /*tp_free*/
+  0, /*tp_is_gc*/
+  0, /*tp_bases*/
+  0, /*tp_mro*/
+  0, /*tp_cache*/
+  0, /*tp_subclasses*/
+  0, /*tp_weaklist*/
+  0, /*tp_del*/
+  0, /*tp_version_tag*/
+  #if PY_VERSION_HEX >= 0x030400a1
+  0, /*tp_finalize*/
+  #endif
+};
+static struct __pyx_vtabstruct_2bx_3bbi_11bigwig_file_BigWigFile __pyx_vtable_2bx_3bbi_11bigwig_file_BigWigFile;
+
+static PyObject *__pyx_tp_new_2bx_3bbi_11bigwig_file_BigWigFile(PyTypeObject *t, PyObject *a, PyObject *k) {
+  struct __pyx_obj_2bx_3bbi_11bigwig_file_BigWigFile *p;
+  PyObject *o = __pyx_ptype_2bx_3bbi_8bbi_file_BBIFile->tp_new(t, a, k);
+  if (unlikely(!o)) return 0;
+  p = ((struct __pyx_obj_2bx_3bbi_11bigwig_file_BigWigFile *)o);
+  p->__pyx_base.__pyx_vtab = (struct __pyx_vtabstruct_2bx_3bbi_8bbi_file_BBIFile*)__pyx_vtabptr_2bx_3bbi_11bigwig_file_BigWigFile;
+  return o;
+}
+
+static void __pyx_tp_dealloc_2bx_3bbi_11bigwig_file_BigWigFile(PyObject *o) {
+  #if PY_VERSION_HEX >= 0x030400a1
+  if (unlikely(Py_TYPE(o)->tp_finalize) && !_PyGC_FINALIZED(o)) {
+    if (PyObject_CallFinalizerFromDealloc(o)) return;
+  }
+  #endif
+  PyObject_GC_UnTrack(o);
+  PyObject_GC_Track(o);
+  if (likely(__pyx_ptype_2bx_3bbi_8bbi_file_BBIFile)) __pyx_ptype_2bx_3bbi_8bbi_file_BBIFile->tp_dealloc(o); else __Pyx_call_next_tp_dealloc(o, __pyx_tp_dealloc_2bx_3bbi_11bigwig_file_BigWigFile);
+}
+
+static int __pyx_tp_traverse_2bx_3bbi_11bigwig_file_BigWigFile(PyObject *o, visitproc v, void *a) {
+  int e;
+  e = ((likely(__pyx_ptype_2bx_3bbi_8bbi_file_BBIFile)) ? ((__pyx_ptype_2bx_3bbi_8bbi_file_BBIFile->tp_traverse) ? __pyx_ptype_2bx_3bbi_8bbi_file_BBIFile->tp_traverse(o, v, a) : 0) : __Pyx_call_next_tp_traverse(o, v, a, __pyx_tp_traverse_2bx_3bbi_11bigwig_file_BigWigFile)); if (e) return e;
+  return 0;
+}
+
+static int __pyx_tp_clear_2bx_3bbi_11bigwig_file_BigWigFile(PyObject *o) {
+  if (likely(__pyx_ptype_2bx_3bbi_8bbi_file_BBIFile)) { if (__pyx_ptype_2bx_3bbi_8bbi_file_BBIFile->tp_clear) __pyx_ptype_2bx_3bbi_8bbi_file_BBIFile->tp_clear(o); } else __Pyx_call_next_tp_clear(o, __pyx_tp_clear_2bx_3bbi_11bigwig_file_BigWigFile);
+  return 0;
+}
+
+static PyMethodDef __pyx_methods_2bx_3bbi_11bigwig_file_BigWigFile[] = {
+  {"get", (PyCFunction)__pyx_pw_2bx_3bbi_11bigwig_file_10BigWigFile_3get, METH_VARARGS|METH_KEYWORDS, __pyx_doc_2bx_3bbi_11bigwig_file_10BigWigFile_2get},
+  {"get_as_array", (PyCFunction)__pyx_pw_2bx_3bbi_11bigwig_file_10BigWigFile_5get_as_array, METH_VARARGS|METH_KEYWORDS, __pyx_doc_2bx_3bbi_11bigwig_file_10BigWigFile_4get_as_array},
+  {0, 0, 0, 0}
+};
+
+static PyTypeObject __pyx_type_2bx_3bbi_11bigwig_file_BigWigFile = {
+  PyVarObject_HEAD_INIT(0, 0)
+  "bx.bbi.bigwig_file.BigWigFile", /*tp_name*/
+  sizeof(struct __pyx_obj_2bx_3bbi_11bigwig_file_BigWigFile), /*tp_basicsize*/
+  0, /*tp_itemsize*/
+  __pyx_tp_dealloc_2bx_3bbi_11bigwig_file_BigWigFile, /*tp_dealloc*/
+  0, /*tp_print*/
+  0, /*tp_getattr*/
+  0, /*tp_setattr*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*tp_compare*/
+  #else
+  0, /*reserved*/
+  #endif
+  0, /*tp_repr*/
+  0, /*tp_as_number*/
+  0, /*tp_as_sequence*/
+  0, /*tp_as_mapping*/
+  0, /*tp_hash*/
+  0, /*tp_call*/
+  0, /*tp_str*/
+  0, /*tp_getattro*/
+  0, /*tp_setattro*/
+  0, /*tp_as_buffer*/
+  Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+  "\n    A \"big binary indexed\" file whose raw data is in wiggle format.\n    ", /*tp_doc*/
+  __pyx_tp_traverse_2bx_3bbi_11bigwig_file_BigWigFile, /*tp_traverse*/
+  __pyx_tp_clear_2bx_3bbi_11bigwig_file_BigWigFile, /*tp_clear*/
+  0, /*tp_richcompare*/
+  0, /*tp_weaklistoffset*/
+  0, /*tp_iter*/
+  0, /*tp_iternext*/
+  __pyx_methods_2bx_3bbi_11bigwig_file_BigWigFile, /*tp_methods*/
+  0, /*tp_members*/
+  0, /*tp_getset*/
+  0, /*tp_base*/
+  0, /*tp_dict*/
+  0, /*tp_descr_get*/
+  0, /*tp_descr_set*/
+  0, /*tp_dictoffset*/
+  __pyx_pw_2bx_3bbi_11bigwig_file_10BigWigFile_1__init__, /*tp_init*/
+  0, /*tp_alloc*/
+  __pyx_tp_new_2bx_3bbi_11bigwig_file_BigWigFile, /*tp_new*/
+  0, /*tp_free*/
+  0, /*tp_is_gc*/
+  0, /*tp_bases*/
+  0, /*tp_mro*/
+  0, /*tp_cache*/
+  0, /*tp_subclasses*/
+  0, /*tp_weaklist*/
+  0, /*tp_del*/
+  0, /*tp_version_tag*/
+  #if PY_VERSION_HEX >= 0x030400a1
+  0, /*tp_finalize*/
+  #endif
+};
+
+static PyMethodDef __pyx_methods[] = {
+  {0, 0, 0, 0}
+};
+
+#if PY_MAJOR_VERSION >= 3
+static struct PyModuleDef __pyx_moduledef = {
+  #if PY_VERSION_HEX < 0x03020000
+    { PyObject_HEAD_INIT(NULL) NULL, 0, NULL },
+  #else
+    PyModuleDef_HEAD_INIT,
+  #endif
+    "bigwig_file",
+    __pyx_k_BigWig_file, /* m_doc */
+    -1, /* m_size */
+    __pyx_methods /* m_methods */,
+    NULL, /* m_reload */
+    NULL, /* m_traverse */
+    NULL, /* m_clear */
+    NULL /* m_free */
+};
+#endif
+
+static __Pyx_StringTabEntry __pyx_string_tab[] = {
+  {&__pyx_n_s_BinaryFileReader, __pyx_k_BinaryFileReader, sizeof(__pyx_k_BinaryFileReader), 0, 0, 1, 1},
+  {&__pyx_kp_u_Format_string_allocated_too_shor, __pyx_k_Format_string_allocated_too_shor, sizeof(__pyx_k_Format_string_allocated_too_shor), 0, 1, 0, 0},
+  {&__pyx_kp_u_Format_string_allocated_too_shor_2, __pyx_k_Format_string_allocated_too_shor_2, sizeof(__pyx_k_Format_string_allocated_too_shor_2), 0, 1, 0, 0},
+  {&__pyx_n_s_LLLLLBBH, __pyx_k_LLLLLBBH, sizeof(__pyx_k_LLLLLBBH), 0, 0, 1, 1},
+  {&__pyx_n_s_LLf, __pyx_k_LLf, sizeof(__pyx_k_LLf), 0, 0, 1, 1},
+  {&__pyx_n_s_Lf, __pyx_k_Lf, sizeof(__pyx_k_Lf), 0, 0, 1, 1},
+  {&__pyx_kp_u_Non_native_byte_order_not_suppor, __pyx_k_Non_native_byte_order_not_suppor, sizeof(__pyx_k_Non_native_byte_order_not_suppor), 0, 1, 0, 0},
+  {&__pyx_n_s_RuntimeError, __pyx_k_RuntimeError, sizeof(__pyx_k_RuntimeError), 0, 0, 1, 1},
+  {&__pyx_n_s_StringIO, __pyx_k_StringIO, sizeof(__pyx_k_StringIO), 0, 0, 1, 1},
+  {&__pyx_n_s_ValueError, __pyx_k_ValueError, sizeof(__pyx_k_ValueError), 0, 0, 1, 1},
+  {&__pyx_n_s_bigwig, __pyx_k_bigwig, sizeof(__pyx_k_bigwig), 0, 0, 1, 1},
+  {&__pyx_n_s_bx_bbi_bigwig_file, __pyx_k_bx_bbi_bigwig_file, sizeof(__pyx_k_bx_bbi_bigwig_file), 0, 0, 1, 1},
+  {&__pyx_n_s_bx_misc_binary_file, __pyx_k_bx_misc_binary_file, sizeof(__pyx_k_bx_misc_binary_file), 0, 0, 1, 1},
+  {&__pyx_n_s_cStringIO, __pyx_k_cStringIO, sizeof(__pyx_k_cStringIO), 0, 0, 1, 1},
+  {&__pyx_n_s_chrom, __pyx_k_chrom, sizeof(__pyx_k_chrom), 0, 0, 1, 1},
+  {&__pyx_n_s_chunks, __pyx_k_chunks, sizeof(__pyx_k_chunks), 0, 0, 1, 1},
+  {&__pyx_n_s_collections, __pyx_k_collections, sizeof(__pyx_k_collections), 0, 0, 1, 1},
+  {&__pyx_n_s_deque, __pyx_k_deque, sizeof(__pyx_k_deque), 0, 0, 1, 1},
+  {&__pyx_n_s_dtype, __pyx_k_dtype, sizeof(__pyx_k_dtype), 0, 0, 1, 1},
+  {&__pyx_n_s_end, __pyx_k_end, sizeof(__pyx_k_end), 0, 0, 1, 1},
+  {&__pyx_n_s_enumerate, __pyx_k_enumerate, sizeof(__pyx_k_enumerate), 0, 0, 1, 1},
+  {&__pyx_n_s_f, __pyx_k_f, sizeof(__pyx_k_f), 0, 0, 1, 1},
+  {&__pyx_n_s_file, __pyx_k_file, sizeof(__pyx_k_file), 0, 0, 1, 1},
+  {&__pyx_n_s_float32, __pyx_k_float32, sizeof(__pyx_k_float32), 0, 0, 1, 1},
+  {&__pyx_n_s_get, __pyx_k_get, sizeof(__pyx_k_get), 0, 0, 1, 1},
+  {&__pyx_n_s_get_as_array, __pyx_k_get_as_array, sizeof(__pyx_k_get_as_array), 0, 0, 1, 1},
+  {&__pyx_n_s_i, __pyx_k_i, sizeof(__pyx_k_i), 0, 0, 1, 1},
+  {&__pyx_n_s_import, __pyx_k_import, sizeof(__pyx_k_import), 0, 0, 1, 1},
+  {&__pyx_n_s_inf, __pyx_k_inf, sizeof(__pyx_k_inf), 0, 0, 1, 1},
+  {&__pyx_n_s_init, __pyx_k_init, sizeof(__pyx_k_init), 0, 0, 1, 1},
+  {&__pyx_n_s_is_little_endian, __pyx_k_is_little_endian, sizeof(__pyx_k_is_little_endian), 0, 0, 1, 1},
+  {&__pyx_n_s_l, __pyx_k_l, sizeof(__pyx_k_l), 0, 0, 1, 1},
+  {&__pyx_n_s_main, __pyx_k_main, sizeof(__pyx_k_main), 0, 0, 1, 1},
+  {&__pyx_n_s_n, __pyx_k_n, sizeof(__pyx_k_n), 0, 0, 1, 1},
+  {&__pyx_n_s_nan, __pyx_k_nan, sizeof(__pyx_k_nan), 0, 0, 1, 1},
+  {&__pyx_kp_u_ndarray_is_not_C_contiguous, __pyx_k_ndarray_is_not_C_contiguous, sizeof(__pyx_k_ndarray_is_not_C_contiguous), 0, 1, 0, 0},
+  {&__pyx_kp_u_ndarray_is_not_Fortran_contiguou, __pyx_k_ndarray_is_not_Fortran_contiguou, sizeof(__pyx_k_ndarray_is_not_Fortran_contiguou), 0, 1, 0, 0},
+  {&__pyx_n_s_numpy, __pyx_k_numpy, sizeof(__pyx_k_numpy), 0, 0, 1, 1},
+  {&__pyx_n_s_pyx_vtable, __pyx_k_pyx_vtable, sizeof(__pyx_k_pyx_vtable), 0, 0, 1, 1},
+  {&__pyx_n_s_range, __pyx_k_range, sizeof(__pyx_k_range), 0, 0, 1, 1},
+  {&__pyx_n_s_read_and_unpack, __pyx_k_read_and_unpack, sizeof(__pyx_k_read_and_unpack), 0, 0, 1, 1},
+  {&__pyx_n_s_round, __pyx_k_round, sizeof(__pyx_k_round), 0, 0, 1, 1},
+  {&__pyx_n_s_start, __pyx_k_start, sizeof(__pyx_k_start), 0, 0, 1, 1},
+  {&__pyx_n_s_summary_size, __pyx_k_summary_size, sizeof(__pyx_k_summary_size), 0, 0, 1, 1},
+  {&__pyx_n_s_test, __pyx_k_test, sizeof(__pyx_k_test), 0, 0, 1, 1},
+  {&__pyx_kp_u_unknown_dtype_code_in_numpy_pxd, __pyx_k_unknown_dtype_code_in_numpy_pxd, sizeof(__pyx_k_unknown_dtype_code_in_numpy_pxd), 0, 1, 0, 0},
+  {&__pyx_kp_s_usr_local_src_bx_python_mod_lib, __pyx_k_usr_local_src_bx_python_mod_lib, sizeof(__pyx_k_usr_local_src_bx_python_mod_lib), 0, 0, 1, 0},
+  {&__pyx_n_s_zeros, __pyx_k_zeros, sizeof(__pyx_k_zeros), 0, 0, 1, 1},
+  {&__pyx_n_s_zlib, __pyx_k_zlib, sizeof(__pyx_k_zlib), 0, 0, 1, 1},
+  {0, 0, 0, 0, 0, 0, 0}
+};
+static int __Pyx_InitCachedBuiltins(void) {
+  __pyx_builtin_range = __Pyx_GetBuiltinName(__pyx_n_s_range); if (!__pyx_builtin_range) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 26; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_builtin_enumerate = __Pyx_GetBuiltinName(__pyx_n_s_enumerate); if (!__pyx_builtin_enumerate) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 58; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_builtin_round = __Pyx_GetBuiltinName(__pyx_n_s_round); if (!__pyx_builtin_round) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 131; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_builtin_ValueError = __Pyx_GetBuiltinName(__pyx_n_s_ValueError); if (!__pyx_builtin_ValueError) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 218; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_builtin_RuntimeError = __Pyx_GetBuiltinName(__pyx_n_s_RuntimeError); if (!__pyx_builtin_RuntimeError) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 802; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  return 0;
+  __pyx_L1_error:;
+  return -1;
+}
+
+static int __Pyx_InitCachedConstants(void) {
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0);
+
+  /* "bx/bbi/bigwig_file.pyx":48
+ *         block_reader = BinaryFileReader( StringIO( block_data ), is_little_endian=bbi_file.reader.is_little_endian )
+ *         # _ is skipped byte
+ *         b_chrom_id, b_start, b_end, b_item_step, b_item_span, b_type, _, b_item_count = block_reader.read_and_unpack("LLLLLBBH", 5*4+1+1+2)             # <<<<<<<<<<<<<<
+ * 
+ *         if b_type == bwg_bed_graph:
+ */
+  __pyx_tuple_ = PyTuple_Pack(2, __pyx_n_s_LLLLLBBH, __pyx_int_24); if (unlikely(!__pyx_tuple_)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 48; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple_);
+  __Pyx_GIVEREF(__pyx_tuple_);
+
+  /* "bx/bbi/bigwig_file.pyx":83
+ *         # What we will load into
+ *         self.sd = SummarizedData( start, end, summary_size )
+ *         self.sd.min_val[:] = numpy.inf             # <<<<<<<<<<<<<<
+ *         self.sd.max_val[:] = -numpy.inf
+ * 
+ */
+  __pyx_slice__2 = PySlice_New(Py_None, Py_None, Py_None); if (unlikely(!__pyx_slice__2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 83; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_slice__2);
+  __Pyx_GIVEREF(__pyx_slice__2);
+
+  /* "bx/bbi/bigwig_file.pyx":84
+ *         self.sd = SummarizedData( start, end, summary_size )
+ *         self.sd.min_val[:] = numpy.inf
+ *         self.sd.max_val[:] = -numpy.inf             # <<<<<<<<<<<<<<
+ * 
+ *     cdef inline handle_interval_value( self, bits32 s, bits32 e, float val ):
+ */
+  __pyx_slice__3 = PySlice_New(Py_None, Py_None, Py_None); if (unlikely(!__pyx_slice__3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 84; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_slice__3);
+  __Pyx_GIVEREF(__pyx_slice__3);
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":218
+ *             if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)
+ *                 and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)):
+ *                 raise ValueError(u"ndarray is not C contiguous")             # <<<<<<<<<<<<<<
+ * 
+ *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
+ */
+  __pyx_tuple__4 = PyTuple_Pack(1, __pyx_kp_u_ndarray_is_not_C_contiguous); if (unlikely(!__pyx_tuple__4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 218; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__4);
+  __Pyx_GIVEREF(__pyx_tuple__4);
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":222
+ *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
+ *                 and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)):
+ *                 raise ValueError(u"ndarray is not Fortran contiguous")             # <<<<<<<<<<<<<<
+ * 
+ *             info.buf = PyArray_DATA(self)
+ */
+  __pyx_tuple__5 = PyTuple_Pack(1, __pyx_kp_u_ndarray_is_not_Fortran_contiguou); if (unlikely(!__pyx_tuple__5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 222; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__5);
+  __Pyx_GIVEREF(__pyx_tuple__5);
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":260
+ *                 if ((descr.byteorder == c'>' and little_endian) or
+ *                     (descr.byteorder == c'<' and not little_endian)):
+ *                     raise ValueError(u"Non-native byte order not supported")             # <<<<<<<<<<<<<<
+ *                 if   t == NPY_BYTE:        f = "b"
+ *                 elif t == NPY_UBYTE:       f = "B"
+ */
+  __pyx_tuple__6 = PyTuple_Pack(1, __pyx_kp_u_Non_native_byte_order_not_suppor); if (unlikely(!__pyx_tuple__6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 260; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__6);
+  __Pyx_GIVEREF(__pyx_tuple__6);
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":802
+ * 
+ *         if (end - f) - <int>(new_offset - offset[0]) < 15:
+ *             raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd")             # <<<<<<<<<<<<<<
+ * 
+ *         if ((child.byteorder == c'>' and little_endian) or
+ */
+  __pyx_tuple__7 = PyTuple_Pack(1, __pyx_kp_u_Format_string_allocated_too_shor); if (unlikely(!__pyx_tuple__7)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 802; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__7);
+  __Pyx_GIVEREF(__pyx_tuple__7);
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":806
+ *         if ((child.byteorder == c'>' and little_endian) or
+ *             (child.byteorder == c'<' and not little_endian)):
+ *             raise ValueError(u"Non-native byte order not supported")             # <<<<<<<<<<<<<<
+ *             # One could encode it in the format string and have Cython
+ *             # complain instead, BUT: < and > in format strings also imply
+ */
+  __pyx_tuple__8 = PyTuple_Pack(1, __pyx_kp_u_Non_native_byte_order_not_suppor); if (unlikely(!__pyx_tuple__8)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 806; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__8);
+  __Pyx_GIVEREF(__pyx_tuple__8);
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":826
+ *             t = child.type_num
+ *             if end - f < 5:
+ *                 raise RuntimeError(u"Format string allocated too short.")             # <<<<<<<<<<<<<<
+ * 
+ *             # Until ticket #99 is fixed, use integers to avoid warnings
+ */
+  __pyx_tuple__9 = PyTuple_Pack(1, __pyx_kp_u_Format_string_allocated_too_shor_2); if (unlikely(!__pyx_tuple__9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 826; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__9);
+  __Pyx_GIVEREF(__pyx_tuple__9);
+
+  /* "bx/bbi/bigwig_file.pyx":24
+ *     return min( end1, end2 ) - max( start1, start2 )
+ * 
+ * def chunks(l, n):             # <<<<<<<<<<<<<<
+ *     n = max(1, n)
+ *     return [l[i:i + n] for i in range(0, len(l), n)]
+ */
+  __pyx_tuple__10 = PyTuple_Pack(3, __pyx_n_s_l, __pyx_n_s_n, __pyx_n_s_i); if (unlikely(!__pyx_tuple__10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 24; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__10);
+  __Pyx_GIVEREF(__pyx_tuple__10);
+  __pyx_codeobj__11 = (PyObject*)__Pyx_PyCode_New(2, 0, 3, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__10, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_usr_local_src_bx_python_mod_lib, __pyx_n_s_chunks, 24, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 24; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_RefNannyFinishContext();
+  return 0;
+  __pyx_L1_error:;
+  __Pyx_RefNannyFinishContext();
+  return -1;
+}
+
+static int __Pyx_InitGlobals(void) {
+  if (__Pyx_InitStrings(__pyx_string_tab) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  __pyx_int_0 = PyInt_FromLong(0); if (unlikely(!__pyx_int_0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_int_1 = PyInt_FromLong(1); if (unlikely(!__pyx_int_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_int_2 = PyInt_FromLong(2); if (unlikely(!__pyx_int_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_int_3 = PyInt_FromLong(3); if (unlikely(!__pyx_int_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_int_24 = PyInt_FromLong(24); if (unlikely(!__pyx_int_24)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_int_2291137574 = PyInt_FromString((char *)"2291137574", 0, 0); if (unlikely(!__pyx_int_2291137574)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  return 0;
+  __pyx_L1_error:;
+  return -1;
+}
+
+#if PY_MAJOR_VERSION < 3
+PyMODINIT_FUNC initbigwig_file(void); /*proto*/
+PyMODINIT_FUNC initbigwig_file(void)
+#else
+PyMODINIT_FUNC PyInit_bigwig_file(void); /*proto*/
+PyMODINIT_FUNC PyInit_bigwig_file(void)
+#endif
+{
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannyDeclarations
+  #if CYTHON_REFNANNY
+  __Pyx_RefNanny = __Pyx_RefNannyImportAPI("refnanny");
+  if (!__Pyx_RefNanny) {
+      PyErr_Clear();
+      __Pyx_RefNanny = __Pyx_RefNannyImportAPI("Cython.Runtime.refnanny");
+      if (!__Pyx_RefNanny)
+          Py_FatalError("failed to import 'refnanny' module");
+  }
+  #endif
+  __Pyx_RefNannySetupContext("PyMODINIT_FUNC PyInit_bigwig_file(void)", 0);
+  if ( __Pyx_check_binary_version() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_bytes)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #ifdef __Pyx_CyFunction_USED
+  if (__Pyx_CyFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #endif
+  #ifdef __Pyx_FusedFunction_USED
+  if (__pyx_FusedFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #endif
+  #ifdef __Pyx_Generator_USED
+  if (__pyx_Generator_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #endif
+  /*--- Library function declarations ---*/
+  /*--- Threads initialization code ---*/
+  #if defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS
+  #ifdef WITH_THREAD /* Python build with threading support? */
+  PyEval_InitThreads();
+  #endif
+  #endif
+  /*--- Module creation code ---*/
+  #if PY_MAJOR_VERSION < 3
+  __pyx_m = Py_InitModule4("bigwig_file", __pyx_methods, __pyx_k_BigWig_file, 0, PYTHON_API_VERSION); Py_XINCREF(__pyx_m);
+  #else
+  __pyx_m = PyModule_Create(&__pyx_moduledef);
+  #endif
+  if (unlikely(!__pyx_m)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_d = PyModule_GetDict(__pyx_m); if (unlikely(!__pyx_d)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  Py_INCREF(__pyx_d);
+  __pyx_b = PyImport_AddModule(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_b)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #if CYTHON_COMPILING_IN_PYPY
+  Py_INCREF(__pyx_b);
+  #endif
+  if (PyObject_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  /*--- Initialize various global constants etc. ---*/
+  if (unlikely(__Pyx_InitGlobals() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #if PY_MAJOR_VERSION < 3 && (__PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT)
+  if (__Pyx_init_sys_getdefaultencoding_params() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #endif
+  if (__pyx_module_is_main_bx__bbi__bigwig_file) {
+    if (PyObject_SetAttrString(__pyx_m, "__name__", __pyx_n_s_main) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  }
+  #if PY_MAJOR_VERSION >= 3
+  {
+    PyObject *modules = PyImport_GetModuleDict(); if (unlikely(!modules)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (!PyDict_GetItemString(modules, "bx.bbi.bigwig_file")) {
+      if (unlikely(PyDict_SetItemString(modules, "bx.bbi.bigwig_file", __pyx_m) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+  }
+  #endif
+  /*--- Builtin init code ---*/
+  if (unlikely(__Pyx_InitCachedBuiltins() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  /*--- Constants init code ---*/
+  if (unlikely(__Pyx_InitCachedConstants() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  /*--- Global init code ---*/
+  /*--- Variable export code ---*/
+  /*--- Function export code ---*/
+  /*--- Type init code ---*/
+  __pyx_ptype_2bx_3bbi_8bbi_file_BlockHandler = __Pyx_ImportType("bx.bbi.bbi_file", "BlockHandler", sizeof(struct __pyx_obj_2bx_3bbi_8bbi_file_BlockHandler), 1); if (unlikely(!__pyx_ptype_2bx_3bbi_8bbi_file_BlockHandler)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_vtabptr_2bx_3bbi_8bbi_file_BlockHandler = (struct __pyx_vtabstruct_2bx_3bbi_8bbi_file_BlockHandler*)__Pyx_GetVtable(__pyx_ptype_2bx_3bbi_8bbi_file_BlockHandler->tp_dict); if (unlikely(!__pyx_vtabptr_2bx_3bbi_8bbi_file_BlockHandler)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_vtabptr_2bx_3bbi_11bigwig_file_BigWigBlockHandler = &__pyx_vtable_2bx_3bbi_11bigwig_file_BigWigBlockHandler;
+  __pyx_vtable_2bx_3bbi_11bigwig_file_BigWigBlockHandler.__pyx_base = *__pyx_vtabptr_2bx_3bbi_8bbi_file_BlockHandler;
+  __pyx_vtable_2bx_3bbi_11bigwig_file_BigWigBlockHandler.__pyx_base.handle_block = (PyObject *(*)(struct __pyx_obj_2bx_3bbi_8bbi_file_BlockHandler *, PyObject *, struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *))__pyx_f_2bx_3bbi_11bigwig_file_18BigWigBlockHandler_handle_block;
+  __pyx_vtable_2bx_3bbi_11bigwig_file_BigWigBlockHandler.handle_interval_value = (PyObject *(*)(struct __pyx_obj_2bx_3bbi_11bigwig_file_BigWigBlockHandler *, __pyx_t_2bx_3bbi_5types_bits32, __pyx_t_2bx_3bbi_5types_bits32, float))__pyx_f_2bx_3bbi_11bigwig_file_18BigWigBlockHandler_handle_interval_value;
+  __pyx_type_2bx_3bbi_11bigwig_file_BigWigBlockHandler.tp_base = __pyx_ptype_2bx_3bbi_8bbi_file_BlockHandler;
+  if (PyType_Ready(&__pyx_type_2bx_3bbi_11bigwig_file_BigWigBlockHandler) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 28; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_type_2bx_3bbi_11bigwig_file_BigWigBlockHandler.tp_print = 0;
+  if (__Pyx_SetVtable(__pyx_type_2bx_3bbi_11bigwig_file_BigWigBlockHandler.tp_dict, __pyx_vtabptr_2bx_3bbi_11bigwig_file_BigWigBlockHandler) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 28; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyObject_SetAttrString(__pyx_m, "BigWigBlockHandler", (PyObject *)&__pyx_type_2bx_3bbi_11bigwig_file_BigWigBlockHandler) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 28; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_2bx_3bbi_11bigwig_file_BigWigBlockHandler = &__pyx_type_2bx_3bbi_11bigwig_file_BigWigBlockHandler;
+  __pyx_vtabptr_2bx_3bbi_11bigwig_file_SummarizingBlockHandler = &__pyx_vtable_2bx_3bbi_11bigwig_file_SummarizingBlockHandler;
+  __pyx_vtable_2bx_3bbi_11bigwig_file_SummarizingBlockHandler.__pyx_base = *__pyx_vtabptr_2bx_3bbi_11bigwig_file_BigWigBlockHandler;
+  __pyx_vtable_2bx_3bbi_11bigwig_file_SummarizingBlockHandler.__pyx_base.handle_interval_value = (PyObject *(*)(struct __pyx_obj_2bx_3bbi_11bigwig_file_BigWigBlockHandler *, __pyx_t_2bx_3bbi_5types_bits32, __pyx_t_2bx_3bbi_5types_bits32, float))__pyx_f_2bx_3bbi_11bigwig_file_23SummarizingBlockHandler_handle_interval_value;
+  __pyx_type_2bx_3bbi_11bigwig_file_SummarizingBlockHandler.tp_base = __pyx_ptype_2bx_3bbi_11bigwig_file_BigWigBlockHandler;
+  if (PyType_Ready(&__pyx_type_2bx_3bbi_11bigwig_file_SummarizingBlockHandler) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 74; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_type_2bx_3bbi_11bigwig_file_SummarizingBlockHandler.tp_print = 0;
+  if (__Pyx_SetVtable(__pyx_type_2bx_3bbi_11bigwig_file_SummarizingBlockHandler.tp_dict, __pyx_vtabptr_2bx_3bbi_11bigwig_file_SummarizingBlockHandler) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 74; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyObject_SetAttrString(__pyx_m, "SummarizingBlockHandler", (PyObject *)&__pyx_type_2bx_3bbi_11bigwig_file_SummarizingBlockHandler) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 74; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_2bx_3bbi_11bigwig_file_SummarizingBlockHandler = &__pyx_type_2bx_3bbi_11bigwig_file_SummarizingBlockHandler;
+  __pyx_vtabptr_2bx_3bbi_11bigwig_file_IntervalAccumulatingBlockHandler = &__pyx_vtable_2bx_3bbi_11bigwig_file_IntervalAccumulatingBlockHandler;
+  __pyx_vtable_2bx_3bbi_11bigwig_file_IntervalAccumulatingBlockHandler.__pyx_base = *__pyx_vtabptr_2bx_3bbi_11bigwig_file_BigWigBlockHandler;
+  __pyx_vtable_2bx_3bbi_11bigwig_file_IntervalAccumulatingBlockHandler.__pyx_base.handle_interval_value = (PyObject *(*)(struct __pyx_obj_2bx_3bbi_11bigwig_file_BigWigBlockHandler *, __pyx_t_2bx_3bbi_5types_bits32, __pyx_t_2bx_3bbi_5types_bits32, float))__pyx_f_2bx_3bbi_11bigwig_file_32IntervalAccumulatingBlockHandler_handle_interval_value;
+  __pyx_type_2bx_3bbi_11bigwig_file_IntervalAccumulatingBlockHandler.tp_base = __pyx_ptype_2bx_3bbi_11bigwig_file_BigWigBlockHandler;
+  if (PyType_Ready(&__pyx_type_2bx_3bbi_11bigwig_file_IntervalAccumulatingBlockHandler) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 89; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_type_2bx_3bbi_11bigwig_file_IntervalAccumulatingBlockHandler.tp_print = 0;
+  if (__Pyx_SetVtable(__pyx_type_2bx_3bbi_11bigwig_file_IntervalAccumulatingBlockHandler.tp_dict, __pyx_vtabptr_2bx_3bbi_11bigwig_file_IntervalAccumulatingBlockHandler) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 89; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyObject_SetAttrString(__pyx_m, "IntervalAccumulatingBlockHandler", (PyObject *)&__pyx_type_2bx_3bbi_11bigwig_file_IntervalAccumulatingBlockHandler) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 89; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_2bx_3bbi_11bigwig_file_IntervalAccumulatingBlockHandler = &__pyx_type_2bx_3bbi_11bigwig_file_IntervalAccumulatingBlockHandler;
+  __pyx_vtabptr_2bx_3bbi_11bigwig_file_ArrayAccumulatingBlockHandler = &__pyx_vtable_2bx_3bbi_11bigwig_file_ArrayAccumulatingBlockHandler;
+  __pyx_vtable_2bx_3bbi_11bigwig_file_ArrayAccumulatingBlockHandler.__pyx_base = *__pyx_vtabptr_2bx_3bbi_11bigwig_file_BigWigBlockHandler;
+  __pyx_vtable_2bx_3bbi_11bigwig_file_ArrayAccumulatingBlockHandler.__pyx_base.handle_interval_value = (PyObject *(*)(struct __pyx_obj_2bx_3bbi_11bigwig_file_BigWigBlockHandler *, __pyx_t_2bx_3bbi_5types_bits32, __pyx_t_2bx_3bbi_5types_bits32, float))__pyx_f_2bx_3bbi_11bigwig_file_29ArrayAccumulatingBlockHandler_handle_interval_value;
+  __pyx_type_2bx_3bbi_11bigwig_file_ArrayAccumulatingBlockHandler.tp_base = __pyx_ptype_2bx_3bbi_11bigwig_file_BigWigBlockHandler;
+  if (PyType_Ready(&__pyx_type_2bx_3bbi_11bigwig_file_ArrayAccumulatingBlockHandler) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 101; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_type_2bx_3bbi_11bigwig_file_ArrayAccumulatingBlockHandler.tp_print = 0;
+  if (__Pyx_SetVtable(__pyx_type_2bx_3bbi_11bigwig_file_ArrayAccumulatingBlockHandler.tp_dict, __pyx_vtabptr_2bx_3bbi_11bigwig_file_ArrayAccumulatingBlockHandler) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 101; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyObject_SetAttrString(__pyx_m, "ArrayAccumulatingBlockHandler", (PyObject *)&__pyx_type_2bx_3bbi_11bigwig_file_ArrayAccumulatingBlockHandler) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 101; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_2bx_3bbi_11bigwig_file_ArrayAccumulatingBlockHandler = &__pyx_type_2bx_3bbi_11bigwig_file_ArrayAccumulatingBlockHandler;
+  __pyx_ptype_2bx_3bbi_8bbi_file_BBIFile = __Pyx_ImportType("bx.bbi.bbi_file", "BBIFile", sizeof(struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile), 1); if (unlikely(!__pyx_ptype_2bx_3bbi_8bbi_file_BBIFile)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_vtabptr_2bx_3bbi_8bbi_file_BBIFile = (struct __pyx_vtabstruct_2bx_3bbi_8bbi_file_BBIFile*)__Pyx_GetVtable(__pyx_ptype_2bx_3bbi_8bbi_file_BBIFile->tp_dict); if (unlikely(!__pyx_vtabptr_2bx_3bbi_8bbi_file_BBIFile)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_vtabptr_2bx_3bbi_11bigwig_file_BigWigFile = &__pyx_vtable_2bx_3bbi_11bigwig_file_BigWigFile;
+  __pyx_vtable_2bx_3bbi_11bigwig_file_BigWigFile.__pyx_base = *__pyx_vtabptr_2bx_3bbi_8bbi_file_BBIFile;
+  __pyx_vtable_2bx_3bbi_11bigwig_file_BigWigFile.__pyx_base._summarize_from_full = (PyObject *(*)(struct __pyx_obj_2bx_3bbi_8bbi_file_BBIFile *, __pyx_t_2bx_3bbi_5types_bits32, __pyx_t_2bx_3bbi_5types_bits32, __pyx_t_2bx_3bbi_5types_bits32, int))__pyx_f_2bx_3bbi_11bigwig_file_10BigWigFile__summarize_from_full;
+  __pyx_vtable_2bx_3bbi_11bigwig_file_BigWigFile.get = (PyObject *(*)(struct __pyx_obj_2bx_3bbi_11bigwig_file_BigWigFile *, char *, __pyx_t_2bx_3bbi_5types_bits32, __pyx_t_2bx_3bbi_5types_bits32, int __pyx_skip_dispatch))__pyx_f_2bx_3bbi_11bigwig_file_10BigWigFile_get;
+  __pyx_vtable_2bx_3bbi_11bigwig_file_BigWigFile.get_as_array = (PyObject *(*)(struct __pyx_obj_2bx_3bbi_11bigwig_file_BigWigFile *, char *, __pyx_t_2bx_3bbi_5types_bits32, __pyx_t_2bx_3bbi_5types_bits32, int __pyx_skip_dispatch))__pyx_f_2bx_3bbi_11bigwig_file_10BigWigFile_get_as_array;
+  __pyx_type_2bx_3bbi_11bigwig_file_BigWigFile.tp_base = __pyx_ptype_2bx_3bbi_8bbi_file_BBIFile;
+  if (PyType_Ready(&__pyx_type_2bx_3bbi_11bigwig_file_BigWigFile) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_type_2bx_3bbi_11bigwig_file_BigWigFile.tp_print = 0;
+  if (__Pyx_SetVtable(__pyx_type_2bx_3bbi_11bigwig_file_BigWigFile.tp_dict, __pyx_vtabptr_2bx_3bbi_11bigwig_file_BigWigFile) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyObject_SetAttrString(__pyx_m, "BigWigFile", (PyObject *)&__pyx_type_2bx_3bbi_11bigwig_file_BigWigFile) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_2bx_3bbi_11bigwig_file_BigWigFile = &__pyx_type_2bx_3bbi_11bigwig_file_BigWigFile;
+  /*--- Type import code ---*/
+  __pyx_ptype_2bx_3bbi_8bpt_file_BPTFile = __Pyx_ImportType("bx.bbi.bpt_file", "BPTFile", sizeof(struct __pyx_obj_2bx_3bbi_8bpt_file_BPTFile), 1); if (unlikely(!__pyx_ptype_2bx_3bbi_8bpt_file_BPTFile)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 5; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_2bx_3bbi_12cirtree_file_CIRTreeFile = __Pyx_ImportType("bx.bbi.cirtree_file", "CIRTreeFile", sizeof(struct __pyx_obj_2bx_3bbi_12cirtree_file_CIRTreeFile), 1); if (unlikely(!__pyx_ptype_2bx_3bbi_12cirtree_file_CIRTreeFile)) {__pyx_filename = __pyx_f[3]; __pyx_lineno = 3; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_7cpython_4type_type = __Pyx_ImportType(__Pyx_BUILTIN_MODULE_NAME, "type", 
+  #if CYTHON_COMPILING_IN_PYPY
+  sizeof(PyTypeObject),
+  #else
+  sizeof(PyHeapTypeObject),
+  #endif
+  0); if (unlikely(!__pyx_ptype_7cpython_4type_type)) {__pyx_filename = __pyx_f[4]; __pyx_lineno = 9; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_5numpy_dtype = __Pyx_ImportType("numpy", "dtype", sizeof(PyArray_Descr), 0); if (unlikely(!__pyx_ptype_5numpy_dtype)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 155; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_5numpy_flatiter = __Pyx_ImportType("numpy", "flatiter", sizeof(PyArrayIterObject), 0); if (unlikely(!__pyx_ptype_5numpy_flatiter)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 168; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_5numpy_broadcast = __Pyx_ImportType("numpy", "broadcast", sizeof(PyArrayMultiIterObject), 0); if (unlikely(!__pyx_ptype_5numpy_broadcast)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 172; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_5numpy_ndarray = __Pyx_ImportType("numpy", "ndarray", sizeof(PyArrayObject), 0); if (unlikely(!__pyx_ptype_5numpy_ndarray)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 181; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_5numpy_ufunc = __Pyx_ImportType("numpy", "ufunc", sizeof(PyUFuncObject), 0); if (unlikely(!__pyx_ptype_5numpy_ufunc)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 864; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_2bx_3bbi_8bbi_file_SummaryBlock = __Pyx_ImportType("bx.bbi.bbi_file", "SummaryBlock", sizeof(struct __pyx_obj_2bx_3bbi_8bbi_file_SummaryBlock), 1); if (unlikely(!__pyx_ptype_2bx_3bbi_8bbi_file_SummaryBlock)) {__pyx_filename = __pyx_f[5]; __pyx_lineno = 8; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_2bx_3bbi_8bbi_file_SummarizedData = __Pyx_ImportType("bx.bbi.bbi_file", "SummarizedData", sizeof(struct __pyx_obj_2bx_3bbi_8bbi_file_SummarizedData), 1); if (unlikely(!__pyx_ptype_2bx_3bbi_8bbi_file_SummarizedData)) {__pyx_filename = __pyx_f[5]; __pyx_lineno = 21; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_vtabptr_2bx_3bbi_8bbi_file_SummarizedData = (struct __pyx_vtabstruct_2bx_3bbi_8bbi_file_SummarizedData*)__Pyx_GetVtable(__pyx_ptype_2bx_3bbi_8bbi_file_SummarizedData->tp_dict); if (unlikely(!__pyx_vtabptr_2bx_3bbi_8bbi_file_SummarizedData)) {__pyx_filename = __pyx_f[5]; __pyx_lineno = 21; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  /*--- Variable import code ---*/
+  /*--- Function import code ---*/
+  /*--- Execution code ---*/
+
+  /* "bx/bbi/bigwig_file.pyx":6
+ * """
+ * 
+ * from collections import deque             # <<<<<<<<<<<<<<
+ * from bbi_file cimport *
+ * from cirtree_file cimport CIRTreeFile
+ */
+  __pyx_t_1 = PyList_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 6; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_INCREF(__pyx_n_s_deque);
+  PyList_SET_ITEM(__pyx_t_1, 0, __pyx_n_s_deque);
+  __Pyx_GIVEREF(__pyx_n_s_deque);
+  __pyx_t_2 = __Pyx_Import(__pyx_n_s_collections, __pyx_t_1, -1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 6; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_1 = __Pyx_ImportFrom(__pyx_t_2, __pyx_n_s_deque); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 6; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_deque, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 6; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+  /* "bx/bbi/bigwig_file.pyx":9
+ * from bbi_file cimport *
+ * from cirtree_file cimport CIRTreeFile
+ * import numpy             # <<<<<<<<<<<<<<
+ * cimport numpy
+ * from types cimport *
+ */
+  __pyx_t_2 = __Pyx_Import(__pyx_n_s_numpy, 0, -1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 9; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_numpy, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 9; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+  /* "bx/bbi/bigwig_file.pyx":12
+ * cimport numpy
+ * from types cimport *
+ * from bx.misc.binary_file import BinaryFileReader             # <<<<<<<<<<<<<<
+ * from cStringIO import StringIO
+ * import zlib
+ */
+  __pyx_t_2 = PyList_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 12; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_INCREF(__pyx_n_s_BinaryFileReader);
+  PyList_SET_ITEM(__pyx_t_2, 0, __pyx_n_s_BinaryFileReader);
+  __Pyx_GIVEREF(__pyx_n_s_BinaryFileReader);
+  __pyx_t_1 = __Pyx_Import(__pyx_n_s_bx_misc_binary_file, __pyx_t_2, -1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 12; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_1, __pyx_n_s_BinaryFileReader); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 12; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_BinaryFileReader, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 12; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "bx/bbi/bigwig_file.pyx":13
+ * from types cimport *
+ * from bx.misc.binary_file import BinaryFileReader
+ * from cStringIO import StringIO             # <<<<<<<<<<<<<<
+ * import zlib
+ * 
+ */
+  __pyx_t_1 = PyList_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 13; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_INCREF(__pyx_n_s_StringIO);
+  PyList_SET_ITEM(__pyx_t_1, 0, __pyx_n_s_StringIO);
+  __Pyx_GIVEREF(__pyx_n_s_StringIO);
+  __pyx_t_2 = __Pyx_Import(__pyx_n_s_cStringIO, __pyx_t_1, -1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 13; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_1 = __Pyx_ImportFrom(__pyx_t_2, __pyx_n_s_StringIO); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 13; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_StringIO, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 13; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+  /* "bx/bbi/bigwig_file.pyx":14
+ * from bx.misc.binary_file import BinaryFileReader
+ * from cStringIO import StringIO
+ * import zlib             # <<<<<<<<<<<<<<
+ * 
+ * DEF big_wig_sig = 0x888FFC26
+ */
+  __pyx_t_2 = __Pyx_Import(__pyx_n_s_zlib, 0, -1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 14; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_zlib, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 14; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+  /* "bx/bbi/bigwig_file.pyx":24
+ *     return min( end1, end2 ) - max( start1, start2 )
+ * 
+ * def chunks(l, n):             # <<<<<<<<<<<<<<
+ *     n = max(1, n)
+ *     return [l[i:i + n] for i in range(0, len(l), n)]
+ */
+  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_2bx_3bbi_11bigwig_file_1chunks, NULL, __pyx_n_s_bx_bbi_bigwig_file); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 24; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_chunks, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 24; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+  /* "bx/bbi/bigwig_file.pyx":1
+ * #cython: profile=False             # <<<<<<<<<<<<<<
+ * """
+ * BigWig file.
+ */
+  __pyx_t_2 = PyDict_New(); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+  /* "../../lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":979
+ *      arr.base = baseptr
+ * 
+ * cdef inline object get_array_base(ndarray arr):             # <<<<<<<<<<<<<<
+ *     if arr.base is NULL:
+ *         return None
+ */
+
+  /*--- Wrapped vars code ---*/
+
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  if (__pyx_m) {
+    if (__pyx_d) {
+      __Pyx_AddTraceback("init bx.bbi.bigwig_file", __pyx_clineno, __pyx_lineno, __pyx_filename);
+    }
+    Py_DECREF(__pyx_m); __pyx_m = 0;
+  } else if (!PyErr_Occurred()) {
+    PyErr_SetString(PyExc_ImportError, "init bx.bbi.bigwig_file");
+  }
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  #if PY_MAJOR_VERSION < 3
+  return;
+  #else
+  return __pyx_m;
+  #endif
+}
+
+/* --- Runtime support code --- */
+#if CYTHON_REFNANNY
+static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) {
+    PyObject *m = NULL, *p = NULL;
+    void *r = NULL;
+    m = PyImport_ImportModule((char *)modname);
+    if (!m) goto end;
+    p = PyObject_GetAttrString(m, (char *)"RefNannyAPI");
+    if (!p) goto end;
+    r = PyLong_AsVoidPtr(p);
+end:
+    Py_XDECREF(p);
+    Py_XDECREF(m);
+    return (__Pyx_RefNannyAPIStruct *)r;
+}
+#endif
+
+static PyObject *__Pyx_GetBuiltinName(PyObject *name) {
+    PyObject* result = __Pyx_PyObject_GetAttrStr(__pyx_b, name);
+    if (unlikely(!result)) {
+        PyErr_Format(PyExc_NameError,
+#if PY_MAJOR_VERSION >= 3
+            "name '%U' is not defined", name);
+#else
+            "name '%.200s' is not defined", PyString_AS_STRING(name));
+#endif
+    }
+    return result;
+}
+
+static void __Pyx_RaiseArgtupleInvalid(
+    const char* func_name,
+    int exact,
+    Py_ssize_t num_min,
+    Py_ssize_t num_max,
+    Py_ssize_t num_found)
+{
+    Py_ssize_t num_expected;
+    const char *more_or_less;
+    if (num_found < num_min) {
+        num_expected = num_min;
+        more_or_less = "at least";
+    } else {
+        num_expected = num_max;
+        more_or_less = "at most";
+    }
+    if (exact) {
+        more_or_less = "exactly";
+    }
+    PyErr_Format(PyExc_TypeError,
+                 "%.200s() takes %.8s %" CYTHON_FORMAT_SSIZE_T "d positional argument%.1s (%" CYTHON_FORMAT_SSIZE_T "d given)",
+                 func_name, more_or_less, num_expected,
+                 (num_expected == 1) ? "" : "s", num_found);
+}
+
+static void __Pyx_RaiseDoubleKeywordsError(
+    const char* func_name,
+    PyObject* kw_name)
+{
+    PyErr_Format(PyExc_TypeError,
+        #if PY_MAJOR_VERSION >= 3
+        "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
+        #else
+        "%s() got multiple values for keyword argument '%s'", func_name,
+        PyString_AsString(kw_name));
+        #endif
+}
+
+static int __Pyx_ParseOptionalKeywords(
+    PyObject *kwds,
+    PyObject **argnames[],
+    PyObject *kwds2,
+    PyObject *values[],
+    Py_ssize_t num_pos_args,
+    const char* function_name)
+{
+    PyObject *key = 0, *value = 0;
+    Py_ssize_t pos = 0;
+    PyObject*** name;
+    PyObject*** first_kw_arg = argnames + num_pos_args;
+    while (PyDict_Next(kwds, &pos, &key, &value)) {
+        name = first_kw_arg;
+        while (*name && (**name != key)) name++;
+        if (*name) {
+            values[name-argnames] = value;
+            continue;
+        }
+        name = first_kw_arg;
+        #if PY_MAJOR_VERSION < 3
+        if (likely(PyString_CheckExact(key)) || likely(PyString_Check(key))) {
+            while (*name) {
+                if ((CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**name) == PyString_GET_SIZE(key))
+                        && _PyString_Eq(**name, key)) {
+                    values[name-argnames] = value;
+                    break;
+                }
+                name++;
+            }
+            if (*name) continue;
+            else {
+                PyObject*** argname = argnames;
+                while (argname != first_kw_arg) {
+                    if ((**argname == key) || (
+                            (CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**argname) == PyString_GET_SIZE(key))
+                             && _PyString_Eq(**argname, key))) {
+                        goto arg_passed_twice;
+                    }
+                    argname++;
+                }
+            }
+        } else
+        #endif
+        if (likely(PyUnicode_Check(key))) {
+            while (*name) {
+                int cmp = (**name == key) ? 0 :
+                #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3
+                    (PyUnicode_GET_SIZE(**name) != PyUnicode_GET_SIZE(key)) ? 1 :
+                #endif
+                    PyUnicode_Compare(**name, key);
+                if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad;
+                if (cmp == 0) {
+                    values[name-argnames] = value;
+                    break;
+                }
+                name++;
+            }
+            if (*name) continue;
+            else {
+                PyObject*** argname = argnames;
+                while (argname != first_kw_arg) {
+                    int cmp = (**argname == key) ? 0 :
+                    #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3
+                        (PyUnicode_GET_SIZE(**argname) != PyUnicode_GET_SIZE(key)) ? 1 :
+                    #endif
+                        PyUnicode_Compare(**argname, key);
+                    if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad;
+                    if (cmp == 0) goto arg_passed_twice;
+                    argname++;
+                }
+            }
+        } else
+            goto invalid_keyword_type;
+        if (kwds2) {
+            if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
+        } else {
+            goto invalid_keyword;
+        }
+    }
+    return 0;
+arg_passed_twice:
+    __Pyx_RaiseDoubleKeywordsError(function_name, key);
+    goto bad;
+invalid_keyword_type:
+    PyErr_Format(PyExc_TypeError,
+        "%.200s() keywords must be strings", function_name);
+    goto bad;
+invalid_keyword:
+    PyErr_Format(PyExc_TypeError,
+    #if PY_MAJOR_VERSION < 3
+        "%.200s() got an unexpected keyword argument '%.200s'",
+        function_name, PyString_AsString(key));
+    #else
+        "%s() got an unexpected keyword argument '%U'",
+        function_name, key);
+    #endif
+bad:
+    return -1;
+}
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw) {
+    PyObject *result;
+    ternaryfunc call = func->ob_type->tp_call;
+    if (unlikely(!call))
+        return PyObject_Call(func, arg, kw);
+    if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object")))
+        return NULL;
+    result = (*call)(func, arg, kw);
+    Py_LeaveRecursiveCall();
+    if (unlikely(!result) && unlikely(!PyErr_Occurred())) {
+        PyErr_SetString(
+            PyExc_SystemError,
+            "NULL result without error in PyObject_Call");
+    }
+    return result;
+}
+#endif
+
+static CYTHON_INLINE PyObject* __Pyx_PyObject_GetSlice(
+        PyObject* obj, Py_ssize_t cstart, Py_ssize_t cstop,
+        PyObject** _py_start, PyObject** _py_stop, PyObject** _py_slice,
+        int has_cstart, int has_cstop, CYTHON_UNUSED int wraparound) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    PyMappingMethods* mp;
+#if PY_MAJOR_VERSION < 3
+    PySequenceMethods* ms = Py_TYPE(obj)->tp_as_sequence;
+    if (likely(ms && ms->sq_slice)) {
+        if (!has_cstart) {
+            if (_py_start && (*_py_start != Py_None)) {
+                cstart = __Pyx_PyIndex_AsSsize_t(*_py_start);
+                if ((cstart == (Py_ssize_t)-1) && PyErr_Occurred()) goto bad;
+            } else
+                cstart = 0;
+        }
+        if (!has_cstop) {
+            if (_py_stop && (*_py_stop != Py_None)) {
+                cstop = __Pyx_PyIndex_AsSsize_t(*_py_stop);
+                if ((cstop == (Py_ssize_t)-1) && PyErr_Occurred()) goto bad;
+            } else
+                cstop = PY_SSIZE_T_MAX;
+        }
+        if (wraparound && unlikely((cstart < 0) | (cstop < 0)) && likely(ms->sq_length)) {
+            Py_ssize_t l = ms->sq_length(obj);
+            if (likely(l >= 0)) {
+                if (cstop < 0) {
+                    cstop += l;
+                    if (cstop < 0) cstop = 0;
+                }
+                if (cstart < 0) {
+                    cstart += l;
+                    if (cstart < 0) cstart = 0;
+                }
+            } else {
+                if (PyErr_ExceptionMatches(PyExc_OverflowError))
+                    PyErr_Clear();
+                else
+                    goto bad;
+            }
+        }
+        return ms->sq_slice(obj, cstart, cstop);
+    }
+#endif
+    mp = Py_TYPE(obj)->tp_as_mapping;
+    if (likely(mp && mp->mp_subscript))
+#endif
+    {
+        PyObject* result;
+        PyObject *py_slice, *py_start, *py_stop;
+        if (_py_slice) {
+            py_slice = *_py_slice;
+        } else {
+            PyObject* owned_start = NULL;
+            PyObject* owned_stop = NULL;
+            if (_py_start) {
+                py_start = *_py_start;
+            } else {
+                if (has_cstart) {
+                    owned_start = py_start = PyInt_FromSsize_t(cstart);
+                    if (unlikely(!py_start)) goto bad;
+                } else
+                    py_start = Py_None;
+            }
+            if (_py_stop) {
+                py_stop = *_py_stop;
+            } else {
+                if (has_cstop) {
+                    owned_stop = py_stop = PyInt_FromSsize_t(cstop);
+                    if (unlikely(!py_stop)) {
+                        Py_XDECREF(owned_start);
+                        goto bad;
+                    }
+                } else
+                    py_stop = Py_None;
+            }
+            py_slice = PySlice_New(py_start, py_stop, Py_None);
+            Py_XDECREF(owned_start);
+            Py_XDECREF(owned_stop);
+            if (unlikely(!py_slice)) goto bad;
+        }
+#if CYTHON_COMPILING_IN_CPYTHON
+        result = mp->mp_subscript(obj, py_slice);
+#else
+        result = PyObject_GetItem(obj, py_slice);
+#endif
+        if (!_py_slice) {
+            Py_DECREF(py_slice);
+        }
+        return result;
+    }
+    PyErr_Format(PyExc_TypeError,
+        "'%.200s' object is unsliceable", Py_TYPE(obj)->tp_name);
+bad:
+    return NULL;
+}
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg) {
+    PyObject *self, *result;
+    PyCFunction cfunc;
+    cfunc = PyCFunction_GET_FUNCTION(func);
+    self = PyCFunction_GET_SELF(func);
+    if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object")))
+        return NULL;
+    result = cfunc(self, arg);
+    Py_LeaveRecursiveCall();
+    if (unlikely(!result) && unlikely(!PyErr_Occurred())) {
+        PyErr_SetString(
+            PyExc_SystemError,
+            "NULL result without error in PyObject_Call");
+    }
+    return result;
+}
+#endif
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static PyObject* __Pyx__PyObject_CallOneArg(PyObject *func, PyObject *arg) {
+    PyObject *result;
+    PyObject *args = PyTuple_New(1);
+    if (unlikely(!args)) return NULL;
+    Py_INCREF(arg);
+    PyTuple_SET_ITEM(args, 0, arg);
+    result = __Pyx_PyObject_Call(func, args, NULL);
+    Py_DECREF(args);
+    return result;
+}
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) {
+#ifdef __Pyx_CyFunction_USED
+    if (likely(PyCFunction_Check(func) || PyObject_TypeCheck(func, __pyx_CyFunctionType))) {
+#else
+    if (likely(PyCFunction_Check(func))) {
+#endif
+        if (likely(PyCFunction_GET_FLAGS(func) & METH_O)) {
+            return __Pyx_PyObject_CallMethO(func, arg);
+        }
+    }
+    return __Pyx__PyObject_CallOneArg(func, arg);
+}
+#else
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) {
+    PyObject* args = PyTuple_Pack(1, arg);
+    return (likely(args)) ? __Pyx_PyObject_Call(func, args, NULL) : NULL;
+}
+#endif
+
+static CYTHON_INLINE PyObject *__Pyx_GetModuleGlobalName(PyObject *name) {
+    PyObject *result;
+#if CYTHON_COMPILING_IN_CPYTHON
+    result = PyDict_GetItem(__pyx_d, name);
+    if (likely(result)) {
+        Py_INCREF(result);
+    } else {
+#else
+    result = PyObject_GetItem(__pyx_d, name);
+    if (!result) {
+        PyErr_Clear();
+#endif
+        result = __Pyx_GetBuiltinName(name);
+    }
+    return result;
+}
+
+static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected) {
+    PyErr_Format(PyExc_ValueError,
+                 "too many values to unpack (expected %" CYTHON_FORMAT_SSIZE_T "d)", expected);
+}
+
+static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index) {
+    PyErr_Format(PyExc_ValueError,
+                 "need more than %" CYTHON_FORMAT_SSIZE_T "d value%.1s to unpack",
+                 index, (index == 1) ? "" : "s");
+}
+
+static CYTHON_INLINE int __Pyx_IterFinish(void) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    PyThreadState *tstate = PyThreadState_GET();
+    PyObject* exc_type = tstate->curexc_type;
+    if (unlikely(exc_type)) {
+        if (likely(exc_type == PyExc_StopIteration) || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration)) {
+            PyObject *exc_value, *exc_tb;
+            exc_value = tstate->curexc_value;
+            exc_tb = tstate->curexc_traceback;
+            tstate->curexc_type = 0;
+            tstate->curexc_value = 0;
+            tstate->curexc_traceback = 0;
+            Py_DECREF(exc_type);
+            Py_XDECREF(exc_value);
+            Py_XDECREF(exc_tb);
+            return 0;
+        } else {
+            return -1;
+        }
+    }
+    return 0;
+#else
+    if (unlikely(PyErr_Occurred())) {
+        if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) {
+            PyErr_Clear();
+            return 0;
+        } else {
+            return -1;
+        }
+    }
+    return 0;
+#endif
+}
+
+static int __Pyx_IternextUnpackEndCheck(PyObject *retval, Py_ssize_t expected) {
+    if (unlikely(retval)) {
+        Py_DECREF(retval);
+        __Pyx_RaiseTooManyValuesError(expected);
+        return -1;
+    } else {
+        return __Pyx_IterFinish();
+    }
+    return 0;
+}
+
+static CYTHON_INLINE void __Pyx_RaiseUnboundLocalError(const char *varname) {
+    PyErr_Format(PyExc_UnboundLocalError, "local variable '%s' referenced before assignment", varname);
+}
+
+static CYTHON_INLINE int __Pyx_PyObject_SetSlice(
+        PyObject* obj, PyObject* value, Py_ssize_t cstart, Py_ssize_t cstop,
+        PyObject** _py_start, PyObject** _py_stop, PyObject** _py_slice,
+        int has_cstart, int has_cstop, CYTHON_UNUSED int wraparound) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    PyMappingMethods* mp;
+#if PY_MAJOR_VERSION < 3
+    PySequenceMethods* ms = Py_TYPE(obj)->tp_as_sequence;
+    if (likely(ms && ms->sq_ass_slice)) {
+        if (!has_cstart) {
+            if (_py_start && (*_py_start != Py_None)) {
+                cstart = __Pyx_PyIndex_AsSsize_t(*_py_start);
+                if ((cstart == (Py_ssize_t)-1) && PyErr_Occurred()) goto bad;
+            } else
+                cstart = 0;
+        }
+        if (!has_cstop) {
+            if (_py_stop && (*_py_stop != Py_None)) {
+                cstop = __Pyx_PyIndex_AsSsize_t(*_py_stop);
+                if ((cstop == (Py_ssize_t)-1) && PyErr_Occurred()) goto bad;
+            } else
+                cstop = PY_SSIZE_T_MAX;
+        }
+        if (wraparound && unlikely((cstart < 0) | (cstop < 0)) && likely(ms->sq_length)) {
+            Py_ssize_t l = ms->sq_length(obj);
+            if (likely(l >= 0)) {
+                if (cstop < 0) {
+                    cstop += l;
+                    if (cstop < 0) cstop = 0;
+                }
+                if (cstart < 0) {
+                    cstart += l;
+                    if (cstart < 0) cstart = 0;
+                }
+            } else {
+                if (PyErr_ExceptionMatches(PyExc_OverflowError))
+                    PyErr_Clear();
+                else
+                    goto bad;
+            }
+        }
+        return ms->sq_ass_slice(obj, cstart, cstop, value);
+    }
+#endif
+    mp = Py_TYPE(obj)->tp_as_mapping;
+    if (likely(mp && mp->mp_ass_subscript))
+#endif
+    {
+        int result;
+        PyObject *py_slice, *py_start, *py_stop;
+        if (_py_slice) {
+            py_slice = *_py_slice;
+        } else {
+            PyObject* owned_start = NULL;
+            PyObject* owned_stop = NULL;
+            if (_py_start) {
+                py_start = *_py_start;
+            } else {
+                if (has_cstart) {
+                    owned_start = py_start = PyInt_FromSsize_t(cstart);
+                    if (unlikely(!py_start)) goto bad;
+                } else
+                    py_start = Py_None;
+            }
+            if (_py_stop) {
+                py_stop = *_py_stop;
+            } else {
+                if (has_cstop) {
+                    owned_stop = py_stop = PyInt_FromSsize_t(cstop);
+                    if (unlikely(!py_stop)) {
+                        Py_XDECREF(owned_start);
+                        goto bad;
+                    }
+                } else
+                    py_stop = Py_None;
+            }
+            py_slice = PySlice_New(py_start, py_stop, Py_None);
+            Py_XDECREF(owned_start);
+            Py_XDECREF(owned_stop);
+            if (unlikely(!py_slice)) goto bad;
+        }
+#if CYTHON_COMPILING_IN_CPYTHON
+        result = mp->mp_ass_subscript(obj, py_slice, value);
+#else
+        result = value ? PyObject_SetItem(obj, py_slice, value) : PyObject_DelItem(obj, py_slice);
+#endif
+        if (!_py_slice) {
+            Py_DECREF(py_slice);
+        }
+        return result;
+    }
+    PyErr_Format(PyExc_TypeError,
+        "'%.200s' object does not support slice %.10s",
+        Py_TYPE(obj)->tp_name, value ? "assignment" : "deletion");
+bad:
+    return -1;
+}
+
+static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type) {
+    if (unlikely(!type)) {
+        PyErr_SetString(PyExc_SystemError, "Missing type object");
+        return 0;
+    }
+    if (likely(PyObject_TypeCheck(obj, type)))
+        return 1;
+    PyErr_Format(PyExc_TypeError, "Cannot convert %.200s to %.200s",
+                 Py_TYPE(obj)->tp_name, type->tp_name);
+    return 0;
+}
+
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j) {
+    PyObject *r;
+    if (!j) return NULL;
+    r = PyObject_GetItem(o, j);
+    Py_DECREF(j);
+    return r;
+}
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i,
+                                                              int wraparound, int boundscheck) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    if (wraparound & unlikely(i < 0)) i += PyList_GET_SIZE(o);
+    if ((!boundscheck) || likely((0 <= i) & (i < PyList_GET_SIZE(o)))) {
+        PyObject *r = PyList_GET_ITEM(o, i);
+        Py_INCREF(r);
+        return r;
+    }
+    return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
+#else
+    return PySequence_GetItem(o, i);
+#endif
+}
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i,
+                                                              int wraparound, int boundscheck) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    if (wraparound & unlikely(i < 0)) i += PyTuple_GET_SIZE(o);
+    if ((!boundscheck) || likely((0 <= i) & (i < PyTuple_GET_SIZE(o)))) {
+        PyObject *r = PyTuple_GET_ITEM(o, i);
+        Py_INCREF(r);
+        return r;
+    }
+    return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
+#else
+    return PySequence_GetItem(o, i);
+#endif
+}
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i,
+                                                     int is_list, int wraparound, int boundscheck) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    if (is_list || PyList_CheckExact(o)) {
+        Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyList_GET_SIZE(o);
+        if ((!boundscheck) || (likely((n >= 0) & (n < PyList_GET_SIZE(o))))) {
+            PyObject *r = PyList_GET_ITEM(o, n);
+            Py_INCREF(r);
+            return r;
+        }
+    }
+    else if (PyTuple_CheckExact(o)) {
+        Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyTuple_GET_SIZE(o);
+        if ((!boundscheck) || likely((n >= 0) & (n < PyTuple_GET_SIZE(o)))) {
+            PyObject *r = PyTuple_GET_ITEM(o, n);
+            Py_INCREF(r);
+            return r;
+        }
+    } else {
+        PySequenceMethods *m = Py_TYPE(o)->tp_as_sequence;
+        if (likely(m && m->sq_item)) {
+            if (wraparound && unlikely(i < 0) && likely(m->sq_length)) {
+                Py_ssize_t l = m->sq_length(o);
+                if (likely(l >= 0)) {
+                    i += l;
+                } else {
+                    if (PyErr_ExceptionMatches(PyExc_OverflowError))
+                        PyErr_Clear();
+                    else
+                        return NULL;
+                }
+            }
+            return m->sq_item(o, i);
+        }
+    }
+#else
+    if (is_list || PySequence_Check(o)) {
+        return PySequence_GetItem(o, i);
+    }
+#endif
+    return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
+}
+
+static CYTHON_INLINE int __Pyx_SetItemInt_Generic(PyObject *o, PyObject *j, PyObject *v) {
+    int r;
+    if (!j) return -1;
+    r = PyObject_SetItem(o, j, v);
+    Py_DECREF(j);
+    return r;
+}
+static CYTHON_INLINE int __Pyx_SetItemInt_Fast(PyObject *o, Py_ssize_t i, PyObject *v,
+                                               int is_list, int wraparound, int boundscheck) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    if (is_list || PyList_CheckExact(o)) {
+        Py_ssize_t n = (!wraparound) ? i : ((likely(i >= 0)) ? i : i + PyList_GET_SIZE(o));
+        if ((!boundscheck) || likely((n >= 0) & (n < PyList_GET_SIZE(o)))) {
+            PyObject* old = PyList_GET_ITEM(o, n);
+            Py_INCREF(v);
+            PyList_SET_ITEM(o, n, v);
+            Py_DECREF(old);
+            return 1;
+        }
+    } else {
+        PySequenceMethods *m = Py_TYPE(o)->tp_as_sequence;
+        if (likely(m && m->sq_ass_item)) {
+            if (wraparound && unlikely(i < 0) && likely(m->sq_length)) {
+                Py_ssize_t l = m->sq_length(o);
+                if (likely(l >= 0)) {
+                    i += l;
+                } else {
+                    if (PyErr_ExceptionMatches(PyExc_OverflowError))
+                        PyErr_Clear();
+                    else
+                        return -1;
+                }
+            }
+            return m->sq_ass_item(o, i, v);
+        }
+    }
+#else
+#if CYTHON_COMPILING_IN_PYPY
+    if (is_list || (PySequence_Check(o) && !PyDict_Check(o))) {
+#else
+    if (is_list || PySequence_Check(o)) {
+#endif
+        return PySequence_SetItem(o, i, v);
+    }
+#endif
+    return __Pyx_SetItemInt_Generic(o, PyInt_FromSsize_t(i), v);
+}
+
+static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    PyObject *tmp_type, *tmp_value, *tmp_tb;
+    PyThreadState *tstate = PyThreadState_GET();
+    tmp_type = tstate->curexc_type;
+    tmp_value = tstate->curexc_value;
+    tmp_tb = tstate->curexc_traceback;
+    tstate->curexc_type = type;
+    tstate->curexc_value = value;
+    tstate->curexc_traceback = tb;
+    Py_XDECREF(tmp_type);
+    Py_XDECREF(tmp_value);
+    Py_XDECREF(tmp_tb);
+#else
+    PyErr_Restore(type, value, tb);
+#endif
+}
+static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    PyThreadState *tstate = PyThreadState_GET();
+    *type = tstate->curexc_type;
+    *value = tstate->curexc_value;
+    *tb = tstate->curexc_traceback;
+    tstate->curexc_type = 0;
+    tstate->curexc_value = 0;
+    tstate->curexc_traceback = 0;
+#else
+    PyErr_Fetch(type, value, tb);
+#endif
+}
+
+#if PY_MAJOR_VERSION < 3
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb,
+                        CYTHON_UNUSED PyObject *cause) {
+    Py_XINCREF(type);
+    if (!value || value == Py_None)
+        value = NULL;
+    else
+        Py_INCREF(value);
+    if (!tb || tb == Py_None)
+        tb = NULL;
+    else {
+        Py_INCREF(tb);
+        if (!PyTraceBack_Check(tb)) {
+            PyErr_SetString(PyExc_TypeError,
+                "raise: arg 3 must be a traceback or None");
+            goto raise_error;
+        }
+    }
+    if (PyType_Check(type)) {
+#if CYTHON_COMPILING_IN_PYPY
+        if (!value) {
+            Py_INCREF(Py_None);
+            value = Py_None;
+        }
+#endif
+        PyErr_NormalizeException(&type, &value, &tb);
+    } else {
+        if (value) {
+            PyErr_SetString(PyExc_TypeError,
+                "instance exception may not have a separate value");
+            goto raise_error;
+        }
+        value = type;
+        type = (PyObject*) Py_TYPE(type);
+        Py_INCREF(type);
+        if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
+            PyErr_SetString(PyExc_TypeError,
+                "raise: exception class must be a subclass of BaseException");
+            goto raise_error;
+        }
+    }
+    __Pyx_ErrRestore(type, value, tb);
+    return;
+raise_error:
+    Py_XDECREF(value);
+    Py_XDECREF(type);
+    Py_XDECREF(tb);
+    return;
+}
+#else
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause) {
+    PyObject* owned_instance = NULL;
+    if (tb == Py_None) {
+        tb = 0;
+    } else if (tb && !PyTraceBack_Check(tb)) {
+        PyErr_SetString(PyExc_TypeError,
+            "raise: arg 3 must be a traceback or None");
+        goto bad;
+    }
+    if (value == Py_None)
+        value = 0;
+    if (PyExceptionInstance_Check(type)) {
+        if (value) {
+            PyErr_SetString(PyExc_TypeError,
+                "instance exception may not have a separate value");
+            goto bad;
+        }
+        value = type;
+        type = (PyObject*) Py_TYPE(value);
+    } else if (PyExceptionClass_Check(type)) {
+        PyObject *instance_class = NULL;
+        if (value && PyExceptionInstance_Check(value)) {
+            instance_class = (PyObject*) Py_TYPE(value);
+            if (instance_class != type) {
+                if (PyObject_IsSubclass(instance_class, type)) {
+                    type = instance_class;
+                } else {
+                    instance_class = NULL;
+                }
+            }
+        }
+        if (!instance_class) {
+            PyObject *args;
+            if (!value)
+                args = PyTuple_New(0);
+            else if (PyTuple_Check(value)) {
+                Py_INCREF(value);
+                args = value;
+            } else
+                args = PyTuple_Pack(1, value);
+            if (!args)
+                goto bad;
+            owned_instance = PyObject_Call(type, args, NULL);
+            Py_DECREF(args);
+            if (!owned_instance)
+                goto bad;
+            value = owned_instance;
+            if (!PyExceptionInstance_Check(value)) {
+                PyErr_Format(PyExc_TypeError,
+                             "calling %R should have returned an instance of "
+                             "BaseException, not %R",
+                             type, Py_TYPE(value));
+                goto bad;
+            }
+        }
+    } else {
+        PyErr_SetString(PyExc_TypeError,
+            "raise: exception class must be a subclass of BaseException");
+        goto bad;
+    }
+#if PY_VERSION_HEX >= 0x03030000
+    if (cause) {
+#else
+    if (cause && cause != Py_None) {
+#endif
+        PyObject *fixed_cause;
+        if (cause == Py_None) {
+            fixed_cause = NULL;
+        } else if (PyExceptionClass_Check(cause)) {
+            fixed_cause = PyObject_CallObject(cause, NULL);
+            if (fixed_cause == NULL)
+                goto bad;
+        } else if (PyExceptionInstance_Check(cause)) {
+            fixed_cause = cause;
+            Py_INCREF(fixed_cause);
+        } else {
+            PyErr_SetString(PyExc_TypeError,
+                            "exception causes must derive from "
+                            "BaseException");
+            goto bad;
+        }
+        PyException_SetCause(value, fixed_cause);
+    }
+    PyErr_SetObject(type, value);
+    if (tb) {
+#if CYTHON_COMPILING_IN_PYPY
+        PyObject *tmp_type, *tmp_value, *tmp_tb;
+        PyErr_Fetch(tmp_type, tmp_value, tmp_tb);
+        Py_INCREF(tb);
+        PyErr_Restore(tmp_type, tmp_value, tb);
+        Py_XDECREF(tmp_tb);
+#else
+        PyThreadState *tstate = PyThreadState_GET();
+        PyObject* tmp_tb = tstate->curexc_traceback;
+        if (tb != tmp_tb) {
+            Py_INCREF(tb);
+            tstate->curexc_traceback = tb;
+            Py_XDECREF(tmp_tb);
+        }
+#endif
+    }
+bad:
+    Py_XDECREF(owned_instance);
+    return;
+}
+#endif
+
+static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void) {
+    PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable");
+}
+
+static void __Pyx_call_next_tp_dealloc(PyObject* obj, destructor current_tp_dealloc) {
+    PyTypeObject* type = Py_TYPE(obj);
+    while (type && type->tp_dealloc != current_tp_dealloc)
+        type = type->tp_base;
+    while (type && type->tp_dealloc == current_tp_dealloc)
+        type = type->tp_base;
+    if (type)
+        type->tp_dealloc(obj);
+}
+
+static int __Pyx_call_next_tp_traverse(PyObject* obj, visitproc v, void *a, traverseproc current_tp_traverse) {
+    PyTypeObject* type = Py_TYPE(obj);
+    while (type && type->tp_traverse != current_tp_traverse)
+        type = type->tp_base;
+    while (type && type->tp_traverse == current_tp_traverse)
+        type = type->tp_base;
+    if (type && type->tp_traverse)
+        return type->tp_traverse(obj, v, a);
+    return 0;
+}
+
+static void __Pyx_call_next_tp_clear(PyObject* obj, inquiry current_tp_clear) {
+    PyTypeObject* type = Py_TYPE(obj);
+    while (type && type->tp_clear != current_tp_clear)
+        type = type->tp_base;
+    while (type && type->tp_clear == current_tp_clear)
+        type = type->tp_base;
+    if (type && type->tp_clear)
+        type->tp_clear(obj);
+}
+
+static void* __Pyx_GetVtable(PyObject *dict) {
+    void* ptr;
+    PyObject *ob = PyObject_GetItem(dict, __pyx_n_s_pyx_vtable);
+    if (!ob)
+        goto bad;
+#if PY_VERSION_HEX >= 0x02070000
+    ptr = PyCapsule_GetPointer(ob, 0);
+#else
+    ptr = PyCObject_AsVoidPtr(ob);
+#endif
+    if (!ptr && !PyErr_Occurred())
+        PyErr_SetString(PyExc_RuntimeError, "invalid vtable found for imported type");
+    Py_DECREF(ob);
+    return ptr;
+bad:
+    Py_XDECREF(ob);
+    return NULL;
+}
+
+static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
+#if PY_VERSION_HEX >= 0x02070000
+    PyObject *ob = PyCapsule_New(vtable, 0, 0);
+#else
+    PyObject *ob = PyCObject_FromVoidPtr(vtable, 0);
+#endif
+    if (!ob)
+        goto bad;
+    if (PyDict_SetItem(dict, __pyx_n_s_pyx_vtable, ob) < 0)
+        goto bad;
+    Py_DECREF(ob);
+    return 0;
+bad:
+    Py_XDECREF(ob);
+    return -1;
+}
+
+static PyObject* __Pyx_ImportFrom(PyObject* module, PyObject* name) {
+    PyObject* value = __Pyx_PyObject_GetAttrStr(module, name);
+    if (unlikely(!value) && PyErr_ExceptionMatches(PyExc_AttributeError)) {
+        PyErr_Format(PyExc_ImportError,
+        #if PY_MAJOR_VERSION < 3
+            "cannot import name %.230s", PyString_AS_STRING(name));
+        #else
+            "cannot import name %S", name);
+        #endif
+    }
+    return value;
+}
+
+static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) {
+    int start = 0, mid = 0, end = count - 1;
+    if (end >= 0 && code_line > entries[end].code_line) {
+        return count;
+    }
+    while (start < end) {
+        mid = (start + end) / 2;
+        if (code_line < entries[mid].code_line) {
+            end = mid;
+        } else if (code_line > entries[mid].code_line) {
+             start = mid + 1;
+        } else {
+            return mid;
+        }
+    }
+    if (code_line <= entries[mid].code_line) {
+        return mid;
+    } else {
+        return mid + 1;
+    }
+}
+static PyCodeObject *__pyx_find_code_object(int code_line) {
+    PyCodeObject* code_object;
+    int pos;
+    if (unlikely(!code_line) || unlikely(!__pyx_code_cache.entries)) {
+        return NULL;
+    }
+    pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line);
+    if (unlikely(pos >= __pyx_code_cache.count) || unlikely(__pyx_code_cache.entries[pos].code_line != code_line)) {
+        return NULL;
+    }
+    code_object = __pyx_code_cache.entries[pos].code_object;
+    Py_INCREF(code_object);
+    return code_object;
+}
+static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) {
+    int pos, i;
+    __Pyx_CodeObjectCacheEntry* entries = __pyx_code_cache.entries;
+    if (unlikely(!code_line)) {
+        return;
+    }
+    if (unlikely(!entries)) {
+        entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Malloc(64*sizeof(__Pyx_CodeObjectCacheEntry));
+        if (likely(entries)) {
+            __pyx_code_cache.entries = entries;
+            __pyx_code_cache.max_count = 64;
+            __pyx_code_cache.count = 1;
+            entries[0].code_line = code_line;
+            entries[0].code_object = code_object;
+            Py_INCREF(code_object);
+        }
+        return;
+    }
+    pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line);
+    if ((pos < __pyx_code_cache.count) && unlikely(__pyx_code_cache.entries[pos].code_line == code_line)) {
+        PyCodeObject* tmp = entries[pos].code_object;
+        entries[pos].code_object = code_object;
+        Py_DECREF(tmp);
+        return;
+    }
+    if (__pyx_code_cache.count == __pyx_code_cache.max_count) {
+        int new_max = __pyx_code_cache.max_count + 64;
+        entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Realloc(
+            __pyx_code_cache.entries, (size_t)new_max*sizeof(__Pyx_CodeObjectCacheEntry));
+        if (unlikely(!entries)) {
+            return;
+        }
+        __pyx_code_cache.entries = entries;
+        __pyx_code_cache.max_count = new_max;
+    }
+    for (i=__pyx_code_cache.count; i>pos; i--) {
+        entries[i] = entries[i-1];
+    }
+    entries[pos].code_line = code_line;
+    entries[pos].code_object = code_object;
+    __pyx_code_cache.count++;
+    Py_INCREF(code_object);
+}
+
+#include "compile.h"
+#include "frameobject.h"
+#include "traceback.h"
+static PyCodeObject* __Pyx_CreateCodeObjectForTraceback(
+            const char *funcname, int c_line,
+            int py_line, const char *filename) {
+    PyCodeObject *py_code = 0;
+    PyObject *py_srcfile = 0;
+    PyObject *py_funcname = 0;
+    #if PY_MAJOR_VERSION < 3
+    py_srcfile = PyString_FromString(filename);
+    #else
+    py_srcfile = PyUnicode_FromString(filename);
+    #endif
+    if (!py_srcfile) goto bad;
+    if (c_line) {
+        #if PY_MAJOR_VERSION < 3
+        py_funcname = PyString_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line);
+        #else
+        py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line);
+        #endif
+    }
+    else {
+        #if PY_MAJOR_VERSION < 3
+        py_funcname = PyString_FromString(funcname);
+        #else
+        py_funcname = PyUnicode_FromString(funcname);
+        #endif
+    }
+    if (!py_funcname) goto bad;
+    py_code = __Pyx_PyCode_New(
+        0,
+        0,
+        0,
+        0,
+        0,
+        __pyx_empty_bytes, /*PyObject *code,*/
+        __pyx_empty_tuple, /*PyObject *consts,*/
+        __pyx_empty_tuple, /*PyObject *names,*/
+        __pyx_empty_tuple, /*PyObject *varnames,*/
+        __pyx_empty_tuple, /*PyObject *freevars,*/
+        __pyx_empty_tuple, /*PyObject *cellvars,*/
+        py_srcfile,   /*PyObject *filename,*/
+        py_funcname,  /*PyObject *name,*/
+        py_line,
+        __pyx_empty_bytes  /*PyObject *lnotab*/
+    );
+    Py_DECREF(py_srcfile);
+    Py_DECREF(py_funcname);
+    return py_code;
+bad:
+    Py_XDECREF(py_srcfile);
+    Py_XDECREF(py_funcname);
+    return NULL;
+}
+static void __Pyx_AddTraceback(const char *funcname, int c_line,
+                               int py_line, const char *filename) {
+    PyCodeObject *py_code = 0;
+    PyFrameObject *py_frame = 0;
+    py_code = __pyx_find_code_object(c_line ? c_line : py_line);
+    if (!py_code) {
+        py_code = __Pyx_CreateCodeObjectForTraceback(
+            funcname, c_line, py_line, filename);
+        if (!py_code) goto bad;
+        __pyx_insert_code_object(c_line ? c_line : py_line, py_code);
+    }
+    py_frame = PyFrame_New(
+        PyThreadState_GET(), /*PyThreadState *tstate,*/
+        py_code,             /*PyCodeObject *code,*/
+        __pyx_d,      /*PyObject *globals,*/
+        0                    /*PyObject *locals*/
+    );
+    if (!py_frame) goto bad;
+    py_frame->f_lineno = py_line;
+    PyTraceBack_Here(py_frame);
+bad:
+    Py_XDECREF(py_code);
+    Py_XDECREF(py_frame);
+}
+
+static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level) {
+    PyObject *empty_list = 0;
+    PyObject *module = 0;
+    PyObject *global_dict = 0;
+    PyObject *empty_dict = 0;
+    PyObject *list;
+    #if PY_VERSION_HEX < 0x03030000
+    PyObject *py_import;
+    py_import = __Pyx_PyObject_GetAttrStr(__pyx_b, __pyx_n_s_import);
+    if (!py_import)
+        goto bad;
+    #endif
+    if (from_list)
+        list = from_list;
+    else {
+        empty_list = PyList_New(0);
+        if (!empty_list)
+            goto bad;
+        list = empty_list;
+    }
+    global_dict = PyModule_GetDict(__pyx_m);
+    if (!global_dict)
+        goto bad;
+    empty_dict = PyDict_New();
+    if (!empty_dict)
+        goto bad;
+    {
+        #if PY_MAJOR_VERSION >= 3
+        if (level == -1) {
+            if (strchr(__Pyx_MODULE_NAME, '.')) {
+                #if PY_VERSION_HEX < 0x03030000
+                PyObject *py_level = PyInt_FromLong(1);
+                if (!py_level)
+                    goto bad;
+                module = PyObject_CallFunctionObjArgs(py_import,
+                    name, global_dict, empty_dict, list, py_level, NULL);
+                Py_DECREF(py_level);
+                #else
+                module = PyImport_ImportModuleLevelObject(
+                    name, global_dict, empty_dict, list, 1);
+                #endif
+                if (!module) {
+                    if (!PyErr_ExceptionMatches(PyExc_ImportError))
+                        goto bad;
+                    PyErr_Clear();
+                }
+            }
+            level = 0;
+        }
+        #endif
+        if (!module) {
+            #if PY_VERSION_HEX < 0x03030000
+            PyObject *py_level = PyInt_FromLong(level);
+            if (!py_level)
+                goto bad;
+            module = PyObject_CallFunctionObjArgs(py_import,
+                name, global_dict, empty_dict, list, py_level, NULL);
+            Py_DECREF(py_level);
+            #else
+            module = PyImport_ImportModuleLevelObject(
+                name, global_dict, empty_dict, list, level);
+            #endif
+        }
+    }
+bad:
+    #if PY_VERSION_HEX < 0x03030000
+    Py_XDECREF(py_import);
+    #endif
+    Py_XDECREF(empty_list);
+    Py_XDECREF(empty_dict);
+    return module;
+}
+
+#define __PYX_VERIFY_RETURN_INT(target_type, func_type, func_value)       \
+    {                                                                     \
+        func_type value = func_value;                                     \
+        if (sizeof(target_type) < sizeof(func_type)) {                    \
+            if (unlikely(value != (func_type) (target_type) value)) {     \
+                func_type zero = 0;                                       \
+                if (is_unsigned && unlikely(value < zero))                \
+                    goto raise_neg_overflow;                              \
+                else                                                      \
+                    goto raise_overflow;                                  \
+            }                                                             \
+        }                                                                 \
+        return (target_type) value;                                       \
+    }
+
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+  #include "longintrepr.h"
+ #endif
+#endif
+
+static CYTHON_INLINE unsigned int __Pyx_PyInt_As_unsigned_int(PyObject *x) {
+    const unsigned int neg_one = (unsigned int) -1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_MAJOR_VERSION < 3
+    if (likely(PyInt_Check(x))) {
+        if (sizeof(unsigned int) < sizeof(long)) {
+            __PYX_VERIFY_RETURN_INT(unsigned int, long, PyInt_AS_LONG(x))
+        } else {
+            long val = PyInt_AS_LONG(x);
+            if (is_unsigned && unlikely(val < 0)) {
+                goto raise_neg_overflow;
+            }
+            return (unsigned int) val;
+        }
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+            switch (Py_SIZE(x)) {
+                case  0: return 0;
+                case  1: __PYX_VERIFY_RETURN_INT(unsigned int, digit, ((PyLongObject*)x)->ob_digit[0]);
+            }
+ #endif
+#endif
+            if (unlikely(Py_SIZE(x) < 0)) {
+                goto raise_neg_overflow;
+            }
+            if (sizeof(unsigned int) <= sizeof(unsigned long)) {
+                __PYX_VERIFY_RETURN_INT(unsigned int, unsigned long, PyLong_AsUnsignedLong(x))
+            } else if (sizeof(unsigned int) <= sizeof(unsigned long long)) {
+                __PYX_VERIFY_RETURN_INT(unsigned int, unsigned long long, PyLong_AsUnsignedLongLong(x))
+            }
+        } else {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+            switch (Py_SIZE(x)) {
+                case  0: return 0;
+                case  1: __PYX_VERIFY_RETURN_INT(unsigned int,  digit, +(((PyLongObject*)x)->ob_digit[0]));
+                case -1: __PYX_VERIFY_RETURN_INT(unsigned int, sdigit, -(sdigit) ((PyLongObject*)x)->ob_digit[0]);
+            }
+ #endif
+#endif
+            if (sizeof(unsigned int) <= sizeof(long)) {
+                __PYX_VERIFY_RETURN_INT(unsigned int, long, PyLong_AsLong(x))
+            } else if (sizeof(unsigned int) <= sizeof(long long)) {
+                __PYX_VERIFY_RETURN_INT(unsigned int, long long, PyLong_AsLongLong(x))
+            }
+        }
+        {
+#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray)
+            PyErr_SetString(PyExc_RuntimeError,
+                            "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers");
+#else
+            unsigned int val;
+            PyObject *v = __Pyx_PyNumber_Int(x);
+ #if PY_MAJOR_VERSION < 3
+            if (likely(v) && !PyLong_Check(v)) {
+                PyObject *tmp = v;
+                v = PyNumber_Long(tmp);
+                Py_DECREF(tmp);
+            }
+ #endif
+            if (likely(v)) {
+                int one = 1; int is_little = (int)*(unsigned char *)&one;
+                unsigned char *bytes = (unsigned char *)&val;
+                int ret = _PyLong_AsByteArray((PyLongObject *)v,
+                                              bytes, sizeof(val),
+                                              is_little, !is_unsigned);
+                Py_DECREF(v);
+                if (likely(!ret))
+                    return val;
+            }
+#endif
+            return (unsigned int) -1;
+        }
+    } else {
+        unsigned int val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (unsigned int) -1;
+        val = __Pyx_PyInt_As_unsigned_int(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+raise_overflow:
+    PyErr_SetString(PyExc_OverflowError,
+        "value too large to convert to unsigned int");
+    return (unsigned int) -1;
+raise_neg_overflow:
+    PyErr_SetString(PyExc_OverflowError,
+        "can't convert negative value to unsigned int");
+    return (unsigned int) -1;
+}
+
+static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *x) {
+    const int neg_one = (int) -1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_MAJOR_VERSION < 3
+    if (likely(PyInt_Check(x))) {
+        if (sizeof(int) < sizeof(long)) {
+            __PYX_VERIFY_RETURN_INT(int, long, PyInt_AS_LONG(x))
+        } else {
+            long val = PyInt_AS_LONG(x);
+            if (is_unsigned && unlikely(val < 0)) {
+                goto raise_neg_overflow;
+            }
+            return (int) val;
+        }
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+            switch (Py_SIZE(x)) {
+                case  0: return 0;
+                case  1: __PYX_VERIFY_RETURN_INT(int, digit, ((PyLongObject*)x)->ob_digit[0]);
+            }
+ #endif
+#endif
+            if (unlikely(Py_SIZE(x) < 0)) {
+                goto raise_neg_overflow;
+            }
+            if (sizeof(int) <= sizeof(unsigned long)) {
+                __PYX_VERIFY_RETURN_INT(int, unsigned long, PyLong_AsUnsignedLong(x))
+            } else if (sizeof(int) <= sizeof(unsigned long long)) {
+                __PYX_VERIFY_RETURN_INT(int, unsigned long long, PyLong_AsUnsignedLongLong(x))
+            }
+        } else {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+            switch (Py_SIZE(x)) {
+                case  0: return 0;
+                case  1: __PYX_VERIFY_RETURN_INT(int,  digit, +(((PyLongObject*)x)->ob_digit[0]));
+                case -1: __PYX_VERIFY_RETURN_INT(int, sdigit, -(sdigit) ((PyLongObject*)x)->ob_digit[0]);
+            }
+ #endif
+#endif
+            if (sizeof(int) <= sizeof(long)) {
+                __PYX_VERIFY_RETURN_INT(int, long, PyLong_AsLong(x))
+            } else if (sizeof(int) <= sizeof(long long)) {
+                __PYX_VERIFY_RETURN_INT(int, long long, PyLong_AsLongLong(x))
+            }
+        }
+        {
+#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray)
+            PyErr_SetString(PyExc_RuntimeError,
+                            "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers");
+#else
+            int val;
+            PyObject *v = __Pyx_PyNumber_Int(x);
+ #if PY_MAJOR_VERSION < 3
+            if (likely(v) && !PyLong_Check(v)) {
+                PyObject *tmp = v;
+                v = PyNumber_Long(tmp);
+                Py_DECREF(tmp);
+            }
+ #endif
+            if (likely(v)) {
+                int one = 1; int is_little = (int)*(unsigned char *)&one;
+                unsigned char *bytes = (unsigned char *)&val;
+                int ret = _PyLong_AsByteArray((PyLongObject *)v,
+                                              bytes, sizeof(val),
+                                              is_little, !is_unsigned);
+                Py_DECREF(v);
+                if (likely(!ret))
+                    return val;
+            }
+#endif
+            return (int) -1;
+        }
+    } else {
+        int val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (int) -1;
+        val = __Pyx_PyInt_As_int(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+raise_overflow:
+    PyErr_SetString(PyExc_OverflowError,
+        "value too large to convert to int");
+    return (int) -1;
+raise_neg_overflow:
+    PyErr_SetString(PyExc_OverflowError,
+        "can't convert negative value to int");
+    return (int) -1;
+}
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value) {
+    const long neg_one = (long) -1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (is_unsigned) {
+        if (sizeof(long) < sizeof(long)) {
+            return PyInt_FromLong((long) value);
+        } else if (sizeof(long) <= sizeof(unsigned long)) {
+            return PyLong_FromUnsignedLong((unsigned long) value);
+        } else if (sizeof(long) <= sizeof(unsigned long long)) {
+            return PyLong_FromUnsignedLongLong((unsigned long long) value);
+        }
+    } else {
+        if (sizeof(long) <= sizeof(long)) {
+            return PyInt_FromLong((long) value);
+        } else if (sizeof(long) <= sizeof(long long)) {
+            return PyLong_FromLongLong((long long) value);
+        }
+    }
+    {
+        int one = 1; int little = (int)*(unsigned char *)&one;
+        unsigned char *bytes = (unsigned char *)&value;
+        return _PyLong_FromByteArray(bytes, sizeof(long),
+                                     little, !is_unsigned);
+    }
+}
+
+static CYTHON_INLINE unsigned char __Pyx_PyInt_As_unsigned_char(PyObject *x) {
+    const unsigned char neg_one = (unsigned char) -1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_MAJOR_VERSION < 3
+    if (likely(PyInt_Check(x))) {
+        if (sizeof(unsigned char) < sizeof(long)) {
+            __PYX_VERIFY_RETURN_INT(unsigned char, long, PyInt_AS_LONG(x))
+        } else {
+            long val = PyInt_AS_LONG(x);
+            if (is_unsigned && unlikely(val < 0)) {
+                goto raise_neg_overflow;
+            }
+            return (unsigned char) val;
+        }
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+            switch (Py_SIZE(x)) {
+                case  0: return 0;
+                case  1: __PYX_VERIFY_RETURN_INT(unsigned char, digit, ((PyLongObject*)x)->ob_digit[0]);
+            }
+ #endif
+#endif
+            if (unlikely(Py_SIZE(x) < 0)) {
+                goto raise_neg_overflow;
+            }
+            if (sizeof(unsigned char) <= sizeof(unsigned long)) {
+                __PYX_VERIFY_RETURN_INT(unsigned char, unsigned long, PyLong_AsUnsignedLong(x))
+            } else if (sizeof(unsigned char) <= sizeof(unsigned long long)) {
+                __PYX_VERIFY_RETURN_INT(unsigned char, unsigned long long, PyLong_AsUnsignedLongLong(x))
+            }
+        } else {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+            switch (Py_SIZE(x)) {
+                case  0: return 0;
+                case  1: __PYX_VERIFY_RETURN_INT(unsigned char,  digit, +(((PyLongObject*)x)->ob_digit[0]));
+                case -1: __PYX_VERIFY_RETURN_INT(unsigned char, sdigit, -(sdigit) ((PyLongObject*)x)->ob_digit[0]);
+            }
+ #endif
+#endif
+            if (sizeof(unsigned char) <= sizeof(long)) {
+                __PYX_VERIFY_RETURN_INT(unsigned char, long, PyLong_AsLong(x))
+            } else if (sizeof(unsigned char) <= sizeof(long long)) {
+                __PYX_VERIFY_RETURN_INT(unsigned char, long long, PyLong_AsLongLong(x))
+            }
+        }
+        {
+#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray)
+            PyErr_SetString(PyExc_RuntimeError,
+                            "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers");
+#else
+            unsigned char val;
+            PyObject *v = __Pyx_PyNumber_Int(x);
+ #if PY_MAJOR_VERSION < 3
+            if (likely(v) && !PyLong_Check(v)) {
+                PyObject *tmp = v;
+                v = PyNumber_Long(tmp);
+                Py_DECREF(tmp);
+            }
+ #endif
+            if (likely(v)) {
+                int one = 1; int is_little = (int)*(unsigned char *)&one;
+                unsigned char *bytes = (unsigned char *)&val;
+                int ret = _PyLong_AsByteArray((PyLongObject *)v,
+                                              bytes, sizeof(val),
+                                              is_little, !is_unsigned);
+                Py_DECREF(v);
+                if (likely(!ret))
+                    return val;
+            }
+#endif
+            return (unsigned char) -1;
+        }
+    } else {
+        unsigned char val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (unsigned char) -1;
+        val = __Pyx_PyInt_As_unsigned_char(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+raise_overflow:
+    PyErr_SetString(PyExc_OverflowError,
+        "value too large to convert to unsigned char");
+    return (unsigned char) -1;
+raise_neg_overflow:
+    PyErr_SetString(PyExc_OverflowError,
+        "can't convert negative value to unsigned char");
+    return (unsigned char) -1;
+}
+
+static CYTHON_INLINE unsigned short __Pyx_PyInt_As_unsigned_short(PyObject *x) {
+    const unsigned short neg_one = (unsigned short) -1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_MAJOR_VERSION < 3
+    if (likely(PyInt_Check(x))) {
+        if (sizeof(unsigned short) < sizeof(long)) {
+            __PYX_VERIFY_RETURN_INT(unsigned short, long, PyInt_AS_LONG(x))
+        } else {
+            long val = PyInt_AS_LONG(x);
+            if (is_unsigned && unlikely(val < 0)) {
+                goto raise_neg_overflow;
+            }
+            return (unsigned short) val;
+        }
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+            switch (Py_SIZE(x)) {
+                case  0: return 0;
+                case  1: __PYX_VERIFY_RETURN_INT(unsigned short, digit, ((PyLongObject*)x)->ob_digit[0]);
+            }
+ #endif
+#endif
+            if (unlikely(Py_SIZE(x) < 0)) {
+                goto raise_neg_overflow;
+            }
+            if (sizeof(unsigned short) <= sizeof(unsigned long)) {
+                __PYX_VERIFY_RETURN_INT(unsigned short, unsigned long, PyLong_AsUnsignedLong(x))
+            } else if (sizeof(unsigned short) <= sizeof(unsigned long long)) {
+                __PYX_VERIFY_RETURN_INT(unsigned short, unsigned long long, PyLong_AsUnsignedLongLong(x))
+            }
+        } else {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+            switch (Py_SIZE(x)) {
+                case  0: return 0;
+                case  1: __PYX_VERIFY_RETURN_INT(unsigned short,  digit, +(((PyLongObject*)x)->ob_digit[0]));
+                case -1: __PYX_VERIFY_RETURN_INT(unsigned short, sdigit, -(sdigit) ((PyLongObject*)x)->ob_digit[0]);
+            }
+ #endif
+#endif
+            if (sizeof(unsigned short) <= sizeof(long)) {
+                __PYX_VERIFY_RETURN_INT(unsigned short, long, PyLong_AsLong(x))
+            } else if (sizeof(unsigned short) <= sizeof(long long)) {
+                __PYX_VERIFY_RETURN_INT(unsigned short, long long, PyLong_AsLongLong(x))
+            }
+        }
+        {
+#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray)
+            PyErr_SetString(PyExc_RuntimeError,
+                            "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers");
+#else
+            unsigned short val;
+            PyObject *v = __Pyx_PyNumber_Int(x);
+ #if PY_MAJOR_VERSION < 3
+            if (likely(v) && !PyLong_Check(v)) {
+                PyObject *tmp = v;
+                v = PyNumber_Long(tmp);
+                Py_DECREF(tmp);
+            }
+ #endif
+            if (likely(v)) {
+                int one = 1; int is_little = (int)*(unsigned char *)&one;
+                unsigned char *bytes = (unsigned char *)&val;
+                int ret = _PyLong_AsByteArray((PyLongObject *)v,
+                                              bytes, sizeof(val),
+                                              is_little, !is_unsigned);
+                Py_DECREF(v);
+                if (likely(!ret))
+                    return val;
+            }
+#endif
+            return (unsigned short) -1;
+        }
+    } else {
+        unsigned short val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (unsigned short) -1;
+        val = __Pyx_PyInt_As_unsigned_short(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+raise_overflow:
+    PyErr_SetString(PyExc_OverflowError,
+        "value too large to convert to unsigned short");
+    return (unsigned short) -1;
+raise_neg_overflow:
+    PyErr_SetString(PyExc_OverflowError,
+        "can't convert negative value to unsigned short");
+    return (unsigned short) -1;
+}
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_unsigned_short(unsigned short value) {
+    const unsigned short neg_one = (unsigned short) -1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (is_unsigned) {
+        if (sizeof(unsigned short) < sizeof(long)) {
+            return PyInt_FromLong((long) value);
+        } else if (sizeof(unsigned short) <= sizeof(unsigned long)) {
+            return PyLong_FromUnsignedLong((unsigned long) value);
+        } else if (sizeof(unsigned short) <= sizeof(unsigned long long)) {
+            return PyLong_FromUnsignedLongLong((unsigned long long) value);
+        }
+    } else {
+        if (sizeof(unsigned short) <= sizeof(long)) {
+            return PyInt_FromLong((long) value);
+        } else if (sizeof(unsigned short) <= sizeof(long long)) {
+            return PyLong_FromLongLong((long long) value);
+        }
+    }
+    {
+        int one = 1; int little = (int)*(unsigned char *)&one;
+        unsigned char *bytes = (unsigned char *)&value;
+        return _PyLong_FromByteArray(bytes, sizeof(unsigned short),
+                                     little, !is_unsigned);
+    }
+}
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value) {
+    const int neg_one = (int) -1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (is_unsigned) {
+        if (sizeof(int) < sizeof(long)) {
+            return PyInt_FromLong((long) value);
+        } else if (sizeof(int) <= sizeof(unsigned long)) {
+            return PyLong_FromUnsignedLong((unsigned long) value);
+        } else if (sizeof(int) <= sizeof(unsigned long long)) {
+            return PyLong_FromUnsignedLongLong((unsigned long long) value);
+        }
+    } else {
+        if (sizeof(int) <= sizeof(long)) {
+            return PyInt_FromLong((long) value);
+        } else if (sizeof(int) <= sizeof(long long)) {
+            return PyLong_FromLongLong((long long) value);
+        }
+    }
+    {
+        int one = 1; int little = (int)*(unsigned char *)&one;
+        unsigned char *bytes = (unsigned char *)&value;
+        return _PyLong_FromByteArray(bytes, sizeof(int),
+                                     little, !is_unsigned);
+    }
+}
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_unsigned_int(unsigned int value) {
+    const unsigned int neg_one = (unsigned int) -1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (is_unsigned) {
+        if (sizeof(unsigned int) < sizeof(long)) {
+            return PyInt_FromLong((long) value);
+        } else if (sizeof(unsigned int) <= sizeof(unsigned long)) {
+            return PyLong_FromUnsignedLong((unsigned long) value);
+        } else if (sizeof(unsigned int) <= sizeof(unsigned long long)) {
+            return PyLong_FromUnsignedLongLong((unsigned long long) value);
+        }
+    } else {
+        if (sizeof(unsigned int) <= sizeof(long)) {
+            return PyInt_FromLong((long) value);
+        } else if (sizeof(unsigned int) <= sizeof(long long)) {
+            return PyLong_FromLongLong((long long) value);
+        }
+    }
+    {
+        int one = 1; int little = (int)*(unsigned char *)&one;
+        unsigned char *bytes = (unsigned char *)&value;
+        return _PyLong_FromByteArray(bytes, sizeof(unsigned int),
+                                     little, !is_unsigned);
+    }
+}
+
+#if CYTHON_CCOMPLEX
+  #ifdef __cplusplus
+    static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float x, float y) {
+      return ::std::complex< float >(x, y);
+    }
+  #else
+    static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float x, float y) {
+      return x + y*(__pyx_t_float_complex)_Complex_I;
+    }
+  #endif
+#else
+    static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float x, float y) {
+      __pyx_t_float_complex z;
+      z.real = x;
+      z.imag = y;
+      return z;
+    }
+#endif
+
+#if CYTHON_CCOMPLEX
+#else
+    static CYTHON_INLINE int __Pyx_c_eqf(__pyx_t_float_complex a, __pyx_t_float_complex b) {
+       return (a.real == b.real) && (a.imag == b.imag);
+    }
+    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_sumf(__pyx_t_float_complex a, __pyx_t_float_complex b) {
+        __pyx_t_float_complex z;
+        z.real = a.real + b.real;
+        z.imag = a.imag + b.imag;
+        return z;
+    }
+    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_difff(__pyx_t_float_complex a, __pyx_t_float_complex b) {
+        __pyx_t_float_complex z;
+        z.real = a.real - b.real;
+        z.imag = a.imag - b.imag;
+        return z;
+    }
+    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_prodf(__pyx_t_float_complex a, __pyx_t_float_complex b) {
+        __pyx_t_float_complex z;
+        z.real = a.real * b.real - a.imag * b.imag;
+        z.imag = a.real * b.imag + a.imag * b.real;
+        return z;
+    }
+    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_quotf(__pyx_t_float_complex a, __pyx_t_float_complex b) {
+        __pyx_t_float_complex z;
+        float denom = b.real * b.real + b.imag * b.imag;
+        z.real = (a.real * b.real + a.imag * b.imag) / denom;
+        z.imag = (a.imag * b.real - a.real * b.imag) / denom;
+        return z;
+    }
+    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_negf(__pyx_t_float_complex a) {
+        __pyx_t_float_complex z;
+        z.real = -a.real;
+        z.imag = -a.imag;
+        return z;
+    }
+    static CYTHON_INLINE int __Pyx_c_is_zerof(__pyx_t_float_complex a) {
+       return (a.real == 0) && (a.imag == 0);
+    }
+    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_conjf(__pyx_t_float_complex a) {
+        __pyx_t_float_complex z;
+        z.real =  a.real;
+        z.imag = -a.imag;
+        return z;
+    }
+    #if 1
+        static CYTHON_INLINE float __Pyx_c_absf(__pyx_t_float_complex z) {
+          #if !defined(HAVE_HYPOT) || defined(_MSC_VER)
+            return sqrtf(z.real*z.real + z.imag*z.imag);
+          #else
+            return hypotf(z.real, z.imag);
+          #endif
+        }
+        static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_powf(__pyx_t_float_complex a, __pyx_t_float_complex b) {
+            __pyx_t_float_complex z;
+            float r, lnr, theta, z_r, z_theta;
+            if (b.imag == 0 && b.real == (int)b.real) {
+                if (b.real < 0) {
+                    float denom = a.real * a.real + a.imag * a.imag;
+                    a.real = a.real / denom;
+                    a.imag = -a.imag / denom;
+                    b.real = -b.real;
+                }
+                switch ((int)b.real) {
+                    case 0:
+                        z.real = 1;
+                        z.imag = 0;
+                        return z;
+                    case 1:
+                        return a;
+                    case 2:
+                        z = __Pyx_c_prodf(a, a);
+                        return __Pyx_c_prodf(a, a);
+                    case 3:
+                        z = __Pyx_c_prodf(a, a);
+                        return __Pyx_c_prodf(z, a);
+                    case 4:
+                        z = __Pyx_c_prodf(a, a);
+                        return __Pyx_c_prodf(z, z);
+                }
+            }
+            if (a.imag == 0) {
+                if (a.real == 0) {
+                    return a;
+                }
+                r = a.real;
+                theta = 0;
+            } else {
+                r = __Pyx_c_absf(a);
+                theta = atan2f(a.imag, a.real);
+            }
+            lnr = logf(r);
+            z_r = expf(lnr * b.real - theta * b.imag);
+            z_theta = theta * b.real + lnr * b.imag;
+            z.real = z_r * cosf(z_theta);
+            z.imag = z_r * sinf(z_theta);
+            return z;
+        }
+    #endif
+#endif
+
+#if CYTHON_CCOMPLEX
+  #ifdef __cplusplus
+    static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) {
+      return ::std::complex< double >(x, y);
+    }
+  #else
+    static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) {
+      return x + y*(__pyx_t_double_complex)_Complex_I;
+    }
+  #endif
+#else
+    static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) {
+      __pyx_t_double_complex z;
+      z.real = x;
+      z.imag = y;
+      return z;
+    }
+#endif
+
+#if CYTHON_CCOMPLEX
+#else
+    static CYTHON_INLINE int __Pyx_c_eq(__pyx_t_double_complex a, __pyx_t_double_complex b) {
+       return (a.real == b.real) && (a.imag == b.imag);
+    }
+    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_sum(__pyx_t_double_complex a, __pyx_t_double_complex b) {
+        __pyx_t_double_complex z;
+        z.real = a.real + b.real;
+        z.imag = a.imag + b.imag;
+        return z;
+    }
+    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_diff(__pyx_t_double_complex a, __pyx_t_double_complex b) {
+        __pyx_t_double_complex z;
+        z.real = a.real - b.real;
+        z.imag = a.imag - b.imag;
+        return z;
+    }
+    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_prod(__pyx_t_double_complex a, __pyx_t_double_complex b) {
+        __pyx_t_double_complex z;
+        z.real = a.real * b.real - a.imag * b.imag;
+        z.imag = a.real * b.imag + a.imag * b.real;
+        return z;
+    }
+    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_quot(__pyx_t_double_complex a, __pyx_t_double_complex b) {
+        __pyx_t_double_complex z;
+        double denom = b.real * b.real + b.imag * b.imag;
+        z.real = (a.real * b.real + a.imag * b.imag) / denom;
+        z.imag = (a.imag * b.real - a.real * b.imag) / denom;
+        return z;
+    }
+    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_neg(__pyx_t_double_complex a) {
+        __pyx_t_double_complex z;
+        z.real = -a.real;
+        z.imag = -a.imag;
+        return z;
+    }
+    static CYTHON_INLINE int __Pyx_c_is_zero(__pyx_t_double_complex a) {
+       return (a.real == 0) && (a.imag == 0);
+    }
+    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_conj(__pyx_t_double_complex a) {
+        __pyx_t_double_complex z;
+        z.real =  a.real;
+        z.imag = -a.imag;
+        return z;
+    }
+    #if 1
+        static CYTHON_INLINE double __Pyx_c_abs(__pyx_t_double_complex z) {
+          #if !defined(HAVE_HYPOT) || defined(_MSC_VER)
+            return sqrt(z.real*z.real + z.imag*z.imag);
+          #else
+            return hypot(z.real, z.imag);
+          #endif
+        }
+        static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_pow(__pyx_t_double_complex a, __pyx_t_double_complex b) {
+            __pyx_t_double_complex z;
+            double r, lnr, theta, z_r, z_theta;
+            if (b.imag == 0 && b.real == (int)b.real) {
+                if (b.real < 0) {
+                    double denom = a.real * a.real + a.imag * a.imag;
+                    a.real = a.real / denom;
+                    a.imag = -a.imag / denom;
+                    b.real = -b.real;
+                }
+                switch ((int)b.real) {
+                    case 0:
+                        z.real = 1;
+                        z.imag = 0;
+                        return z;
+                    case 1:
+                        return a;
+                    case 2:
+                        z = __Pyx_c_prod(a, a);
+                        return __Pyx_c_prod(a, a);
+                    case 3:
+                        z = __Pyx_c_prod(a, a);
+                        return __Pyx_c_prod(z, a);
+                    case 4:
+                        z = __Pyx_c_prod(a, a);
+                        return __Pyx_c_prod(z, z);
+                }
+            }
+            if (a.imag == 0) {
+                if (a.real == 0) {
+                    return a;
+                }
+                r = a.real;
+                theta = 0;
+            } else {
+                r = __Pyx_c_abs(a);
+                theta = atan2(a.imag, a.real);
+            }
+            lnr = log(r);
+            z_r = exp(lnr * b.real - theta * b.imag);
+            z_theta = theta * b.real + lnr * b.imag;
+            z.real = z_r * cos(z_theta);
+            z.imag = z_r * sin(z_theta);
+            return z;
+        }
+    #endif
+#endif
+
+static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *x) {
+    const long neg_one = (long) -1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_MAJOR_VERSION < 3
+    if (likely(PyInt_Check(x))) {
+        if (sizeof(long) < sizeof(long)) {
+            __PYX_VERIFY_RETURN_INT(long, long, PyInt_AS_LONG(x))
+        } else {
+            long val = PyInt_AS_LONG(x);
+            if (is_unsigned && unlikely(val < 0)) {
+                goto raise_neg_overflow;
+            }
+            return (long) val;
+        }
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+            switch (Py_SIZE(x)) {
+                case  0: return 0;
+                case  1: __PYX_VERIFY_RETURN_INT(long, digit, ((PyLongObject*)x)->ob_digit[0]);
+            }
+ #endif
+#endif
+            if (unlikely(Py_SIZE(x) < 0)) {
+                goto raise_neg_overflow;
+            }
+            if (sizeof(long) <= sizeof(unsigned long)) {
+                __PYX_VERIFY_RETURN_INT(long, unsigned long, PyLong_AsUnsignedLong(x))
+            } else if (sizeof(long) <= sizeof(unsigned long long)) {
+                __PYX_VERIFY_RETURN_INT(long, unsigned long long, PyLong_AsUnsignedLongLong(x))
+            }
+        } else {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+            switch (Py_SIZE(x)) {
+                case  0: return 0;
+                case  1: __PYX_VERIFY_RETURN_INT(long,  digit, +(((PyLongObject*)x)->ob_digit[0]));
+                case -1: __PYX_VERIFY_RETURN_INT(long, sdigit, -(sdigit) ((PyLongObject*)x)->ob_digit[0]);
+            }
+ #endif
+#endif
+            if (sizeof(long) <= sizeof(long)) {
+                __PYX_VERIFY_RETURN_INT(long, long, PyLong_AsLong(x))
+            } else if (sizeof(long) <= sizeof(long long)) {
+                __PYX_VERIFY_RETURN_INT(long, long long, PyLong_AsLongLong(x))
+            }
+        }
+        {
+#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray)
+            PyErr_SetString(PyExc_RuntimeError,
+                            "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers");
+#else
+            long val;
+            PyObject *v = __Pyx_PyNumber_Int(x);
+ #if PY_MAJOR_VERSION < 3
+            if (likely(v) && !PyLong_Check(v)) {
+                PyObject *tmp = v;
+                v = PyNumber_Long(tmp);
+                Py_DECREF(tmp);
+            }
+ #endif
+            if (likely(v)) {
+                int one = 1; int is_little = (int)*(unsigned char *)&one;
+                unsigned char *bytes = (unsigned char *)&val;
+                int ret = _PyLong_AsByteArray((PyLongObject *)v,
+                                              bytes, sizeof(val),
+                                              is_little, !is_unsigned);
+                Py_DECREF(v);
+                if (likely(!ret))
+                    return val;
+            }
+#endif
+            return (long) -1;
+        }
+    } else {
+        long val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (long) -1;
+        val = __Pyx_PyInt_As_long(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+raise_overflow:
+    PyErr_SetString(PyExc_OverflowError,
+        "value too large to convert to long");
+    return (long) -1;
+raise_neg_overflow:
+    PyErr_SetString(PyExc_OverflowError,
+        "can't convert negative value to long");
+    return (long) -1;
+}
+
+static int __Pyx_check_binary_version(void) {
+    char ctversion[4], rtversion[4];
+    PyOS_snprintf(ctversion, 4, "%d.%d", PY_MAJOR_VERSION, PY_MINOR_VERSION);
+    PyOS_snprintf(rtversion, 4, "%s", Py_GetVersion());
+    if (ctversion[0] != rtversion[0] || ctversion[2] != rtversion[2]) {
+        char message[200];
+        PyOS_snprintf(message, sizeof(message),
+                      "compiletime version %s of module '%.100s' "
+                      "does not match runtime version %s",
+                      ctversion, __Pyx_MODULE_NAME, rtversion);
+        return PyErr_WarnEx(NULL, message, 1);
+    }
+    return 0;
+}
+
+#ifndef __PYX_HAVE_RT_ImportModule
+#define __PYX_HAVE_RT_ImportModule
+static PyObject *__Pyx_ImportModule(const char *name) {
+    PyObject *py_name = 0;
+    PyObject *py_module = 0;
+    py_name = __Pyx_PyIdentifier_FromString(name);
+    if (!py_name)
+        goto bad;
+    py_module = PyImport_Import(py_name);
+    Py_DECREF(py_name);
+    return py_module;
+bad:
+    Py_XDECREF(py_name);
+    return 0;
+}
+#endif
+
+#ifndef __PYX_HAVE_RT_ImportType
+#define __PYX_HAVE_RT_ImportType
+static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name,
+    size_t size, int strict)
+{
+    PyObject *py_module = 0;
+    PyObject *result = 0;
+    PyObject *py_name = 0;
+    char warning[200];
+    Py_ssize_t basicsize;
+#ifdef Py_LIMITED_API
+    PyObject *py_basicsize;
+#endif
+    py_module = __Pyx_ImportModule(module_name);
+    if (!py_module)
+        goto bad;
+    py_name = __Pyx_PyIdentifier_FromString(class_name);
+    if (!py_name)
+        goto bad;
+    result = PyObject_GetAttr(py_module, py_name);
+    Py_DECREF(py_name);
+    py_name = 0;
+    Py_DECREF(py_module);
+    py_module = 0;
+    if (!result)
+        goto bad;
+    if (!PyType_Check(result)) {
+        PyErr_Format(PyExc_TypeError,
+            "%.200s.%.200s is not a type object",
+            module_name, class_name);
+        goto bad;
+    }
+#ifndef Py_LIMITED_API
+    basicsize = ((PyTypeObject *)result)->tp_basicsize;
+#else
+    py_basicsize = PyObject_GetAttrString(result, "__basicsize__");
+    if (!py_basicsize)
+        goto bad;
+    basicsize = PyLong_AsSsize_t(py_basicsize);
+    Py_DECREF(py_basicsize);
+    py_basicsize = 0;
+    if (basicsize == (Py_ssize_t)-1 && PyErr_Occurred())
+        goto bad;
+#endif
+    if (!strict && (size_t)basicsize > size) {
+        PyOS_snprintf(warning, sizeof(warning),
+            "%s.%s size changed, may indicate binary incompatibility",
+            module_name, class_name);
+        if (PyErr_WarnEx(NULL, warning, 0) < 0) goto bad;
+    }
+    else if ((size_t)basicsize != size) {
+        PyErr_Format(PyExc_ValueError,
+            "%.200s.%.200s has the wrong size, try recompiling",
+            module_name, class_name);
+        goto bad;
+    }
+    return (PyTypeObject *)result;
+bad:
+    Py_XDECREF(py_module);
+    Py_XDECREF(result);
+    return NULL;
+}
+#endif
+
+static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
+    while (t->p) {
+        #if PY_MAJOR_VERSION < 3
+        if (t->is_unicode) {
+            *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
+        } else if (t->intern) {
+            *t->p = PyString_InternFromString(t->s);
+        } else {
+            *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
+        }
+        #else
+        if (t->is_unicode | t->is_str) {
+            if (t->intern) {
+                *t->p = PyUnicode_InternFromString(t->s);
+            } else if (t->encoding) {
+                *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL);
+            } else {
+                *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
+            }
+        } else {
+            *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
+        }
+        #endif
+        if (!*t->p)
+            return -1;
+        ++t;
+    }
+    return 0;
+}
+
+static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char* c_str) {
+    return __Pyx_PyUnicode_FromStringAndSize(c_str, (Py_ssize_t)strlen(c_str));
+}
+static CYTHON_INLINE char* __Pyx_PyObject_AsString(PyObject* o) {
+    Py_ssize_t ignore;
+    return __Pyx_PyObject_AsStringAndSize(o, &ignore);
+}
+static CYTHON_INLINE char* __Pyx_PyObject_AsStringAndSize(PyObject* o, Py_ssize_t *length) {
+#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT
+    if (
+#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII
+            __Pyx_sys_getdefaultencoding_not_ascii &&
+#endif
+            PyUnicode_Check(o)) {
+#if PY_VERSION_HEX < 0x03030000
+        char* defenc_c;
+        PyObject* defenc = _PyUnicode_AsDefaultEncodedString(o, NULL);
+        if (!defenc) return NULL;
+        defenc_c = PyBytes_AS_STRING(defenc);
+#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII
+        {
+            char* end = defenc_c + PyBytes_GET_SIZE(defenc);
+            char* c;
+            for (c = defenc_c; c < end; c++) {
+                if ((unsigned char) (*c) >= 128) {
+                    PyUnicode_AsASCIIString(o);
+                    return NULL;
+                }
+            }
+        }
+#endif
+        *length = PyBytes_GET_SIZE(defenc);
+        return defenc_c;
+#else
+        if (__Pyx_PyUnicode_READY(o) == -1) return NULL;
+#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII
+        if (PyUnicode_IS_ASCII(o)) {
+            *length = PyUnicode_GET_LENGTH(o);
+            return PyUnicode_AsUTF8(o);
+        } else {
+            PyUnicode_AsASCIIString(o);
+            return NULL;
+        }
+#else
+        return PyUnicode_AsUTF8AndSize(o, length);
+#endif
+#endif
+    } else
+#endif
+#if !CYTHON_COMPILING_IN_PYPY
+    if (PyByteArray_Check(o)) {
+        *length = PyByteArray_GET_SIZE(o);
+        return PyByteArray_AS_STRING(o);
+    } else
+#endif
+    {
+        char* result;
+        int r = PyBytes_AsStringAndSize(o, &result, length);
+        if (unlikely(r < 0)) {
+            return NULL;
+        } else {
+            return result;
+        }
+    }
+}
+static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) {
+   int is_true = x == Py_True;
+   if (is_true | (x == Py_False) | (x == Py_None)) return is_true;
+   else return PyObject_IsTrue(x);
+}
+static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x) {
+  PyNumberMethods *m;
+  const char *name = NULL;
+  PyObject *res = NULL;
+#if PY_MAJOR_VERSION < 3
+  if (PyInt_Check(x) || PyLong_Check(x))
+#else
+  if (PyLong_Check(x))
+#endif
+    return Py_INCREF(x), x;
+  m = Py_TYPE(x)->tp_as_number;
+#if PY_MAJOR_VERSION < 3
+  if (m && m->nb_int) {
+    name = "int";
+    res = PyNumber_Int(x);
+  }
+  else if (m && m->nb_long) {
+    name = "long";
+    res = PyNumber_Long(x);
+  }
+#else
+  if (m && m->nb_int) {
+    name = "int";
+    res = PyNumber_Long(x);
+  }
+#endif
+  if (res) {
+#if PY_MAJOR_VERSION < 3
+    if (!PyInt_Check(res) && !PyLong_Check(res)) {
+#else
+    if (!PyLong_Check(res)) {
+#endif
+      PyErr_Format(PyExc_TypeError,
+                   "__%.4s__ returned non-%.4s (type %.200s)",
+                   name, name, Py_TYPE(res)->tp_name);
+      Py_DECREF(res);
+      return NULL;
+    }
+  }
+  else if (!PyErr_Occurred()) {
+    PyErr_SetString(PyExc_TypeError,
+                    "an integer is required");
+  }
+  return res;
+}
+static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) {
+  Py_ssize_t ival;
+  PyObject *x;
+#if PY_MAJOR_VERSION < 3
+  if (likely(PyInt_CheckExact(b)))
+      return PyInt_AS_LONG(b);
+#endif
+  if (likely(PyLong_CheckExact(b))) {
+    #if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+     #if CYTHON_USE_PYLONG_INTERNALS
+       switch (Py_SIZE(b)) {
+       case -1: return -(sdigit)((PyLongObject*)b)->ob_digit[0];
+       case  0: return 0;
+       case  1: return ((PyLongObject*)b)->ob_digit[0];
+       }
+     #endif
+    #endif
+    return PyLong_AsSsize_t(b);
+  }
+  x = PyNumber_Index(b);
+  if (!x) return -1;
+  ival = PyInt_AsSsize_t(x);
+  Py_DECREF(x);
+  return ival;
+}
+static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) {
+    return PyInt_FromSize_t(ival);
+}
+
+
+#endif /* Py_PYTHON_H */
diff --git a/lib/bx/bbi/bigwig_file.pyx b/lib/bx/bbi/bigwig_file.pyx
new file mode 100644
index 0000000..73ec601
--- /dev/null
+++ b/lib/bx/bbi/bigwig_file.pyx
@@ -0,0 +1,165 @@
+#cython: profile=False
+"""
+BigWig file.
+"""
+
+from collections import deque
+from bbi_file cimport *
+from cirtree_file cimport CIRTreeFile
+import numpy
+cimport numpy
+from types cimport *
+from bx.misc.binary_file import BinaryFileReader
+from cStringIO import StringIO
+import zlib
+
+DEF big_wig_sig = 0x888FFC26
+DEF bwg_bed_graph = 1
+DEF bwg_variable_step = 2
+DEF bwg_fixed_step = 3
+
+cdef inline int range_intersection( int start1, int end1, int start2, int end2 ):
+    return min( end1, end2 ) - max( start1, start2 )
+
+def chunks(l, n):
+    n = max(1, n)
+    return [l[i:i + n] for i in range(0, len(l), n)]
+
+cdef class BigWigBlockHandler( BlockHandler ):
+    """
+    BlockHandler that parses the block into a series of wiggle records, and calls `handle_interval_value` for each.
+    """
+    cdef bits32 start
+    cdef bits32 end
+    def __init__( self, bits32 start, bits32 end ):
+        BlockHandler.__init__( self )
+        self.start = start
+        self.end = end
+    cdef handle_block( self, str block_data, BBIFile bbi_file ):
+        cdef bits32 b_chrom_id, b_start, b_end, b_valid_count
+        cdef bits32 b_item_step, b_item_span
+        cdef bits16 b_item_count
+        cdef UBYTE b_type
+        cdef int s, e
+        cdef float val
+        # Now we parse the block, first the header
+        block_reader = BinaryFileReader( StringIO( block_data ), is_little_endian=bbi_file.reader.is_little_endian )
+        # _ is skipped byte
+        b_chrom_id, b_start, b_end, b_item_step, b_item_span, b_type, _, b_item_count = block_reader.read_and_unpack("LLLLLBBH", 5*4+1+1+2)
+
+        if b_type == bwg_bed_graph: 
+            # [(start, end, val), ...]
+            sevs = chunks(block_reader.read_and_unpack("LLf" * b_item_count, (2 * 4 + 4) * b_item_count), 3)
+        elif b_type == bwg_variable_step:
+            svs = chunks(block_reader.read_and_unpack("Lf" * b_item_count, (4 + 4) * b_item_count), 2)
+            sevs = [(s, s + b_item_span, v) for s, v in svs]
+        elif b_type == bwg_fixed_step:
+            vs = block_reader.read_and_unpack("f" * b_item_count, 4 * b_item_count)
+            sevs = [(b_start + (i * b_item_span), b_start + (i * b_item_span) + b_item_span, v) for i, v in enumerate(vs)]
+
+        # TODO: change handle_interval to take a numpy array and this will be
+        # much faster.
+        for s, e, val in sevs:
+            if s < self.start: 
+                s = self.start
+            if e > self.end: 
+                e = self.end
+            if s >= e: 
+                continue
+            self.handle_interval_value( s, e, val )
+
+    cdef handle_interval_value( self, bits32 s, bits32 e, float val ):
+        pass
+
+cdef class SummarizingBlockHandler( BigWigBlockHandler ):
+    """
+    Accumulates intervals into a SummarizedData
+    """
+    cdef SummarizedData sd
+    def __init__( self, bits32 start, bits32 end, int summary_size ):
+        BigWigBlockHandler.__init__( self, start, end )
+        # What we will load into
+        self.sd = SummarizedData( start, end, summary_size )
+        self.sd.min_val[:] = numpy.inf
+        self.sd.max_val[:] = -numpy.inf
+
+    cdef inline handle_interval_value( self, bits32 s, bits32 e, float val ):
+        self.sd.accumulate_interval_value( s, e, val )
+
+cdef class IntervalAccumulatingBlockHandler( BigWigBlockHandler ):
+    cdef list intervals
+    """
+    Accumulates intervals into a list of intervals with values
+    """
+    def __init__( self, bits32 start, bits32 end ):
+        BigWigBlockHandler.__init__( self, start, end )
+        self.intervals = []
+
+    cdef handle_interval_value( self, bits32 s, bits32 e, float val ):
+        self.intervals.append( ( s, e, val ) )
+
+cdef class ArrayAccumulatingBlockHandler( BigWigBlockHandler ):
+    """
+    Accumulates intervals into a list of intervals with values
+    """
+    cdef numpy.ndarray array
+    def __init__( self, bits32 start, bits32 end ):
+        BigWigBlockHandler.__init__( self, start, end )
+        self.array = numpy.zeros( end - start, dtype=numpy.float32 )
+        self.array[...] = numpy.nan
+
+    cdef handle_interval_value( self, bits32 s, bits32 e, float val ):
+        #cdef numpy.ndarray[ numpy.float32_t, ndim=1 ] array = self.array
+        # Slicing is optimized by Cython
+        self.array[s - self.start:e - self.start] = val
+
+cdef class BigWigFile( BBIFile ): 
+    """
+    A "big binary indexed" file whose raw data is in wiggle format.
+    """
+    def __init__( self, file=None ):
+        BBIFile.__init__( self, file, big_wig_sig, "bigwig" )
+
+    cdef _summarize_from_full( self, bits32 chrom_id, bits32 start, bits32 end, int summary_size ):
+        """
+        Create summary from full data.
+        """
+        v = SummarizingBlockHandler( start, end, summary_size )
+        self.visit_blocks_in_region( chrom_id, start, end, v )
+        # Round valid count, in place
+        for i from 0 <= i < summary_size:
+            v.sd.valid_count[i] = round( v.sd.valid_count[i] )
+        return v.sd
+        
+    cpdef get( self, char * chrom, bits32 start, bits32 end ):
+        """
+        Gets all data points over the regions `chrom`:`start`-`end`.
+        """
+        if start >= end:
+            return None
+        chrom_id, chrom_size = self._get_chrom_id_and_size( chrom )
+        if chrom_id is None:
+            return None
+        v = IntervalAccumulatingBlockHandler( start, end )
+        self.visit_blocks_in_region( chrom_id, start, end, v )
+        return v.intervals
+
+    cpdef get_as_array( self, char * chrom, bits32 start, bits32 end ):
+        """
+        Gets all data points over the regions `chrom`:`start`-`end`.
+        """
+        if start >= end:
+            return None
+        chrom_id, chrom_size = self._get_chrom_id_and_size( chrom )
+        if chrom_id is None:
+            return None
+        v = ArrayAccumulatingBlockHandler( start, end )
+        self.visit_blocks_in_region( chrom_id, start, end, v )
+        return v.array
+
+
+
+
+
+
+
diff --git a/lib/bx/bbi/bigwig_tests.py b/lib/bx/bbi/bigwig_tests.py
new file mode 100644
index 0000000..6d4f355
--- /dev/null
+++ b/lib/bx/bbi/bigwig_tests.py
@@ -0,0 +1,83 @@
+import sys, os
+import unittest
+import numpy
+
+try:
+    sys.path.insert(0, os.path.dirname(os.path.dirname(__file__)))
+except:
+    sys.path.insert(0, os.path.dirname(os.path.abspath(".")))
+
+from bx.bbi.bigwig_file import BigWigFile
+
+def allclose( a, b, tol=0.00001 ):
+    """
+    Like numpy.allclose but treat Nan == Nan 
+    """
+    d = numpy.absolute( a - b )
+    return numpy.all( numpy.isnan( d ) | ( d < tol ) )
+
+class TestBigWig(unittest.TestCase):
+    def setUp(self):
+        f = open( "test_data/bbi_tests/test.bw" )
+        self.bw = BigWigFile(file=f)
+        
+    def test_get_summary(self):
+        data = self.bw.query("chr1", 10000, 20000, 10)
+        means = [ x['mean'] for x in data ]
+        assert numpy.allclose( map(float, means), [-0.17557571594973645, -0.054009292602539061, -0.056892242431640622, -0.03650328826904297, 0.036112907409667966, 0.0064466032981872557, 0.036949024200439454, 0.076638259887695306, 0.043518108367919923, 0.01554749584197998] )
+        
+        # Summarize variant
+        sd = self.bw.summarize( "chr1", 10000, 20000, 10)
+        assert numpy.allclose( sd.sum_data / sd.valid_count, [-0.17557571594973645, -0.054009292602539061, -0.056892242431640622, -0.03650328826904297, 0.036112907409667966, 0.0064466032981872557, 0.036949024200439454, 0.076638259887695306, 0.043518108367919923, 0.01554749584197998] )
+        
+        # Test min and max for this entire summary region
+        data = self.bw.query("chr1", 10000, 20000, 1)
+        maxs = [ x['max'] for x in data ]
+        mins = [ x['min'] for x in data ]
+        self.assertEqual( map(float, maxs), [0.289000004529953] )
+        self.assertEqual( map(float, mins), [-3.9100000858306885] )
+        
+    def test_get_leaf(self):
+        data = self.bw.query("chr1", 11000, 11005, 5)
+        means = [ x['mean'] for x in data ]
+        assert numpy.allclose( map(float, means), [0.050842501223087311, -2.4589500427246094, 0.050842501223087311, 0.050842501223087311, 0.050842501223087311] )
+        
+        # Test min and max for this entire leaf region
+        data = self.bw.query("chr1", 11000, 11005, 1)
+        maxs = [ x['max'] for x in data ]
+        mins = [ x['min'] for x in data ]
+        self.assertEqual( map(float, maxs), [0.050842501223087311] )
+        self.assertEqual( map(float, mins), [-2.4589500427246094] )
+        
+    def test_wrong_nochrom(self):
+        data = self.bw.query("chr2", 0, 10000, 10)
+        self.assertEqual( data, None )
+
+# Nose test generator
+def test_summaries_from_file():
+    bw = BigWigFile( file=open( "test_data/bbi_tests/test.bw" ) )
+    def check_summary( line ):
+        fields = line.split()
+        chrom = fields[0]
+        start = int( fields[1] )
+        end = int( fields[2] )
+        n = int( fields[3] )
+        t = fields[4]
+        values = [ float( v.replace( 'n/a', 'NaN' ) ) for v in fields[5:] ]
+        sd = bw.summarize( chrom, start, end, n )
+        if t == 'mean':
+            print sd.sum_data / sd.valid_count
+            print values
+            assert allclose( sd.sum_data / sd.valid_count, values )
+        elif t == 'min':
+            assert allclose( sd.min_val, values )
+        elif t == 'max':
+            assert allclose( sd.max_val, values )
+        #elif t == 'std':
+        #    assert numpy.allclose( sd.max_val, values )
+    for line in open( "test_data/bbi_tests/test.expectation" ):
+        yield check_summary, line
+
+        
+if __name__ == '__main__':
+    unittest.main()
diff --git a/lib/bx/bbi/bpt_file.c b/lib/bx/bbi/bpt_file.c
new file mode 100644
index 0000000..8ae1465
--- /dev/null
+++ b/lib/bx/bbi/bpt_file.c
@@ -0,0 +1,2868 @@
+/* Generated by Cython 0.18 on Mon Jul 15 13:25:44 2013 */
+
+#define PY_SSIZE_T_CLEAN
+#include "Python.h"
+#ifndef Py_PYTHON_H
+    #error Python headers needed to compile C extensions, please install development version of Python.
+#elif PY_VERSION_HEX < 0x02040000
+    #error Cython requires Python 2.4+.
+#else
+#include <stddef.h> /* For offsetof */
+#ifndef offsetof
+#define offsetof(type, member) ( (size_t) & ((type*)0) -> member )
+#endif
+#if !defined(WIN32) && !defined(MS_WINDOWS)
+  #ifndef __stdcall
+    #define __stdcall
+  #endif
+  #ifndef __cdecl
+    #define __cdecl
+  #endif
+  #ifndef __fastcall
+    #define __fastcall
+  #endif
+#endif
+#ifndef DL_IMPORT
+  #define DL_IMPORT(t) t
+#endif
+#ifndef DL_EXPORT
+  #define DL_EXPORT(t) t
+#endif
+#ifndef PY_LONG_LONG
+  #define PY_LONG_LONG LONG_LONG
+#endif
+#ifndef Py_HUGE_VAL
+  #define Py_HUGE_VAL HUGE_VAL
+#endif
+#ifdef PYPY_VERSION
+#define CYTHON_COMPILING_IN_PYPY 1
+#define CYTHON_COMPILING_IN_CPYTHON 0
+#else
+#define CYTHON_COMPILING_IN_PYPY 0
+#define CYTHON_COMPILING_IN_CPYTHON 1
+#endif
+#if PY_VERSION_HEX < 0x02050000
+  typedef int Py_ssize_t;
+  #define PY_SSIZE_T_MAX INT_MAX
+  #define PY_SSIZE_T_MIN INT_MIN
+  #define PY_FORMAT_SIZE_T ""
+  #define CYTHON_FORMAT_SSIZE_T ""
+  #define PyInt_FromSsize_t(z) PyInt_FromLong(z)
+  #define PyInt_AsSsize_t(o)   __Pyx_PyInt_AsInt(o)
+  #define PyNumber_Index(o)    ((PyNumber_Check(o) && !PyFloat_Check(o)) ? PyNumber_Int(o) : \
+                                (PyErr_Format(PyExc_TypeError, \
+                                              "expected index value, got %.200s", Py_TYPE(o)->tp_name), \
+                                 (PyObject*)0))
+  #define __Pyx_PyIndex_Check(o) (PyNumber_Check(o) && !PyFloat_Check(o) && \
+                                  !PyComplex_Check(o))
+  #define PyIndex_Check __Pyx_PyIndex_Check
+  #define PyErr_WarnEx(category, message, stacklevel) PyErr_Warn(category, message)
+  #define __PYX_BUILD_PY_SSIZE_T "i"
+#else
+  #define __PYX_BUILD_PY_SSIZE_T "n"
+  #define CYTHON_FORMAT_SSIZE_T "z"
+  #define __Pyx_PyIndex_Check PyIndex_Check
+#endif
+#if PY_VERSION_HEX < 0x02060000
+  #define Py_REFCNT(ob) (((PyObject*)(ob))->ob_refcnt)
+  #define Py_TYPE(ob)   (((PyObject*)(ob))->ob_type)
+  #define Py_SIZE(ob)   (((PyVarObject*)(ob))->ob_size)
+  #define PyVarObject_HEAD_INIT(type, size) \
+          PyObject_HEAD_INIT(type) size,
+  #define PyType_Modified(t)
+  typedef struct {
+     void *buf;
+     PyObject *obj;
+     Py_ssize_t len;
+     Py_ssize_t itemsize;
+     int readonly;
+     int ndim;
+     char *format;
+     Py_ssize_t *shape;
+     Py_ssize_t *strides;
+     Py_ssize_t *suboffsets;
+     void *internal;
+  } Py_buffer;
+  #define PyBUF_SIMPLE 0
+  #define PyBUF_WRITABLE 0x0001
+  #define PyBUF_FORMAT 0x0004
+  #define PyBUF_ND 0x0008
+  #define PyBUF_STRIDES (0x0010 | PyBUF_ND)
+  #define PyBUF_C_CONTIGUOUS (0x0020 | PyBUF_STRIDES)
+  #define PyBUF_F_CONTIGUOUS (0x0040 | PyBUF_STRIDES)
+  #define PyBUF_ANY_CONTIGUOUS (0x0080 | PyBUF_STRIDES)
+  #define PyBUF_INDIRECT (0x0100 | PyBUF_STRIDES)
+  #define PyBUF_RECORDS (PyBUF_STRIDES | PyBUF_FORMAT | PyBUF_WRITABLE)
+  #define PyBUF_FULL (PyBUF_INDIRECT | PyBUF_FORMAT | PyBUF_WRITABLE)
+  typedef int (*getbufferproc)(PyObject *, Py_buffer *, int);
+  typedef void (*releasebufferproc)(PyObject *, Py_buffer *);
+#endif
+#if PY_MAJOR_VERSION < 3
+  #define __Pyx_BUILTIN_MODULE_NAME "__builtin__"
+  #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \
+          PyCode_New(a, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
+#else
+  #define __Pyx_BUILTIN_MODULE_NAME "builtins"
+  #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \
+          PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
+#endif
+#if PY_MAJOR_VERSION < 3 && PY_MINOR_VERSION < 6
+  #define PyUnicode_FromString(s) PyUnicode_Decode(s, strlen(s), "UTF-8", "strict")
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define Py_TPFLAGS_CHECKTYPES 0
+  #define Py_TPFLAGS_HAVE_INDEX 0
+#endif
+#if (PY_VERSION_HEX < 0x02060000) || (PY_MAJOR_VERSION >= 3)
+  #define Py_TPFLAGS_HAVE_NEWBUFFER 0
+#endif
+#if PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND)
+  #define CYTHON_PEP393_ENABLED 1
+  #define __Pyx_PyUnicode_READY(op)       (likely(PyUnicode_IS_READY(op)) ? \
+                                              0 : _PyUnicode_Ready((PyObject *)(op)))
+  #define __Pyx_PyUnicode_GET_LENGTH(u)   PyUnicode_GET_LENGTH(u)
+  #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_READ_CHAR(u, i)
+  #define __Pyx_PyUnicode_READ(k, d, i)   PyUnicode_READ(k, d, i)
+#else
+  #define CYTHON_PEP393_ENABLED 0
+  #define __Pyx_PyUnicode_READY(op)       (0)
+  #define __Pyx_PyUnicode_GET_LENGTH(u)   PyUnicode_GET_SIZE(u)
+  #define __Pyx_PyUnicode_READ_CHAR(u, i) ((Py_UCS4)(PyUnicode_AS_UNICODE(u)[i]))
+  #define __Pyx_PyUnicode_READ(k, d, i)   ((k=k), (Py_UCS4)(((Py_UNICODE*)d)[i]))
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define PyBaseString_Type            PyUnicode_Type
+  #define PyStringObject               PyUnicodeObject
+  #define PyString_Type                PyUnicode_Type
+  #define PyString_Check               PyUnicode_Check
+  #define PyString_CheckExact          PyUnicode_CheckExact
+#endif
+#if PY_VERSION_HEX < 0x02060000
+  #define PyBytesObject                PyStringObject
+  #define PyBytes_Type                 PyString_Type
+  #define PyBytes_Check                PyString_Check
+  #define PyBytes_CheckExact           PyString_CheckExact
+  #define PyBytes_FromString           PyString_FromString
+  #define PyBytes_FromStringAndSize    PyString_FromStringAndSize
+  #define PyBytes_FromFormat           PyString_FromFormat
+  #define PyBytes_DecodeEscape         PyString_DecodeEscape
+  #define PyBytes_AsString             PyString_AsString
+  #define PyBytes_AsStringAndSize      PyString_AsStringAndSize
+  #define PyBytes_Size                 PyString_Size
+  #define PyBytes_AS_STRING            PyString_AS_STRING
+  #define PyBytes_GET_SIZE             PyString_GET_SIZE
+  #define PyBytes_Repr                 PyString_Repr
+  #define PyBytes_Concat               PyString_Concat
+  #define PyBytes_ConcatAndDel         PyString_ConcatAndDel
+#endif
+#if PY_VERSION_HEX < 0x02060000
+  #define PySet_Check(obj)             PyObject_TypeCheck(obj, &PySet_Type)
+  #define PyFrozenSet_Check(obj)       PyObject_TypeCheck(obj, &PyFrozenSet_Type)
+#endif
+#ifndef PySet_CheckExact
+  #define PySet_CheckExact(obj)        (Py_TYPE(obj) == &PySet_Type)
+#endif
+#define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type)
+#if PY_MAJOR_VERSION >= 3
+  #define PyIntObject                  PyLongObject
+  #define PyInt_Type                   PyLong_Type
+  #define PyInt_Check(op)              PyLong_Check(op)
+  #define PyInt_CheckExact(op)         PyLong_CheckExact(op)
+  #define PyInt_FromString             PyLong_FromString
+  #define PyInt_FromUnicode            PyLong_FromUnicode
+  #define PyInt_FromLong               PyLong_FromLong
+  #define PyInt_FromSize_t             PyLong_FromSize_t
+  #define PyInt_FromSsize_t            PyLong_FromSsize_t
+  #define PyInt_AsLong                 PyLong_AsLong
+  #define PyInt_AS_LONG                PyLong_AS_LONG
+  #define PyInt_AsSsize_t              PyLong_AsSsize_t
+  #define PyInt_AsUnsignedLongMask     PyLong_AsUnsignedLongMask
+  #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define PyBoolObject                 PyLongObject
+#endif
+#if PY_VERSION_HEX < 0x03020000
+  typedef long Py_hash_t;
+  #define __Pyx_PyInt_FromHash_t PyInt_FromLong
+  #define __Pyx_PyInt_AsHash_t   PyInt_AsLong
+#else
+  #define __Pyx_PyInt_FromHash_t PyInt_FromSsize_t
+  #define __Pyx_PyInt_AsHash_t   PyInt_AsSsize_t
+#endif
+#if (PY_MAJOR_VERSION < 3) || (PY_VERSION_HEX >= 0x03010300)
+  #define __Pyx_PySequence_GetSlice(obj, a, b) PySequence_GetSlice(obj, a, b)
+  #define __Pyx_PySequence_SetSlice(obj, a, b, value) PySequence_SetSlice(obj, a, b, value)
+  #define __Pyx_PySequence_DelSlice(obj, a, b) PySequence_DelSlice(obj, a, b)
+#else
+  #define __Pyx_PySequence_GetSlice(obj, a, b) (unlikely(!(obj)) ? \
+        (PyErr_SetString(PyExc_SystemError, "null argument to internal routine"), (PyObject*)0) : \
+        (likely((obj)->ob_type->tp_as_mapping) ? (PySequence_GetSlice(obj, a, b)) : \
+            (PyErr_Format(PyExc_TypeError, "'%.200s' object is unsliceable", (obj)->ob_type->tp_name), (PyObject*)0)))
+  #define __Pyx_PySequence_SetSlice(obj, a, b, value) (unlikely(!(obj)) ? \
+        (PyErr_SetString(PyExc_SystemError, "null argument to internal routine"), -1) : \
+        (likely((obj)->ob_type->tp_as_mapping) ? (PySequence_SetSlice(obj, a, b, value)) : \
+            (PyErr_Format(PyExc_TypeError, "'%.200s' object doesn't support slice assignment", (obj)->ob_type->tp_name), -1)))
+  #define __Pyx_PySequence_DelSlice(obj, a, b) (unlikely(!(obj)) ? \
+        (PyErr_SetString(PyExc_SystemError, "null argument to internal routine"), -1) : \
+        (likely((obj)->ob_type->tp_as_mapping) ? (PySequence_DelSlice(obj, a, b)) : \
+            (PyErr_Format(PyExc_TypeError, "'%.200s' object doesn't support slice deletion", (obj)->ob_type->tp_name), -1)))
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define PyMethod_New(func, self, klass) ((self) ? PyMethod_New(func, self) : PyInstanceMethod_New(func))
+#endif
+#if PY_VERSION_HEX < 0x02050000
+  #define __Pyx_GetAttrString(o,n)   PyObject_GetAttrString((o),((char *)(n)))
+  #define __Pyx_SetAttrString(o,n,a) PyObject_SetAttrString((o),((char *)(n)),(a))
+  #define __Pyx_DelAttrString(o,n)   PyObject_DelAttrString((o),((char *)(n)))
+#else
+  #define __Pyx_GetAttrString(o,n)   PyObject_GetAttrString((o),(n))
+  #define __Pyx_SetAttrString(o,n,a) PyObject_SetAttrString((o),(n),(a))
+  #define __Pyx_DelAttrString(o,n)   PyObject_DelAttrString((o),(n))
+#endif
+#if PY_VERSION_HEX < 0x02050000
+  #define __Pyx_NAMESTR(n) ((char *)(n))
+  #define __Pyx_DOCSTR(n)  ((char *)(n))
+#else
+  #define __Pyx_NAMESTR(n) (n)
+  #define __Pyx_DOCSTR(n)  (n)
+#endif
+
+
+#if PY_MAJOR_VERSION >= 3
+  #define __Pyx_PyNumber_Divide(x,y)         PyNumber_TrueDivide(x,y)
+  #define __Pyx_PyNumber_InPlaceDivide(x,y)  PyNumber_InPlaceTrueDivide(x,y)
+#else
+  #define __Pyx_PyNumber_Divide(x,y)         PyNumber_Divide(x,y)
+  #define __Pyx_PyNumber_InPlaceDivide(x,y)  PyNumber_InPlaceDivide(x,y)
+#endif
+
+#ifndef __PYX_EXTERN_C
+  #ifdef __cplusplus
+    #define __PYX_EXTERN_C extern "C"
+  #else
+    #define __PYX_EXTERN_C extern
+  #endif
+#endif
+
+#if defined(WIN32) || defined(MS_WINDOWS)
+#define _USE_MATH_DEFINES
+#endif
+#include <math.h>
+#define __PYX_HAVE__bx__bbi__bpt_file
+#define __PYX_HAVE_API__bx__bbi__bpt_file
+#ifdef _OPENMP
+#include <omp.h>
+#endif /* _OPENMP */
+
+#ifdef PYREX_WITHOUT_ASSERTIONS
+#define CYTHON_WITHOUT_ASSERTIONS
+#endif
+
+#ifndef CYTHON_INLINE
+  #if defined(__GNUC__)
+    #define CYTHON_INLINE __inline__
+  #elif defined(_MSC_VER)
+    #define CYTHON_INLINE __inline
+  #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+    #define CYTHON_INLINE inline
+  #else
+    #define CYTHON_INLINE
+  #endif
+#endif
+#ifndef CYTHON_UNUSED
+# if defined(__GNUC__)
+#   if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
+#     define CYTHON_UNUSED __attribute__ ((__unused__))
+#   else
+#     define CYTHON_UNUSED
+#   endif
+# elif defined(__ICC) || (defined(__INTEL_COMPILER) && !defined(_MSC_VER))
+#   define CYTHON_UNUSED __attribute__ ((__unused__))
+# else
+#   define CYTHON_UNUSED
+# endif
+#endif
+typedef struct {PyObject **p; char *s; const long n; const char* encoding; const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry; /*proto*/
+
+#define __Pyx_PyBytes_FromUString(s) PyBytes_FromString((char*)s)
+#define __Pyx_PyBytes_AsUString(s)   ((unsigned char*) PyBytes_AsString(s))
+#define __Pyx_Owned_Py_None(b) (Py_INCREF(Py_None), Py_None)
+#define __Pyx_PyBool_FromLong(b) ((b) ? (Py_INCREF(Py_True), Py_True) : (Py_INCREF(Py_False), Py_False))
+static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*);
+static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x);
+static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*);
+static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t);
+static CYTHON_INLINE size_t __Pyx_PyInt_AsSize_t(PyObject*);
+#if CYTHON_COMPILING_IN_CPYTHON
+#define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x))
+#else
+#define __pyx_PyFloat_AsDouble(x) PyFloat_AsDouble(x)
+#endif
+#define __pyx_PyFloat_AsFloat(x) ((float) __pyx_PyFloat_AsDouble(x))
+
+
+#ifdef __GNUC__
+  /* Test for GCC > 2.95 */
+  #if __GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))
+    #define likely(x)   __builtin_expect(!!(x), 1)
+    #define unlikely(x) __builtin_expect(!!(x), 0)
+  #else /* __GNUC__ > 2 ... */
+    #define likely(x)   (x)
+    #define unlikely(x) (x)
+  #endif /* __GNUC__ > 2 ... */
+#else /* __GNUC__ */
+  #define likely(x)   (x)
+  #define unlikely(x) (x)
+#endif /* __GNUC__ */
+    
+static PyObject *__pyx_m;
+static PyObject *__pyx_b;
+static PyObject *__pyx_empty_tuple;
+static PyObject *__pyx_empty_bytes;
+static int __pyx_lineno;
+static int __pyx_clineno = 0;
+static const char * __pyx_cfilenm= __FILE__;
+static const char *__pyx_filename;
+
+
+static const char *__pyx_f[] = {
+  "bpt_file.pyx",
+};
+
+/* "types.pxd":1
+ * ctypedef unsigned char UBYTE             # <<<<<<<<<<<<<<
+ * ctypedef signed char BYTE
+ * ctypedef unsigned short UWORD
+ */
+typedef unsigned char __pyx_t_2bx_3bbi_5types_UBYTE;
+
+/* "types.pxd":2
+ * ctypedef unsigned char UBYTE
+ * ctypedef signed char BYTE             # <<<<<<<<<<<<<<
+ * ctypedef unsigned short UWORD
+ * ctypedef short WORD
+ */
+typedef signed char __pyx_t_2bx_3bbi_5types_BYTE;
+
+/* "types.pxd":3
+ * ctypedef unsigned char UBYTE
+ * ctypedef signed char BYTE
+ * ctypedef unsigned short UWORD             # <<<<<<<<<<<<<<
+ * ctypedef short WORD
+ * ctypedef unsigned long long bits64
+ */
+typedef unsigned short __pyx_t_2bx_3bbi_5types_UWORD;
+
+/* "types.pxd":4
+ * ctypedef signed char BYTE
+ * ctypedef unsigned short UWORD
+ * ctypedef short WORD             # <<<<<<<<<<<<<<
+ * ctypedef unsigned long long bits64
+ * ctypedef unsigned bits32
+ */
+typedef short __pyx_t_2bx_3bbi_5types_WORD;
+
+/* "types.pxd":5
+ * ctypedef unsigned short UWORD
+ * ctypedef short WORD
+ * ctypedef unsigned long long bits64             # <<<<<<<<<<<<<<
+ * ctypedef unsigned bits32
+ * ctypedef unsigned short bits16
+ */
+typedef unsigned PY_LONG_LONG __pyx_t_2bx_3bbi_5types_bits64;
+
+/* "types.pxd":6
+ * ctypedef short WORD
+ * ctypedef unsigned long long bits64
+ * ctypedef unsigned bits32             # <<<<<<<<<<<<<<
+ * ctypedef unsigned short bits16
+ * ctypedef unsigned char bits8
+ */
+typedef unsigned int __pyx_t_2bx_3bbi_5types_bits32;
+
+/* "types.pxd":7
+ * ctypedef unsigned long long bits64
+ * ctypedef unsigned bits32
+ * ctypedef unsigned short bits16             # <<<<<<<<<<<<<<
+ * ctypedef unsigned char bits8
+ * ctypedef int signed32
+ */
+typedef unsigned short __pyx_t_2bx_3bbi_5types_bits16;
+
+/* "types.pxd":8
+ * ctypedef unsigned bits32
+ * ctypedef unsigned short bits16
+ * ctypedef unsigned char bits8             # <<<<<<<<<<<<<<
+ * ctypedef int signed32
+ * 
+ */
+typedef unsigned char __pyx_t_2bx_3bbi_5types_bits8;
+
+/* "types.pxd":9
+ * ctypedef unsigned short bits16
+ * ctypedef unsigned char bits8
+ * ctypedef int signed32             # <<<<<<<<<<<<<<
+ * 
+ * ctypedef bint boolean
+ */
+typedef int __pyx_t_2bx_3bbi_5types_signed32;
+
+/* "types.pxd":11
+ * ctypedef int signed32
+ * 
+ * ctypedef bint boolean             # <<<<<<<<<<<<<<
+ * 
+ */
+typedef int __pyx_t_2bx_3bbi_5types_boolean;
+
+/*--- Type declarations ---*/
+struct __pyx_obj_2bx_3bbi_8bpt_file_BPTFile;
+
+/* "bx/bbi/bpt_file.pxd":5
+ * from types cimport *
+ * 
+ * cdef class BPTFile:             # <<<<<<<<<<<<<<
+ *     """
+ *     On disk B+ tree compatible with Jim Kent's bPlusTree.c
+ */
+struct __pyx_obj_2bx_3bbi_8bpt_file_BPTFile {
+  PyObject_HEAD
+  PyObject *file;
+  PyObject *reader;
+  __pyx_t_2bx_3bbi_5types_boolean is_byteswapped;
+  __pyx_t_2bx_3bbi_5types_bits32 block_size;
+  __pyx_t_2bx_3bbi_5types_bits32 key_size;
+  __pyx_t_2bx_3bbi_5types_bits32 value_size;
+  __pyx_t_2bx_3bbi_5types_bits64 item_count;
+  __pyx_t_2bx_3bbi_5types_bits64 root_offset;
+};
+
+#ifndef CYTHON_REFNANNY
+  #define CYTHON_REFNANNY 0
+#endif
+#if CYTHON_REFNANNY
+  typedef struct {
+    void (*INCREF)(void*, PyObject*, int);
+    void (*DECREF)(void*, PyObject*, int);
+    void (*GOTREF)(void*, PyObject*, int);
+    void (*GIVEREF)(void*, PyObject*, int);
+    void* (*SetupContext)(const char*, int, const char*);
+    void (*FinishContext)(void**);
+  } __Pyx_RefNannyAPIStruct;
+  static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL;
+  static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname); /*proto*/
+  #define __Pyx_RefNannyDeclarations void *__pyx_refnanny = NULL;
+#ifdef WITH_THREAD
+  #define __Pyx_RefNannySetupContext(name, acquire_gil) \
+          if (acquire_gil) { \
+              PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure(); \
+              __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__); \
+              PyGILState_Release(__pyx_gilstate_save); \
+          } else { \
+              __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__); \
+          }
+#else
+  #define __Pyx_RefNannySetupContext(name, acquire_gil) \
+          __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__)
+#endif
+  #define __Pyx_RefNannyFinishContext() \
+          __Pyx_RefNanny->FinishContext(&__pyx_refnanny)
+  #define __Pyx_INCREF(r)  __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_DECREF(r)  __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_GOTREF(r)  __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_XINCREF(r)  do { if((r) != NULL) {__Pyx_INCREF(r); }} while(0)
+  #define __Pyx_XDECREF(r)  do { if((r) != NULL) {__Pyx_DECREF(r); }} while(0)
+  #define __Pyx_XGOTREF(r)  do { if((r) != NULL) {__Pyx_GOTREF(r); }} while(0)
+  #define __Pyx_XGIVEREF(r) do { if((r) != NULL) {__Pyx_GIVEREF(r);}} while(0)
+#else
+  #define __Pyx_RefNannyDeclarations
+  #define __Pyx_RefNannySetupContext(name, acquire_gil)
+  #define __Pyx_RefNannyFinishContext()
+  #define __Pyx_INCREF(r) Py_INCREF(r)
+  #define __Pyx_DECREF(r) Py_DECREF(r)
+  #define __Pyx_GOTREF(r)
+  #define __Pyx_GIVEREF(r)
+  #define __Pyx_XINCREF(r) Py_XINCREF(r)
+  #define __Pyx_XDECREF(r) Py_XDECREF(r)
+  #define __Pyx_XGOTREF(r)
+  #define __Pyx_XGIVEREF(r)
+#endif /* CYTHON_REFNANNY */
+#define __Pyx_CLEAR(r)    do { PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);} while(0)
+#define __Pyx_XCLEAR(r)   do { if((r) != NULL) {PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);}} while(0)
+
+static void __Pyx_RaiseDoubleKeywordsError(const char* func_name, PyObject* kw_name); /*proto*/
+
+static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
+    PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
+    const char* function_name); /*proto*/
+
+static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
+    Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/
+
+static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/
+
+static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level); /*proto*/
+
+static CYTHON_INLINE void __Pyx_RaiseImportError(PyObject *name);
+
+static CYTHON_INLINE unsigned char __Pyx_PyInt_AsUnsignedChar(PyObject *);
+
+static CYTHON_INLINE unsigned short __Pyx_PyInt_AsUnsignedShort(PyObject *);
+
+static CYTHON_INLINE unsigned int __Pyx_PyInt_AsUnsignedInt(PyObject *);
+
+static CYTHON_INLINE char __Pyx_PyInt_AsChar(PyObject *);
+
+static CYTHON_INLINE short __Pyx_PyInt_AsShort(PyObject *);
+
+static CYTHON_INLINE int __Pyx_PyInt_AsInt(PyObject *);
+
+static CYTHON_INLINE signed char __Pyx_PyInt_AsSignedChar(PyObject *);
+
+static CYTHON_INLINE signed short __Pyx_PyInt_AsSignedShort(PyObject *);
+
+static CYTHON_INLINE signed int __Pyx_PyInt_AsSignedInt(PyObject *);
+
+static CYTHON_INLINE int __Pyx_PyInt_AsLongDouble(PyObject *);
+
+static CYTHON_INLINE unsigned long __Pyx_PyInt_AsUnsignedLong(PyObject *);
+
+static CYTHON_INLINE unsigned PY_LONG_LONG __Pyx_PyInt_AsUnsignedLongLong(PyObject *);
+
+static CYTHON_INLINE long __Pyx_PyInt_AsLong(PyObject *);
+
+static CYTHON_INLINE PY_LONG_LONG __Pyx_PyInt_AsLongLong(PyObject *);
+
+static CYTHON_INLINE signed long __Pyx_PyInt_AsSignedLong(PyObject *);
+
+static CYTHON_INLINE signed PY_LONG_LONG __Pyx_PyInt_AsSignedLongLong(PyObject *);
+
+static int __Pyx_check_binary_version(void);
+
+typedef struct {
+    int code_line;
+    PyCodeObject* code_object;
+} __Pyx_CodeObjectCacheEntry;
+struct __Pyx_CodeObjectCache {
+    int count;
+    int max_count;
+    __Pyx_CodeObjectCacheEntry* entries;
+};
+static struct __Pyx_CodeObjectCache __pyx_code_cache = {0,0,NULL};
+static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line);
+static PyCodeObject *__pyx_find_code_object(int code_line);
+static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object);
+
+static void __Pyx_AddTraceback(const char *funcname, int c_line,
+                               int py_line, const char *filename); /*proto*/
+
+static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
+
+
+/* Module declarations from 'bx.bbi.types' */
+
+/* Module declarations from 'bx.bbi.bpt_file' */
+static PyTypeObject *__pyx_ptype_2bx_3bbi_8bpt_file_BPTFile = 0;
+#define __Pyx_MODULE_NAME "bx.bbi.bpt_file"
+int __pyx_module_is_main_bx__bbi__bpt_file = 0;
+
+/* Implementation of 'bx.bbi.bpt_file' */
+static int __pyx_pf_2bx_3bbi_8bpt_file_7BPTFile___init__(struct __pyx_obj_2bx_3bbi_8bpt_file_BPTFile *__pyx_v_self, PyObject *__pyx_v_file); /* proto */
+static PyObject *__pyx_pf_2bx_3bbi_8bpt_file_7BPTFile_2attach(struct __pyx_obj_2bx_3bbi_8bpt_file_BPTFile *__pyx_v_self, PyObject *__pyx_v_file); /* proto */
+static PyObject *__pyx_pf_2bx_3bbi_8bpt_file_7BPTFile_4r_find(struct __pyx_obj_2bx_3bbi_8bpt_file_BPTFile *__pyx_v_self, __pyx_t_2bx_3bbi_5types_bits64 __pyx_v_block_start, PyObject *__pyx_v_key); /* proto */
+static PyObject *__pyx_pf_2bx_3bbi_8bpt_file_7BPTFile_6find(struct __pyx_obj_2bx_3bbi_8bpt_file_BPTFile *__pyx_v_self, PyObject *__pyx_v_key); /* proto */
+static char __pyx_k_2[] = "\000";
+static char __pyx_k_3[] = "bx.misc.binary_file";
+static char __pyx_k__key[] = "key";
+static char __pyx_k__file[] = "file";
+static char __pyx_k__read[] = "read";
+static char __pyx_k__seek[] = "seek";
+static char __pyx_k__skip[] = "skip";
+static char __pyx_k__tell[] = "tell";
+static char __pyx_k__attach[] = "attach";
+static char __pyx_k__r_find[] = "r_find";
+static char __pyx_k____main__[] = "__main__";
+static char __pyx_k____test__[] = "__test__";
+static char __pyx_k__read_uint8[] = "read_uint8";
+static char __pyx_k__block_start[] = "block_start";
+static char __pyx_k__read_uint16[] = "read_uint16";
+static char __pyx_k__read_uint32[] = "read_uint32";
+static char __pyx_k__read_uint64[] = "read_uint64";
+static char __pyx_k__byteswap_needed[] = "byteswap_needed";
+static char __pyx_k__BinaryFileReader[] = "BinaryFileReader";
+static PyObject *__pyx_kp_s_2;
+static PyObject *__pyx_n_s_3;
+static PyObject *__pyx_n_s__BinaryFileReader;
+static PyObject *__pyx_n_s____main__;
+static PyObject *__pyx_n_s____test__;
+static PyObject *__pyx_n_s__attach;
+static PyObject *__pyx_n_s__block_start;
+static PyObject *__pyx_n_s__byteswap_needed;
+static PyObject *__pyx_n_s__file;
+static PyObject *__pyx_n_s__key;
+static PyObject *__pyx_n_s__r_find;
+static PyObject *__pyx_n_s__read;
+static PyObject *__pyx_n_s__read_uint16;
+static PyObject *__pyx_n_s__read_uint32;
+static PyObject *__pyx_n_s__read_uint64;
+static PyObject *__pyx_n_s__read_uint8;
+static PyObject *__pyx_n_s__seek;
+static PyObject *__pyx_n_s__skip;
+static PyObject *__pyx_n_s__tell;
+static PyObject *__pyx_int_8;
+static PyObject *__pyx_int_2026540177;
+static PyObject *__pyx_k_tuple_1;
+
+/* Python wrapper */
+static int __pyx_pw_2bx_3bbi_8bpt_file_7BPTFile_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static int __pyx_pw_2bx_3bbi_8bpt_file_7BPTFile_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_file = 0;
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__init__ (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__file,0};
+    PyObject* values[1] = {0};
+
+    /* "bx/bbi/bpt_file.pyx":13
+ *     """
+ * 
+ *     def __init__( self, file=None ):             # <<<<<<<<<<<<<<
+ *         if file is not None:
+ *             self.attach( file )
+ */
+    values[0] = ((PyObject *)Py_None);
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s__file);
+          if (value) { values[0] = value; kw_args--; }
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 13; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else {
+      switch (PyTuple_GET_SIZE(__pyx_args)) {
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+    }
+    __pyx_v_file = values[0];
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("__init__", 0, 0, 1, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 13; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.bbi.bpt_file.BPTFile.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return -1;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_3bbi_8bpt_file_7BPTFile___init__(((struct __pyx_obj_2bx_3bbi_8bpt_file_BPTFile *)__pyx_v_self), __pyx_v_file);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_2bx_3bbi_8bpt_file_7BPTFile___init__(struct __pyx_obj_2bx_3bbi_8bpt_file_BPTFile *__pyx_v_self, PyObject *__pyx_v_file) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__init__", 0);
+
+  /* "bx/bbi/bpt_file.pyx":14
+ * 
+ *     def __init__( self, file=None ):
+ *         if file is not None:             # <<<<<<<<<<<<<<
+ *             self.attach( file )
+ * 
+ */
+  __pyx_t_1 = (__pyx_v_file != Py_None);
+  if (__pyx_t_1) {
+
+    /* "bx/bbi/bpt_file.pyx":15
+ *     def __init__( self, file=None ):
+ *         if file is not None:
+ *             self.attach( file )             # <<<<<<<<<<<<<<
+ * 
+ *     def attach( self, file ):
+ */
+    __pyx_t_2 = PyObject_GetAttr(((PyObject *)__pyx_v_self), __pyx_n_s__attach); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 15; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 15; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_INCREF(__pyx_v_file);
+    PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_file);
+    __Pyx_GIVEREF(__pyx_v_file);
+    __pyx_t_4 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 15; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_AddTraceback("bx.bbi.bpt_file.BPTFile.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = -1;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_3bbi_8bpt_file_7BPTFile_3attach(PyObject *__pyx_v_self, PyObject *__pyx_v_file); /*proto*/
+static char __pyx_doc_2bx_3bbi_8bpt_file_7BPTFile_2attach[] = "\n        Attach to an open file\n        ";
+static PyObject *__pyx_pw_2bx_3bbi_8bpt_file_7BPTFile_3attach(PyObject *__pyx_v_self, PyObject *__pyx_v_file) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("attach (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_3bbi_8bpt_file_7BPTFile_2attach(((struct __pyx_obj_2bx_3bbi_8bpt_file_BPTFile *)__pyx_v_self), ((PyObject *)__pyx_v_file));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bbi/bpt_file.pyx":17
+ *             self.attach( file )
+ * 
+ *     def attach( self, file ):             # <<<<<<<<<<<<<<
+ *         """
+ *         Attach to an open file
+ */
+
+static PyObject *__pyx_pf_2bx_3bbi_8bpt_file_7BPTFile_2attach(struct __pyx_obj_2bx_3bbi_8bpt_file_BPTFile *__pyx_v_self, PyObject *__pyx_v_file) {
+  PyObject *__pyx_v_reader = NULL;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  __pyx_t_2bx_3bbi_5types_boolean __pyx_t_4;
+  __pyx_t_2bx_3bbi_5types_bits32 __pyx_t_5;
+  __pyx_t_2bx_3bbi_5types_bits64 __pyx_t_6;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("attach", 0);
+
+  /* "bx/bbi/bpt_file.pyx":21
+ *         Attach to an open file
+ *         """
+ *         self.file = file             # <<<<<<<<<<<<<<
+ *         self.reader = reader = BinaryFileReader( file, bpt_sig )
+ *         self.is_byteswapped = self.reader.byteswap_needed
+ */
+  __Pyx_INCREF(__pyx_v_file);
+  __Pyx_GIVEREF(__pyx_v_file);
+  __Pyx_GOTREF(__pyx_v_self->file);
+  __Pyx_DECREF(__pyx_v_self->file);
+  __pyx_v_self->file = __pyx_v_file;
+
+  /* "bx/bbi/bpt_file.pyx":22
+ *         """
+ *         self.file = file
+ *         self.reader = reader = BinaryFileReader( file, bpt_sig )             # <<<<<<<<<<<<<<
+ *         self.is_byteswapped = self.reader.byteswap_needed
+ *         # Read header stuff
+ */
+  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__BinaryFileReader); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 22; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 22; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_INCREF(__pyx_v_file);
+  PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_file);
+  __Pyx_GIVEREF(__pyx_v_file);
+  __Pyx_INCREF(__pyx_int_2026540177);
+  PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_int_2026540177);
+  __Pyx_GIVEREF(__pyx_int_2026540177);
+  __pyx_t_3 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 22; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
+  __Pyx_INCREF(__pyx_t_3);
+  __Pyx_GIVEREF(__pyx_t_3);
+  __Pyx_GOTREF(__pyx_v_self->reader);
+  __Pyx_DECREF(__pyx_v_self->reader);
+  __pyx_v_self->reader = __pyx_t_3;
+  __Pyx_INCREF(__pyx_t_3);
+  __pyx_v_reader = __pyx_t_3;
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+  /* "bx/bbi/bpt_file.pyx":23
+ *         self.file = file
+ *         self.reader = reader = BinaryFileReader( file, bpt_sig )
+ *         self.is_byteswapped = self.reader.byteswap_needed             # <<<<<<<<<<<<<<
+ *         # Read header stuff
+ *         self.block_size = reader.read_uint32()
+ */
+  __pyx_t_3 = PyObject_GetAttr(__pyx_v_self->reader, __pyx_n_s__byteswap_needed); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 23; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely((__pyx_t_4 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 23; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __pyx_v_self->is_byteswapped = __pyx_t_4;
+
+  /* "bx/bbi/bpt_file.pyx":25
+ *         self.is_byteswapped = self.reader.byteswap_needed
+ *         # Read header stuff
+ *         self.block_size = reader.read_uint32()             # <<<<<<<<<<<<<<
+ *         self.key_size = reader.read_uint32()
+ *         self.value_size = reader.read_uint32()
+ */
+  __pyx_t_3 = PyObject_GetAttr(__pyx_v_reader, __pyx_n_s__read_uint32); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 25; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_2 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 25; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __pyx_t_5 = __Pyx_PyInt_AsUnsignedInt(__pyx_t_2); if (unlikely((__pyx_t_5 == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 25; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_v_self->block_size = __pyx_t_5;
+
+  /* "bx/bbi/bpt_file.pyx":26
+ *         # Read header stuff
+ *         self.block_size = reader.read_uint32()
+ *         self.key_size = reader.read_uint32()             # <<<<<<<<<<<<<<
+ *         self.value_size = reader.read_uint32()
+ *         self.item_count = reader.read_uint64()
+ */
+  __pyx_t_2 = PyObject_GetAttr(__pyx_v_reader, __pyx_n_s__read_uint32); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 26; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 26; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_5 = __Pyx_PyInt_AsUnsignedInt(__pyx_t_3); if (unlikely((__pyx_t_5 == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 26; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __pyx_v_self->key_size = __pyx_t_5;
+
+  /* "bx/bbi/bpt_file.pyx":27
+ *         self.block_size = reader.read_uint32()
+ *         self.key_size = reader.read_uint32()
+ *         self.value_size = reader.read_uint32()             # <<<<<<<<<<<<<<
+ *         self.item_count = reader.read_uint64()
+ *         reader.skip( 8 )
+ */
+  __pyx_t_3 = PyObject_GetAttr(__pyx_v_reader, __pyx_n_s__read_uint32); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 27; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_2 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 27; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __pyx_t_5 = __Pyx_PyInt_AsUnsignedInt(__pyx_t_2); if (unlikely((__pyx_t_5 == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 27; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_v_self->value_size = __pyx_t_5;
+
+  /* "bx/bbi/bpt_file.pyx":28
+ *         self.key_size = reader.read_uint32()
+ *         self.value_size = reader.read_uint32()
+ *         self.item_count = reader.read_uint64()             # <<<<<<<<<<<<<<
+ *         reader.skip( 8 )
+ *         self.root_offset = reader.tell()
+ */
+  __pyx_t_2 = PyObject_GetAttr(__pyx_v_reader, __pyx_n_s__read_uint64); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 28; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 28; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_6 = __Pyx_PyInt_AsUnsignedLongLong(__pyx_t_3); if (unlikely((__pyx_t_6 == (unsigned PY_LONG_LONG)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 28; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __pyx_v_self->item_count = __pyx_t_6;
+
+  /* "bx/bbi/bpt_file.pyx":29
+ *         self.value_size = reader.read_uint32()
+ *         self.item_count = reader.read_uint64()
+ *         reader.skip( 8 )             # <<<<<<<<<<<<<<
+ *         self.root_offset = reader.tell()
+ * 
+ */
+  __pyx_t_3 = PyObject_GetAttr(__pyx_v_reader, __pyx_n_s__skip); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 29; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_2 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_k_tuple_1), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 29; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+  /* "bx/bbi/bpt_file.pyx":30
+ *         self.item_count = reader.read_uint64()
+ *         reader.skip( 8 )
+ *         self.root_offset = reader.tell()             # <<<<<<<<<<<<<<
+ * 
+ *     def r_find( self, bits64 block_start, key ):
+ */
+  __pyx_t_2 = PyObject_GetAttr(__pyx_v_reader, __pyx_n_s__tell); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 30; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 30; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_6 = __Pyx_PyInt_AsUnsignedLongLong(__pyx_t_3); if (unlikely((__pyx_t_6 == (unsigned PY_LONG_LONG)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 30; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __pyx_v_self->root_offset = __pyx_t_6;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_AddTraceback("bx.bbi.bpt_file.BPTFile.attach", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_reader);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_3bbi_8bpt_file_7BPTFile_5r_find(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_2bx_3bbi_8bpt_file_7BPTFile_4r_find[] = "\n        Recursively seek the value matching key under the subtree starting\n        at file offset `block_start`\n        ";
+static PyObject *__pyx_pw_2bx_3bbi_8bpt_file_7BPTFile_5r_find(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  __pyx_t_2bx_3bbi_5types_bits64 __pyx_v_block_start;
+  PyObject *__pyx_v_key = 0;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("r_find (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__block_start,&__pyx_n_s__key,0};
+    PyObject* values[2] = {0,0};
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__block_start)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__key)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("r_find", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 32; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "r_find") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 32; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
+      goto __pyx_L5_argtuple_error;
+    } else {
+      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+    }
+    __pyx_v_block_start = __Pyx_PyInt_AsUnsignedLongLong(values[0]); if (unlikely((__pyx_v_block_start == (unsigned PY_LONG_LONG)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 32; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_key = values[1];
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("r_find", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 32; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.bbi.bpt_file.BPTFile.r_find", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_3bbi_8bpt_file_7BPTFile_4r_find(((struct __pyx_obj_2bx_3bbi_8bpt_file_BPTFile *)__pyx_v_self), __pyx_v_block_start, __pyx_v_key);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bbi/bpt_file.pyx":32
+ *         self.root_offset = reader.tell()
+ * 
+ *     def r_find( self, bits64 block_start, key ):             # <<<<<<<<<<<<<<
+ *         """
+ *         Recursively seek the value matching key under the subtree starting
+ */
+
+static PyObject *__pyx_pf_2bx_3bbi_8bpt_file_7BPTFile_4r_find(struct __pyx_obj_2bx_3bbi_8bpt_file_BPTFile *__pyx_v_self, __pyx_t_2bx_3bbi_5types_bits64 __pyx_v_block_start, PyObject *__pyx_v_key) {
+  __pyx_t_2bx_3bbi_5types_UBYTE __pyx_v_is_leaf;
+  __pyx_t_2bx_3bbi_5types_bits16 __pyx_v_child_count;
+  __pyx_t_2bx_3bbi_5types_bits64 __pyx_v_offset;
+  CYTHON_UNUSED long __pyx_v_i;
+  PyObject *__pyx_v_node_key = NULL;
+  PyObject *__pyx_v_node_value = NULL;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  __pyx_t_2bx_3bbi_5types_UBYTE __pyx_t_4;
+  __pyx_t_2bx_3bbi_5types_bits16 __pyx_t_5;
+  int __pyx_t_6;
+  __pyx_t_2bx_3bbi_5types_bits64 __pyx_t_7;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("r_find", 0);
+
+  /* "bx/bbi/bpt_file.pyx":40
+ *         cdef bits16 child_count
+ *         cdef bits64 offset
+ *         self.reader.seek( block_start )             # <<<<<<<<<<<<<<
+ *         # Block header
+ *         is_leaf = self.reader.read_uint8()
+ */
+  __pyx_t_1 = PyObject_GetAttr(__pyx_v_self->reader, __pyx_n_s__seek); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 40; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = PyLong_FromUnsignedLongLong(__pyx_v_block_start); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 40; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 40; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_2);
+  __Pyx_GIVEREF(__pyx_t_2);
+  __pyx_t_2 = 0;
+  __pyx_t_2 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 40; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+  /* "bx/bbi/bpt_file.pyx":42
+ *         self.reader.seek( block_start )
+ *         # Block header
+ *         is_leaf = self.reader.read_uint8()             # <<<<<<<<<<<<<<
+ *         self.reader.read_uint8()
+ *         child_count = self.reader.read_uint16()
+ */
+  __pyx_t_2 = PyObject_GetAttr(__pyx_v_self->reader, __pyx_n_s__read_uint8); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 42; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 42; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_4 = __Pyx_PyInt_AsUnsignedChar(__pyx_t_3); if (unlikely((__pyx_t_4 == (unsigned char)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 42; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __pyx_v_is_leaf = __pyx_t_4;
+
+  /* "bx/bbi/bpt_file.pyx":43
+ *         # Block header
+ *         is_leaf = self.reader.read_uint8()
+ *         self.reader.read_uint8()             # <<<<<<<<<<<<<<
+ *         child_count = self.reader.read_uint16()
+ *         if is_leaf:
+ */
+  __pyx_t_3 = PyObject_GetAttr(__pyx_v_self->reader, __pyx_n_s__read_uint8); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 43; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_2 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 43; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+  /* "bx/bbi/bpt_file.pyx":44
+ *         is_leaf = self.reader.read_uint8()
+ *         self.reader.read_uint8()
+ *         child_count = self.reader.read_uint16()             # <<<<<<<<<<<<<<
+ *         if is_leaf:
+ *             for i from 0 <= i < child_count:
+ */
+  __pyx_t_2 = PyObject_GetAttr(__pyx_v_self->reader, __pyx_n_s__read_uint16); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 44; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 44; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_5 = __Pyx_PyInt_AsUnsignedShort(__pyx_t_3); if (unlikely((__pyx_t_5 == (unsigned short)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 44; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __pyx_v_child_count = __pyx_t_5;
+
+  /* "bx/bbi/bpt_file.pyx":45
+ *         self.reader.read_uint8()
+ *         child_count = self.reader.read_uint16()
+ *         if is_leaf:             # <<<<<<<<<<<<<<
+ *             for i from 0 <= i < child_count:
+ *                 node_key = self.reader.read( self.key_size )
+ */
+  if (__pyx_v_is_leaf) {
+
+    /* "bx/bbi/bpt_file.pyx":46
+ *         child_count = self.reader.read_uint16()
+ *         if is_leaf:
+ *             for i from 0 <= i < child_count:             # <<<<<<<<<<<<<<
+ *                 node_key = self.reader.read( self.key_size )
+ *                 node_value = self.reader.read( self.value_size )
+ */
+    __pyx_t_5 = __pyx_v_child_count;
+    for (__pyx_v_i = 0; __pyx_v_i < __pyx_t_5; __pyx_v_i++) {
+
+      /* "bx/bbi/bpt_file.pyx":47
+ *         if is_leaf:
+ *             for i from 0 <= i < child_count:
+ *                 node_key = self.reader.read( self.key_size )             # <<<<<<<<<<<<<<
+ *                 node_value = self.reader.read( self.value_size )
+ *                 if node_key == key:
+ */
+      __pyx_t_3 = PyObject_GetAttr(__pyx_v_self->reader, __pyx_n_s__read); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 47; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_2 = PyLong_FromUnsignedLong(__pyx_v_self->key_size); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 47; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_2);
+      __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 47; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_1);
+      PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_2);
+      __Pyx_GIVEREF(__pyx_t_2);
+      __pyx_t_2 = 0;
+      __pyx_t_2 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 47; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_2);
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+      __Pyx_XDECREF(__pyx_v_node_key);
+      __pyx_v_node_key = __pyx_t_2;
+      __pyx_t_2 = 0;
+
+      /* "bx/bbi/bpt_file.pyx":48
+ *             for i from 0 <= i < child_count:
+ *                 node_key = self.reader.read( self.key_size )
+ *                 node_value = self.reader.read( self.value_size )             # <<<<<<<<<<<<<<
+ *                 if node_key == key:
+ *                     return node_value
+ */
+      __pyx_t_2 = PyObject_GetAttr(__pyx_v_self->reader, __pyx_n_s__read); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 48; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_2);
+      __pyx_t_1 = PyLong_FromUnsignedLong(__pyx_v_self->value_size); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 48; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_1);
+      __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 48; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1);
+      __Pyx_GIVEREF(__pyx_t_1);
+      __pyx_t_1 = 0;
+      __pyx_t_1 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 48; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_1);
+      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+      __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
+      __Pyx_XDECREF(__pyx_v_node_value);
+      __pyx_v_node_value = __pyx_t_1;
+      __pyx_t_1 = 0;
+
+      /* "bx/bbi/bpt_file.pyx":49
+ *                 node_key = self.reader.read( self.key_size )
+ *                 node_value = self.reader.read( self.value_size )
+ *                 if node_key == key:             # <<<<<<<<<<<<<<
+ *                     return node_value
+ *             return None
+ */
+      __pyx_t_1 = PyObject_RichCompare(__pyx_v_node_key, __pyx_v_key, Py_EQ); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 49; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 49; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+      if (__pyx_t_6) {
+
+        /* "bx/bbi/bpt_file.pyx":50
+ *                 node_value = self.reader.read( self.value_size )
+ *                 if node_key == key:
+ *                     return node_value             # <<<<<<<<<<<<<<
+ *             return None
+ *         else:
+ */
+        __Pyx_XDECREF(__pyx_r);
+        __Pyx_INCREF(__pyx_v_node_value);
+        __pyx_r = __pyx_v_node_value;
+        goto __pyx_L0;
+        goto __pyx_L6;
+      }
+      __pyx_L6:;
+    }
+
+    /* "bx/bbi/bpt_file.pyx":51
+ *                 if node_key == key:
+ *                     return node_value
+ *             return None             # <<<<<<<<<<<<<<
+ *         else:
+ *             # Read and discard first key, store offset
+ */
+    __Pyx_XDECREF(__pyx_r);
+    __Pyx_INCREF(Py_None);
+    __pyx_r = Py_None;
+    goto __pyx_L0;
+    goto __pyx_L3;
+  }
+  /*else*/ {
+
+    /* "bx/bbi/bpt_file.pyx":54
+ *         else:
+ *             # Read and discard first key, store offset
+ *             self.reader.read( self.key_size )             # <<<<<<<<<<<<<<
+ *             offset = self.reader.read_uint64()
+ *             # Loop until correct subtree is found
+ */
+    __pyx_t_1 = PyObject_GetAttr(__pyx_v_self->reader, __pyx_n_s__read); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 54; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __pyx_t_3 = PyLong_FromUnsignedLong(__pyx_v_self->key_size); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 54; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 54; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_3);
+    __Pyx_GIVEREF(__pyx_t_3);
+    __pyx_t_3 = 0;
+    __pyx_t_3 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 54; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+    /* "bx/bbi/bpt_file.pyx":55
+ *             # Read and discard first key, store offset
+ *             self.reader.read( self.key_size )
+ *             offset = self.reader.read_uint64()             # <<<<<<<<<<<<<<
+ *             # Loop until correct subtree is found
+ *             for i from 0 <= i < child_count:
+ */
+    __pyx_t_3 = PyObject_GetAttr(__pyx_v_self->reader, __pyx_n_s__read_uint64); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 55; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __pyx_t_2 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 55; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __pyx_t_7 = __Pyx_PyInt_AsUnsignedLongLong(__pyx_t_2); if (unlikely((__pyx_t_7 == (unsigned PY_LONG_LONG)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 55; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    __pyx_v_offset = __pyx_t_7;
+
+    /* "bx/bbi/bpt_file.pyx":57
+ *             offset = self.reader.read_uint64()
+ *             # Loop until correct subtree is found
+ *             for i from 0 <= i < child_count:             # <<<<<<<<<<<<<<
+ *                 node_key = self.reader.read( self.key_size )
+ *                 if node_key > key:
+ */
+    __pyx_t_5 = __pyx_v_child_count;
+    for (__pyx_v_i = 0; __pyx_v_i < __pyx_t_5; __pyx_v_i++) {
+
+      /* "bx/bbi/bpt_file.pyx":58
+ *             # Loop until correct subtree is found
+ *             for i from 0 <= i < child_count:
+ *                 node_key = self.reader.read( self.key_size )             # <<<<<<<<<<<<<<
+ *                 if node_key > key:
+ *                     break
+ */
+      __pyx_t_2 = PyObject_GetAttr(__pyx_v_self->reader, __pyx_n_s__read); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 58; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_2);
+      __pyx_t_3 = PyLong_FromUnsignedLong(__pyx_v_self->key_size); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 58; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 58; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_1);
+      PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_3);
+      __Pyx_GIVEREF(__pyx_t_3);
+      __pyx_t_3 = 0;
+      __pyx_t_3 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 58; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+      __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+      __Pyx_XDECREF(__pyx_v_node_key);
+      __pyx_v_node_key = __pyx_t_3;
+      __pyx_t_3 = 0;
+
+      /* "bx/bbi/bpt_file.pyx":59
+ *             for i from 0 <= i < child_count:
+ *                 node_key = self.reader.read( self.key_size )
+ *                 if node_key > key:             # <<<<<<<<<<<<<<
+ *                     break
+ *                 offset = self.reader.read_uint64()
+ */
+      __pyx_t_3 = PyObject_RichCompare(__pyx_v_node_key, __pyx_v_key, Py_GT); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 59; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 59; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      if (__pyx_t_6) {
+
+        /* "bx/bbi/bpt_file.pyx":60
+ *                 node_key = self.reader.read( self.key_size )
+ *                 if node_key > key:
+ *                     break             # <<<<<<<<<<<<<<
+ *                 offset = self.reader.read_uint64()
+ *             return self.r_find( offset, key )
+ */
+        goto __pyx_L8_break;
+        goto __pyx_L9;
+      }
+      __pyx_L9:;
+
+      /* "bx/bbi/bpt_file.pyx":61
+ *                 if node_key > key:
+ *                     break
+ *                 offset = self.reader.read_uint64()             # <<<<<<<<<<<<<<
+ *             return self.r_find( offset, key )
+ * 
+ */
+      __pyx_t_3 = PyObject_GetAttr(__pyx_v_self->reader, __pyx_n_s__read_uint64); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 61; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_1 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 61; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_1);
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_t_7 = __Pyx_PyInt_AsUnsignedLongLong(__pyx_t_1); if (unlikely((__pyx_t_7 == (unsigned PY_LONG_LONG)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 61; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+      __pyx_v_offset = __pyx_t_7;
+    }
+    __pyx_L8_break:;
+
+    /* "bx/bbi/bpt_file.pyx":62
+ *                     break
+ *                 offset = self.reader.read_uint64()
+ *             return self.r_find( offset, key )             # <<<<<<<<<<<<<<
+ * 
+ *     def find( self, key ):
+ */
+    __Pyx_XDECREF(__pyx_r);
+    __pyx_t_1 = PyObject_GetAttr(((PyObject *)__pyx_v_self), __pyx_n_s__r_find); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 62; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __pyx_t_3 = PyLong_FromUnsignedLongLong(__pyx_v_offset); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 62; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 62; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_3);
+    __Pyx_GIVEREF(__pyx_t_3);
+    __Pyx_INCREF(__pyx_v_key);
+    PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_v_key);
+    __Pyx_GIVEREF(__pyx_v_key);
+    __pyx_t_3 = 0;
+    __pyx_t_3 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 62; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
+    __pyx_r = __pyx_t_3;
+    __pyx_t_3 = 0;
+    goto __pyx_L0;
+  }
+  __pyx_L3:;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_AddTraceback("bx.bbi.bpt_file.BPTFile.r_find", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_node_key);
+  __Pyx_XDECREF(__pyx_v_node_value);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_3bbi_8bpt_file_7BPTFile_7find(PyObject *__pyx_v_self, PyObject *__pyx_v_key); /*proto*/
+static char __pyx_doc_2bx_3bbi_8bpt_file_7BPTFile_6find[] = "\n        Find the value matching `key` (a bytestring). Returns the matching\n        value as a bytestring if found, or None\n        ";
+static PyObject *__pyx_pw_2bx_3bbi_8bpt_file_7BPTFile_7find(PyObject *__pyx_v_self, PyObject *__pyx_v_key) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("find (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_3bbi_8bpt_file_7BPTFile_6find(((struct __pyx_obj_2bx_3bbi_8bpt_file_BPTFile *)__pyx_v_self), ((PyObject *)__pyx_v_key));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bbi/bpt_file.pyx":64
+ *             return self.r_find( offset, key )
+ * 
+ *     def find( self, key ):             # <<<<<<<<<<<<<<
+ *         """
+ *         Find the value matching `key` (a bytestring). Returns the matching
+ */
+
+static PyObject *__pyx_pf_2bx_3bbi_8bpt_file_7BPTFile_6find(struct __pyx_obj_2bx_3bbi_8bpt_file_BPTFile *__pyx_v_self, PyObject *__pyx_v_key) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  Py_ssize_t __pyx_t_1;
+  int __pyx_t_2;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  PyObject *__pyx_t_5 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("find", 0);
+  __Pyx_INCREF(__pyx_v_key);
+
+  /* "bx/bbi/bpt_file.pyx":70
+ *         """
+ *         # Key is greater than key_size, must not be a match
+ *         if len(key) > self.key_size:             # <<<<<<<<<<<<<<
+ *             return None
+ *         # Key is less than key_size, right pad with 0 bytes
+ */
+  __pyx_t_1 = PyObject_Length(__pyx_v_key); if (unlikely(__pyx_t_1 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 70; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = (__pyx_t_1 > __pyx_v_self->key_size);
+  if (__pyx_t_2) {
+
+    /* "bx/bbi/bpt_file.pyx":71
+ *         # Key is greater than key_size, must not be a match
+ *         if len(key) > self.key_size:
+ *             return None             # <<<<<<<<<<<<<<
+ *         # Key is less than key_size, right pad with 0 bytes
+ *         if len(key) < self.key_size:
+ */
+    __Pyx_XDECREF(__pyx_r);
+    __Pyx_INCREF(Py_None);
+    __pyx_r = Py_None;
+    goto __pyx_L0;
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  /* "bx/bbi/bpt_file.pyx":73
+ *             return None
+ *         # Key is less than key_size, right pad with 0 bytes
+ *         if len(key) < self.key_size:             # <<<<<<<<<<<<<<
+ *             key += ( '\0' * ( self.key_size - len(key) ) )
+ *         # Call the recursive finder
+ */
+  __pyx_t_1 = PyObject_Length(__pyx_v_key); if (unlikely(__pyx_t_1 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 73; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = (__pyx_t_1 < __pyx_v_self->key_size);
+  if (__pyx_t_2) {
+
+    /* "bx/bbi/bpt_file.pyx":74
+ *         # Key is less than key_size, right pad with 0 bytes
+ *         if len(key) < self.key_size:
+ *             key += ( '\0' * ( self.key_size - len(key) ) )             # <<<<<<<<<<<<<<
+ *         # Call the recursive finder
+ *         return self.r_find( self.root_offset, key )
+ */
+    __pyx_t_1 = PyObject_Length(__pyx_v_key); if (unlikely(__pyx_t_1 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 74; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = PyInt_FromSsize_t((__pyx_v_self->key_size - __pyx_t_1)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 74; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __pyx_t_4 = PyNumber_Multiply(((PyObject *)__pyx_kp_s_2), __pyx_t_3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 74; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(((PyObject *)__pyx_t_4));
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __pyx_t_3 = PyNumber_InPlaceAdd(__pyx_v_key, ((PyObject *)__pyx_t_4)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 74; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
+    __Pyx_DECREF(__pyx_v_key);
+    __pyx_v_key = __pyx_t_3;
+    __pyx_t_3 = 0;
+    goto __pyx_L4;
+  }
+  __pyx_L4:;
+
+  /* "bx/bbi/bpt_file.pyx":76
+ *             key += ( '\0' * ( self.key_size - len(key) ) )
+ *         # Call the recursive finder
+ *         return self.r_find( self.root_offset, key )             # <<<<<<<<<<<<<<
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_3 = PyObject_GetAttr(((PyObject *)__pyx_v_self), __pyx_n_s__r_find); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 76; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_4 = PyLong_FromUnsignedLongLong(__pyx_v_self->root_offset); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 76; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 76; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_4);
+  __Pyx_GIVEREF(__pyx_t_4);
+  __Pyx_INCREF(__pyx_v_key);
+  PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_v_key);
+  __Pyx_GIVEREF(__pyx_v_key);
+  __pyx_t_4 = 0;
+  __pyx_t_4 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_t_5), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 76; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_5)); __pyx_t_5 = 0;
+  __pyx_r = __pyx_t_4;
+  __pyx_t_4 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_XDECREF(__pyx_t_5);
+  __Pyx_AddTraceback("bx.bbi.bpt_file.BPTFile.find", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_key);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_tp_new_2bx_3bbi_8bpt_file_BPTFile(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) {
+  struct __pyx_obj_2bx_3bbi_8bpt_file_BPTFile *p;
+  PyObject *o = (*t->tp_alloc)(t, 0);
+  if (!o) return 0;
+  p = ((struct __pyx_obj_2bx_3bbi_8bpt_file_BPTFile *)o);
+  p->file = Py_None; Py_INCREF(Py_None);
+  p->reader = Py_None; Py_INCREF(Py_None);
+  return o;
+}
+
+static void __pyx_tp_dealloc_2bx_3bbi_8bpt_file_BPTFile(PyObject *o) {
+  struct __pyx_obj_2bx_3bbi_8bpt_file_BPTFile *p = (struct __pyx_obj_2bx_3bbi_8bpt_file_BPTFile *)o;
+  PyObject_GC_UnTrack(o);
+  Py_CLEAR(p->file);
+  Py_CLEAR(p->reader);
+  PyObject_GC_Track(o);
+  (*Py_TYPE(o)->tp_free)(o);
+}
+
+static int __pyx_tp_traverse_2bx_3bbi_8bpt_file_BPTFile(PyObject *o, visitproc v, void *a) {
+  int e;
+  struct __pyx_obj_2bx_3bbi_8bpt_file_BPTFile *p = (struct __pyx_obj_2bx_3bbi_8bpt_file_BPTFile *)o;
+  if (p->file) {
+    e = (*v)(p->file, a); if (e) return e;
+  }
+  if (p->reader) {
+    e = (*v)(p->reader, a); if (e) return e;
+  }
+  return 0;
+}
+
+static int __pyx_tp_clear_2bx_3bbi_8bpt_file_BPTFile(PyObject *o) {
+  struct __pyx_obj_2bx_3bbi_8bpt_file_BPTFile *p = (struct __pyx_obj_2bx_3bbi_8bpt_file_BPTFile *)o;
+  PyObject* tmp;
+  tmp = ((PyObject*)p->file);
+  p->file = Py_None; Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  tmp = ((PyObject*)p->reader);
+  p->reader = Py_None; Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  return 0;
+}
+
+static PyMethodDef __pyx_methods_2bx_3bbi_8bpt_file_BPTFile[] = {
+  {__Pyx_NAMESTR("attach"), (PyCFunction)__pyx_pw_2bx_3bbi_8bpt_file_7BPTFile_3attach, METH_O, __Pyx_DOCSTR(__pyx_doc_2bx_3bbi_8bpt_file_7BPTFile_2attach)},
+  {__Pyx_NAMESTR("r_find"), (PyCFunction)__pyx_pw_2bx_3bbi_8bpt_file_7BPTFile_5r_find, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(__pyx_doc_2bx_3bbi_8bpt_file_7BPTFile_4r_find)},
+  {__Pyx_NAMESTR("find"), (PyCFunction)__pyx_pw_2bx_3bbi_8bpt_file_7BPTFile_7find, METH_O, __Pyx_DOCSTR(__pyx_doc_2bx_3bbi_8bpt_file_7BPTFile_6find)},
+  {0, 0, 0, 0}
+};
+
+static PyNumberMethods __pyx_tp_as_number_BPTFile = {
+  0, /*nb_add*/
+  0, /*nb_subtract*/
+  0, /*nb_multiply*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_divide*/
+  #endif
+  0, /*nb_remainder*/
+  0, /*nb_divmod*/
+  0, /*nb_power*/
+  0, /*nb_negative*/
+  0, /*nb_positive*/
+  0, /*nb_absolute*/
+  0, /*nb_nonzero*/
+  0, /*nb_invert*/
+  0, /*nb_lshift*/
+  0, /*nb_rshift*/
+  0, /*nb_and*/
+  0, /*nb_xor*/
+  0, /*nb_or*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_coerce*/
+  #endif
+  0, /*nb_int*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_long*/
+  #else
+  0, /*reserved*/
+  #endif
+  0, /*nb_float*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_oct*/
+  #endif
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_hex*/
+  #endif
+  0, /*nb_inplace_add*/
+  0, /*nb_inplace_subtract*/
+  0, /*nb_inplace_multiply*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_inplace_divide*/
+  #endif
+  0, /*nb_inplace_remainder*/
+  0, /*nb_inplace_power*/
+  0, /*nb_inplace_lshift*/
+  0, /*nb_inplace_rshift*/
+  0, /*nb_inplace_and*/
+  0, /*nb_inplace_xor*/
+  0, /*nb_inplace_or*/
+  0, /*nb_floor_divide*/
+  0, /*nb_true_divide*/
+  0, /*nb_inplace_floor_divide*/
+  0, /*nb_inplace_true_divide*/
+  #if PY_VERSION_HEX >= 0x02050000
+  0, /*nb_index*/
+  #endif
+};
+
+static PySequenceMethods __pyx_tp_as_sequence_BPTFile = {
+  0, /*sq_length*/
+  0, /*sq_concat*/
+  0, /*sq_repeat*/
+  0, /*sq_item*/
+  0, /*sq_slice*/
+  0, /*sq_ass_item*/
+  0, /*sq_ass_slice*/
+  0, /*sq_contains*/
+  0, /*sq_inplace_concat*/
+  0, /*sq_inplace_repeat*/
+};
+
+static PyMappingMethods __pyx_tp_as_mapping_BPTFile = {
+  0, /*mp_length*/
+  0, /*mp_subscript*/
+  0, /*mp_ass_subscript*/
+};
+
+static PyBufferProcs __pyx_tp_as_buffer_BPTFile = {
+  #if PY_MAJOR_VERSION < 3
+  0, /*bf_getreadbuffer*/
+  #endif
+  #if PY_MAJOR_VERSION < 3
+  0, /*bf_getwritebuffer*/
+  #endif
+  #if PY_MAJOR_VERSION < 3
+  0, /*bf_getsegcount*/
+  #endif
+  #if PY_MAJOR_VERSION < 3
+  0, /*bf_getcharbuffer*/
+  #endif
+  #if PY_VERSION_HEX >= 0x02060000
+  0, /*bf_getbuffer*/
+  #endif
+  #if PY_VERSION_HEX >= 0x02060000
+  0, /*bf_releasebuffer*/
+  #endif
+};
+
+static PyTypeObject __pyx_type_2bx_3bbi_8bpt_file_BPTFile = {
+  PyVarObject_HEAD_INIT(0, 0)
+  __Pyx_NAMESTR("bx.bbi.bpt_file.BPTFile"), /*tp_name*/
+  sizeof(struct __pyx_obj_2bx_3bbi_8bpt_file_BPTFile), /*tp_basicsize*/
+  0, /*tp_itemsize*/
+  __pyx_tp_dealloc_2bx_3bbi_8bpt_file_BPTFile, /*tp_dealloc*/
+  0, /*tp_print*/
+  0, /*tp_getattr*/
+  0, /*tp_setattr*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*tp_compare*/
+  #else
+  0, /*reserved*/
+  #endif
+  0, /*tp_repr*/
+  &__pyx_tp_as_number_BPTFile, /*tp_as_number*/
+  &__pyx_tp_as_sequence_BPTFile, /*tp_as_sequence*/
+  &__pyx_tp_as_mapping_BPTFile, /*tp_as_mapping*/
+  0, /*tp_hash*/
+  0, /*tp_call*/
+  0, /*tp_str*/
+  0, /*tp_getattro*/
+  0, /*tp_setattro*/
+  &__pyx_tp_as_buffer_BPTFile, /*tp_as_buffer*/
+  Py_TPFLAGS_DEFAULT|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+  __Pyx_DOCSTR("\n    On disk B+ tree compatible with Jim Kent's bPlusTree.c\n    "), /*tp_doc*/
+  __pyx_tp_traverse_2bx_3bbi_8bpt_file_BPTFile, /*tp_traverse*/
+  __pyx_tp_clear_2bx_3bbi_8bpt_file_BPTFile, /*tp_clear*/
+  0, /*tp_richcompare*/
+  0, /*tp_weaklistoffset*/
+  0, /*tp_iter*/
+  0, /*tp_iternext*/
+  __pyx_methods_2bx_3bbi_8bpt_file_BPTFile, /*tp_methods*/
+  0, /*tp_members*/
+  0, /*tp_getset*/
+  0, /*tp_base*/
+  0, /*tp_dict*/
+  0, /*tp_descr_get*/
+  0, /*tp_descr_set*/
+  0, /*tp_dictoffset*/
+  __pyx_pw_2bx_3bbi_8bpt_file_7BPTFile_1__init__, /*tp_init*/
+  0, /*tp_alloc*/
+  __pyx_tp_new_2bx_3bbi_8bpt_file_BPTFile, /*tp_new*/
+  0, /*tp_free*/
+  0, /*tp_is_gc*/
+  0, /*tp_bases*/
+  0, /*tp_mro*/
+  0, /*tp_cache*/
+  0, /*tp_subclasses*/
+  0, /*tp_weaklist*/
+  0, /*tp_del*/
+  #if PY_VERSION_HEX >= 0x02060000
+  0, /*tp_version_tag*/
+  #endif
+};
+
+static PyMethodDef __pyx_methods[] = {
+  {0, 0, 0, 0}
+};
+
+#if PY_MAJOR_VERSION >= 3
+static struct PyModuleDef __pyx_moduledef = {
+  #if PY_VERSION_HEX < 0x03020000
+    { PyObject_HEAD_INIT(NULL) NULL, 0, NULL },
+  #else
+    PyModuleDef_HEAD_INIT,
+  #endif
+    __Pyx_NAMESTR("bpt_file"),
+    0, /* m_doc */
+    -1, /* m_size */
+    __pyx_methods /* m_methods */,
+    NULL, /* m_reload */
+    NULL, /* m_traverse */
+    NULL, /* m_clear */
+    NULL /* m_free */
+};
+#endif
+
+static __Pyx_StringTabEntry __pyx_string_tab[] = {
+  {&__pyx_kp_s_2, __pyx_k_2, sizeof(__pyx_k_2), 0, 0, 1, 0},
+  {&__pyx_n_s_3, __pyx_k_3, sizeof(__pyx_k_3), 0, 0, 1, 1},
+  {&__pyx_n_s__BinaryFileReader, __pyx_k__BinaryFileReader, sizeof(__pyx_k__BinaryFileReader), 0, 0, 1, 1},
+  {&__pyx_n_s____main__, __pyx_k____main__, sizeof(__pyx_k____main__), 0, 0, 1, 1},
+  {&__pyx_n_s____test__, __pyx_k____test__, sizeof(__pyx_k____test__), 0, 0, 1, 1},
+  {&__pyx_n_s__attach, __pyx_k__attach, sizeof(__pyx_k__attach), 0, 0, 1, 1},
+  {&__pyx_n_s__block_start, __pyx_k__block_start, sizeof(__pyx_k__block_start), 0, 0, 1, 1},
+  {&__pyx_n_s__byteswap_needed, __pyx_k__byteswap_needed, sizeof(__pyx_k__byteswap_needed), 0, 0, 1, 1},
+  {&__pyx_n_s__file, __pyx_k__file, sizeof(__pyx_k__file), 0, 0, 1, 1},
+  {&__pyx_n_s__key, __pyx_k__key, sizeof(__pyx_k__key), 0, 0, 1, 1},
+  {&__pyx_n_s__r_find, __pyx_k__r_find, sizeof(__pyx_k__r_find), 0, 0, 1, 1},
+  {&__pyx_n_s__read, __pyx_k__read, sizeof(__pyx_k__read), 0, 0, 1, 1},
+  {&__pyx_n_s__read_uint16, __pyx_k__read_uint16, sizeof(__pyx_k__read_uint16), 0, 0, 1, 1},
+  {&__pyx_n_s__read_uint32, __pyx_k__read_uint32, sizeof(__pyx_k__read_uint32), 0, 0, 1, 1},
+  {&__pyx_n_s__read_uint64, __pyx_k__read_uint64, sizeof(__pyx_k__read_uint64), 0, 0, 1, 1},
+  {&__pyx_n_s__read_uint8, __pyx_k__read_uint8, sizeof(__pyx_k__read_uint8), 0, 0, 1, 1},
+  {&__pyx_n_s__seek, __pyx_k__seek, sizeof(__pyx_k__seek), 0, 0, 1, 1},
+  {&__pyx_n_s__skip, __pyx_k__skip, sizeof(__pyx_k__skip), 0, 0, 1, 1},
+  {&__pyx_n_s__tell, __pyx_k__tell, sizeof(__pyx_k__tell), 0, 0, 1, 1},
+  {0, 0, 0, 0, 0, 0, 0}
+};
+static int __Pyx_InitCachedBuiltins(void) {
+  return 0;
+}
+
+static int __Pyx_InitCachedConstants(void) {
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0);
+
+  /* "bx/bbi/bpt_file.pyx":29
+ *         self.value_size = reader.read_uint32()
+ *         self.item_count = reader.read_uint64()
+ *         reader.skip( 8 )             # <<<<<<<<<<<<<<
+ *         self.root_offset = reader.tell()
+ * 
+ */
+  __pyx_k_tuple_1 = PyTuple_Pack(1, __pyx_int_8); if (unlikely(!__pyx_k_tuple_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 29; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_k_tuple_1);
+  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_1));
+  __Pyx_RefNannyFinishContext();
+  return 0;
+  __pyx_L1_error:;
+  __Pyx_RefNannyFinishContext();
+  return -1;
+}
+
+static int __Pyx_InitGlobals(void) {
+  if (__Pyx_InitStrings(__pyx_string_tab) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  __pyx_int_8 = PyInt_FromLong(8); if (unlikely(!__pyx_int_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  __pyx_int_2026540177 = PyInt_FromLong(2026540177); if (unlikely(!__pyx_int_2026540177)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  return 0;
+  __pyx_L1_error:;
+  return -1;
+}
+
+#if PY_MAJOR_VERSION < 3
+PyMODINIT_FUNC initbpt_file(void); /*proto*/
+PyMODINIT_FUNC initbpt_file(void)
+#else
+PyMODINIT_FUNC PyInit_bpt_file(void); /*proto*/
+PyMODINIT_FUNC PyInit_bpt_file(void)
+#endif
+{
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  __Pyx_RefNannyDeclarations
+  #if CYTHON_REFNANNY
+  __Pyx_RefNanny = __Pyx_RefNannyImportAPI("refnanny");
+  if (!__Pyx_RefNanny) {
+      PyErr_Clear();
+      __Pyx_RefNanny = __Pyx_RefNannyImportAPI("Cython.Runtime.refnanny");
+      if (!__Pyx_RefNanny)
+          Py_FatalError("failed to import 'refnanny' module");
+  }
+  #endif
+  __Pyx_RefNannySetupContext("PyMODINIT_FUNC PyInit_bpt_file(void)", 0);
+  if ( __Pyx_check_binary_version() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_bytes)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #ifdef __Pyx_CyFunction_USED
+  if (__Pyx_CyFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #endif
+  #ifdef __Pyx_FusedFunction_USED
+  if (__pyx_FusedFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #endif
+  #ifdef __Pyx_Generator_USED
+  if (__pyx_Generator_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #endif
+  /*--- Library function declarations ---*/
+  /*--- Threads initialization code ---*/
+  #if defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS
+  #ifdef WITH_THREAD /* Python build with threading support? */
+  PyEval_InitThreads();
+  #endif
+  #endif
+  /*--- Module creation code ---*/
+  #if PY_MAJOR_VERSION < 3
+  __pyx_m = Py_InitModule4(__Pyx_NAMESTR("bpt_file"), __pyx_methods, 0, 0, PYTHON_API_VERSION); Py_XINCREF(__pyx_m);
+  #else
+  __pyx_m = PyModule_Create(&__pyx_moduledef);
+  #endif
+  if (unlikely(!__pyx_m)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #if PY_MAJOR_VERSION >= 3
+  {
+    PyObject *modules = PyImport_GetModuleDict(); if (unlikely(!modules)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (!PyDict_GetItemString(modules, "bx.bbi.bpt_file")) {
+      if (unlikely(PyDict_SetItemString(modules, "bx.bbi.bpt_file", __pyx_m) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+  }
+  #endif
+  __pyx_b = PyImport_AddModule(__Pyx_NAMESTR(__Pyx_BUILTIN_MODULE_NAME)); if (unlikely(!__pyx_b)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #if CYTHON_COMPILING_IN_PYPY
+  Py_INCREF(__pyx_b);
+  #endif
+  if (__Pyx_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  /*--- Initialize various global constants etc. ---*/
+  if (unlikely(__Pyx_InitGlobals() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (__pyx_module_is_main_bx__bbi__bpt_file) {
+    if (__Pyx_SetAttrString(__pyx_m, "__name__", __pyx_n_s____main__) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  }
+  /*--- Builtin init code ---*/
+  if (unlikely(__Pyx_InitCachedBuiltins() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  /*--- Constants init code ---*/
+  if (unlikely(__Pyx_InitCachedConstants() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  /*--- Global init code ---*/
+  /*--- Variable export code ---*/
+  /*--- Function export code ---*/
+  /*--- Type init code ---*/
+  if (PyType_Ready(&__pyx_type_2bx_3bbi_8bpt_file_BPTFile) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 8; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (__Pyx_SetAttrString(__pyx_m, "BPTFile", (PyObject *)&__pyx_type_2bx_3bbi_8bpt_file_BPTFile) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 8; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_2bx_3bbi_8bpt_file_BPTFile = &__pyx_type_2bx_3bbi_8bpt_file_BPTFile;
+  /*--- Type import code ---*/
+  /*--- Variable import code ---*/
+  /*--- Function import code ---*/
+  /*--- Execution code ---*/
+
+  /* "bx/bbi/bpt_file.pyx":1
+ * from bx.misc.binary_file import BinaryFileReader             # <<<<<<<<<<<<<<
+ * 
+ * DEF bpt_sig = 0x78CA8C91
+ */
+  __pyx_t_1 = PyList_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_INCREF(((PyObject *)__pyx_n_s__BinaryFileReader));
+  PyList_SET_ITEM(__pyx_t_1, 0, ((PyObject *)__pyx_n_s__BinaryFileReader));
+  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__BinaryFileReader));
+  __pyx_t_2 = __Pyx_Import(((PyObject *)__pyx_n_s_3), ((PyObject *)__pyx_t_1), -1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+  __pyx_t_1 = PyObject_GetAttr(__pyx_t_2, __pyx_n_s__BinaryFileReader);
+  if (__pyx_t_1 == NULL) {
+    if (PyErr_ExceptionMatches(PyExc_AttributeError)) __Pyx_RaiseImportError(__pyx_n_s__BinaryFileReader);
+    if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s__BinaryFileReader, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+  /* "bx/bbi/bpt_file.pyx":64
+ *             return self.r_find( offset, key )
+ * 
+ *     def find( self, key ):             # <<<<<<<<<<<<<<
+ *         """
+ *         Find the value matching `key` (a bytestring). Returns the matching
+ */
+  __pyx_t_2 = PyDict_New(); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(((PyObject *)__pyx_t_2));
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s____test__, ((PyObject *)__pyx_t_2)) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  if (__pyx_m) {
+    __Pyx_AddTraceback("init bx.bbi.bpt_file", __pyx_clineno, __pyx_lineno, __pyx_filename);
+    Py_DECREF(__pyx_m); __pyx_m = 0;
+  } else if (!PyErr_Occurred()) {
+    PyErr_SetString(PyExc_ImportError, "init bx.bbi.bpt_file");
+  }
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  #if PY_MAJOR_VERSION < 3
+  return;
+  #else
+  return __pyx_m;
+  #endif
+}
+
+/* Runtime support code */
+#if CYTHON_REFNANNY
+static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) {
+    PyObject *m = NULL, *p = NULL;
+    void *r = NULL;
+    m = PyImport_ImportModule((char *)modname);
+    if (!m) goto end;
+    p = PyObject_GetAttrString(m, (char *)"RefNannyAPI");
+    if (!p) goto end;
+    r = PyLong_AsVoidPtr(p);
+end:
+    Py_XDECREF(p);
+    Py_XDECREF(m);
+    return (__Pyx_RefNannyAPIStruct *)r;
+}
+#endif /* CYTHON_REFNANNY */
+
+static void __Pyx_RaiseDoubleKeywordsError(
+    const char* func_name,
+    PyObject* kw_name)
+{
+    PyErr_Format(PyExc_TypeError,
+        #if PY_MAJOR_VERSION >= 3
+        "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
+        #else
+        "%s() got multiple values for keyword argument '%s'", func_name,
+        PyString_AsString(kw_name));
+        #endif
+}
+
+static int __Pyx_ParseOptionalKeywords(
+    PyObject *kwds,
+    PyObject **argnames[],
+    PyObject *kwds2,
+    PyObject *values[],
+    Py_ssize_t num_pos_args,
+    const char* function_name)
+{
+    PyObject *key = 0, *value = 0;
+    Py_ssize_t pos = 0;
+    PyObject*** name;
+    PyObject*** first_kw_arg = argnames + num_pos_args;
+    while (PyDict_Next(kwds, &pos, &key, &value)) {
+        name = first_kw_arg;
+        while (*name && (**name != key)) name++;
+        if (*name) {
+            values[name-argnames] = value;
+            continue;
+        }
+        name = first_kw_arg;
+        #if PY_MAJOR_VERSION < 3
+        if (likely(PyString_CheckExact(key)) || likely(PyString_Check(key))) {
+            while (*name) {
+                if ((CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**name) == PyString_GET_SIZE(key))
+                        && _PyString_Eq(**name, key)) {
+                    values[name-argnames] = value;
+                    break;
+                }
+                name++;
+            }
+            if (*name) continue;
+            else {
+                PyObject*** argname = argnames;
+                while (argname != first_kw_arg) {
+                    if ((**argname == key) || (
+                            (CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**argname) == PyString_GET_SIZE(key))
+                             && _PyString_Eq(**argname, key))) {
+                        goto arg_passed_twice;
+                    }
+                    argname++;
+                }
+            }
+        } else
+        #endif
+        if (likely(PyUnicode_Check(key))) {
+            while (*name) {
+                int cmp = (**name == key) ? 0 :
+                #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3
+                    (PyUnicode_GET_SIZE(**name) != PyUnicode_GET_SIZE(key)) ? 1 :
+                #endif
+                    PyUnicode_Compare(**name, key);
+                if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad;
+                if (cmp == 0) {
+                    values[name-argnames] = value;
+                    break;
+                }
+                name++;
+            }
+            if (*name) continue;
+            else {
+                PyObject*** argname = argnames;
+                while (argname != first_kw_arg) {
+                    int cmp = (**argname == key) ? 0 :
+                    #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3
+                        (PyUnicode_GET_SIZE(**argname) != PyUnicode_GET_SIZE(key)) ? 1 :
+                    #endif
+                        PyUnicode_Compare(**argname, key);
+                    if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad;
+                    if (cmp == 0) goto arg_passed_twice;
+                    argname++;
+                }
+            }
+        } else
+            goto invalid_keyword_type;
+        if (kwds2) {
+            if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
+        } else {
+            goto invalid_keyword;
+        }
+    }
+    return 0;
+arg_passed_twice:
+    __Pyx_RaiseDoubleKeywordsError(function_name, key);
+    goto bad;
+invalid_keyword_type:
+    PyErr_Format(PyExc_TypeError,
+        "%s() keywords must be strings", function_name);
+    goto bad;
+invalid_keyword:
+    PyErr_Format(PyExc_TypeError,
+    #if PY_MAJOR_VERSION < 3
+        "%s() got an unexpected keyword argument '%s'",
+        function_name, PyString_AsString(key));
+    #else
+        "%s() got an unexpected keyword argument '%U'",
+        function_name, key);
+    #endif
+bad:
+    return -1;
+}
+
+static void __Pyx_RaiseArgtupleInvalid(
+    const char* func_name,
+    int exact,
+    Py_ssize_t num_min,
+    Py_ssize_t num_max,
+    Py_ssize_t num_found)
+{
+    Py_ssize_t num_expected;
+    const char *more_or_less;
+    if (num_found < num_min) {
+        num_expected = num_min;
+        more_or_less = "at least";
+    } else {
+        num_expected = num_max;
+        more_or_less = "at most";
+    }
+    if (exact) {
+        more_or_less = "exactly";
+    }
+    PyErr_Format(PyExc_TypeError,
+                 "%s() takes %s %" CYTHON_FORMAT_SSIZE_T "d positional argument%s (%" CYTHON_FORMAT_SSIZE_T "d given)",
+                 func_name, more_or_less, num_expected,
+                 (num_expected == 1) ? "" : "s", num_found);
+}
+
+static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name) {
+    PyObject *result;
+    result = PyObject_GetAttr(dict, name);
+    if (!result) {
+        if (dict != __pyx_b) {
+            PyErr_Clear();
+            result = PyObject_GetAttr(__pyx_b, name);
+        }
+        if (!result) {
+            PyErr_SetObject(PyExc_NameError, name);
+        }
+    }
+    return result;
+}
+
+static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level) {
+    PyObject *empty_list = 0;
+    PyObject *module = 0;
+    PyObject *global_dict = 0;
+    PyObject *empty_dict = 0;
+    PyObject *list;
+    #if PY_VERSION_HEX < 0x03030000
+    PyObject *py_import = 0;
+    py_import = __Pyx_GetAttrString(__pyx_b, "__import__");
+    if (!py_import)
+        goto bad;
+    #endif
+    if (from_list)
+        list = from_list;
+    else {
+        empty_list = PyList_New(0);
+        if (!empty_list)
+            goto bad;
+        list = empty_list;
+    }
+    global_dict = PyModule_GetDict(__pyx_m);
+    if (!global_dict)
+        goto bad;
+    empty_dict = PyDict_New();
+    if (!empty_dict)
+        goto bad;
+    #if PY_VERSION_HEX >= 0x02050000
+    {
+        #if PY_MAJOR_VERSION >= 3
+        if (level == -1) {
+            if (strchr(__Pyx_MODULE_NAME, '.')) {
+                #if PY_VERSION_HEX < 0x03030000
+                PyObject *py_level = PyInt_FromLong(1);
+                if (!py_level)
+                    goto bad;
+                module = PyObject_CallFunctionObjArgs(py_import,
+                    name, global_dict, empty_dict, list, py_level, NULL);
+                Py_DECREF(py_level);
+                #else
+                module = PyImport_ImportModuleLevelObject(
+                    name, global_dict, empty_dict, list, 1);
+                #endif
+                if (!module) {
+                    if (!PyErr_ExceptionMatches(PyExc_ImportError))
+                        goto bad;
+                    PyErr_Clear();
+                }
+            }
+            level = 0; /* try absolute import on failure */
+        }
+        #endif
+        if (!module) {
+            #if PY_VERSION_HEX < 0x03030000
+            PyObject *py_level = PyInt_FromLong(level);
+            if (!py_level)
+                goto bad;
+            module = PyObject_CallFunctionObjArgs(py_import,
+                name, global_dict, empty_dict, list, py_level, NULL);
+            Py_DECREF(py_level);
+            #else
+            module = PyImport_ImportModuleLevelObject(
+                name, global_dict, empty_dict, list, level);
+            #endif
+        }
+    }
+    #else
+    if (level>0) {
+        PyErr_SetString(PyExc_RuntimeError, "Relative import is not supported for Python <=2.4.");
+        goto bad;
+    }
+    module = PyObject_CallFunctionObjArgs(py_import,
+        name, global_dict, empty_dict, list, NULL);
+    #endif
+bad:
+    #if PY_VERSION_HEX < 0x03030000
+    Py_XDECREF(py_import);
+    #endif
+    Py_XDECREF(empty_list);
+    Py_XDECREF(empty_dict);
+    return module;
+}
+
+static CYTHON_INLINE void __Pyx_RaiseImportError(PyObject *name) {
+#if PY_MAJOR_VERSION < 3
+    PyErr_Format(PyExc_ImportError, "cannot import name %.230s",
+                 PyString_AsString(name));
+#else
+    PyErr_Format(PyExc_ImportError, "cannot import name %S", name);
+#endif
+}
+
+static CYTHON_INLINE unsigned char __Pyx_PyInt_AsUnsignedChar(PyObject* x) {
+    const unsigned char neg_one = (unsigned char)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(unsigned char) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(unsigned char)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to unsigned char" :
+                    "value too large to convert to unsigned char");
+            }
+            return (unsigned char)-1;
+        }
+        return (unsigned char)val;
+    }
+    return (unsigned char)__Pyx_PyInt_AsUnsignedLong(x);
+}
+
+static CYTHON_INLINE unsigned short __Pyx_PyInt_AsUnsignedShort(PyObject* x) {
+    const unsigned short neg_one = (unsigned short)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(unsigned short) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(unsigned short)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to unsigned short" :
+                    "value too large to convert to unsigned short");
+            }
+            return (unsigned short)-1;
+        }
+        return (unsigned short)val;
+    }
+    return (unsigned short)__Pyx_PyInt_AsUnsignedLong(x);
+}
+
+static CYTHON_INLINE unsigned int __Pyx_PyInt_AsUnsignedInt(PyObject* x) {
+    const unsigned int neg_one = (unsigned int)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(unsigned int) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(unsigned int)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to unsigned int" :
+                    "value too large to convert to unsigned int");
+            }
+            return (unsigned int)-1;
+        }
+        return (unsigned int)val;
+    }
+    return (unsigned int)__Pyx_PyInt_AsUnsignedLong(x);
+}
+
+static CYTHON_INLINE char __Pyx_PyInt_AsChar(PyObject* x) {
+    const char neg_one = (char)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(char) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(char)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to char" :
+                    "value too large to convert to char");
+            }
+            return (char)-1;
+        }
+        return (char)val;
+    }
+    return (char)__Pyx_PyInt_AsLong(x);
+}
+
+static CYTHON_INLINE short __Pyx_PyInt_AsShort(PyObject* x) {
+    const short neg_one = (short)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(short) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(short)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to short" :
+                    "value too large to convert to short");
+            }
+            return (short)-1;
+        }
+        return (short)val;
+    }
+    return (short)__Pyx_PyInt_AsLong(x);
+}
+
+static CYTHON_INLINE int __Pyx_PyInt_AsInt(PyObject* x) {
+    const int neg_one = (int)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(int) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(int)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to int" :
+                    "value too large to convert to int");
+            }
+            return (int)-1;
+        }
+        return (int)val;
+    }
+    return (int)__Pyx_PyInt_AsLong(x);
+}
+
+static CYTHON_INLINE signed char __Pyx_PyInt_AsSignedChar(PyObject* x) {
+    const signed char neg_one = (signed char)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(signed char) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(signed char)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to signed char" :
+                    "value too large to convert to signed char");
+            }
+            return (signed char)-1;
+        }
+        return (signed char)val;
+    }
+    return (signed char)__Pyx_PyInt_AsSignedLong(x);
+}
+
+static CYTHON_INLINE signed short __Pyx_PyInt_AsSignedShort(PyObject* x) {
+    const signed short neg_one = (signed short)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(signed short) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(signed short)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to signed short" :
+                    "value too large to convert to signed short");
+            }
+            return (signed short)-1;
+        }
+        return (signed short)val;
+    }
+    return (signed short)__Pyx_PyInt_AsSignedLong(x);
+}
+
+static CYTHON_INLINE signed int __Pyx_PyInt_AsSignedInt(PyObject* x) {
+    const signed int neg_one = (signed int)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(signed int) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(signed int)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to signed int" :
+                    "value too large to convert to signed int");
+            }
+            return (signed int)-1;
+        }
+        return (signed int)val;
+    }
+    return (signed int)__Pyx_PyInt_AsSignedLong(x);
+}
+
+static CYTHON_INLINE int __Pyx_PyInt_AsLongDouble(PyObject* x) {
+    const int neg_one = (int)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(int) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(int)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to int" :
+                    "value too large to convert to int");
+            }
+            return (int)-1;
+        }
+        return (int)val;
+    }
+    return (int)__Pyx_PyInt_AsLong(x);
+}
+
+static CYTHON_INLINE unsigned long __Pyx_PyInt_AsUnsignedLong(PyObject* x) {
+    const unsigned long neg_one = (unsigned long)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to unsigned long");
+            return (unsigned long)-1;
+        }
+        return (unsigned long)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to unsigned long");
+                return (unsigned long)-1;
+            }
+            return (unsigned long)PyLong_AsUnsignedLong(x);
+        } else {
+            return (unsigned long)PyLong_AsLong(x);
+        }
+    } else {
+        unsigned long val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (unsigned long)-1;
+        val = __Pyx_PyInt_AsUnsignedLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE unsigned PY_LONG_LONG __Pyx_PyInt_AsUnsignedLongLong(PyObject* x) {
+    const unsigned PY_LONG_LONG neg_one = (unsigned PY_LONG_LONG)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to unsigned PY_LONG_LONG");
+            return (unsigned PY_LONG_LONG)-1;
+        }
+        return (unsigned PY_LONG_LONG)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to unsigned PY_LONG_LONG");
+                return (unsigned PY_LONG_LONG)-1;
+            }
+            return (unsigned PY_LONG_LONG)PyLong_AsUnsignedLongLong(x);
+        } else {
+            return (unsigned PY_LONG_LONG)PyLong_AsLongLong(x);
+        }
+    } else {
+        unsigned PY_LONG_LONG val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (unsigned PY_LONG_LONG)-1;
+        val = __Pyx_PyInt_AsUnsignedLongLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE long __Pyx_PyInt_AsLong(PyObject* x) {
+    const long neg_one = (long)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to long");
+            return (long)-1;
+        }
+        return (long)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to long");
+                return (long)-1;
+            }
+            return (long)PyLong_AsUnsignedLong(x);
+        } else {
+            return (long)PyLong_AsLong(x);
+        }
+    } else {
+        long val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (long)-1;
+        val = __Pyx_PyInt_AsLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE PY_LONG_LONG __Pyx_PyInt_AsLongLong(PyObject* x) {
+    const PY_LONG_LONG neg_one = (PY_LONG_LONG)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to PY_LONG_LONG");
+            return (PY_LONG_LONG)-1;
+        }
+        return (PY_LONG_LONG)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to PY_LONG_LONG");
+                return (PY_LONG_LONG)-1;
+            }
+            return (PY_LONG_LONG)PyLong_AsUnsignedLongLong(x);
+        } else {
+            return (PY_LONG_LONG)PyLong_AsLongLong(x);
+        }
+    } else {
+        PY_LONG_LONG val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (PY_LONG_LONG)-1;
+        val = __Pyx_PyInt_AsLongLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE signed long __Pyx_PyInt_AsSignedLong(PyObject* x) {
+    const signed long neg_one = (signed long)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to signed long");
+            return (signed long)-1;
+        }
+        return (signed long)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to signed long");
+                return (signed long)-1;
+            }
+            return (signed long)PyLong_AsUnsignedLong(x);
+        } else {
+            return (signed long)PyLong_AsLong(x);
+        }
+    } else {
+        signed long val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (signed long)-1;
+        val = __Pyx_PyInt_AsSignedLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE signed PY_LONG_LONG __Pyx_PyInt_AsSignedLongLong(PyObject* x) {
+    const signed PY_LONG_LONG neg_one = (signed PY_LONG_LONG)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to signed PY_LONG_LONG");
+            return (signed PY_LONG_LONG)-1;
+        }
+        return (signed PY_LONG_LONG)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to signed PY_LONG_LONG");
+                return (signed PY_LONG_LONG)-1;
+            }
+            return (signed PY_LONG_LONG)PyLong_AsUnsignedLongLong(x);
+        } else {
+            return (signed PY_LONG_LONG)PyLong_AsLongLong(x);
+        }
+    } else {
+        signed PY_LONG_LONG val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (signed PY_LONG_LONG)-1;
+        val = __Pyx_PyInt_AsSignedLongLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static int __Pyx_check_binary_version(void) {
+    char ctversion[4], rtversion[4];
+    PyOS_snprintf(ctversion, 4, "%d.%d", PY_MAJOR_VERSION, PY_MINOR_VERSION);
+    PyOS_snprintf(rtversion, 4, "%s", Py_GetVersion());
+    if (ctversion[0] != rtversion[0] || ctversion[2] != rtversion[2]) {
+        char message[200];
+        PyOS_snprintf(message, sizeof(message),
+                      "compiletime version %s of module '%.100s' "
+                      "does not match runtime version %s",
+                      ctversion, __Pyx_MODULE_NAME, rtversion);
+        #if PY_VERSION_HEX < 0x02050000
+        return PyErr_Warn(NULL, message);
+        #else
+        return PyErr_WarnEx(NULL, message, 1);
+        #endif
+    }
+    return 0;
+}
+
+static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) {
+    int start = 0, mid = 0, end = count - 1;
+    if (end >= 0 && code_line > entries[end].code_line) {
+        return count;
+    }
+    while (start < end) {
+        mid = (start + end) / 2;
+        if (code_line < entries[mid].code_line) {
+            end = mid;
+        } else if (code_line > entries[mid].code_line) {
+             start = mid + 1;
+        } else {
+            return mid;
+        }
+    }
+    if (code_line <= entries[mid].code_line) {
+        return mid;
+    } else {
+        return mid + 1;
+    }
+}
+static PyCodeObject *__pyx_find_code_object(int code_line) {
+    PyCodeObject* code_object;
+    int pos;
+    if (unlikely(!code_line) || unlikely(!__pyx_code_cache.entries)) {
+        return NULL;
+    }
+    pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line);
+    if (unlikely(pos >= __pyx_code_cache.count) || unlikely(__pyx_code_cache.entries[pos].code_line != code_line)) {
+        return NULL;
+    }
+    code_object = __pyx_code_cache.entries[pos].code_object;
+    Py_INCREF(code_object);
+    return code_object;
+}
+static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) {
+    int pos, i;
+    __Pyx_CodeObjectCacheEntry* entries = __pyx_code_cache.entries;
+    if (unlikely(!code_line)) {
+        return;
+    }
+    if (unlikely(!entries)) {
+        entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Malloc(64*sizeof(__Pyx_CodeObjectCacheEntry));
+        if (likely(entries)) {
+            __pyx_code_cache.entries = entries;
+            __pyx_code_cache.max_count = 64;
+            __pyx_code_cache.count = 1;
+            entries[0].code_line = code_line;
+            entries[0].code_object = code_object;
+            Py_INCREF(code_object);
+        }
+        return;
+    }
+    pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line);
+    if ((pos < __pyx_code_cache.count) && unlikely(__pyx_code_cache.entries[pos].code_line == code_line)) {
+        PyCodeObject* tmp = entries[pos].code_object;
+        entries[pos].code_object = code_object;
+        Py_DECREF(tmp);
+        return;
+    }
+    if (__pyx_code_cache.count == __pyx_code_cache.max_count) {
+        int new_max = __pyx_code_cache.max_count + 64;
+        entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Realloc(
+            __pyx_code_cache.entries, new_max*sizeof(__Pyx_CodeObjectCacheEntry));
+        if (unlikely(!entries)) {
+            return;
+        }
+        __pyx_code_cache.entries = entries;
+        __pyx_code_cache.max_count = new_max;
+    }
+    for (i=__pyx_code_cache.count; i>pos; i--) {
+        entries[i] = entries[i-1];
+    }
+    entries[pos].code_line = code_line;
+    entries[pos].code_object = code_object;
+    __pyx_code_cache.count++;
+    Py_INCREF(code_object);
+}
+
+#include "compile.h"
+#include "frameobject.h"
+#include "traceback.h"
+static PyCodeObject* __Pyx_CreateCodeObjectForTraceback(
+            const char *funcname, int c_line,
+            int py_line, const char *filename) {
+    PyCodeObject *py_code = 0;
+    PyObject *py_srcfile = 0;
+    PyObject *py_funcname = 0;
+    #if PY_MAJOR_VERSION < 3
+    py_srcfile = PyString_FromString(filename);
+    #else
+    py_srcfile = PyUnicode_FromString(filename);
+    #endif
+    if (!py_srcfile) goto bad;
+    if (c_line) {
+        #if PY_MAJOR_VERSION < 3
+        py_funcname = PyString_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line);
+        #else
+        py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line);
+        #endif
+    }
+    else {
+        #if PY_MAJOR_VERSION < 3
+        py_funcname = PyString_FromString(funcname);
+        #else
+        py_funcname = PyUnicode_FromString(funcname);
+        #endif
+    }
+    if (!py_funcname) goto bad;
+    py_code = __Pyx_PyCode_New(
+        0,            /*int argcount,*/
+        0,            /*int kwonlyargcount,*/
+        0,            /*int nlocals,*/
+        0,            /*int stacksize,*/
+        0,            /*int flags,*/
+        __pyx_empty_bytes, /*PyObject *code,*/
+        __pyx_empty_tuple, /*PyObject *consts,*/
+        __pyx_empty_tuple, /*PyObject *names,*/
+        __pyx_empty_tuple, /*PyObject *varnames,*/
+        __pyx_empty_tuple, /*PyObject *freevars,*/
+        __pyx_empty_tuple, /*PyObject *cellvars,*/
+        py_srcfile,   /*PyObject *filename,*/
+        py_funcname,  /*PyObject *name,*/
+        py_line,      /*int firstlineno,*/
+        __pyx_empty_bytes  /*PyObject *lnotab*/
+    );
+    Py_DECREF(py_srcfile);
+    Py_DECREF(py_funcname);
+    return py_code;
+bad:
+    Py_XDECREF(py_srcfile);
+    Py_XDECREF(py_funcname);
+    return NULL;
+}
+static void __Pyx_AddTraceback(const char *funcname, int c_line,
+                               int py_line, const char *filename) {
+    PyCodeObject *py_code = 0;
+    PyObject *py_globals = 0;
+    PyFrameObject *py_frame = 0;
+    py_code = __pyx_find_code_object(c_line ? c_line : py_line);
+    if (!py_code) {
+        py_code = __Pyx_CreateCodeObjectForTraceback(
+            funcname, c_line, py_line, filename);
+        if (!py_code) goto bad;
+        __pyx_insert_code_object(c_line ? c_line : py_line, py_code);
+    }
+    py_globals = PyModule_GetDict(__pyx_m);
+    if (!py_globals) goto bad;
+    py_frame = PyFrame_New(
+        PyThreadState_GET(), /*PyThreadState *tstate,*/
+        py_code,             /*PyCodeObject *code,*/
+        py_globals,          /*PyObject *globals,*/
+        0                    /*PyObject *locals*/
+    );
+    if (!py_frame) goto bad;
+    py_frame->f_lineno = py_line;
+    PyTraceBack_Here(py_frame);
+bad:
+    Py_XDECREF(py_code);
+    Py_XDECREF(py_frame);
+}
+
+static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
+    while (t->p) {
+        #if PY_MAJOR_VERSION < 3
+        if (t->is_unicode) {
+            *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
+        } else if (t->intern) {
+            *t->p = PyString_InternFromString(t->s);
+        } else {
+            *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
+        }
+        #else  /* Python 3+ has unicode identifiers */
+        if (t->is_unicode | t->is_str) {
+            if (t->intern) {
+                *t->p = PyUnicode_InternFromString(t->s);
+            } else if (t->encoding) {
+                *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL);
+            } else {
+                *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
+            }
+        } else {
+            *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
+        }
+        #endif
+        if (!*t->p)
+            return -1;
+        ++t;
+    }
+    return 0;
+}
+
+static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) {
+   int is_true = x == Py_True;
+   if (is_true | (x == Py_False) | (x == Py_None)) return is_true;
+   else return PyObject_IsTrue(x);
+}
+static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x) {
+  PyNumberMethods *m;
+  const char *name = NULL;
+  PyObject *res = NULL;
+#if PY_VERSION_HEX < 0x03000000
+  if (PyInt_Check(x) || PyLong_Check(x))
+#else
+  if (PyLong_Check(x))
+#endif
+    return Py_INCREF(x), x;
+  m = Py_TYPE(x)->tp_as_number;
+#if PY_VERSION_HEX < 0x03000000
+  if (m && m->nb_int) {
+    name = "int";
+    res = PyNumber_Int(x);
+  }
+  else if (m && m->nb_long) {
+    name = "long";
+    res = PyNumber_Long(x);
+  }
+#else
+  if (m && m->nb_int) {
+    name = "int";
+    res = PyNumber_Long(x);
+  }
+#endif
+  if (res) {
+#if PY_VERSION_HEX < 0x03000000
+    if (!PyInt_Check(res) && !PyLong_Check(res)) {
+#else
+    if (!PyLong_Check(res)) {
+#endif
+      PyErr_Format(PyExc_TypeError,
+                   "__%s__ returned non-%s (type %.200s)",
+                   name, name, Py_TYPE(res)->tp_name);
+      Py_DECREF(res);
+      return NULL;
+    }
+  }
+  else if (!PyErr_Occurred()) {
+    PyErr_SetString(PyExc_TypeError,
+                    "an integer is required");
+  }
+  return res;
+}
+static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) {
+  Py_ssize_t ival;
+  PyObject* x = PyNumber_Index(b);
+  if (!x) return -1;
+  ival = PyInt_AsSsize_t(x);
+  Py_DECREF(x);
+  return ival;
+}
+static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) {
+#if PY_VERSION_HEX < 0x02050000
+   if (ival <= LONG_MAX)
+       return PyInt_FromLong((long)ival);
+   else {
+       unsigned char *bytes = (unsigned char *) &ival;
+       int one = 1; int little = (int)*(unsigned char*)&one;
+       return _PyLong_FromByteArray(bytes, sizeof(size_t), little, 0);
+   }
+#else
+   return PyInt_FromSize_t(ival);
+#endif
+}
+static CYTHON_INLINE size_t __Pyx_PyInt_AsSize_t(PyObject* x) {
+   unsigned PY_LONG_LONG val = __Pyx_PyInt_AsUnsignedLongLong(x);
+   if (unlikely(val == (unsigned PY_LONG_LONG)-1 && PyErr_Occurred())) {
+       return (size_t)-1;
+   } else if (unlikely(val != (unsigned PY_LONG_LONG)(size_t)val)) {
+       PyErr_SetString(PyExc_OverflowError,
+                       "value too large to convert to size_t");
+       return (size_t)-1;
+   }
+   return (size_t)val;
+}
+
+
+#endif /* Py_PYTHON_H */
diff --git a/lib/bx/bbi/bpt_file.pxd b/lib/bx/bbi/bpt_file.pxd
new file mode 100644
index 0000000..d5c2e2a
--- /dev/null
+++ b/lib/bx/bbi/bpt_file.pxd
@@ -0,0 +1,16 @@
+from bx.misc.binary_file import BinaryFileReader
+
+from types cimport *
+
+cdef class BPTFile:
+    """
+    On disk B+ tree compatible with Jim Kent's bPlusTree.c
+    """
+    cdef object file
+    cdef object reader
+    cdef boolean is_byteswapped
+    cdef bits32 block_size
+    cdef bits32 key_size
+    cdef bits32 value_size
+    cdef bits64 item_count
+    cdef bits64 root_offset
diff --git a/lib/bx/bbi/bpt_file.pyx b/lib/bx/bbi/bpt_file.pyx
new file mode 100644
index 0000000..956d321
--- /dev/null
+++ b/lib/bx/bbi/bpt_file.pyx
@@ -0,0 +1,76 @@
+from bx.misc.binary_file import BinaryFileReader
+
+DEF bpt_sig = 0x78CA8C91
+
+# bptFileHeaderSize = 32
+# bptBlockHeaderSize = 4
+
+cdef class BPTFile:
+    """
+    On disk B+ tree compatible with Jim Kent's bPlusTree.c
+    """
+
+    def __init__( self, file=None ):
+        if file is not None:
+            self.attach( file )
+
+    def attach( self, file ):
+        """
+        Attach to an open file
+        """
+        self.file = file
+        self.reader = reader = BinaryFileReader( file, bpt_sig )
+        self.is_byteswapped = self.reader.byteswap_needed
+        # Read header stuff
+        self.block_size = reader.read_uint32()
+        self.key_size = reader.read_uint32()
+        self.value_size = reader.read_uint32()
+        self.item_count = reader.read_uint64()
+        reader.skip( 8 )
+        self.root_offset = reader.tell()
+
+    def r_find( self, bits64 block_start, key ):
+        """
+        Recursively seek the value matching key under the subtree starting
+        at file offset `block_start`
+        """
+        cdef UBYTE is_leaf
+        cdef bits16 child_count
+        cdef bits64 offset
+        self.reader.seek( block_start )
+        # Block header
+        is_leaf = self.reader.read_uint8()
+        self.reader.read_uint8()
+        child_count = self.reader.read_uint16()
+        if is_leaf:
+            for i from 0 <= i < child_count:
+                node_key = self.reader.read( self.key_size )
+                node_value = self.reader.read( self.value_size )
+                if node_key == key:
+                    return node_value
+            return None
+        else:
+            # Read and discard first key, store offset
+            self.reader.read( self.key_size )
+            offset = self.reader.read_uint64()
+            # Loop until correct subtree is found
+            for i from 0 <= i < child_count:
+                node_key = self.reader.read( self.key_size )
+                if node_key > key:
+                    break
+                offset = self.reader.read_uint64()
+            return self.r_find( offset, key )
+
+    def find( self, key ):
+        """
+        Find the value matching `key` (a bytestring). Returns the matching
+        value as a bytestring if found, or None
+        """
+        # Key is greater than key_size, must not be a match
+        if len(key) > self.key_size:
+            return None
+        # Key is less than key_size, right pad with 0 bytes
+        if len(key) < self.key_size:
+            key += ( '\0' * ( self.key_size - len(key) ) )
+        # Call the recursive finder
+        return self.r_find( self.root_offset, key )
diff --git a/lib/bx/bbi/cirtree_file.c b/lib/bx/bbi/cirtree_file.c
new file mode 100644
index 0000000..2c096ac
--- /dev/null
+++ b/lib/bx/bbi/cirtree_file.c
@@ -0,0 +1,3901 @@
+/* Generated by Cython 0.18 on Mon Jul 15 13:25:44 2013 */
+
+#define PY_SSIZE_T_CLEAN
+#include "Python.h"
+#ifndef Py_PYTHON_H
+    #error Python headers needed to compile C extensions, please install development version of Python.
+#elif PY_VERSION_HEX < 0x02040000
+    #error Cython requires Python 2.4+.
+#else
+#include <stddef.h> /* For offsetof */
+#ifndef offsetof
+#define offsetof(type, member) ( (size_t) & ((type*)0) -> member )
+#endif
+#if !defined(WIN32) && !defined(MS_WINDOWS)
+  #ifndef __stdcall
+    #define __stdcall
+  #endif
+  #ifndef __cdecl
+    #define __cdecl
+  #endif
+  #ifndef __fastcall
+    #define __fastcall
+  #endif
+#endif
+#ifndef DL_IMPORT
+  #define DL_IMPORT(t) t
+#endif
+#ifndef DL_EXPORT
+  #define DL_EXPORT(t) t
+#endif
+#ifndef PY_LONG_LONG
+  #define PY_LONG_LONG LONG_LONG
+#endif
+#ifndef Py_HUGE_VAL
+  #define Py_HUGE_VAL HUGE_VAL
+#endif
+#ifdef PYPY_VERSION
+#define CYTHON_COMPILING_IN_PYPY 1
+#define CYTHON_COMPILING_IN_CPYTHON 0
+#else
+#define CYTHON_COMPILING_IN_PYPY 0
+#define CYTHON_COMPILING_IN_CPYTHON 1
+#endif
+#if PY_VERSION_HEX < 0x02050000
+  typedef int Py_ssize_t;
+  #define PY_SSIZE_T_MAX INT_MAX
+  #define PY_SSIZE_T_MIN INT_MIN
+  #define PY_FORMAT_SIZE_T ""
+  #define CYTHON_FORMAT_SSIZE_T ""
+  #define PyInt_FromSsize_t(z) PyInt_FromLong(z)
+  #define PyInt_AsSsize_t(o)   __Pyx_PyInt_AsInt(o)
+  #define PyNumber_Index(o)    ((PyNumber_Check(o) && !PyFloat_Check(o)) ? PyNumber_Int(o) : \
+                                (PyErr_Format(PyExc_TypeError, \
+                                              "expected index value, got %.200s", Py_TYPE(o)->tp_name), \
+                                 (PyObject*)0))
+  #define __Pyx_PyIndex_Check(o) (PyNumber_Check(o) && !PyFloat_Check(o) && \
+                                  !PyComplex_Check(o))
+  #define PyIndex_Check __Pyx_PyIndex_Check
+  #define PyErr_WarnEx(category, message, stacklevel) PyErr_Warn(category, message)
+  #define __PYX_BUILD_PY_SSIZE_T "i"
+#else
+  #define __PYX_BUILD_PY_SSIZE_T "n"
+  #define CYTHON_FORMAT_SSIZE_T "z"
+  #define __Pyx_PyIndex_Check PyIndex_Check
+#endif
+#if PY_VERSION_HEX < 0x02060000
+  #define Py_REFCNT(ob) (((PyObject*)(ob))->ob_refcnt)
+  #define Py_TYPE(ob)   (((PyObject*)(ob))->ob_type)
+  #define Py_SIZE(ob)   (((PyVarObject*)(ob))->ob_size)
+  #define PyVarObject_HEAD_INIT(type, size) \
+          PyObject_HEAD_INIT(type) size,
+  #define PyType_Modified(t)
+  typedef struct {
+     void *buf;
+     PyObject *obj;
+     Py_ssize_t len;
+     Py_ssize_t itemsize;
+     int readonly;
+     int ndim;
+     char *format;
+     Py_ssize_t *shape;
+     Py_ssize_t *strides;
+     Py_ssize_t *suboffsets;
+     void *internal;
+  } Py_buffer;
+  #define PyBUF_SIMPLE 0
+  #define PyBUF_WRITABLE 0x0001
+  #define PyBUF_FORMAT 0x0004
+  #define PyBUF_ND 0x0008
+  #define PyBUF_STRIDES (0x0010 | PyBUF_ND)
+  #define PyBUF_C_CONTIGUOUS (0x0020 | PyBUF_STRIDES)
+  #define PyBUF_F_CONTIGUOUS (0x0040 | PyBUF_STRIDES)
+  #define PyBUF_ANY_CONTIGUOUS (0x0080 | PyBUF_STRIDES)
+  #define PyBUF_INDIRECT (0x0100 | PyBUF_STRIDES)
+  #define PyBUF_RECORDS (PyBUF_STRIDES | PyBUF_FORMAT | PyBUF_WRITABLE)
+  #define PyBUF_FULL (PyBUF_INDIRECT | PyBUF_FORMAT | PyBUF_WRITABLE)
+  typedef int (*getbufferproc)(PyObject *, Py_buffer *, int);
+  typedef void (*releasebufferproc)(PyObject *, Py_buffer *);
+#endif
+#if PY_MAJOR_VERSION < 3
+  #define __Pyx_BUILTIN_MODULE_NAME "__builtin__"
+  #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \
+          PyCode_New(a, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
+#else
+  #define __Pyx_BUILTIN_MODULE_NAME "builtins"
+  #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \
+          PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
+#endif
+#if PY_MAJOR_VERSION < 3 && PY_MINOR_VERSION < 6
+  #define PyUnicode_FromString(s) PyUnicode_Decode(s, strlen(s), "UTF-8", "strict")
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define Py_TPFLAGS_CHECKTYPES 0
+  #define Py_TPFLAGS_HAVE_INDEX 0
+#endif
+#if (PY_VERSION_HEX < 0x02060000) || (PY_MAJOR_VERSION >= 3)
+  #define Py_TPFLAGS_HAVE_NEWBUFFER 0
+#endif
+#if PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND)
+  #define CYTHON_PEP393_ENABLED 1
+  #define __Pyx_PyUnicode_READY(op)       (likely(PyUnicode_IS_READY(op)) ? \
+                                              0 : _PyUnicode_Ready((PyObject *)(op)))
+  #define __Pyx_PyUnicode_GET_LENGTH(u)   PyUnicode_GET_LENGTH(u)
+  #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_READ_CHAR(u, i)
+  #define __Pyx_PyUnicode_READ(k, d, i)   PyUnicode_READ(k, d, i)
+#else
+  #define CYTHON_PEP393_ENABLED 0
+  #define __Pyx_PyUnicode_READY(op)       (0)
+  #define __Pyx_PyUnicode_GET_LENGTH(u)   PyUnicode_GET_SIZE(u)
+  #define __Pyx_PyUnicode_READ_CHAR(u, i) ((Py_UCS4)(PyUnicode_AS_UNICODE(u)[i]))
+  #define __Pyx_PyUnicode_READ(k, d, i)   ((k=k), (Py_UCS4)(((Py_UNICODE*)d)[i]))
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define PyBaseString_Type            PyUnicode_Type
+  #define PyStringObject               PyUnicodeObject
+  #define PyString_Type                PyUnicode_Type
+  #define PyString_Check               PyUnicode_Check
+  #define PyString_CheckExact          PyUnicode_CheckExact
+#endif
+#if PY_VERSION_HEX < 0x02060000
+  #define PyBytesObject                PyStringObject
+  #define PyBytes_Type                 PyString_Type
+  #define PyBytes_Check                PyString_Check
+  #define PyBytes_CheckExact           PyString_CheckExact
+  #define PyBytes_FromString           PyString_FromString
+  #define PyBytes_FromStringAndSize    PyString_FromStringAndSize
+  #define PyBytes_FromFormat           PyString_FromFormat
+  #define PyBytes_DecodeEscape         PyString_DecodeEscape
+  #define PyBytes_AsString             PyString_AsString
+  #define PyBytes_AsStringAndSize      PyString_AsStringAndSize
+  #define PyBytes_Size                 PyString_Size
+  #define PyBytes_AS_STRING            PyString_AS_STRING
+  #define PyBytes_GET_SIZE             PyString_GET_SIZE
+  #define PyBytes_Repr                 PyString_Repr
+  #define PyBytes_Concat               PyString_Concat
+  #define PyBytes_ConcatAndDel         PyString_ConcatAndDel
+#endif
+#if PY_VERSION_HEX < 0x02060000
+  #define PySet_Check(obj)             PyObject_TypeCheck(obj, &PySet_Type)
+  #define PyFrozenSet_Check(obj)       PyObject_TypeCheck(obj, &PyFrozenSet_Type)
+#endif
+#ifndef PySet_CheckExact
+  #define PySet_CheckExact(obj)        (Py_TYPE(obj) == &PySet_Type)
+#endif
+#define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type)
+#if PY_MAJOR_VERSION >= 3
+  #define PyIntObject                  PyLongObject
+  #define PyInt_Type                   PyLong_Type
+  #define PyInt_Check(op)              PyLong_Check(op)
+  #define PyInt_CheckExact(op)         PyLong_CheckExact(op)
+  #define PyInt_FromString             PyLong_FromString
+  #define PyInt_FromUnicode            PyLong_FromUnicode
+  #define PyInt_FromLong               PyLong_FromLong
+  #define PyInt_FromSize_t             PyLong_FromSize_t
+  #define PyInt_FromSsize_t            PyLong_FromSsize_t
+  #define PyInt_AsLong                 PyLong_AsLong
+  #define PyInt_AS_LONG                PyLong_AS_LONG
+  #define PyInt_AsSsize_t              PyLong_AsSsize_t
+  #define PyInt_AsUnsignedLongMask     PyLong_AsUnsignedLongMask
+  #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define PyBoolObject                 PyLongObject
+#endif
+#if PY_VERSION_HEX < 0x03020000
+  typedef long Py_hash_t;
+  #define __Pyx_PyInt_FromHash_t PyInt_FromLong
+  #define __Pyx_PyInt_AsHash_t   PyInt_AsLong
+#else
+  #define __Pyx_PyInt_FromHash_t PyInt_FromSsize_t
+  #define __Pyx_PyInt_AsHash_t   PyInt_AsSsize_t
+#endif
+#if (PY_MAJOR_VERSION < 3) || (PY_VERSION_HEX >= 0x03010300)
+  #define __Pyx_PySequence_GetSlice(obj, a, b) PySequence_GetSlice(obj, a, b)
+  #define __Pyx_PySequence_SetSlice(obj, a, b, value) PySequence_SetSlice(obj, a, b, value)
+  #define __Pyx_PySequence_DelSlice(obj, a, b) PySequence_DelSlice(obj, a, b)
+#else
+  #define __Pyx_PySequence_GetSlice(obj, a, b) (unlikely(!(obj)) ? \
+        (PyErr_SetString(PyExc_SystemError, "null argument to internal routine"), (PyObject*)0) : \
+        (likely((obj)->ob_type->tp_as_mapping) ? (PySequence_GetSlice(obj, a, b)) : \
+            (PyErr_Format(PyExc_TypeError, "'%.200s' object is unsliceable", (obj)->ob_type->tp_name), (PyObject*)0)))
+  #define __Pyx_PySequence_SetSlice(obj, a, b, value) (unlikely(!(obj)) ? \
+        (PyErr_SetString(PyExc_SystemError, "null argument to internal routine"), -1) : \
+        (likely((obj)->ob_type->tp_as_mapping) ? (PySequence_SetSlice(obj, a, b, value)) : \
+            (PyErr_Format(PyExc_TypeError, "'%.200s' object doesn't support slice assignment", (obj)->ob_type->tp_name), -1)))
+  #define __Pyx_PySequence_DelSlice(obj, a, b) (unlikely(!(obj)) ? \
+        (PyErr_SetString(PyExc_SystemError, "null argument to internal routine"), -1) : \
+        (likely((obj)->ob_type->tp_as_mapping) ? (PySequence_DelSlice(obj, a, b)) : \
+            (PyErr_Format(PyExc_TypeError, "'%.200s' object doesn't support slice deletion", (obj)->ob_type->tp_name), -1)))
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define PyMethod_New(func, self, klass) ((self) ? PyMethod_New(func, self) : PyInstanceMethod_New(func))
+#endif
+#if PY_VERSION_HEX < 0x02050000
+  #define __Pyx_GetAttrString(o,n)   PyObject_GetAttrString((o),((char *)(n)))
+  #define __Pyx_SetAttrString(o,n,a) PyObject_SetAttrString((o),((char *)(n)),(a))
+  #define __Pyx_DelAttrString(o,n)   PyObject_DelAttrString((o),((char *)(n)))
+#else
+  #define __Pyx_GetAttrString(o,n)   PyObject_GetAttrString((o),(n))
+  #define __Pyx_SetAttrString(o,n,a) PyObject_SetAttrString((o),(n),(a))
+  #define __Pyx_DelAttrString(o,n)   PyObject_DelAttrString((o),(n))
+#endif
+#if PY_VERSION_HEX < 0x02050000
+  #define __Pyx_NAMESTR(n) ((char *)(n))
+  #define __Pyx_DOCSTR(n)  ((char *)(n))
+#else
+  #define __Pyx_NAMESTR(n) (n)
+  #define __Pyx_DOCSTR(n)  (n)
+#endif
+
+
+#if PY_MAJOR_VERSION >= 3
+  #define __Pyx_PyNumber_Divide(x,y)         PyNumber_TrueDivide(x,y)
+  #define __Pyx_PyNumber_InPlaceDivide(x,y)  PyNumber_InPlaceTrueDivide(x,y)
+#else
+  #define __Pyx_PyNumber_Divide(x,y)         PyNumber_Divide(x,y)
+  #define __Pyx_PyNumber_InPlaceDivide(x,y)  PyNumber_InPlaceDivide(x,y)
+#endif
+
+#ifndef __PYX_EXTERN_C
+  #ifdef __cplusplus
+    #define __PYX_EXTERN_C extern "C"
+  #else
+    #define __PYX_EXTERN_C extern
+  #endif
+#endif
+
+#if defined(WIN32) || defined(MS_WINDOWS)
+#define _USE_MATH_DEFINES
+#endif
+#include <math.h>
+#define __PYX_HAVE__bx__bbi__cirtree_file
+#define __PYX_HAVE_API__bx__bbi__cirtree_file
+#ifdef _OPENMP
+#include <omp.h>
+#endif /* _OPENMP */
+
+#ifdef PYREX_WITHOUT_ASSERTIONS
+#define CYTHON_WITHOUT_ASSERTIONS
+#endif
+
+#ifndef CYTHON_INLINE
+  #if defined(__GNUC__)
+    #define CYTHON_INLINE __inline__
+  #elif defined(_MSC_VER)
+    #define CYTHON_INLINE __inline
+  #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+    #define CYTHON_INLINE inline
+  #else
+    #define CYTHON_INLINE
+  #endif
+#endif
+#ifndef CYTHON_UNUSED
+# if defined(__GNUC__)
+#   if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
+#     define CYTHON_UNUSED __attribute__ ((__unused__))
+#   else
+#     define CYTHON_UNUSED
+#   endif
+# elif defined(__ICC) || (defined(__INTEL_COMPILER) && !defined(_MSC_VER))
+#   define CYTHON_UNUSED __attribute__ ((__unused__))
+# else
+#   define CYTHON_UNUSED
+# endif
+#endif
+typedef struct {PyObject **p; char *s; const long n; const char* encoding; const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry; /*proto*/
+
+#define __Pyx_PyBytes_FromUString(s) PyBytes_FromString((char*)s)
+#define __Pyx_PyBytes_AsUString(s)   ((unsigned char*) PyBytes_AsString(s))
+#define __Pyx_Owned_Py_None(b) (Py_INCREF(Py_None), Py_None)
+#define __Pyx_PyBool_FromLong(b) ((b) ? (Py_INCREF(Py_True), Py_True) : (Py_INCREF(Py_False), Py_False))
+static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*);
+static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x);
+static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*);
+static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t);
+static CYTHON_INLINE size_t __Pyx_PyInt_AsSize_t(PyObject*);
+#if CYTHON_COMPILING_IN_CPYTHON
+#define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x))
+#else
+#define __pyx_PyFloat_AsDouble(x) PyFloat_AsDouble(x)
+#endif
+#define __pyx_PyFloat_AsFloat(x) ((float) __pyx_PyFloat_AsDouble(x))
+
+
+#ifdef __GNUC__
+  /* Test for GCC > 2.95 */
+  #if __GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))
+    #define likely(x)   __builtin_expect(!!(x), 1)
+    #define unlikely(x) __builtin_expect(!!(x), 0)
+  #else /* __GNUC__ > 2 ... */
+    #define likely(x)   (x)
+    #define unlikely(x) (x)
+  #endif /* __GNUC__ > 2 ... */
+#else /* __GNUC__ */
+  #define likely(x)   (x)
+  #define unlikely(x) (x)
+#endif /* __GNUC__ */
+    
+static PyObject *__pyx_m;
+static PyObject *__pyx_b;
+static PyObject *__pyx_empty_tuple;
+static PyObject *__pyx_empty_bytes;
+static int __pyx_lineno;
+static int __pyx_clineno = 0;
+static const char * __pyx_cfilenm= __FILE__;
+static const char *__pyx_filename;
+
+
+static const char *__pyx_f[] = {
+  "cirtree_file.pyx",
+};
+
+/* "types.pxd":1
+ * ctypedef unsigned char UBYTE             # <<<<<<<<<<<<<<
+ * ctypedef signed char BYTE
+ * ctypedef unsigned short UWORD
+ */
+typedef unsigned char __pyx_t_2bx_3bbi_5types_UBYTE;
+
+/* "types.pxd":2
+ * ctypedef unsigned char UBYTE
+ * ctypedef signed char BYTE             # <<<<<<<<<<<<<<
+ * ctypedef unsigned short UWORD
+ * ctypedef short WORD
+ */
+typedef signed char __pyx_t_2bx_3bbi_5types_BYTE;
+
+/* "types.pxd":3
+ * ctypedef unsigned char UBYTE
+ * ctypedef signed char BYTE
+ * ctypedef unsigned short UWORD             # <<<<<<<<<<<<<<
+ * ctypedef short WORD
+ * ctypedef unsigned long long bits64
+ */
+typedef unsigned short __pyx_t_2bx_3bbi_5types_UWORD;
+
+/* "types.pxd":4
+ * ctypedef signed char BYTE
+ * ctypedef unsigned short UWORD
+ * ctypedef short WORD             # <<<<<<<<<<<<<<
+ * ctypedef unsigned long long bits64
+ * ctypedef unsigned bits32
+ */
+typedef short __pyx_t_2bx_3bbi_5types_WORD;
+
+/* "types.pxd":5
+ * ctypedef unsigned short UWORD
+ * ctypedef short WORD
+ * ctypedef unsigned long long bits64             # <<<<<<<<<<<<<<
+ * ctypedef unsigned bits32
+ * ctypedef unsigned short bits16
+ */
+typedef unsigned PY_LONG_LONG __pyx_t_2bx_3bbi_5types_bits64;
+
+/* "types.pxd":6
+ * ctypedef short WORD
+ * ctypedef unsigned long long bits64
+ * ctypedef unsigned bits32             # <<<<<<<<<<<<<<
+ * ctypedef unsigned short bits16
+ * ctypedef unsigned char bits8
+ */
+typedef unsigned int __pyx_t_2bx_3bbi_5types_bits32;
+
+/* "types.pxd":7
+ * ctypedef unsigned long long bits64
+ * ctypedef unsigned bits32
+ * ctypedef unsigned short bits16             # <<<<<<<<<<<<<<
+ * ctypedef unsigned char bits8
+ * ctypedef int signed32
+ */
+typedef unsigned short __pyx_t_2bx_3bbi_5types_bits16;
+
+/* "types.pxd":8
+ * ctypedef unsigned bits32
+ * ctypedef unsigned short bits16
+ * ctypedef unsigned char bits8             # <<<<<<<<<<<<<<
+ * ctypedef int signed32
+ * 
+ */
+typedef unsigned char __pyx_t_2bx_3bbi_5types_bits8;
+
+/* "types.pxd":9
+ * ctypedef unsigned short bits16
+ * ctypedef unsigned char bits8
+ * ctypedef int signed32             # <<<<<<<<<<<<<<
+ * 
+ * ctypedef bint boolean
+ */
+typedef int __pyx_t_2bx_3bbi_5types_signed32;
+
+/* "types.pxd":11
+ * ctypedef int signed32
+ * 
+ * ctypedef bint boolean             # <<<<<<<<<<<<<<
+ * 
+ */
+typedef int __pyx_t_2bx_3bbi_5types_boolean;
+
+/*--- Type declarations ---*/
+struct __pyx_obj_2bx_3bbi_12cirtree_file_CIRTreeFile;
+
+/* "bx/bbi/cirtree_file.pxd":3
+ * from types cimport *
+ * 
+ * cdef class CIRTreeFile:             # <<<<<<<<<<<<<<
+ *     cdef object file
+ *     cdef object reader
+ */
+struct __pyx_obj_2bx_3bbi_12cirtree_file_CIRTreeFile {
+  PyObject_HEAD
+  PyObject *file;
+  PyObject *reader;
+  __pyx_t_2bx_3bbi_5types_boolean is_byteswapped;
+  __pyx_t_2bx_3bbi_5types_bits64 root_offset;
+  __pyx_t_2bx_3bbi_5types_bits32 block_size;
+  __pyx_t_2bx_3bbi_5types_bits64 item_count;
+  __pyx_t_2bx_3bbi_5types_bits32 start_chrom_ix;
+  __pyx_t_2bx_3bbi_5types_bits32 start_base;
+  __pyx_t_2bx_3bbi_5types_bits32 end_chrom_ix;
+  __pyx_t_2bx_3bbi_5types_bits32 end_base;
+  __pyx_t_2bx_3bbi_5types_bits64 file_size;
+  __pyx_t_2bx_3bbi_5types_bits32 items_per_slot;
+};
+
+#ifndef CYTHON_REFNANNY
+  #define CYTHON_REFNANNY 0
+#endif
+#if CYTHON_REFNANNY
+  typedef struct {
+    void (*INCREF)(void*, PyObject*, int);
+    void (*DECREF)(void*, PyObject*, int);
+    void (*GOTREF)(void*, PyObject*, int);
+    void (*GIVEREF)(void*, PyObject*, int);
+    void* (*SetupContext)(const char*, int, const char*);
+    void (*FinishContext)(void**);
+  } __Pyx_RefNannyAPIStruct;
+  static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL;
+  static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname); /*proto*/
+  #define __Pyx_RefNannyDeclarations void *__pyx_refnanny = NULL;
+#ifdef WITH_THREAD
+  #define __Pyx_RefNannySetupContext(name, acquire_gil) \
+          if (acquire_gil) { \
+              PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure(); \
+              __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__); \
+              PyGILState_Release(__pyx_gilstate_save); \
+          } else { \
+              __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__); \
+          }
+#else
+  #define __Pyx_RefNannySetupContext(name, acquire_gil) \
+          __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__)
+#endif
+  #define __Pyx_RefNannyFinishContext() \
+          __Pyx_RefNanny->FinishContext(&__pyx_refnanny)
+  #define __Pyx_INCREF(r)  __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_DECREF(r)  __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_GOTREF(r)  __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_XINCREF(r)  do { if((r) != NULL) {__Pyx_INCREF(r); }} while(0)
+  #define __Pyx_XDECREF(r)  do { if((r) != NULL) {__Pyx_DECREF(r); }} while(0)
+  #define __Pyx_XGOTREF(r)  do { if((r) != NULL) {__Pyx_GOTREF(r); }} while(0)
+  #define __Pyx_XGIVEREF(r) do { if((r) != NULL) {__Pyx_GIVEREF(r);}} while(0)
+#else
+  #define __Pyx_RefNannyDeclarations
+  #define __Pyx_RefNannySetupContext(name, acquire_gil)
+  #define __Pyx_RefNannyFinishContext()
+  #define __Pyx_INCREF(r) Py_INCREF(r)
+  #define __Pyx_DECREF(r) Py_DECREF(r)
+  #define __Pyx_GOTREF(r)
+  #define __Pyx_GIVEREF(r)
+  #define __Pyx_XINCREF(r) Py_XINCREF(r)
+  #define __Pyx_XDECREF(r) Py_XDECREF(r)
+  #define __Pyx_XGOTREF(r)
+  #define __Pyx_XGIVEREF(r)
+#endif /* CYTHON_REFNANNY */
+#define __Pyx_CLEAR(r)    do { PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);} while(0)
+#define __Pyx_XCLEAR(r)   do { if((r) != NULL) {PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);}} while(0)
+
+static void __Pyx_RaiseDoubleKeywordsError(const char* func_name, PyObject* kw_name); /*proto*/
+
+static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
+    PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
+    const char* function_name); /*proto*/
+
+static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
+    Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/
+
+static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/
+
+static CYTHON_INLINE PyObject* __Pyx_PyObject_Append(PyObject* L, PyObject* x) {
+    if (likely(PyList_CheckExact(L))) {
+        if (unlikely(PyList_Append(L, x) < 0)) return NULL;
+        Py_INCREF(Py_None);
+        return Py_None; /* this is just to have an accurate signature */
+    } else {
+        PyObject *r, *m;
+        m = __Pyx_GetAttrString(L, "append");
+        if (!m) return NULL;
+        r = PyObject_CallFunctionObjArgs(m, x, NULL);
+        Py_DECREF(m);
+        return r;
+    }
+}
+
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j) {
+    PyObject *r;
+    if (!j) return NULL;
+    r = PyObject_GetItem(o, j);
+    Py_DECREF(j);
+    return r;
+}
+#define __Pyx_GetItemInt_List(o, i, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \
+                                                    __Pyx_GetItemInt_List_Fast(o, i) : \
+                                                    __Pyx_GetItemInt_Generic(o, to_py_func(i)))
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    if (likely((0 <= i) & (i < PyList_GET_SIZE(o)))) {
+        PyObject *r = PyList_GET_ITEM(o, i);
+        Py_INCREF(r);
+        return r;
+    }
+    else if ((-PyList_GET_SIZE(o) <= i) & (i < 0)) {
+        PyObject *r = PyList_GET_ITEM(o, PyList_GET_SIZE(o) + i);
+        Py_INCREF(r);
+        return r;
+    }
+    return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
+#else
+    return PySequence_GetItem(o, i);
+#endif
+}
+#define __Pyx_GetItemInt_Tuple(o, i, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \
+                                                    __Pyx_GetItemInt_Tuple_Fast(o, i) : \
+                                                    __Pyx_GetItemInt_Generic(o, to_py_func(i)))
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    if (likely((0 <= i) & (i < PyTuple_GET_SIZE(o)))) {
+        PyObject *r = PyTuple_GET_ITEM(o, i);
+        Py_INCREF(r);
+        return r;
+    }
+    else if ((-PyTuple_GET_SIZE(o) <= i) & (i < 0)) {
+        PyObject *r = PyTuple_GET_ITEM(o, PyTuple_GET_SIZE(o) + i);
+        Py_INCREF(r);
+        return r;
+    }
+    return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
+#else
+    return PySequence_GetItem(o, i);
+#endif
+}
+#define __Pyx_GetItemInt(o, i, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \
+                                                    __Pyx_GetItemInt_Fast(o, i) : \
+                                                    __Pyx_GetItemInt_Generic(o, to_py_func(i)))
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    if (PyList_CheckExact(o)) {
+        Py_ssize_t n = (likely(i >= 0)) ? i : i + PyList_GET_SIZE(o);
+        if (likely((n >= 0) & (n < PyList_GET_SIZE(o)))) {
+            PyObject *r = PyList_GET_ITEM(o, n);
+            Py_INCREF(r);
+            return r;
+        }
+    }
+    else if (PyTuple_CheckExact(o)) {
+        Py_ssize_t n = (likely(i >= 0)) ? i : i + PyTuple_GET_SIZE(o);
+        if (likely((n >= 0) & (n < PyTuple_GET_SIZE(o)))) {
+            PyObject *r = PyTuple_GET_ITEM(o, n);
+            Py_INCREF(r);
+            return r;
+        }
+    } else {  /* inlined PySequence_GetItem() */
+        PySequenceMethods *m = Py_TYPE(o)->tp_as_sequence;
+        if (likely(m && m->sq_item)) {
+            if (unlikely(i < 0) && likely(m->sq_length)) {
+                Py_ssize_t l = m->sq_length(o);
+                if (unlikely(l < 0)) return NULL;
+                i += l;
+            }
+            return m->sq_item(o, i);
+        }
+    }
+#else
+    if (PySequence_Check(o)) {
+        return PySequence_GetItem(o, i);
+    }
+#endif
+    return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
+}
+
+static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level); /*proto*/
+
+static CYTHON_INLINE void __Pyx_RaiseImportError(PyObject *name);
+
+static CYTHON_INLINE unsigned char __Pyx_PyInt_AsUnsignedChar(PyObject *);
+
+static CYTHON_INLINE unsigned short __Pyx_PyInt_AsUnsignedShort(PyObject *);
+
+static CYTHON_INLINE unsigned int __Pyx_PyInt_AsUnsignedInt(PyObject *);
+
+static CYTHON_INLINE char __Pyx_PyInt_AsChar(PyObject *);
+
+static CYTHON_INLINE short __Pyx_PyInt_AsShort(PyObject *);
+
+static CYTHON_INLINE int __Pyx_PyInt_AsInt(PyObject *);
+
+static CYTHON_INLINE signed char __Pyx_PyInt_AsSignedChar(PyObject *);
+
+static CYTHON_INLINE signed short __Pyx_PyInt_AsSignedShort(PyObject *);
+
+static CYTHON_INLINE signed int __Pyx_PyInt_AsSignedInt(PyObject *);
+
+static CYTHON_INLINE int __Pyx_PyInt_AsLongDouble(PyObject *);
+
+static CYTHON_INLINE unsigned long __Pyx_PyInt_AsUnsignedLong(PyObject *);
+
+static CYTHON_INLINE unsigned PY_LONG_LONG __Pyx_PyInt_AsUnsignedLongLong(PyObject *);
+
+static CYTHON_INLINE long __Pyx_PyInt_AsLong(PyObject *);
+
+static CYTHON_INLINE PY_LONG_LONG __Pyx_PyInt_AsLongLong(PyObject *);
+
+static CYTHON_INLINE signed long __Pyx_PyInt_AsSignedLong(PyObject *);
+
+static CYTHON_INLINE signed PY_LONG_LONG __Pyx_PyInt_AsSignedLongLong(PyObject *);
+
+static int __Pyx_check_binary_version(void);
+
+typedef struct {
+    int code_line;
+    PyCodeObject* code_object;
+} __Pyx_CodeObjectCacheEntry;
+struct __Pyx_CodeObjectCache {
+    int count;
+    int max_count;
+    __Pyx_CodeObjectCacheEntry* entries;
+};
+static struct __Pyx_CodeObjectCache __pyx_code_cache = {0,0,NULL};
+static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line);
+static PyCodeObject *__pyx_find_code_object(int code_line);
+static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object);
+
+static void __Pyx_AddTraceback(const char *funcname, int c_line,
+                               int py_line, const char *filename); /*proto*/
+
+static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
+
+
+/* Module declarations from 'bx.bbi.types' */
+
+/* Module declarations from 'bx.bbi.cirtree_file' */
+static PyTypeObject *__pyx_ptype_2bx_3bbi_12cirtree_file_CIRTreeFile = 0;
+static int __pyx_f_2bx_3bbi_12cirtree_file_ovcmp(__pyx_t_2bx_3bbi_5types_bits32, __pyx_t_2bx_3bbi_5types_bits32, __pyx_t_2bx_3bbi_5types_bits32, __pyx_t_2bx_3bbi_5types_bits32); /*proto*/
+static PyObject *__pyx_f_2bx_3bbi_12cirtree_file_overlaps(PyObject *, PyObject *, PyObject *, PyObject *, PyObject *, PyObject *, PyObject *); /*proto*/
+#define __Pyx_MODULE_NAME "bx.bbi.cirtree_file"
+int __pyx_module_is_main_bx__bbi__cirtree_file = 0;
+
+/* Implementation of 'bx.bbi.cirtree_file' */
+static int __pyx_pf_2bx_3bbi_12cirtree_file_11CIRTreeFile___init__(struct __pyx_obj_2bx_3bbi_12cirtree_file_CIRTreeFile *__pyx_v_self, PyObject *__pyx_v_file); /* proto */
+static PyObject *__pyx_pf_2bx_3bbi_12cirtree_file_11CIRTreeFile_2attach(struct __pyx_obj_2bx_3bbi_12cirtree_file_CIRTreeFile *__pyx_v_self, PyObject *__pyx_v_file); /* proto */
+static PyObject *__pyx_pf_2bx_3bbi_12cirtree_file_11CIRTreeFile_4r_find_overlapping(struct __pyx_obj_2bx_3bbi_12cirtree_file_CIRTreeFile *__pyx_v_self, int __pyx_v_level, __pyx_t_2bx_3bbi_5types_bits64 __pyx_v_index_file_offset, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_chrom_ix, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_start, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_end, PyObject *__pyx_v_rval, PyObject *__pyx_v_reader); /* proto */
+static PyObject *__pyx_pf_2bx_3bbi_12cirtree_file_11CIRTreeFile_6r_find_overlapping_leaf(CYTHON_UNUSED struct __pyx_obj_2bx_3bbi_12cirtree_file_CIRTreeFile *__pyx_v_self, CYTHON_UNUSED int __pyx_v_level, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_chrom_ix, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_start, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_end, PyObject *__pyx_v_rval, __pyx_t_2bx_3bbi_5types_bits16 __pyx_v_child_count, PyObject *__pyx_v_reader); /* proto */
+static PyObject *__pyx_pf_2bx_3bbi_12cirtree_file_11CIRTreeFile_8r_find_overlapping_parent(struct __pyx_obj_2bx_3bbi_12cirtree_file_CIRTreeFile *__pyx_v_self, int __pyx_v_level, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_chrom_ix, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_start, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_end, PyObject *__pyx_v_rval, __pyx_t_2bx_3bbi_5types_bits16 __pyx_v_child_count, PyObject *__pyx_v_reader); /* proto */
+static PyObject *__pyx_pf_2bx_3bbi_12cirtree_file_11CIRTreeFile_10find_overlapping_blocks(struct __pyx_obj_2bx_3bbi_12cirtree_file_CIRTreeFile *__pyx_v_self, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_chrom_ix, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_start, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_end); /* proto */
+static char __pyx_k_1[] = "r_find_overlapping_leaf";
+static char __pyx_k_2[] = "r_find_overlapping_parent";
+static char __pyx_k_3[] = "bx.misc.binary_file";
+static char __pyx_k__end[] = "end";
+static char __pyx_k__file[] = "file";
+static char __pyx_k__rval[] = "rval";
+static char __pyx_k__seek[] = "seek";
+static char __pyx_k__tell[] = "tell";
+static char __pyx_k__level[] = "level";
+static char __pyx_k__start[] = "start";
+static char __pyx_k__attach[] = "attach";
+static char __pyx_k__reader[] = "reader";
+static char __pyx_k____main__[] = "__main__";
+static char __pyx_k____test__[] = "__test__";
+static char __pyx_k__chrom_ix[] = "chrom_ix";
+static char __pyx_k__read_uint8[] = "read_uint8";
+static char __pyx_k__child_count[] = "child_count";
+static char __pyx_k__read_uint16[] = "read_uint16";
+static char __pyx_k__read_uint32[] = "read_uint32";
+static char __pyx_k__read_uint64[] = "read_uint64";
+static char __pyx_k__byteswap_needed[] = "byteswap_needed";
+static char __pyx_k__BinaryFileReader[] = "BinaryFileReader";
+static char __pyx_k__index_file_offset[] = "index_file_offset";
+static char __pyx_k__r_find_overlapping[] = "r_find_overlapping";
+static PyObject *__pyx_n_s_1;
+static PyObject *__pyx_n_s_2;
+static PyObject *__pyx_n_s_3;
+static PyObject *__pyx_n_s__BinaryFileReader;
+static PyObject *__pyx_n_s____main__;
+static PyObject *__pyx_n_s____test__;
+static PyObject *__pyx_n_s__attach;
+static PyObject *__pyx_n_s__byteswap_needed;
+static PyObject *__pyx_n_s__child_count;
+static PyObject *__pyx_n_s__chrom_ix;
+static PyObject *__pyx_n_s__end;
+static PyObject *__pyx_n_s__file;
+static PyObject *__pyx_n_s__index_file_offset;
+static PyObject *__pyx_n_s__level;
+static PyObject *__pyx_n_s__r_find_overlapping;
+static PyObject *__pyx_n_s__read_uint16;
+static PyObject *__pyx_n_s__read_uint32;
+static PyObject *__pyx_n_s__read_uint64;
+static PyObject *__pyx_n_s__read_uint8;
+static PyObject *__pyx_n_s__reader;
+static PyObject *__pyx_n_s__rval;
+static PyObject *__pyx_n_s__seek;
+static PyObject *__pyx_n_s__start;
+static PyObject *__pyx_n_s__tell;
+static PyObject *__pyx_int_0;
+static PyObject *__pyx_int_610839776;
+
+/* "bx/bbi/cirtree_file.pyx":5
+ * DEF cir_tree_sig = 0x2468ACE0
+ * 
+ * cdef int ovcmp( bits32 a_hi, bits32 a_lo, bits32 b_hi, bits32 b_lo ):             # <<<<<<<<<<<<<<
+ *     if a_hi < b_hi:
+ *         return 1
+ */
+
+static int __pyx_f_2bx_3bbi_12cirtree_file_ovcmp(__pyx_t_2bx_3bbi_5types_bits32 __pyx_v_a_hi, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_a_lo, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_b_hi, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_b_lo) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("ovcmp", 0);
+
+  /* "bx/bbi/cirtree_file.pyx":6
+ * 
+ * cdef int ovcmp( bits32 a_hi, bits32 a_lo, bits32 b_hi, bits32 b_lo ):
+ *     if a_hi < b_hi:             # <<<<<<<<<<<<<<
+ *         return 1
+ *     elif a_hi > b_hi:
+ */
+  __pyx_t_1 = (__pyx_v_a_hi < __pyx_v_b_hi);
+  if (__pyx_t_1) {
+
+    /* "bx/bbi/cirtree_file.pyx":7
+ * cdef int ovcmp( bits32 a_hi, bits32 a_lo, bits32 b_hi, bits32 b_lo ):
+ *     if a_hi < b_hi:
+ *         return 1             # <<<<<<<<<<<<<<
+ *     elif a_hi > b_hi:
+ *         return -1
+ */
+    __pyx_r = 1;
+    goto __pyx_L0;
+    goto __pyx_L3;
+  }
+
+  /* "bx/bbi/cirtree_file.pyx":8
+ *     if a_hi < b_hi:
+ *         return 1
+ *     elif a_hi > b_hi:             # <<<<<<<<<<<<<<
+ *         return -1
+ *     else:
+ */
+  __pyx_t_1 = (__pyx_v_a_hi > __pyx_v_b_hi);
+  if (__pyx_t_1) {
+
+    /* "bx/bbi/cirtree_file.pyx":9
+ *         return 1
+ *     elif a_hi > b_hi:
+ *         return -1             # <<<<<<<<<<<<<<
+ *     else:
+ *         if a_lo < b_lo:
+ */
+    __pyx_r = -1;
+    goto __pyx_L0;
+    goto __pyx_L3;
+  }
+  /*else*/ {
+
+    /* "bx/bbi/cirtree_file.pyx":11
+ *         return -1
+ *     else:
+ *         if a_lo < b_lo:             # <<<<<<<<<<<<<<
+ *             return 1
+ *         elif a_lo > b_lo:
+ */
+    __pyx_t_1 = (__pyx_v_a_lo < __pyx_v_b_lo);
+    if (__pyx_t_1) {
+
+      /* "bx/bbi/cirtree_file.pyx":12
+ *     else:
+ *         if a_lo < b_lo:
+ *             return 1             # <<<<<<<<<<<<<<
+ *         elif a_lo > b_lo:
+ *             return -1
+ */
+      __pyx_r = 1;
+      goto __pyx_L0;
+      goto __pyx_L4;
+    }
+
+    /* "bx/bbi/cirtree_file.pyx":13
+ *         if a_lo < b_lo:
+ *             return 1
+ *         elif a_lo > b_lo:             # <<<<<<<<<<<<<<
+ *             return -1
+ *         else:
+ */
+    __pyx_t_1 = (__pyx_v_a_lo > __pyx_v_b_lo);
+    if (__pyx_t_1) {
+
+      /* "bx/bbi/cirtree_file.pyx":14
+ *             return 1
+ *         elif a_lo > b_lo:
+ *             return -1             # <<<<<<<<<<<<<<
+ *         else:
+ *             return 0
+ */
+      __pyx_r = -1;
+      goto __pyx_L0;
+      goto __pyx_L4;
+    }
+    /*else*/ {
+
+      /* "bx/bbi/cirtree_file.pyx":16
+ *             return -1
+ *         else:
+ *             return 0             # <<<<<<<<<<<<<<
+ * 
+ * cdef overlaps( qchrom, qstart, qend, rstartchrom, rstartbase, rendchrom, rendbase ):
+ */
+      __pyx_r = 0;
+      goto __pyx_L0;
+    }
+    __pyx_L4:;
+  }
+  __pyx_L3:;
+
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bbi/cirtree_file.pyx":18
+ *             return 0
+ * 
+ * cdef overlaps( qchrom, qstart, qend, rstartchrom, rstartbase, rendchrom, rendbase ):             # <<<<<<<<<<<<<<
+ *     return ( ovcmp( qchrom, qstart, rendchrom, rendbase ) > 0 ) and \
+ *            ( ovcmp( qchrom, qend, rstartchrom, rstartbase ) < 0 )
+ */
+
+static PyObject *__pyx_f_2bx_3bbi_12cirtree_file_overlaps(PyObject *__pyx_v_qchrom, PyObject *__pyx_v_qstart, PyObject *__pyx_v_qend, PyObject *__pyx_v_rstartchrom, PyObject *__pyx_v_rstartbase, PyObject *__pyx_v_rendchrom, PyObject *__pyx_v_rendbase) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  __pyx_t_2bx_3bbi_5types_bits32 __pyx_t_1;
+  __pyx_t_2bx_3bbi_5types_bits32 __pyx_t_2;
+  __pyx_t_2bx_3bbi_5types_bits32 __pyx_t_3;
+  __pyx_t_2bx_3bbi_5types_bits32 __pyx_t_4;
+  int __pyx_t_5;
+  int __pyx_t_6;
+  int __pyx_t_7;
+  PyObject *__pyx_t_8 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("overlaps", 0);
+
+  /* "bx/bbi/cirtree_file.pyx":19
+ * 
+ * cdef overlaps( qchrom, qstart, qend, rstartchrom, rstartbase, rendchrom, rendbase ):
+ *     return ( ovcmp( qchrom, qstart, rendchrom, rendbase ) > 0 ) and \             # <<<<<<<<<<<<<<
+ *            ( ovcmp( qchrom, qend, rstartchrom, rstartbase ) < 0 )
+ * 
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = __Pyx_PyInt_AsUnsignedInt(__pyx_v_qchrom); if (unlikely((__pyx_t_1 == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 19; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = __Pyx_PyInt_AsUnsignedInt(__pyx_v_qstart); if (unlikely((__pyx_t_2 == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 19; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = __Pyx_PyInt_AsUnsignedInt(__pyx_v_rendchrom); if (unlikely((__pyx_t_3 == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 19; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_4 = __Pyx_PyInt_AsUnsignedInt(__pyx_v_rendbase); if (unlikely((__pyx_t_4 == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 19; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_5 = (__pyx_f_2bx_3bbi_12cirtree_file_ovcmp(__pyx_t_1, __pyx_t_2, __pyx_t_3, __pyx_t_4) > 0);
+  if (__pyx_t_5) {
+
+    /* "bx/bbi/cirtree_file.pyx":20
+ * cdef overlaps( qchrom, qstart, qend, rstartchrom, rstartbase, rendchrom, rendbase ):
+ *     return ( ovcmp( qchrom, qstart, rendchrom, rendbase ) > 0 ) and \
+ *            ( ovcmp( qchrom, qend, rstartchrom, rstartbase ) < 0 )             # <<<<<<<<<<<<<<
+ * 
+ * cdef class CIRTreeFile:
+ */
+    __pyx_t_4 = __Pyx_PyInt_AsUnsignedInt(__pyx_v_qchrom); if (unlikely((__pyx_t_4 == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 20; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = __Pyx_PyInt_AsUnsignedInt(__pyx_v_qend); if (unlikely((__pyx_t_3 == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 20; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = __Pyx_PyInt_AsUnsignedInt(__pyx_v_rstartchrom); if (unlikely((__pyx_t_2 == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 20; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = __Pyx_PyInt_AsUnsignedInt(__pyx_v_rstartbase); if (unlikely((__pyx_t_1 == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 20; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_6 = (__pyx_f_2bx_3bbi_12cirtree_file_ovcmp(__pyx_t_4, __pyx_t_3, __pyx_t_2, __pyx_t_1) < 0);
+    __pyx_t_7 = __pyx_t_6;
+  } else {
+    __pyx_t_7 = __pyx_t_5;
+  }
+  __pyx_t_8 = __Pyx_PyBool_FromLong(__pyx_t_7); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 19; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_8);
+  __pyx_r = __pyx_t_8;
+  __pyx_t_8 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_8);
+  __Pyx_AddTraceback("bx.bbi.cirtree_file.overlaps", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_2bx_3bbi_12cirtree_file_11CIRTreeFile_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static int __pyx_pw_2bx_3bbi_12cirtree_file_11CIRTreeFile_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_file = 0;
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__init__ (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__file,0};
+    PyObject* values[1] = {0};
+
+    /* "bx/bbi/cirtree_file.pyx":24
+ * cdef class CIRTreeFile:
+ * 
+ *     def __init__( self, file=None ):             # <<<<<<<<<<<<<<
+ *         if file is not None:
+ *             self.attach( file )
+ */
+    values[0] = ((PyObject *)Py_None);
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s__file);
+          if (value) { values[0] = value; kw_args--; }
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 24; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else {
+      switch (PyTuple_GET_SIZE(__pyx_args)) {
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+    }
+    __pyx_v_file = values[0];
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("__init__", 0, 0, 1, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 24; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.bbi.cirtree_file.CIRTreeFile.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return -1;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_3bbi_12cirtree_file_11CIRTreeFile___init__(((struct __pyx_obj_2bx_3bbi_12cirtree_file_CIRTreeFile *)__pyx_v_self), __pyx_v_file);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_2bx_3bbi_12cirtree_file_11CIRTreeFile___init__(struct __pyx_obj_2bx_3bbi_12cirtree_file_CIRTreeFile *__pyx_v_self, PyObject *__pyx_v_file) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__init__", 0);
+
+  /* "bx/bbi/cirtree_file.pyx":25
+ * 
+ *     def __init__( self, file=None ):
+ *         if file is not None:             # <<<<<<<<<<<<<<
+ *             self.attach( file )
+ * 
+ */
+  __pyx_t_1 = (__pyx_v_file != Py_None);
+  if (__pyx_t_1) {
+
+    /* "bx/bbi/cirtree_file.pyx":26
+ *     def __init__( self, file=None ):
+ *         if file is not None:
+ *             self.attach( file )             # <<<<<<<<<<<<<<
+ * 
+ *     def attach( self, file ):
+ */
+    __pyx_t_2 = PyObject_GetAttr(((PyObject *)__pyx_v_self), __pyx_n_s__attach); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 26; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 26; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_INCREF(__pyx_v_file);
+    PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_file);
+    __Pyx_GIVEREF(__pyx_v_file);
+    __pyx_t_4 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 26; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_AddTraceback("bx.bbi.cirtree_file.CIRTreeFile.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = -1;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_3bbi_12cirtree_file_11CIRTreeFile_3attach(PyObject *__pyx_v_self, PyObject *__pyx_v_file); /*proto*/
+static char __pyx_doc_2bx_3bbi_12cirtree_file_11CIRTreeFile_2attach[] = "\n        Attach to an open file\n        ";
+static PyObject *__pyx_pw_2bx_3bbi_12cirtree_file_11CIRTreeFile_3attach(PyObject *__pyx_v_self, PyObject *__pyx_v_file) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("attach (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_3bbi_12cirtree_file_11CIRTreeFile_2attach(((struct __pyx_obj_2bx_3bbi_12cirtree_file_CIRTreeFile *)__pyx_v_self), ((PyObject *)__pyx_v_file));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bbi/cirtree_file.pyx":28
+ *             self.attach( file )
+ * 
+ *     def attach( self, file ):             # <<<<<<<<<<<<<<
+ *         """
+ *         Attach to an open file
+ */
+
+static PyObject *__pyx_pf_2bx_3bbi_12cirtree_file_11CIRTreeFile_2attach(struct __pyx_obj_2bx_3bbi_12cirtree_file_CIRTreeFile *__pyx_v_self, PyObject *__pyx_v_file) {
+  PyObject *__pyx_v_reader = NULL;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  __pyx_t_2bx_3bbi_5types_boolean __pyx_t_4;
+  __pyx_t_2bx_3bbi_5types_bits32 __pyx_t_5;
+  __pyx_t_2bx_3bbi_5types_bits64 __pyx_t_6;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("attach", 0);
+
+  /* "bx/bbi/cirtree_file.pyx":32
+ *         Attach to an open file
+ *         """
+ *         self.file = file             # <<<<<<<<<<<<<<
+ *         self.reader = reader = BinaryFileReader( file, cir_tree_sig )
+ *         self.is_byteswapped = self.reader.byteswap_needed
+ */
+  __Pyx_INCREF(__pyx_v_file);
+  __Pyx_GIVEREF(__pyx_v_file);
+  __Pyx_GOTREF(__pyx_v_self->file);
+  __Pyx_DECREF(__pyx_v_self->file);
+  __pyx_v_self->file = __pyx_v_file;
+
+  /* "bx/bbi/cirtree_file.pyx":33
+ *         """
+ *         self.file = file
+ *         self.reader = reader = BinaryFileReader( file, cir_tree_sig )             # <<<<<<<<<<<<<<
+ *         self.is_byteswapped = self.reader.byteswap_needed
+ *         # Header
+ */
+  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__BinaryFileReader); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 33; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 33; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_INCREF(__pyx_v_file);
+  PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_file);
+  __Pyx_GIVEREF(__pyx_v_file);
+  __Pyx_INCREF(__pyx_int_610839776);
+  PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_int_610839776);
+  __Pyx_GIVEREF(__pyx_int_610839776);
+  __pyx_t_3 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 33; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
+  __Pyx_INCREF(__pyx_t_3);
+  __Pyx_GIVEREF(__pyx_t_3);
+  __Pyx_GOTREF(__pyx_v_self->reader);
+  __Pyx_DECREF(__pyx_v_self->reader);
+  __pyx_v_self->reader = __pyx_t_3;
+  __Pyx_INCREF(__pyx_t_3);
+  __pyx_v_reader = __pyx_t_3;
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+  /* "bx/bbi/cirtree_file.pyx":34
+ *         self.file = file
+ *         self.reader = reader = BinaryFileReader( file, cir_tree_sig )
+ *         self.is_byteswapped = self.reader.byteswap_needed             # <<<<<<<<<<<<<<
+ *         # Header
+ *         self.block_size = reader.read_uint32()
+ */
+  __pyx_t_3 = PyObject_GetAttr(__pyx_v_self->reader, __pyx_n_s__byteswap_needed); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 34; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely((__pyx_t_4 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 34; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __pyx_v_self->is_byteswapped = __pyx_t_4;
+
+  /* "bx/bbi/cirtree_file.pyx":36
+ *         self.is_byteswapped = self.reader.byteswap_needed
+ *         # Header
+ *         self.block_size = reader.read_uint32()             # <<<<<<<<<<<<<<
+ *         self.item_count = reader.read_uint64()
+ *         self.start_chrom_ix  = reader.read_uint32()
+ */
+  __pyx_t_3 = PyObject_GetAttr(__pyx_v_reader, __pyx_n_s__read_uint32); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 36; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_2 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 36; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __pyx_t_5 = __Pyx_PyInt_AsUnsignedInt(__pyx_t_2); if (unlikely((__pyx_t_5 == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 36; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_v_self->block_size = __pyx_t_5;
+
+  /* "bx/bbi/cirtree_file.pyx":37
+ *         # Header
+ *         self.block_size = reader.read_uint32()
+ *         self.item_count = reader.read_uint64()             # <<<<<<<<<<<<<<
+ *         self.start_chrom_ix  = reader.read_uint32()
+ *         self.start_base = reader.read_uint32()
+ */
+  __pyx_t_2 = PyObject_GetAttr(__pyx_v_reader, __pyx_n_s__read_uint64); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 37; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 37; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_6 = __Pyx_PyInt_AsUnsignedLongLong(__pyx_t_3); if (unlikely((__pyx_t_6 == (unsigned PY_LONG_LONG)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 37; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __pyx_v_self->item_count = __pyx_t_6;
+
+  /* "bx/bbi/cirtree_file.pyx":38
+ *         self.block_size = reader.read_uint32()
+ *         self.item_count = reader.read_uint64()
+ *         self.start_chrom_ix  = reader.read_uint32()             # <<<<<<<<<<<<<<
+ *         self.start_base = reader.read_uint32()
+ *         self.end_chrom_ix = reader.read_uint32()
+ */
+  __pyx_t_3 = PyObject_GetAttr(__pyx_v_reader, __pyx_n_s__read_uint32); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 38; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_2 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 38; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __pyx_t_5 = __Pyx_PyInt_AsUnsignedInt(__pyx_t_2); if (unlikely((__pyx_t_5 == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 38; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_v_self->start_chrom_ix = __pyx_t_5;
+
+  /* "bx/bbi/cirtree_file.pyx":39
+ *         self.item_count = reader.read_uint64()
+ *         self.start_chrom_ix  = reader.read_uint32()
+ *         self.start_base = reader.read_uint32()             # <<<<<<<<<<<<<<
+ *         self.end_chrom_ix = reader.read_uint32()
+ *         self.end_base = reader.read_uint32()
+ */
+  __pyx_t_2 = PyObject_GetAttr(__pyx_v_reader, __pyx_n_s__read_uint32); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 39; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 39; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_5 = __Pyx_PyInt_AsUnsignedInt(__pyx_t_3); if (unlikely((__pyx_t_5 == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 39; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __pyx_v_self->start_base = __pyx_t_5;
+
+  /* "bx/bbi/cirtree_file.pyx":40
+ *         self.start_chrom_ix  = reader.read_uint32()
+ *         self.start_base = reader.read_uint32()
+ *         self.end_chrom_ix = reader.read_uint32()             # <<<<<<<<<<<<<<
+ *         self.end_base = reader.read_uint32()
+ *         self.file_size = reader.read_uint64()
+ */
+  __pyx_t_3 = PyObject_GetAttr(__pyx_v_reader, __pyx_n_s__read_uint32); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 40; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_2 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 40; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __pyx_t_5 = __Pyx_PyInt_AsUnsignedInt(__pyx_t_2); if (unlikely((__pyx_t_5 == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 40; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_v_self->end_chrom_ix = __pyx_t_5;
+
+  /* "bx/bbi/cirtree_file.pyx":41
+ *         self.start_base = reader.read_uint32()
+ *         self.end_chrom_ix = reader.read_uint32()
+ *         self.end_base = reader.read_uint32()             # <<<<<<<<<<<<<<
+ *         self.file_size = reader.read_uint64()
+ *         self.items_per_slot = reader.read_uint32()
+ */
+  __pyx_t_2 = PyObject_GetAttr(__pyx_v_reader, __pyx_n_s__read_uint32); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 41; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 41; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_5 = __Pyx_PyInt_AsUnsignedInt(__pyx_t_3); if (unlikely((__pyx_t_5 == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 41; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __pyx_v_self->end_base = __pyx_t_5;
+
+  /* "bx/bbi/cirtree_file.pyx":42
+ *         self.end_chrom_ix = reader.read_uint32()
+ *         self.end_base = reader.read_uint32()
+ *         self.file_size = reader.read_uint64()             # <<<<<<<<<<<<<<
+ *         self.items_per_slot = reader.read_uint32()
+ *         # Skip reserved
+ */
+  __pyx_t_3 = PyObject_GetAttr(__pyx_v_reader, __pyx_n_s__read_uint64); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 42; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_2 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 42; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __pyx_t_6 = __Pyx_PyInt_AsUnsignedLongLong(__pyx_t_2); if (unlikely((__pyx_t_6 == (unsigned PY_LONG_LONG)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 42; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_v_self->file_size = __pyx_t_6;
+
+  /* "bx/bbi/cirtree_file.pyx":43
+ *         self.end_base = reader.read_uint32()
+ *         self.file_size = reader.read_uint64()
+ *         self.items_per_slot = reader.read_uint32()             # <<<<<<<<<<<<<<
+ *         # Skip reserved
+ *         reader.read_uint32()
+ */
+  __pyx_t_2 = PyObject_GetAttr(__pyx_v_reader, __pyx_n_s__read_uint32); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 43; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 43; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_5 = __Pyx_PyInt_AsUnsignedInt(__pyx_t_3); if (unlikely((__pyx_t_5 == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 43; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __pyx_v_self->items_per_slot = __pyx_t_5;
+
+  /* "bx/bbi/cirtree_file.pyx":45
+ *         self.items_per_slot = reader.read_uint32()
+ *         # Skip reserved
+ *         reader.read_uint32()             # <<<<<<<<<<<<<<
+ *         # Save root
+ *         self.root_offset = reader.tell()
+ */
+  __pyx_t_3 = PyObject_GetAttr(__pyx_v_reader, __pyx_n_s__read_uint32); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 45; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_2 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 45; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+  /* "bx/bbi/cirtree_file.pyx":47
+ *         reader.read_uint32()
+ *         # Save root
+ *         self.root_offset = reader.tell()             # <<<<<<<<<<<<<<
+ * 
+ *     def r_find_overlapping( self, int level, bits64 index_file_offset, bits32 chrom_ix, bits32 start, bits32 end, object rval, object reader ):
+ */
+  __pyx_t_2 = PyObject_GetAttr(__pyx_v_reader, __pyx_n_s__tell); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 47; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 47; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_6 = __Pyx_PyInt_AsUnsignedLongLong(__pyx_t_3); if (unlikely((__pyx_t_6 == (unsigned PY_LONG_LONG)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 47; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __pyx_v_self->root_offset = __pyx_t_6;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_AddTraceback("bx.bbi.cirtree_file.CIRTreeFile.attach", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_reader);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_3bbi_12cirtree_file_11CIRTreeFile_5r_find_overlapping(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyObject *__pyx_pw_2bx_3bbi_12cirtree_file_11CIRTreeFile_5r_find_overlapping(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  int __pyx_v_level;
+  __pyx_t_2bx_3bbi_5types_bits64 __pyx_v_index_file_offset;
+  __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_chrom_ix;
+  __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_start;
+  __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_end;
+  PyObject *__pyx_v_rval = 0;
+  PyObject *__pyx_v_reader = 0;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("r_find_overlapping (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__level,&__pyx_n_s__index_file_offset,&__pyx_n_s__chrom_ix,&__pyx_n_s__start,&__pyx_n_s__end,&__pyx_n_s__rval,&__pyx_n_s__reader,0};
+    PyObject* values[7] = {0,0,0,0,0,0,0};
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+        case  6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+        case  5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+        case  4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__level)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__index_file_offset)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("r_find_overlapping", 1, 7, 7, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 49; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+        case  2:
+        if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__chrom_ix)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("r_find_overlapping", 1, 7, 7, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 49; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+        case  3:
+        if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__start)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("r_find_overlapping", 1, 7, 7, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 49; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+        case  4:
+        if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__end)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("r_find_overlapping", 1, 7, 7, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 49; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+        case  5:
+        if (likely((values[5] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__rval)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("r_find_overlapping", 1, 7, 7, 5); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 49; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+        case  6:
+        if (likely((values[6] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__reader)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("r_find_overlapping", 1, 7, 7, 6); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 49; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "r_find_overlapping") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 49; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else if (PyTuple_GET_SIZE(__pyx_args) != 7) {
+      goto __pyx_L5_argtuple_error;
+    } else {
+      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+      values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+      values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+      values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+      values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+      values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+    }
+    __pyx_v_level = __Pyx_PyInt_AsInt(values[0]); if (unlikely((__pyx_v_level == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 49; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_index_file_offset = __Pyx_PyInt_AsUnsignedLongLong(values[1]); if (unlikely((__pyx_v_index_file_offset == (unsigned PY_LONG_LONG)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 49; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_chrom_ix = __Pyx_PyInt_AsUnsignedInt(values[2]); if (unlikely((__pyx_v_chrom_ix == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 49; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_start = __Pyx_PyInt_AsUnsignedInt(values[3]); if (unlikely((__pyx_v_start == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 49; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_end = __Pyx_PyInt_AsUnsignedInt(values[4]); if (unlikely((__pyx_v_end == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 49; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_rval = values[5];
+    __pyx_v_reader = values[6];
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("r_find_overlapping", 1, 7, 7, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 49; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.bbi.cirtree_file.CIRTreeFile.r_find_overlapping", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_3bbi_12cirtree_file_11CIRTreeFile_4r_find_overlapping(((struct __pyx_obj_2bx_3bbi_12cirtree_file_CIRTreeFile *)__pyx_v_self), __pyx_v_level, __pyx_v_index_file_offset, __pyx_v_chrom_ix, __pyx_v_start, __pyx_v_end, __pyx_v_rval, __pyx_v_reader);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bbi/cirtree_file.pyx":49
+ *         self.root_offset = reader.tell()
+ * 
+ *     def r_find_overlapping( self, int level, bits64 index_file_offset, bits32 chrom_ix, bits32 start, bits32 end, object rval, object reader ):             # <<<<<<<<<<<<<<
+ *         cdef UBYTE is_leaf
+ *         cdef bits16 child_count
+ */
+
+static PyObject *__pyx_pf_2bx_3bbi_12cirtree_file_11CIRTreeFile_4r_find_overlapping(struct __pyx_obj_2bx_3bbi_12cirtree_file_CIRTreeFile *__pyx_v_self, int __pyx_v_level, __pyx_t_2bx_3bbi_5types_bits64 __pyx_v_index_file_offset, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_chrom_ix, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_start, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_end, PyObject *__pyx_v_rval, PyObject *__pyx_v_reader) {
+  __pyx_t_2bx_3bbi_5types_UBYTE __pyx_v_is_leaf;
+  __pyx_t_2bx_3bbi_5types_bits16 __pyx_v_child_count;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  __pyx_t_2bx_3bbi_5types_UBYTE __pyx_t_4;
+  int __pyx_t_5;
+  __pyx_t_2bx_3bbi_5types_bits16 __pyx_t_6;
+  PyObject *__pyx_t_7 = NULL;
+  PyObject *__pyx_t_8 = NULL;
+  PyObject *__pyx_t_9 = NULL;
+  PyObject *__pyx_t_10 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("r_find_overlapping", 0);
+
+  /* "bx/bbi/cirtree_file.pyx":52
+ *         cdef UBYTE is_leaf
+ *         cdef bits16 child_count
+ *         reader.seek( index_file_offset )             # <<<<<<<<<<<<<<
+ *         # Block header
+ *         is_leaf = reader.read_uint8()
+ */
+  __pyx_t_1 = PyObject_GetAttr(__pyx_v_reader, __pyx_n_s__seek); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 52; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = PyLong_FromUnsignedLongLong(__pyx_v_index_file_offset); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 52; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 52; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_2);
+  __Pyx_GIVEREF(__pyx_t_2);
+  __pyx_t_2 = 0;
+  __pyx_t_2 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 52; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+  /* "bx/bbi/cirtree_file.pyx":54
+ *         reader.seek( index_file_offset )
+ *         # Block header
+ *         is_leaf = reader.read_uint8()             # <<<<<<<<<<<<<<
+ *         assert is_leaf == 0 or is_leaf == 1
+ *         reader.read_uint8()
+ */
+  __pyx_t_2 = PyObject_GetAttr(__pyx_v_reader, __pyx_n_s__read_uint8); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 54; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 54; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_4 = __Pyx_PyInt_AsUnsignedChar(__pyx_t_3); if (unlikely((__pyx_t_4 == (unsigned char)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 54; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __pyx_v_is_leaf = __pyx_t_4;
+
+  /* "bx/bbi/cirtree_file.pyx":55
+ *         # Block header
+ *         is_leaf = reader.read_uint8()
+ *         assert is_leaf == 0 or is_leaf == 1             # <<<<<<<<<<<<<<
+ *         reader.read_uint8()
+ *         child_count = reader.read_uint16()
+ */
+  #ifndef CYTHON_WITHOUT_ASSERTIONS
+  switch (__pyx_v_is_leaf) {
+    case 0:
+    case 1:
+    __pyx_t_5 = 1;
+    break;
+    default:
+    __pyx_t_5 = 0;
+    break;
+  }
+  if (unlikely(!__pyx_t_5)) {
+    PyErr_SetNone(PyExc_AssertionError);
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 55; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  #endif
+
+  /* "bx/bbi/cirtree_file.pyx":56
+ *         is_leaf = reader.read_uint8()
+ *         assert is_leaf == 0 or is_leaf == 1
+ *         reader.read_uint8()             # <<<<<<<<<<<<<<
+ *         child_count = reader.read_uint16()
+ *         # Read block
+ */
+  __pyx_t_3 = PyObject_GetAttr(__pyx_v_reader, __pyx_n_s__read_uint8); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 56; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_2 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 56; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+  /* "bx/bbi/cirtree_file.pyx":57
+ *         assert is_leaf == 0 or is_leaf == 1
+ *         reader.read_uint8()
+ *         child_count = reader.read_uint16()             # <<<<<<<<<<<<<<
+ *         # Read block
+ *         if is_leaf:
+ */
+  __pyx_t_2 = PyObject_GetAttr(__pyx_v_reader, __pyx_n_s__read_uint16); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 57; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 57; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_6 = __Pyx_PyInt_AsUnsignedShort(__pyx_t_3); if (unlikely((__pyx_t_6 == (unsigned short)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 57; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __pyx_v_child_count = __pyx_t_6;
+
+  /* "bx/bbi/cirtree_file.pyx":59
+ *         child_count = reader.read_uint16()
+ *         # Read block
+ *         if is_leaf:             # <<<<<<<<<<<<<<
+ *             self.r_find_overlapping_leaf( level, chrom_ix, start, end, rval, child_count, reader )
+ *         else:
+ */
+  if (__pyx_v_is_leaf) {
+
+    /* "bx/bbi/cirtree_file.pyx":60
+ *         # Read block
+ *         if is_leaf:
+ *             self.r_find_overlapping_leaf( level, chrom_ix, start, end, rval, child_count, reader )             # <<<<<<<<<<<<<<
+ *         else:
+ *             self.r_find_overlapping_parent( level, chrom_ix, start, end, rval, child_count, reader )
+ */
+    __pyx_t_3 = PyObject_GetAttr(((PyObject *)__pyx_v_self), __pyx_n_s_1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 60; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __pyx_t_2 = PyInt_FromLong(__pyx_v_level); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 60; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_t_1 = PyLong_FromUnsignedLong(__pyx_v_chrom_ix); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 60; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __pyx_t_7 = PyLong_FromUnsignedLong(__pyx_v_start); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 60; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_7);
+    __pyx_t_8 = PyLong_FromUnsignedLong(__pyx_v_end); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 60; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_8);
+    __pyx_t_9 = PyInt_FromLong(__pyx_v_child_count); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 60; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_9);
+    __pyx_t_10 = PyTuple_New(7); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 60; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_10);
+    PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_2);
+    __Pyx_GIVEREF(__pyx_t_2);
+    PyTuple_SET_ITEM(__pyx_t_10, 1, __pyx_t_1);
+    __Pyx_GIVEREF(__pyx_t_1);
+    PyTuple_SET_ITEM(__pyx_t_10, 2, __pyx_t_7);
+    __Pyx_GIVEREF(__pyx_t_7);
+    PyTuple_SET_ITEM(__pyx_t_10, 3, __pyx_t_8);
+    __Pyx_GIVEREF(__pyx_t_8);
+    __Pyx_INCREF(__pyx_v_rval);
+    PyTuple_SET_ITEM(__pyx_t_10, 4, __pyx_v_rval);
+    __Pyx_GIVEREF(__pyx_v_rval);
+    PyTuple_SET_ITEM(__pyx_t_10, 5, __pyx_t_9);
+    __Pyx_GIVEREF(__pyx_t_9);
+    __Pyx_INCREF(__pyx_v_reader);
+    PyTuple_SET_ITEM(__pyx_t_10, 6, __pyx_v_reader);
+    __Pyx_GIVEREF(__pyx_v_reader);
+    __pyx_t_2 = 0;
+    __pyx_t_1 = 0;
+    __pyx_t_7 = 0;
+    __pyx_t_8 = 0;
+    __pyx_t_9 = 0;
+    __pyx_t_9 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_t_10), NULL); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 60; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_9);
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __Pyx_DECREF(((PyObject *)__pyx_t_10)); __pyx_t_10 = 0;
+    __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+    goto __pyx_L3;
+  }
+  /*else*/ {
+
+    /* "bx/bbi/cirtree_file.pyx":62
+ *             self.r_find_overlapping_leaf( level, chrom_ix, start, end, rval, child_count, reader )
+ *         else:
+ *             self.r_find_overlapping_parent( level, chrom_ix, start, end, rval, child_count, reader )             # <<<<<<<<<<<<<<
+ * 
+ *     def r_find_overlapping_leaf( self, int level, bits32 chrom_ix, bits32 start, bits32 end, object rval,
+ */
+    __pyx_t_9 = PyObject_GetAttr(((PyObject *)__pyx_v_self), __pyx_n_s_2); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 62; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_9);
+    __pyx_t_10 = PyInt_FromLong(__pyx_v_level); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 62; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_10);
+    __pyx_t_3 = PyLong_FromUnsignedLong(__pyx_v_chrom_ix); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 62; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __pyx_t_8 = PyLong_FromUnsignedLong(__pyx_v_start); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 62; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_8);
+    __pyx_t_7 = PyLong_FromUnsignedLong(__pyx_v_end); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 62; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_7);
+    __pyx_t_1 = PyInt_FromLong(__pyx_v_child_count); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 62; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __pyx_t_2 = PyTuple_New(7); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 62; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_10);
+    __Pyx_GIVEREF(__pyx_t_10);
+    PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_3);
+    __Pyx_GIVEREF(__pyx_t_3);
+    PyTuple_SET_ITEM(__pyx_t_2, 2, __pyx_t_8);
+    __Pyx_GIVEREF(__pyx_t_8);
+    PyTuple_SET_ITEM(__pyx_t_2, 3, __pyx_t_7);
+    __Pyx_GIVEREF(__pyx_t_7);
+    __Pyx_INCREF(__pyx_v_rval);
+    PyTuple_SET_ITEM(__pyx_t_2, 4, __pyx_v_rval);
+    __Pyx_GIVEREF(__pyx_v_rval);
+    PyTuple_SET_ITEM(__pyx_t_2, 5, __pyx_t_1);
+    __Pyx_GIVEREF(__pyx_t_1);
+    __Pyx_INCREF(__pyx_v_reader);
+    PyTuple_SET_ITEM(__pyx_t_2, 6, __pyx_v_reader);
+    __Pyx_GIVEREF(__pyx_v_reader);
+    __pyx_t_10 = 0;
+    __pyx_t_3 = 0;
+    __pyx_t_8 = 0;
+    __pyx_t_7 = 0;
+    __pyx_t_1 = 0;
+    __pyx_t_1 = PyObject_Call(__pyx_t_9, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 62; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+    __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  }
+  __pyx_L3:;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_7);
+  __Pyx_XDECREF(__pyx_t_8);
+  __Pyx_XDECREF(__pyx_t_9);
+  __Pyx_XDECREF(__pyx_t_10);
+  __Pyx_AddTraceback("bx.bbi.cirtree_file.CIRTreeFile.r_find_overlapping", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_3bbi_12cirtree_file_11CIRTreeFile_7r_find_overlapping_leaf(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyObject *__pyx_pw_2bx_3bbi_12cirtree_file_11CIRTreeFile_7r_find_overlapping_leaf(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  CYTHON_UNUSED int __pyx_v_level;
+  __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_chrom_ix;
+  __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_start;
+  __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_end;
+  PyObject *__pyx_v_rval = 0;
+  __pyx_t_2bx_3bbi_5types_bits16 __pyx_v_child_count;
+  PyObject *__pyx_v_reader = 0;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("r_find_overlapping_leaf (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__level,&__pyx_n_s__chrom_ix,&__pyx_n_s__start,&__pyx_n_s__end,&__pyx_n_s__rval,&__pyx_n_s__child_count,&__pyx_n_s__reader,0};
+    PyObject* values[7] = {0,0,0,0,0,0,0};
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+        case  6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+        case  5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+        case  4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__level)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__chrom_ix)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("r_find_overlapping_leaf", 1, 7, 7, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 64; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+        case  2:
+        if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__start)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("r_find_overlapping_leaf", 1, 7, 7, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 64; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+        case  3:
+        if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__end)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("r_find_overlapping_leaf", 1, 7, 7, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 64; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+        case  4:
+        if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__rval)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("r_find_overlapping_leaf", 1, 7, 7, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 64; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+        case  5:
+        if (likely((values[5] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__child_count)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("r_find_overlapping_leaf", 1, 7, 7, 5); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 64; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+        case  6:
+        if (likely((values[6] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__reader)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("r_find_overlapping_leaf", 1, 7, 7, 6); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 64; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "r_find_overlapping_leaf") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 64; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else if (PyTuple_GET_SIZE(__pyx_args) != 7) {
+      goto __pyx_L5_argtuple_error;
+    } else {
+      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+      values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+      values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+      values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+      values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+      values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+    }
+    __pyx_v_level = __Pyx_PyInt_AsInt(values[0]); if (unlikely((__pyx_v_level == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 64; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_chrom_ix = __Pyx_PyInt_AsUnsignedInt(values[1]); if (unlikely((__pyx_v_chrom_ix == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 64; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_start = __Pyx_PyInt_AsUnsignedInt(values[2]); if (unlikely((__pyx_v_start == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 64; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_end = __Pyx_PyInt_AsUnsignedInt(values[3]); if (unlikely((__pyx_v_end == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 64; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_rval = values[4];
+    __pyx_v_child_count = __Pyx_PyInt_AsUnsignedShort(values[5]); if (unlikely((__pyx_v_child_count == (unsigned short)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 65; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_reader = values[6];
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("r_find_overlapping_leaf", 1, 7, 7, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 64; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.bbi.cirtree_file.CIRTreeFile.r_find_overlapping_leaf", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_3bbi_12cirtree_file_11CIRTreeFile_6r_find_overlapping_leaf(((struct __pyx_obj_2bx_3bbi_12cirtree_file_CIRTreeFile *)__pyx_v_self), __pyx_v_level, __pyx_v_chrom_ix, __pyx_v_start, __pyx_v_end, __pyx_v_rval, __pyx_v_child_count, __pyx_v_reader);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bbi/cirtree_file.pyx":64
+ *             self.r_find_overlapping_parent( level, chrom_ix, start, end, rval, child_count, reader )
+ * 
+ *     def r_find_overlapping_leaf( self, int level, bits32 chrom_ix, bits32 start, bits32 end, object rval,             # <<<<<<<<<<<<<<
+ *                                 bits16 child_count, object reader ):
+ *         cdef bits32 start_chrom_ix, start_base, end_chrom_ix, end_base
+ */
+
+static PyObject *__pyx_pf_2bx_3bbi_12cirtree_file_11CIRTreeFile_6r_find_overlapping_leaf(CYTHON_UNUSED struct __pyx_obj_2bx_3bbi_12cirtree_file_CIRTreeFile *__pyx_v_self, CYTHON_UNUSED int __pyx_v_level, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_chrom_ix, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_start, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_end, PyObject *__pyx_v_rval, __pyx_t_2bx_3bbi_5types_bits16 __pyx_v_child_count, PyObject *__pyx_v_reader) {
+  __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_start_chrom_ix;
+  __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_start_base;
+  __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_end_chrom_ix;
+  __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_end_base;
+  __pyx_t_2bx_3bbi_5types_bits64 __pyx_v_offset;
+  __pyx_t_2bx_3bbi_5types_bits64 __pyx_v_size;
+  CYTHON_UNUSED long __pyx_v_i;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  __pyx_t_2bx_3bbi_5types_bits16 __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  __pyx_t_2bx_3bbi_5types_bits32 __pyx_t_4;
+  __pyx_t_2bx_3bbi_5types_bits64 __pyx_t_5;
+  PyObject *__pyx_t_6 = NULL;
+  PyObject *__pyx_t_7 = NULL;
+  PyObject *__pyx_t_8 = NULL;
+  PyObject *__pyx_t_9 = NULL;
+  PyObject *__pyx_t_10 = NULL;
+  PyObject *__pyx_t_11 = NULL;
+  int __pyx_t_12;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("r_find_overlapping_leaf", 0);
+
+  /* "bx/bbi/cirtree_file.pyx":69
+ *         cdef bits64 offset
+ *         cdef bits64 size
+ *         for i from 0 <= i < child_count:             # <<<<<<<<<<<<<<
+ *             start_chrom_ix = reader.read_uint32()
+ *             start_base = reader.read_uint32()
+ */
+  __pyx_t_1 = __pyx_v_child_count;
+  for (__pyx_v_i = 0; __pyx_v_i < __pyx_t_1; __pyx_v_i++) {
+
+    /* "bx/bbi/cirtree_file.pyx":70
+ *         cdef bits64 size
+ *         for i from 0 <= i < child_count:
+ *             start_chrom_ix = reader.read_uint32()             # <<<<<<<<<<<<<<
+ *             start_base = reader.read_uint32()
+ *             end_chrom_ix = reader.read_uint32()
+ */
+    __pyx_t_2 = PyObject_GetAttr(__pyx_v_reader, __pyx_n_s__read_uint32); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 70; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_t_3 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 70; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    __pyx_t_4 = __Pyx_PyInt_AsUnsignedInt(__pyx_t_3); if (unlikely((__pyx_t_4 == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 70; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __pyx_v_start_chrom_ix = __pyx_t_4;
+
+    /* "bx/bbi/cirtree_file.pyx":71
+ *         for i from 0 <= i < child_count:
+ *             start_chrom_ix = reader.read_uint32()
+ *             start_base = reader.read_uint32()             # <<<<<<<<<<<<<<
+ *             end_chrom_ix = reader.read_uint32()
+ *             end_base = reader.read_uint32()
+ */
+    __pyx_t_3 = PyObject_GetAttr(__pyx_v_reader, __pyx_n_s__read_uint32); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 71; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __pyx_t_2 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 71; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __pyx_t_4 = __Pyx_PyInt_AsUnsignedInt(__pyx_t_2); if (unlikely((__pyx_t_4 == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 71; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    __pyx_v_start_base = __pyx_t_4;
+
+    /* "bx/bbi/cirtree_file.pyx":72
+ *             start_chrom_ix = reader.read_uint32()
+ *             start_base = reader.read_uint32()
+ *             end_chrom_ix = reader.read_uint32()             # <<<<<<<<<<<<<<
+ *             end_base = reader.read_uint32()
+ *             offset = reader.read_uint64()
+ */
+    __pyx_t_2 = PyObject_GetAttr(__pyx_v_reader, __pyx_n_s__read_uint32); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 72; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_t_3 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 72; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    __pyx_t_4 = __Pyx_PyInt_AsUnsignedInt(__pyx_t_3); if (unlikely((__pyx_t_4 == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 72; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __pyx_v_end_chrom_ix = __pyx_t_4;
+
+    /* "bx/bbi/cirtree_file.pyx":73
+ *             start_base = reader.read_uint32()
+ *             end_chrom_ix = reader.read_uint32()
+ *             end_base = reader.read_uint32()             # <<<<<<<<<<<<<<
+ *             offset = reader.read_uint64()
+ *             size = reader.read_uint64()
+ */
+    __pyx_t_3 = PyObject_GetAttr(__pyx_v_reader, __pyx_n_s__read_uint32); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 73; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __pyx_t_2 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 73; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __pyx_t_4 = __Pyx_PyInt_AsUnsignedInt(__pyx_t_2); if (unlikely((__pyx_t_4 == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 73; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    __pyx_v_end_base = __pyx_t_4;
+
+    /* "bx/bbi/cirtree_file.pyx":74
+ *             end_chrom_ix = reader.read_uint32()
+ *             end_base = reader.read_uint32()
+ *             offset = reader.read_uint64()             # <<<<<<<<<<<<<<
+ *             size = reader.read_uint64()
+ *             if overlaps( chrom_ix, start, end, start_chrom_ix, start_base, end_chrom_ix, end_base ):
+ */
+    __pyx_t_2 = PyObject_GetAttr(__pyx_v_reader, __pyx_n_s__read_uint64); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 74; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_t_3 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 74; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    __pyx_t_5 = __Pyx_PyInt_AsUnsignedLongLong(__pyx_t_3); if (unlikely((__pyx_t_5 == (unsigned PY_LONG_LONG)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 74; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __pyx_v_offset = __pyx_t_5;
+
+    /* "bx/bbi/cirtree_file.pyx":75
+ *             end_base = reader.read_uint32()
+ *             offset = reader.read_uint64()
+ *             size = reader.read_uint64()             # <<<<<<<<<<<<<<
+ *             if overlaps( chrom_ix, start, end, start_chrom_ix, start_base, end_chrom_ix, end_base ):
+ *                 rval.append( ( offset, size ) )
+ */
+    __pyx_t_3 = PyObject_GetAttr(__pyx_v_reader, __pyx_n_s__read_uint64); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 75; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __pyx_t_2 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 75; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __pyx_t_5 = __Pyx_PyInt_AsUnsignedLongLong(__pyx_t_2); if (unlikely((__pyx_t_5 == (unsigned PY_LONG_LONG)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 75; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    __pyx_v_size = __pyx_t_5;
+
+    /* "bx/bbi/cirtree_file.pyx":76
+ *             offset = reader.read_uint64()
+ *             size = reader.read_uint64()
+ *             if overlaps( chrom_ix, start, end, start_chrom_ix, start_base, end_chrom_ix, end_base ):             # <<<<<<<<<<<<<<
+ *                 rval.append( ( offset, size ) )
+ * 
+ */
+    __pyx_t_2 = PyLong_FromUnsignedLong(__pyx_v_chrom_ix); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 76; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_t_3 = PyLong_FromUnsignedLong(__pyx_v_start); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 76; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __pyx_t_6 = PyLong_FromUnsignedLong(__pyx_v_end); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 76; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_6);
+    __pyx_t_7 = PyLong_FromUnsignedLong(__pyx_v_start_chrom_ix); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 76; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_7);
+    __pyx_t_8 = PyLong_FromUnsignedLong(__pyx_v_start_base); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 76; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_8);
+    __pyx_t_9 = PyLong_FromUnsignedLong(__pyx_v_end_chrom_ix); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 76; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_9);
+    __pyx_t_10 = PyLong_FromUnsignedLong(__pyx_v_end_base); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 76; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_10);
+    __pyx_t_11 = __pyx_f_2bx_3bbi_12cirtree_file_overlaps(__pyx_t_2, __pyx_t_3, __pyx_t_6, __pyx_t_7, __pyx_t_8, __pyx_t_9, __pyx_t_10); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 76; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_11);
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+    __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+    __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+    __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+    __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+    __pyx_t_12 = __Pyx_PyObject_IsTrue(__pyx_t_11); if (unlikely(__pyx_t_12 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 76; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+    if (__pyx_t_12) {
+
+      /* "bx/bbi/cirtree_file.pyx":77
+ *             size = reader.read_uint64()
+ *             if overlaps( chrom_ix, start, end, start_chrom_ix, start_base, end_chrom_ix, end_base ):
+ *                 rval.append( ( offset, size ) )             # <<<<<<<<<<<<<<
+ * 
+ *     def r_find_overlapping_parent( self, int level, bits32 chrom_ix, bits32 start, bits32 end, object rval,
+ */
+      __pyx_t_11 = PyLong_FromUnsignedLongLong(__pyx_v_offset); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 77; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_11);
+      __pyx_t_10 = PyLong_FromUnsignedLongLong(__pyx_v_size); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 77; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_10);
+      __pyx_t_9 = PyTuple_New(2); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 77; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_9);
+      PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_11);
+      __Pyx_GIVEREF(__pyx_t_11);
+      PyTuple_SET_ITEM(__pyx_t_9, 1, __pyx_t_10);
+      __Pyx_GIVEREF(__pyx_t_10);
+      __pyx_t_11 = 0;
+      __pyx_t_10 = 0;
+      __pyx_t_10 = __Pyx_PyObject_Append(__pyx_v_rval, ((PyObject *)__pyx_t_9)); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 77; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_10);
+      __Pyx_DECREF(((PyObject *)__pyx_t_9)); __pyx_t_9 = 0;
+      __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+      goto __pyx_L5;
+    }
+    __pyx_L5:;
+  }
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_6);
+  __Pyx_XDECREF(__pyx_t_7);
+  __Pyx_XDECREF(__pyx_t_8);
+  __Pyx_XDECREF(__pyx_t_9);
+  __Pyx_XDECREF(__pyx_t_10);
+  __Pyx_XDECREF(__pyx_t_11);
+  __Pyx_AddTraceback("bx.bbi.cirtree_file.CIRTreeFile.r_find_overlapping_leaf", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_3bbi_12cirtree_file_11CIRTreeFile_9r_find_overlapping_parent(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyObject *__pyx_pw_2bx_3bbi_12cirtree_file_11CIRTreeFile_9r_find_overlapping_parent(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  int __pyx_v_level;
+  __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_chrom_ix;
+  __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_start;
+  __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_end;
+  PyObject *__pyx_v_rval = 0;
+  __pyx_t_2bx_3bbi_5types_bits16 __pyx_v_child_count;
+  PyObject *__pyx_v_reader = 0;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("r_find_overlapping_parent (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__level,&__pyx_n_s__chrom_ix,&__pyx_n_s__start,&__pyx_n_s__end,&__pyx_n_s__rval,&__pyx_n_s__child_count,&__pyx_n_s__reader,0};
+    PyObject* values[7] = {0,0,0,0,0,0,0};
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+        case  6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+        case  5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+        case  4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__level)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__chrom_ix)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("r_find_overlapping_parent", 1, 7, 7, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 79; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+        case  2:
+        if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__start)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("r_find_overlapping_parent", 1, 7, 7, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 79; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+        case  3:
+        if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__end)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("r_find_overlapping_parent", 1, 7, 7, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 79; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+        case  4:
+        if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__rval)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("r_find_overlapping_parent", 1, 7, 7, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 79; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+        case  5:
+        if (likely((values[5] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__child_count)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("r_find_overlapping_parent", 1, 7, 7, 5); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 79; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+        case  6:
+        if (likely((values[6] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__reader)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("r_find_overlapping_parent", 1, 7, 7, 6); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 79; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "r_find_overlapping_parent") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 79; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else if (PyTuple_GET_SIZE(__pyx_args) != 7) {
+      goto __pyx_L5_argtuple_error;
+    } else {
+      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+      values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+      values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+      values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+      values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+      values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+    }
+    __pyx_v_level = __Pyx_PyInt_AsInt(values[0]); if (unlikely((__pyx_v_level == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 79; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_chrom_ix = __Pyx_PyInt_AsUnsignedInt(values[1]); if (unlikely((__pyx_v_chrom_ix == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 79; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_start = __Pyx_PyInt_AsUnsignedInt(values[2]); if (unlikely((__pyx_v_start == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 79; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_end = __Pyx_PyInt_AsUnsignedInt(values[3]); if (unlikely((__pyx_v_end == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 79; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_rval = values[4];
+    __pyx_v_child_count = __Pyx_PyInt_AsUnsignedShort(values[5]); if (unlikely((__pyx_v_child_count == (unsigned short)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 80; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_reader = values[6];
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("r_find_overlapping_parent", 1, 7, 7, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 79; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.bbi.cirtree_file.CIRTreeFile.r_find_overlapping_parent", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_3bbi_12cirtree_file_11CIRTreeFile_8r_find_overlapping_parent(((struct __pyx_obj_2bx_3bbi_12cirtree_file_CIRTreeFile *)__pyx_v_self), __pyx_v_level, __pyx_v_chrom_ix, __pyx_v_start, __pyx_v_end, __pyx_v_rval, __pyx_v_child_count, __pyx_v_reader);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bbi/cirtree_file.pyx":79
+ *                 rval.append( ( offset, size ) )
+ * 
+ *     def r_find_overlapping_parent( self, int level, bits32 chrom_ix, bits32 start, bits32 end, object rval,             # <<<<<<<<<<<<<<
+ *                                   bits16 child_count, object reader ):
+ *         # Read and cache offsets for all children to avoid excessive seeking
+ */
+
+static PyObject *__pyx_pf_2bx_3bbi_12cirtree_file_11CIRTreeFile_8r_find_overlapping_parent(struct __pyx_obj_2bx_3bbi_12cirtree_file_CIRTreeFile *__pyx_v_self, int __pyx_v_level, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_chrom_ix, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_start, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_end, PyObject *__pyx_v_rval, __pyx_t_2bx_3bbi_5types_bits16 __pyx_v_child_count, PyObject *__pyx_v_reader) {
+  PyObject *__pyx_v_start_chrom_ix = NULL;
+  PyObject *__pyx_v_start_base = NULL;
+  PyObject *__pyx_v_end_chrom_ix = NULL;
+  PyObject *__pyx_v_end_base = NULL;
+  PyObject *__pyx_v_offset = NULL;
+  long __pyx_v_i;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  __pyx_t_2bx_3bbi_5types_bits16 __pyx_t_2;
+  PyObject *__pyx_t_3 = NULL;
+  int __pyx_t_4;
+  PyObject *__pyx_t_5 = NULL;
+  PyObject *__pyx_t_6 = NULL;
+  PyObject *__pyx_t_7 = NULL;
+  PyObject *__pyx_t_8 = NULL;
+  PyObject *__pyx_t_9 = NULL;
+  PyObject *__pyx_t_10 = NULL;
+  int __pyx_t_11;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("r_find_overlapping_parent", 0);
+
+  /* "bx/bbi/cirtree_file.pyx":84
+ *         ## cdef bits32 start_chrom_ix[child_count], start_base[child_count], end_chrom_ix[child_count], end_base[child_count]
+ *         ## cdef bits64 offset[child_count]
+ *         start_chrom_ix = []; start_base = []; end_chrom_ix = []; end_base = []             # <<<<<<<<<<<<<<
+ *         offset = []
+ *         for i from 0 <= i < child_count:
+ */
+  __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 84; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_v_start_chrom_ix = ((PyObject*)__pyx_t_1);
+  __pyx_t_1 = 0;
+  __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 84; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_v_start_base = ((PyObject*)__pyx_t_1);
+  __pyx_t_1 = 0;
+  __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 84; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_v_end_chrom_ix = ((PyObject*)__pyx_t_1);
+  __pyx_t_1 = 0;
+  __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 84; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_v_end_base = ((PyObject*)__pyx_t_1);
+  __pyx_t_1 = 0;
+
+  /* "bx/bbi/cirtree_file.pyx":85
+ *         ## cdef bits64 offset[child_count]
+ *         start_chrom_ix = []; start_base = []; end_chrom_ix = []; end_base = []
+ *         offset = []             # <<<<<<<<<<<<<<
+ *         for i from 0 <= i < child_count:
+ *             ## start_chrom_ix[i] = reader.read_bits32()
+ */
+  __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 85; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_v_offset = ((PyObject*)__pyx_t_1);
+  __pyx_t_1 = 0;
+
+  /* "bx/bbi/cirtree_file.pyx":86
+ *         start_chrom_ix = []; start_base = []; end_chrom_ix = []; end_base = []
+ *         offset = []
+ *         for i from 0 <= i < child_count:             # <<<<<<<<<<<<<<
+ *             ## start_chrom_ix[i] = reader.read_bits32()
+ *             ## start_base[i] = reader.read_bits32()
+ */
+  __pyx_t_2 = __pyx_v_child_count;
+  for (__pyx_v_i = 0; __pyx_v_i < __pyx_t_2; __pyx_v_i++) {
+
+    /* "bx/bbi/cirtree_file.pyx":92
+ *             ## end_base[i] = reader.read_bits32()
+ *             ## offset[i] = reader.read_bits64()
+ *             start_chrom_ix.append( reader.read_uint32() )             # <<<<<<<<<<<<<<
+ *             start_base.append( reader.read_uint32() )
+ *             end_chrom_ix.append( reader.read_uint32() )
+ */
+    __pyx_t_1 = PyObject_GetAttr(__pyx_v_reader, __pyx_n_s__read_uint32); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 92; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __pyx_t_3 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 92; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    __pyx_t_4 = PyList_Append(__pyx_v_start_chrom_ix, __pyx_t_3); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 92; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+    /* "bx/bbi/cirtree_file.pyx":93
+ *             ## offset[i] = reader.read_bits64()
+ *             start_chrom_ix.append( reader.read_uint32() )
+ *             start_base.append( reader.read_uint32() )             # <<<<<<<<<<<<<<
+ *             end_chrom_ix.append( reader.read_uint32() )
+ *             end_base.append( reader.read_uint32() )
+ */
+    __pyx_t_3 = PyObject_GetAttr(__pyx_v_reader, __pyx_n_s__read_uint32); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 93; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __pyx_t_1 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 93; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __pyx_t_4 = PyList_Append(__pyx_v_start_base, __pyx_t_1); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 93; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+    /* "bx/bbi/cirtree_file.pyx":94
+ *             start_chrom_ix.append( reader.read_uint32() )
+ *             start_base.append( reader.read_uint32() )
+ *             end_chrom_ix.append( reader.read_uint32() )             # <<<<<<<<<<<<<<
+ *             end_base.append( reader.read_uint32() )
+ *             offset.append( reader.read_uint64() )
+ */
+    __pyx_t_1 = PyObject_GetAttr(__pyx_v_reader, __pyx_n_s__read_uint32); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 94; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __pyx_t_3 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 94; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    __pyx_t_4 = PyList_Append(__pyx_v_end_chrom_ix, __pyx_t_3); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 94; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+    /* "bx/bbi/cirtree_file.pyx":95
+ *             start_base.append( reader.read_uint32() )
+ *             end_chrom_ix.append( reader.read_uint32() )
+ *             end_base.append( reader.read_uint32() )             # <<<<<<<<<<<<<<
+ *             offset.append( reader.read_uint64() )
+ *         # Now recurse
+ */
+    __pyx_t_3 = PyObject_GetAttr(__pyx_v_reader, __pyx_n_s__read_uint32); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 95; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __pyx_t_1 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 95; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __pyx_t_4 = PyList_Append(__pyx_v_end_base, __pyx_t_1); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 95; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+    /* "bx/bbi/cirtree_file.pyx":96
+ *             end_chrom_ix.append( reader.read_uint32() )
+ *             end_base.append( reader.read_uint32() )
+ *             offset.append( reader.read_uint64() )             # <<<<<<<<<<<<<<
+ *         # Now recurse
+ *         for i from 0 <= i < child_count:
+ */
+    __pyx_t_1 = PyObject_GetAttr(__pyx_v_reader, __pyx_n_s__read_uint64); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 96; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __pyx_t_3 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 96; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    __pyx_t_4 = PyList_Append(__pyx_v_offset, __pyx_t_3); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 96; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  }
+
+  /* "bx/bbi/cirtree_file.pyx":98
+ *             offset.append( reader.read_uint64() )
+ *         # Now recurse
+ *         for i from 0 <= i < child_count:             # <<<<<<<<<<<<<<
+ *             if overlaps( chrom_ix, start, end, start_chrom_ix[i], start_base[i], end_chrom_ix[i], end_base[i] ):
+ *                 self.r_find_overlapping( level + 1, offset[i], chrom_ix, start, end, rval, reader )
+ */
+  __pyx_t_2 = __pyx_v_child_count;
+  for (__pyx_v_i = 0; __pyx_v_i < __pyx_t_2; __pyx_v_i++) {
+
+    /* "bx/bbi/cirtree_file.pyx":99
+ *         # Now recurse
+ *         for i from 0 <= i < child_count:
+ *             if overlaps( chrom_ix, start, end, start_chrom_ix[i], start_base[i], end_chrom_ix[i], end_base[i] ):             # <<<<<<<<<<<<<<
+ *                 self.r_find_overlapping( level + 1, offset[i], chrom_ix, start, end, rval, reader )
+ * 
+ */
+    __pyx_t_3 = PyLong_FromUnsignedLong(__pyx_v_chrom_ix); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 99; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __pyx_t_1 = PyLong_FromUnsignedLong(__pyx_v_start); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 99; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __pyx_t_5 = PyLong_FromUnsignedLong(__pyx_v_end); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 99; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_5);
+    __pyx_t_6 = __Pyx_GetItemInt_List(((PyObject *)__pyx_v_start_chrom_ix), __pyx_v_i, sizeof(long), PyInt_FromLong); if (!__pyx_t_6) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 99; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_6);
+    __pyx_t_7 = __Pyx_GetItemInt_List(((PyObject *)__pyx_v_start_base), __pyx_v_i, sizeof(long), PyInt_FromLong); if (!__pyx_t_7) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 99; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_7);
+    __pyx_t_8 = __Pyx_GetItemInt_List(((PyObject *)__pyx_v_end_chrom_ix), __pyx_v_i, sizeof(long), PyInt_FromLong); if (!__pyx_t_8) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 99; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_8);
+    __pyx_t_9 = __Pyx_GetItemInt_List(((PyObject *)__pyx_v_end_base), __pyx_v_i, sizeof(long), PyInt_FromLong); if (!__pyx_t_9) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 99; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_9);
+    __pyx_t_10 = __pyx_f_2bx_3bbi_12cirtree_file_overlaps(__pyx_t_3, __pyx_t_1, __pyx_t_5, __pyx_t_6, __pyx_t_7, __pyx_t_8, __pyx_t_9); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 99; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_10);
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+    __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+    __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+    __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+    __pyx_t_11 = __Pyx_PyObject_IsTrue(__pyx_t_10); if (unlikely(__pyx_t_11 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 99; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+    if (__pyx_t_11) {
+
+      /* "bx/bbi/cirtree_file.pyx":100
+ *         for i from 0 <= i < child_count:
+ *             if overlaps( chrom_ix, start, end, start_chrom_ix[i], start_base[i], end_chrom_ix[i], end_base[i] ):
+ *                 self.r_find_overlapping( level + 1, offset[i], chrom_ix, start, end, rval, reader )             # <<<<<<<<<<<<<<
+ * 
+ *     def find_overlapping_blocks( self, bits32 chrom_ix, bits32 start, bits32 end ):
+ */
+      __pyx_t_10 = PyObject_GetAttr(((PyObject *)__pyx_v_self), __pyx_n_s__r_find_overlapping); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 100; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_10);
+      __pyx_t_9 = PyInt_FromLong((__pyx_v_level + 1)); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 100; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_9);
+      __pyx_t_8 = __Pyx_GetItemInt_List(((PyObject *)__pyx_v_offset), __pyx_v_i, sizeof(long), PyInt_FromLong); if (!__pyx_t_8) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 100; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_8);
+      __pyx_t_7 = PyLong_FromUnsignedLong(__pyx_v_chrom_ix); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 100; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_7);
+      __pyx_t_6 = PyLong_FromUnsignedLong(__pyx_v_start); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 100; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_6);
+      __pyx_t_5 = PyLong_FromUnsignedLong(__pyx_v_end); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 100; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_5);
+      __pyx_t_1 = PyTuple_New(7); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 100; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_1);
+      PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_9);
+      __Pyx_GIVEREF(__pyx_t_9);
+      PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_t_8);
+      __Pyx_GIVEREF(__pyx_t_8);
+      PyTuple_SET_ITEM(__pyx_t_1, 2, __pyx_t_7);
+      __Pyx_GIVEREF(__pyx_t_7);
+      PyTuple_SET_ITEM(__pyx_t_1, 3, __pyx_t_6);
+      __Pyx_GIVEREF(__pyx_t_6);
+      PyTuple_SET_ITEM(__pyx_t_1, 4, __pyx_t_5);
+      __Pyx_GIVEREF(__pyx_t_5);
+      __Pyx_INCREF(__pyx_v_rval);
+      PyTuple_SET_ITEM(__pyx_t_1, 5, __pyx_v_rval);
+      __Pyx_GIVEREF(__pyx_v_rval);
+      __Pyx_INCREF(__pyx_v_reader);
+      PyTuple_SET_ITEM(__pyx_t_1, 6, __pyx_v_reader);
+      __Pyx_GIVEREF(__pyx_v_reader);
+      __pyx_t_9 = 0;
+      __pyx_t_8 = 0;
+      __pyx_t_7 = 0;
+      __pyx_t_6 = 0;
+      __pyx_t_5 = 0;
+      __pyx_t_5 = PyObject_Call(__pyx_t_10, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 100; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_5);
+      __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+      __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      goto __pyx_L7;
+    }
+    __pyx_L7:;
+  }
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_5);
+  __Pyx_XDECREF(__pyx_t_6);
+  __Pyx_XDECREF(__pyx_t_7);
+  __Pyx_XDECREF(__pyx_t_8);
+  __Pyx_XDECREF(__pyx_t_9);
+  __Pyx_XDECREF(__pyx_t_10);
+  __Pyx_AddTraceback("bx.bbi.cirtree_file.CIRTreeFile.r_find_overlapping_parent", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_start_chrom_ix);
+  __Pyx_XDECREF(__pyx_v_start_base);
+  __Pyx_XDECREF(__pyx_v_end_chrom_ix);
+  __Pyx_XDECREF(__pyx_v_end_base);
+  __Pyx_XDECREF(__pyx_v_offset);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_3bbi_12cirtree_file_11CIRTreeFile_11find_overlapping_blocks(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyObject *__pyx_pw_2bx_3bbi_12cirtree_file_11CIRTreeFile_11find_overlapping_blocks(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_chrom_ix;
+  __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_start;
+  __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_end;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("find_overlapping_blocks (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__chrom_ix,&__pyx_n_s__start,&__pyx_n_s__end,0};
+    PyObject* values[3] = {0,0,0};
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__chrom_ix)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__start)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("find_overlapping_blocks", 1, 3, 3, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 102; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+        case  2:
+        if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__end)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("find_overlapping_blocks", 1, 3, 3, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 102; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "find_overlapping_blocks") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 102; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else if (PyTuple_GET_SIZE(__pyx_args) != 3) {
+      goto __pyx_L5_argtuple_error;
+    } else {
+      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+      values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+    }
+    __pyx_v_chrom_ix = __Pyx_PyInt_AsUnsignedInt(values[0]); if (unlikely((__pyx_v_chrom_ix == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 102; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_start = __Pyx_PyInt_AsUnsignedInt(values[1]); if (unlikely((__pyx_v_start == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 102; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_end = __Pyx_PyInt_AsUnsignedInt(values[2]); if (unlikely((__pyx_v_end == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 102; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("find_overlapping_blocks", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 102; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.bbi.cirtree_file.CIRTreeFile.find_overlapping_blocks", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_3bbi_12cirtree_file_11CIRTreeFile_10find_overlapping_blocks(((struct __pyx_obj_2bx_3bbi_12cirtree_file_CIRTreeFile *)__pyx_v_self), __pyx_v_chrom_ix, __pyx_v_start, __pyx_v_end);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bbi/cirtree_file.pyx":102
+ *                 self.r_find_overlapping( level + 1, offset[i], chrom_ix, start, end, rval, reader )
+ * 
+ *     def find_overlapping_blocks( self, bits32 chrom_ix, bits32 start, bits32 end ):             # <<<<<<<<<<<<<<
+ *         rval = []
+ *         self.r_find_overlapping( 0, self.root_offset, chrom_ix, start, end, rval, self.reader )
+ */
+
+static PyObject *__pyx_pf_2bx_3bbi_12cirtree_file_11CIRTreeFile_10find_overlapping_blocks(struct __pyx_obj_2bx_3bbi_12cirtree_file_CIRTreeFile *__pyx_v_self, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_chrom_ix, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_start, __pyx_t_2bx_3bbi_5types_bits32 __pyx_v_end) {
+  PyObject *__pyx_v_rval = NULL;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  PyObject *__pyx_t_5 = NULL;
+  PyObject *__pyx_t_6 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("find_overlapping_blocks", 0);
+
+  /* "bx/bbi/cirtree_file.pyx":103
+ * 
+ *     def find_overlapping_blocks( self, bits32 chrom_ix, bits32 start, bits32 end ):
+ *         rval = []             # <<<<<<<<<<<<<<
+ *         self.r_find_overlapping( 0, self.root_offset, chrom_ix, start, end, rval, self.reader )
+ *         return rval
+ */
+  __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 103; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_v_rval = ((PyObject*)__pyx_t_1);
+  __pyx_t_1 = 0;
+
+  /* "bx/bbi/cirtree_file.pyx":104
+ *     def find_overlapping_blocks( self, bits32 chrom_ix, bits32 start, bits32 end ):
+ *         rval = []
+ *         self.r_find_overlapping( 0, self.root_offset, chrom_ix, start, end, rval, self.reader )             # <<<<<<<<<<<<<<
+ *         return rval
+ */
+  __pyx_t_1 = PyObject_GetAttr(((PyObject *)__pyx_v_self), __pyx_n_s__r_find_overlapping); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 104; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = PyLong_FromUnsignedLongLong(__pyx_v_self->root_offset); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 104; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = PyLong_FromUnsignedLong(__pyx_v_chrom_ix); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 104; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_4 = PyLong_FromUnsignedLong(__pyx_v_start); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 104; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __pyx_t_5 = PyLong_FromUnsignedLong(__pyx_v_end); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 104; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __pyx_t_6 = PyTuple_New(7); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 104; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_6);
+  __Pyx_INCREF(__pyx_int_0);
+  PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_int_0);
+  __Pyx_GIVEREF(__pyx_int_0);
+  PyTuple_SET_ITEM(__pyx_t_6, 1, __pyx_t_2);
+  __Pyx_GIVEREF(__pyx_t_2);
+  PyTuple_SET_ITEM(__pyx_t_6, 2, __pyx_t_3);
+  __Pyx_GIVEREF(__pyx_t_3);
+  PyTuple_SET_ITEM(__pyx_t_6, 3, __pyx_t_4);
+  __Pyx_GIVEREF(__pyx_t_4);
+  PyTuple_SET_ITEM(__pyx_t_6, 4, __pyx_t_5);
+  __Pyx_GIVEREF(__pyx_t_5);
+  __Pyx_INCREF(((PyObject *)__pyx_v_rval));
+  PyTuple_SET_ITEM(__pyx_t_6, 5, ((PyObject *)__pyx_v_rval));
+  __Pyx_GIVEREF(((PyObject *)__pyx_v_rval));
+  __Pyx_INCREF(__pyx_v_self->reader);
+  PyTuple_SET_ITEM(__pyx_t_6, 6, __pyx_v_self->reader);
+  __Pyx_GIVEREF(__pyx_v_self->reader);
+  __pyx_t_2 = 0;
+  __pyx_t_3 = 0;
+  __pyx_t_4 = 0;
+  __pyx_t_5 = 0;
+  __pyx_t_5 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_6), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 104; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_6)); __pyx_t_6 = 0;
+  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+
+  /* "bx/bbi/cirtree_file.pyx":105
+ *         rval = []
+ *         self.r_find_overlapping( 0, self.root_offset, chrom_ix, start, end, rval, self.reader )
+ *         return rval             # <<<<<<<<<<<<<<
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __Pyx_INCREF(((PyObject *)__pyx_v_rval));
+  __pyx_r = ((PyObject *)__pyx_v_rval);
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_XDECREF(__pyx_t_5);
+  __Pyx_XDECREF(__pyx_t_6);
+  __Pyx_AddTraceback("bx.bbi.cirtree_file.CIRTreeFile.find_overlapping_blocks", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_rval);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_tp_new_2bx_3bbi_12cirtree_file_CIRTreeFile(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) {
+  struct __pyx_obj_2bx_3bbi_12cirtree_file_CIRTreeFile *p;
+  PyObject *o = (*t->tp_alloc)(t, 0);
+  if (!o) return 0;
+  p = ((struct __pyx_obj_2bx_3bbi_12cirtree_file_CIRTreeFile *)o);
+  p->file = Py_None; Py_INCREF(Py_None);
+  p->reader = Py_None; Py_INCREF(Py_None);
+  return o;
+}
+
+static void __pyx_tp_dealloc_2bx_3bbi_12cirtree_file_CIRTreeFile(PyObject *o) {
+  struct __pyx_obj_2bx_3bbi_12cirtree_file_CIRTreeFile *p = (struct __pyx_obj_2bx_3bbi_12cirtree_file_CIRTreeFile *)o;
+  PyObject_GC_UnTrack(o);
+  Py_CLEAR(p->file);
+  Py_CLEAR(p->reader);
+  PyObject_GC_Track(o);
+  (*Py_TYPE(o)->tp_free)(o);
+}
+
+static int __pyx_tp_traverse_2bx_3bbi_12cirtree_file_CIRTreeFile(PyObject *o, visitproc v, void *a) {
+  int e;
+  struct __pyx_obj_2bx_3bbi_12cirtree_file_CIRTreeFile *p = (struct __pyx_obj_2bx_3bbi_12cirtree_file_CIRTreeFile *)o;
+  if (p->file) {
+    e = (*v)(p->file, a); if (e) return e;
+  }
+  if (p->reader) {
+    e = (*v)(p->reader, a); if (e) return e;
+  }
+  return 0;
+}
+
+static int __pyx_tp_clear_2bx_3bbi_12cirtree_file_CIRTreeFile(PyObject *o) {
+  struct __pyx_obj_2bx_3bbi_12cirtree_file_CIRTreeFile *p = (struct __pyx_obj_2bx_3bbi_12cirtree_file_CIRTreeFile *)o;
+  PyObject* tmp;
+  tmp = ((PyObject*)p->file);
+  p->file = Py_None; Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  tmp = ((PyObject*)p->reader);
+  p->reader = Py_None; Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  return 0;
+}
+
+static PyMethodDef __pyx_methods_2bx_3bbi_12cirtree_file_CIRTreeFile[] = {
+  {__Pyx_NAMESTR("attach"), (PyCFunction)__pyx_pw_2bx_3bbi_12cirtree_file_11CIRTreeFile_3attach, METH_O, __Pyx_DOCSTR(__pyx_doc_2bx_3bbi_12cirtree_file_11CIRTreeFile_2attach)},
+  {__Pyx_NAMESTR("r_find_overlapping"), (PyCFunction)__pyx_pw_2bx_3bbi_12cirtree_file_11CIRTreeFile_5r_find_overlapping, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(0)},
+  {__Pyx_NAMESTR("r_find_overlapping_leaf"), (PyCFunction)__pyx_pw_2bx_3bbi_12cirtree_file_11CIRTreeFile_7r_find_overlapping_leaf, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(0)},
+  {__Pyx_NAMESTR("r_find_overlapping_parent"), (PyCFunction)__pyx_pw_2bx_3bbi_12cirtree_file_11CIRTreeFile_9r_find_overlapping_parent, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(0)},
+  {__Pyx_NAMESTR("find_overlapping_blocks"), (PyCFunction)__pyx_pw_2bx_3bbi_12cirtree_file_11CIRTreeFile_11find_overlapping_blocks, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(0)},
+  {0, 0, 0, 0}
+};
+
+static PyNumberMethods __pyx_tp_as_number_CIRTreeFile = {
+  0, /*nb_add*/
+  0, /*nb_subtract*/
+  0, /*nb_multiply*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_divide*/
+  #endif
+  0, /*nb_remainder*/
+  0, /*nb_divmod*/
+  0, /*nb_power*/
+  0, /*nb_negative*/
+  0, /*nb_positive*/
+  0, /*nb_absolute*/
+  0, /*nb_nonzero*/
+  0, /*nb_invert*/
+  0, /*nb_lshift*/
+  0, /*nb_rshift*/
+  0, /*nb_and*/
+  0, /*nb_xor*/
+  0, /*nb_or*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_coerce*/
+  #endif
+  0, /*nb_int*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_long*/
+  #else
+  0, /*reserved*/
+  #endif
+  0, /*nb_float*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_oct*/
+  #endif
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_hex*/
+  #endif
+  0, /*nb_inplace_add*/
+  0, /*nb_inplace_subtract*/
+  0, /*nb_inplace_multiply*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_inplace_divide*/
+  #endif
+  0, /*nb_inplace_remainder*/
+  0, /*nb_inplace_power*/
+  0, /*nb_inplace_lshift*/
+  0, /*nb_inplace_rshift*/
+  0, /*nb_inplace_and*/
+  0, /*nb_inplace_xor*/
+  0, /*nb_inplace_or*/
+  0, /*nb_floor_divide*/
+  0, /*nb_true_divide*/
+  0, /*nb_inplace_floor_divide*/
+  0, /*nb_inplace_true_divide*/
+  #if PY_VERSION_HEX >= 0x02050000
+  0, /*nb_index*/
+  #endif
+};
+
+static PySequenceMethods __pyx_tp_as_sequence_CIRTreeFile = {
+  0, /*sq_length*/
+  0, /*sq_concat*/
+  0, /*sq_repeat*/
+  0, /*sq_item*/
+  0, /*sq_slice*/
+  0, /*sq_ass_item*/
+  0, /*sq_ass_slice*/
+  0, /*sq_contains*/
+  0, /*sq_inplace_concat*/
+  0, /*sq_inplace_repeat*/
+};
+
+static PyMappingMethods __pyx_tp_as_mapping_CIRTreeFile = {
+  0, /*mp_length*/
+  0, /*mp_subscript*/
+  0, /*mp_ass_subscript*/
+};
+
+static PyBufferProcs __pyx_tp_as_buffer_CIRTreeFile = {
+  #if PY_MAJOR_VERSION < 3
+  0, /*bf_getreadbuffer*/
+  #endif
+  #if PY_MAJOR_VERSION < 3
+  0, /*bf_getwritebuffer*/
+  #endif
+  #if PY_MAJOR_VERSION < 3
+  0, /*bf_getsegcount*/
+  #endif
+  #if PY_MAJOR_VERSION < 3
+  0, /*bf_getcharbuffer*/
+  #endif
+  #if PY_VERSION_HEX >= 0x02060000
+  0, /*bf_getbuffer*/
+  #endif
+  #if PY_VERSION_HEX >= 0x02060000
+  0, /*bf_releasebuffer*/
+  #endif
+};
+
+static PyTypeObject __pyx_type_2bx_3bbi_12cirtree_file_CIRTreeFile = {
+  PyVarObject_HEAD_INIT(0, 0)
+  __Pyx_NAMESTR("bx.bbi.cirtree_file.CIRTreeFile"), /*tp_name*/
+  sizeof(struct __pyx_obj_2bx_3bbi_12cirtree_file_CIRTreeFile), /*tp_basicsize*/
+  0, /*tp_itemsize*/
+  __pyx_tp_dealloc_2bx_3bbi_12cirtree_file_CIRTreeFile, /*tp_dealloc*/
+  0, /*tp_print*/
+  0, /*tp_getattr*/
+  0, /*tp_setattr*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*tp_compare*/
+  #else
+  0, /*reserved*/
+  #endif
+  0, /*tp_repr*/
+  &__pyx_tp_as_number_CIRTreeFile, /*tp_as_number*/
+  &__pyx_tp_as_sequence_CIRTreeFile, /*tp_as_sequence*/
+  &__pyx_tp_as_mapping_CIRTreeFile, /*tp_as_mapping*/
+  0, /*tp_hash*/
+  0, /*tp_call*/
+  0, /*tp_str*/
+  0, /*tp_getattro*/
+  0, /*tp_setattro*/
+  &__pyx_tp_as_buffer_CIRTreeFile, /*tp_as_buffer*/
+  Py_TPFLAGS_DEFAULT|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+  0, /*tp_doc*/
+  __pyx_tp_traverse_2bx_3bbi_12cirtree_file_CIRTreeFile, /*tp_traverse*/
+  __pyx_tp_clear_2bx_3bbi_12cirtree_file_CIRTreeFile, /*tp_clear*/
+  0, /*tp_richcompare*/
+  0, /*tp_weaklistoffset*/
+  0, /*tp_iter*/
+  0, /*tp_iternext*/
+  __pyx_methods_2bx_3bbi_12cirtree_file_CIRTreeFile, /*tp_methods*/
+  0, /*tp_members*/
+  0, /*tp_getset*/
+  0, /*tp_base*/
+  0, /*tp_dict*/
+  0, /*tp_descr_get*/
+  0, /*tp_descr_set*/
+  0, /*tp_dictoffset*/
+  __pyx_pw_2bx_3bbi_12cirtree_file_11CIRTreeFile_1__init__, /*tp_init*/
+  0, /*tp_alloc*/
+  __pyx_tp_new_2bx_3bbi_12cirtree_file_CIRTreeFile, /*tp_new*/
+  0, /*tp_free*/
+  0, /*tp_is_gc*/
+  0, /*tp_bases*/
+  0, /*tp_mro*/
+  0, /*tp_cache*/
+  0, /*tp_subclasses*/
+  0, /*tp_weaklist*/
+  0, /*tp_del*/
+  #if PY_VERSION_HEX >= 0x02060000
+  0, /*tp_version_tag*/
+  #endif
+};
+
+static PyMethodDef __pyx_methods[] = {
+  {0, 0, 0, 0}
+};
+
+#if PY_MAJOR_VERSION >= 3
+static struct PyModuleDef __pyx_moduledef = {
+  #if PY_VERSION_HEX < 0x03020000
+    { PyObject_HEAD_INIT(NULL) NULL, 0, NULL },
+  #else
+    PyModuleDef_HEAD_INIT,
+  #endif
+    __Pyx_NAMESTR("cirtree_file"),
+    0, /* m_doc */
+    -1, /* m_size */
+    __pyx_methods /* m_methods */,
+    NULL, /* m_reload */
+    NULL, /* m_traverse */
+    NULL, /* m_clear */
+    NULL /* m_free */
+};
+#endif
+
+static __Pyx_StringTabEntry __pyx_string_tab[] = {
+  {&__pyx_n_s_1, __pyx_k_1, sizeof(__pyx_k_1), 0, 0, 1, 1},
+  {&__pyx_n_s_2, __pyx_k_2, sizeof(__pyx_k_2), 0, 0, 1, 1},
+  {&__pyx_n_s_3, __pyx_k_3, sizeof(__pyx_k_3), 0, 0, 1, 1},
+  {&__pyx_n_s__BinaryFileReader, __pyx_k__BinaryFileReader, sizeof(__pyx_k__BinaryFileReader), 0, 0, 1, 1},
+  {&__pyx_n_s____main__, __pyx_k____main__, sizeof(__pyx_k____main__), 0, 0, 1, 1},
+  {&__pyx_n_s____test__, __pyx_k____test__, sizeof(__pyx_k____test__), 0, 0, 1, 1},
+  {&__pyx_n_s__attach, __pyx_k__attach, sizeof(__pyx_k__attach), 0, 0, 1, 1},
+  {&__pyx_n_s__byteswap_needed, __pyx_k__byteswap_needed, sizeof(__pyx_k__byteswap_needed), 0, 0, 1, 1},
+  {&__pyx_n_s__child_count, __pyx_k__child_count, sizeof(__pyx_k__child_count), 0, 0, 1, 1},
+  {&__pyx_n_s__chrom_ix, __pyx_k__chrom_ix, sizeof(__pyx_k__chrom_ix), 0, 0, 1, 1},
+  {&__pyx_n_s__end, __pyx_k__end, sizeof(__pyx_k__end), 0, 0, 1, 1},
+  {&__pyx_n_s__file, __pyx_k__file, sizeof(__pyx_k__file), 0, 0, 1, 1},
+  {&__pyx_n_s__index_file_offset, __pyx_k__index_file_offset, sizeof(__pyx_k__index_file_offset), 0, 0, 1, 1},
+  {&__pyx_n_s__level, __pyx_k__level, sizeof(__pyx_k__level), 0, 0, 1, 1},
+  {&__pyx_n_s__r_find_overlapping, __pyx_k__r_find_overlapping, sizeof(__pyx_k__r_find_overlapping), 0, 0, 1, 1},
+  {&__pyx_n_s__read_uint16, __pyx_k__read_uint16, sizeof(__pyx_k__read_uint16), 0, 0, 1, 1},
+  {&__pyx_n_s__read_uint32, __pyx_k__read_uint32, sizeof(__pyx_k__read_uint32), 0, 0, 1, 1},
+  {&__pyx_n_s__read_uint64, __pyx_k__read_uint64, sizeof(__pyx_k__read_uint64), 0, 0, 1, 1},
+  {&__pyx_n_s__read_uint8, __pyx_k__read_uint8, sizeof(__pyx_k__read_uint8), 0, 0, 1, 1},
+  {&__pyx_n_s__reader, __pyx_k__reader, sizeof(__pyx_k__reader), 0, 0, 1, 1},
+  {&__pyx_n_s__rval, __pyx_k__rval, sizeof(__pyx_k__rval), 0, 0, 1, 1},
+  {&__pyx_n_s__seek, __pyx_k__seek, sizeof(__pyx_k__seek), 0, 0, 1, 1},
+  {&__pyx_n_s__start, __pyx_k__start, sizeof(__pyx_k__start), 0, 0, 1, 1},
+  {&__pyx_n_s__tell, __pyx_k__tell, sizeof(__pyx_k__tell), 0, 0, 1, 1},
+  {0, 0, 0, 0, 0, 0, 0}
+};
+static int __Pyx_InitCachedBuiltins(void) {
+  return 0;
+}
+
+static int __Pyx_InitCachedConstants(void) {
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0);
+  __Pyx_RefNannyFinishContext();
+  return 0;
+}
+
+static int __Pyx_InitGlobals(void) {
+  if (__Pyx_InitStrings(__pyx_string_tab) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  __pyx_int_0 = PyInt_FromLong(0); if (unlikely(!__pyx_int_0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  __pyx_int_610839776 = PyInt_FromLong(610839776); if (unlikely(!__pyx_int_610839776)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  return 0;
+  __pyx_L1_error:;
+  return -1;
+}
+
+#if PY_MAJOR_VERSION < 3
+PyMODINIT_FUNC initcirtree_file(void); /*proto*/
+PyMODINIT_FUNC initcirtree_file(void)
+#else
+PyMODINIT_FUNC PyInit_cirtree_file(void); /*proto*/
+PyMODINIT_FUNC PyInit_cirtree_file(void)
+#endif
+{
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  __Pyx_RefNannyDeclarations
+  #if CYTHON_REFNANNY
+  __Pyx_RefNanny = __Pyx_RefNannyImportAPI("refnanny");
+  if (!__Pyx_RefNanny) {
+      PyErr_Clear();
+      __Pyx_RefNanny = __Pyx_RefNannyImportAPI("Cython.Runtime.refnanny");
+      if (!__Pyx_RefNanny)
+          Py_FatalError("failed to import 'refnanny' module");
+  }
+  #endif
+  __Pyx_RefNannySetupContext("PyMODINIT_FUNC PyInit_cirtree_file(void)", 0);
+  if ( __Pyx_check_binary_version() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_bytes)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #ifdef __Pyx_CyFunction_USED
+  if (__Pyx_CyFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #endif
+  #ifdef __Pyx_FusedFunction_USED
+  if (__pyx_FusedFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #endif
+  #ifdef __Pyx_Generator_USED
+  if (__pyx_Generator_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #endif
+  /*--- Library function declarations ---*/
+  /*--- Threads initialization code ---*/
+  #if defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS
+  #ifdef WITH_THREAD /* Python build with threading support? */
+  PyEval_InitThreads();
+  #endif
+  #endif
+  /*--- Module creation code ---*/
+  #if PY_MAJOR_VERSION < 3
+  __pyx_m = Py_InitModule4(__Pyx_NAMESTR("cirtree_file"), __pyx_methods, 0, 0, PYTHON_API_VERSION); Py_XINCREF(__pyx_m);
+  #else
+  __pyx_m = PyModule_Create(&__pyx_moduledef);
+  #endif
+  if (unlikely(!__pyx_m)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #if PY_MAJOR_VERSION >= 3
+  {
+    PyObject *modules = PyImport_GetModuleDict(); if (unlikely(!modules)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (!PyDict_GetItemString(modules, "bx.bbi.cirtree_file")) {
+      if (unlikely(PyDict_SetItemString(modules, "bx.bbi.cirtree_file", __pyx_m) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+  }
+  #endif
+  __pyx_b = PyImport_AddModule(__Pyx_NAMESTR(__Pyx_BUILTIN_MODULE_NAME)); if (unlikely(!__pyx_b)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #if CYTHON_COMPILING_IN_PYPY
+  Py_INCREF(__pyx_b);
+  #endif
+  if (__Pyx_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  /*--- Initialize various global constants etc. ---*/
+  if (unlikely(__Pyx_InitGlobals() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (__pyx_module_is_main_bx__bbi__cirtree_file) {
+    if (__Pyx_SetAttrString(__pyx_m, "__name__", __pyx_n_s____main__) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  }
+  /*--- Builtin init code ---*/
+  if (unlikely(__Pyx_InitCachedBuiltins() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  /*--- Constants init code ---*/
+  if (unlikely(__Pyx_InitCachedConstants() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  /*--- Global init code ---*/
+  /*--- Variable export code ---*/
+  /*--- Function export code ---*/
+  /*--- Type init code ---*/
+  if (PyType_Ready(&__pyx_type_2bx_3bbi_12cirtree_file_CIRTreeFile) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 22; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (__Pyx_SetAttrString(__pyx_m, "CIRTreeFile", (PyObject *)&__pyx_type_2bx_3bbi_12cirtree_file_CIRTreeFile) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 22; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_2bx_3bbi_12cirtree_file_CIRTreeFile = &__pyx_type_2bx_3bbi_12cirtree_file_CIRTreeFile;
+  /*--- Type import code ---*/
+  /*--- Variable import code ---*/
+  /*--- Function import code ---*/
+  /*--- Execution code ---*/
+
+  /* "bx/bbi/cirtree_file.pyx":1
+ * from bx.misc.binary_file import BinaryFileReader             # <<<<<<<<<<<<<<
+ * 
+ * DEF cir_tree_sig = 0x2468ACE0
+ */
+  __pyx_t_1 = PyList_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_INCREF(((PyObject *)__pyx_n_s__BinaryFileReader));
+  PyList_SET_ITEM(__pyx_t_1, 0, ((PyObject *)__pyx_n_s__BinaryFileReader));
+  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__BinaryFileReader));
+  __pyx_t_2 = __Pyx_Import(((PyObject *)__pyx_n_s_3), ((PyObject *)__pyx_t_1), -1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+  __pyx_t_1 = PyObject_GetAttr(__pyx_t_2, __pyx_n_s__BinaryFileReader);
+  if (__pyx_t_1 == NULL) {
+    if (PyErr_ExceptionMatches(PyExc_AttributeError)) __Pyx_RaiseImportError(__pyx_n_s__BinaryFileReader);
+    if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s__BinaryFileReader, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+  /* "bx/bbi/cirtree_file.pyx":102
+ *                 self.r_find_overlapping( level + 1, offset[i], chrom_ix, start, end, rval, reader )
+ * 
+ *     def find_overlapping_blocks( self, bits32 chrom_ix, bits32 start, bits32 end ):             # <<<<<<<<<<<<<<
+ *         rval = []
+ *         self.r_find_overlapping( 0, self.root_offset, chrom_ix, start, end, rval, self.reader )
+ */
+  __pyx_t_2 = PyDict_New(); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(((PyObject *)__pyx_t_2));
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s____test__, ((PyObject *)__pyx_t_2)) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  if (__pyx_m) {
+    __Pyx_AddTraceback("init bx.bbi.cirtree_file", __pyx_clineno, __pyx_lineno, __pyx_filename);
+    Py_DECREF(__pyx_m); __pyx_m = 0;
+  } else if (!PyErr_Occurred()) {
+    PyErr_SetString(PyExc_ImportError, "init bx.bbi.cirtree_file");
+  }
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  #if PY_MAJOR_VERSION < 3
+  return;
+  #else
+  return __pyx_m;
+  #endif
+}
+
+/* Runtime support code */
+#if CYTHON_REFNANNY
+static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) {
+    PyObject *m = NULL, *p = NULL;
+    void *r = NULL;
+    m = PyImport_ImportModule((char *)modname);
+    if (!m) goto end;
+    p = PyObject_GetAttrString(m, (char *)"RefNannyAPI");
+    if (!p) goto end;
+    r = PyLong_AsVoidPtr(p);
+end:
+    Py_XDECREF(p);
+    Py_XDECREF(m);
+    return (__Pyx_RefNannyAPIStruct *)r;
+}
+#endif /* CYTHON_REFNANNY */
+
+static void __Pyx_RaiseDoubleKeywordsError(
+    const char* func_name,
+    PyObject* kw_name)
+{
+    PyErr_Format(PyExc_TypeError,
+        #if PY_MAJOR_VERSION >= 3
+        "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
+        #else
+        "%s() got multiple values for keyword argument '%s'", func_name,
+        PyString_AsString(kw_name));
+        #endif
+}
+
+static int __Pyx_ParseOptionalKeywords(
+    PyObject *kwds,
+    PyObject **argnames[],
+    PyObject *kwds2,
+    PyObject *values[],
+    Py_ssize_t num_pos_args,
+    const char* function_name)
+{
+    PyObject *key = 0, *value = 0;
+    Py_ssize_t pos = 0;
+    PyObject*** name;
+    PyObject*** first_kw_arg = argnames + num_pos_args;
+    while (PyDict_Next(kwds, &pos, &key, &value)) {
+        name = first_kw_arg;
+        while (*name && (**name != key)) name++;
+        if (*name) {
+            values[name-argnames] = value;
+            continue;
+        }
+        name = first_kw_arg;
+        #if PY_MAJOR_VERSION < 3
+        if (likely(PyString_CheckExact(key)) || likely(PyString_Check(key))) {
+            while (*name) {
+                if ((CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**name) == PyString_GET_SIZE(key))
+                        && _PyString_Eq(**name, key)) {
+                    values[name-argnames] = value;
+                    break;
+                }
+                name++;
+            }
+            if (*name) continue;
+            else {
+                PyObject*** argname = argnames;
+                while (argname != first_kw_arg) {
+                    if ((**argname == key) || (
+                            (CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**argname) == PyString_GET_SIZE(key))
+                             && _PyString_Eq(**argname, key))) {
+                        goto arg_passed_twice;
+                    }
+                    argname++;
+                }
+            }
+        } else
+        #endif
+        if (likely(PyUnicode_Check(key))) {
+            while (*name) {
+                int cmp = (**name == key) ? 0 :
+                #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3
+                    (PyUnicode_GET_SIZE(**name) != PyUnicode_GET_SIZE(key)) ? 1 :
+                #endif
+                    PyUnicode_Compare(**name, key);
+                if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad;
+                if (cmp == 0) {
+                    values[name-argnames] = value;
+                    break;
+                }
+                name++;
+            }
+            if (*name) continue;
+            else {
+                PyObject*** argname = argnames;
+                while (argname != first_kw_arg) {
+                    int cmp = (**argname == key) ? 0 :
+                    #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3
+                        (PyUnicode_GET_SIZE(**argname) != PyUnicode_GET_SIZE(key)) ? 1 :
+                    #endif
+                        PyUnicode_Compare(**argname, key);
+                    if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad;
+                    if (cmp == 0) goto arg_passed_twice;
+                    argname++;
+                }
+            }
+        } else
+            goto invalid_keyword_type;
+        if (kwds2) {
+            if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
+        } else {
+            goto invalid_keyword;
+        }
+    }
+    return 0;
+arg_passed_twice:
+    __Pyx_RaiseDoubleKeywordsError(function_name, key);
+    goto bad;
+invalid_keyword_type:
+    PyErr_Format(PyExc_TypeError,
+        "%s() keywords must be strings", function_name);
+    goto bad;
+invalid_keyword:
+    PyErr_Format(PyExc_TypeError,
+    #if PY_MAJOR_VERSION < 3
+        "%s() got an unexpected keyword argument '%s'",
+        function_name, PyString_AsString(key));
+    #else
+        "%s() got an unexpected keyword argument '%U'",
+        function_name, key);
+    #endif
+bad:
+    return -1;
+}
+
+static void __Pyx_RaiseArgtupleInvalid(
+    const char* func_name,
+    int exact,
+    Py_ssize_t num_min,
+    Py_ssize_t num_max,
+    Py_ssize_t num_found)
+{
+    Py_ssize_t num_expected;
+    const char *more_or_less;
+    if (num_found < num_min) {
+        num_expected = num_min;
+        more_or_less = "at least";
+    } else {
+        num_expected = num_max;
+        more_or_less = "at most";
+    }
+    if (exact) {
+        more_or_less = "exactly";
+    }
+    PyErr_Format(PyExc_TypeError,
+                 "%s() takes %s %" CYTHON_FORMAT_SSIZE_T "d positional argument%s (%" CYTHON_FORMAT_SSIZE_T "d given)",
+                 func_name, more_or_less, num_expected,
+                 (num_expected == 1) ? "" : "s", num_found);
+}
+
+static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name) {
+    PyObject *result;
+    result = PyObject_GetAttr(dict, name);
+    if (!result) {
+        if (dict != __pyx_b) {
+            PyErr_Clear();
+            result = PyObject_GetAttr(__pyx_b, name);
+        }
+        if (!result) {
+            PyErr_SetObject(PyExc_NameError, name);
+        }
+    }
+    return result;
+}
+
+static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level) {
+    PyObject *empty_list = 0;
+    PyObject *module = 0;
+    PyObject *global_dict = 0;
+    PyObject *empty_dict = 0;
+    PyObject *list;
+    #if PY_VERSION_HEX < 0x03030000
+    PyObject *py_import = 0;
+    py_import = __Pyx_GetAttrString(__pyx_b, "__import__");
+    if (!py_import)
+        goto bad;
+    #endif
+    if (from_list)
+        list = from_list;
+    else {
+        empty_list = PyList_New(0);
+        if (!empty_list)
+            goto bad;
+        list = empty_list;
+    }
+    global_dict = PyModule_GetDict(__pyx_m);
+    if (!global_dict)
+        goto bad;
+    empty_dict = PyDict_New();
+    if (!empty_dict)
+        goto bad;
+    #if PY_VERSION_HEX >= 0x02050000
+    {
+        #if PY_MAJOR_VERSION >= 3
+        if (level == -1) {
+            if (strchr(__Pyx_MODULE_NAME, '.')) {
+                #if PY_VERSION_HEX < 0x03030000
+                PyObject *py_level = PyInt_FromLong(1);
+                if (!py_level)
+                    goto bad;
+                module = PyObject_CallFunctionObjArgs(py_import,
+                    name, global_dict, empty_dict, list, py_level, NULL);
+                Py_DECREF(py_level);
+                #else
+                module = PyImport_ImportModuleLevelObject(
+                    name, global_dict, empty_dict, list, 1);
+                #endif
+                if (!module) {
+                    if (!PyErr_ExceptionMatches(PyExc_ImportError))
+                        goto bad;
+                    PyErr_Clear();
+                }
+            }
+            level = 0; /* try absolute import on failure */
+        }
+        #endif
+        if (!module) {
+            #if PY_VERSION_HEX < 0x03030000
+            PyObject *py_level = PyInt_FromLong(level);
+            if (!py_level)
+                goto bad;
+            module = PyObject_CallFunctionObjArgs(py_import,
+                name, global_dict, empty_dict, list, py_level, NULL);
+            Py_DECREF(py_level);
+            #else
+            module = PyImport_ImportModuleLevelObject(
+                name, global_dict, empty_dict, list, level);
+            #endif
+        }
+    }
+    #else
+    if (level>0) {
+        PyErr_SetString(PyExc_RuntimeError, "Relative import is not supported for Python <=2.4.");
+        goto bad;
+    }
+    module = PyObject_CallFunctionObjArgs(py_import,
+        name, global_dict, empty_dict, list, NULL);
+    #endif
+bad:
+    #if PY_VERSION_HEX < 0x03030000
+    Py_XDECREF(py_import);
+    #endif
+    Py_XDECREF(empty_list);
+    Py_XDECREF(empty_dict);
+    return module;
+}
+
+static CYTHON_INLINE void __Pyx_RaiseImportError(PyObject *name) {
+#if PY_MAJOR_VERSION < 3
+    PyErr_Format(PyExc_ImportError, "cannot import name %.230s",
+                 PyString_AsString(name));
+#else
+    PyErr_Format(PyExc_ImportError, "cannot import name %S", name);
+#endif
+}
+
+static CYTHON_INLINE unsigned char __Pyx_PyInt_AsUnsignedChar(PyObject* x) {
+    const unsigned char neg_one = (unsigned char)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(unsigned char) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(unsigned char)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to unsigned char" :
+                    "value too large to convert to unsigned char");
+            }
+            return (unsigned char)-1;
+        }
+        return (unsigned char)val;
+    }
+    return (unsigned char)__Pyx_PyInt_AsUnsignedLong(x);
+}
+
+static CYTHON_INLINE unsigned short __Pyx_PyInt_AsUnsignedShort(PyObject* x) {
+    const unsigned short neg_one = (unsigned short)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(unsigned short) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(unsigned short)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to unsigned short" :
+                    "value too large to convert to unsigned short");
+            }
+            return (unsigned short)-1;
+        }
+        return (unsigned short)val;
+    }
+    return (unsigned short)__Pyx_PyInt_AsUnsignedLong(x);
+}
+
+static CYTHON_INLINE unsigned int __Pyx_PyInt_AsUnsignedInt(PyObject* x) {
+    const unsigned int neg_one = (unsigned int)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(unsigned int) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(unsigned int)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to unsigned int" :
+                    "value too large to convert to unsigned int");
+            }
+            return (unsigned int)-1;
+        }
+        return (unsigned int)val;
+    }
+    return (unsigned int)__Pyx_PyInt_AsUnsignedLong(x);
+}
+
+static CYTHON_INLINE char __Pyx_PyInt_AsChar(PyObject* x) {
+    const char neg_one = (char)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(char) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(char)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to char" :
+                    "value too large to convert to char");
+            }
+            return (char)-1;
+        }
+        return (char)val;
+    }
+    return (char)__Pyx_PyInt_AsLong(x);
+}
+
+static CYTHON_INLINE short __Pyx_PyInt_AsShort(PyObject* x) {
+    const short neg_one = (short)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(short) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(short)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to short" :
+                    "value too large to convert to short");
+            }
+            return (short)-1;
+        }
+        return (short)val;
+    }
+    return (short)__Pyx_PyInt_AsLong(x);
+}
+
+static CYTHON_INLINE int __Pyx_PyInt_AsInt(PyObject* x) {
+    const int neg_one = (int)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(int) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(int)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to int" :
+                    "value too large to convert to int");
+            }
+            return (int)-1;
+        }
+        return (int)val;
+    }
+    return (int)__Pyx_PyInt_AsLong(x);
+}
+
+static CYTHON_INLINE signed char __Pyx_PyInt_AsSignedChar(PyObject* x) {
+    const signed char neg_one = (signed char)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(signed char) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(signed char)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to signed char" :
+                    "value too large to convert to signed char");
+            }
+            return (signed char)-1;
+        }
+        return (signed char)val;
+    }
+    return (signed char)__Pyx_PyInt_AsSignedLong(x);
+}
+
+static CYTHON_INLINE signed short __Pyx_PyInt_AsSignedShort(PyObject* x) {
+    const signed short neg_one = (signed short)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(signed short) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(signed short)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to signed short" :
+                    "value too large to convert to signed short");
+            }
+            return (signed short)-1;
+        }
+        return (signed short)val;
+    }
+    return (signed short)__Pyx_PyInt_AsSignedLong(x);
+}
+
+static CYTHON_INLINE signed int __Pyx_PyInt_AsSignedInt(PyObject* x) {
+    const signed int neg_one = (signed int)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(signed int) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(signed int)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to signed int" :
+                    "value too large to convert to signed int");
+            }
+            return (signed int)-1;
+        }
+        return (signed int)val;
+    }
+    return (signed int)__Pyx_PyInt_AsSignedLong(x);
+}
+
+static CYTHON_INLINE int __Pyx_PyInt_AsLongDouble(PyObject* x) {
+    const int neg_one = (int)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(int) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(int)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to int" :
+                    "value too large to convert to int");
+            }
+            return (int)-1;
+        }
+        return (int)val;
+    }
+    return (int)__Pyx_PyInt_AsLong(x);
+}
+
+static CYTHON_INLINE unsigned long __Pyx_PyInt_AsUnsignedLong(PyObject* x) {
+    const unsigned long neg_one = (unsigned long)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to unsigned long");
+            return (unsigned long)-1;
+        }
+        return (unsigned long)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to unsigned long");
+                return (unsigned long)-1;
+            }
+            return (unsigned long)PyLong_AsUnsignedLong(x);
+        } else {
+            return (unsigned long)PyLong_AsLong(x);
+        }
+    } else {
+        unsigned long val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (unsigned long)-1;
+        val = __Pyx_PyInt_AsUnsignedLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE unsigned PY_LONG_LONG __Pyx_PyInt_AsUnsignedLongLong(PyObject* x) {
+    const unsigned PY_LONG_LONG neg_one = (unsigned PY_LONG_LONG)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to unsigned PY_LONG_LONG");
+            return (unsigned PY_LONG_LONG)-1;
+        }
+        return (unsigned PY_LONG_LONG)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to unsigned PY_LONG_LONG");
+                return (unsigned PY_LONG_LONG)-1;
+            }
+            return (unsigned PY_LONG_LONG)PyLong_AsUnsignedLongLong(x);
+        } else {
+            return (unsigned PY_LONG_LONG)PyLong_AsLongLong(x);
+        }
+    } else {
+        unsigned PY_LONG_LONG val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (unsigned PY_LONG_LONG)-1;
+        val = __Pyx_PyInt_AsUnsignedLongLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE long __Pyx_PyInt_AsLong(PyObject* x) {
+    const long neg_one = (long)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to long");
+            return (long)-1;
+        }
+        return (long)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to long");
+                return (long)-1;
+            }
+            return (long)PyLong_AsUnsignedLong(x);
+        } else {
+            return (long)PyLong_AsLong(x);
+        }
+    } else {
+        long val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (long)-1;
+        val = __Pyx_PyInt_AsLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE PY_LONG_LONG __Pyx_PyInt_AsLongLong(PyObject* x) {
+    const PY_LONG_LONG neg_one = (PY_LONG_LONG)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to PY_LONG_LONG");
+            return (PY_LONG_LONG)-1;
+        }
+        return (PY_LONG_LONG)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to PY_LONG_LONG");
+                return (PY_LONG_LONG)-1;
+            }
+            return (PY_LONG_LONG)PyLong_AsUnsignedLongLong(x);
+        } else {
+            return (PY_LONG_LONG)PyLong_AsLongLong(x);
+        }
+    } else {
+        PY_LONG_LONG val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (PY_LONG_LONG)-1;
+        val = __Pyx_PyInt_AsLongLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE signed long __Pyx_PyInt_AsSignedLong(PyObject* x) {
+    const signed long neg_one = (signed long)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to signed long");
+            return (signed long)-1;
+        }
+        return (signed long)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to signed long");
+                return (signed long)-1;
+            }
+            return (signed long)PyLong_AsUnsignedLong(x);
+        } else {
+            return (signed long)PyLong_AsLong(x);
+        }
+    } else {
+        signed long val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (signed long)-1;
+        val = __Pyx_PyInt_AsSignedLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE signed PY_LONG_LONG __Pyx_PyInt_AsSignedLongLong(PyObject* x) {
+    const signed PY_LONG_LONG neg_one = (signed PY_LONG_LONG)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to signed PY_LONG_LONG");
+            return (signed PY_LONG_LONG)-1;
+        }
+        return (signed PY_LONG_LONG)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to signed PY_LONG_LONG");
+                return (signed PY_LONG_LONG)-1;
+            }
+            return (signed PY_LONG_LONG)PyLong_AsUnsignedLongLong(x);
+        } else {
+            return (signed PY_LONG_LONG)PyLong_AsLongLong(x);
+        }
+    } else {
+        signed PY_LONG_LONG val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (signed PY_LONG_LONG)-1;
+        val = __Pyx_PyInt_AsSignedLongLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static int __Pyx_check_binary_version(void) {
+    char ctversion[4], rtversion[4];
+    PyOS_snprintf(ctversion, 4, "%d.%d", PY_MAJOR_VERSION, PY_MINOR_VERSION);
+    PyOS_snprintf(rtversion, 4, "%s", Py_GetVersion());
+    if (ctversion[0] != rtversion[0] || ctversion[2] != rtversion[2]) {
+        char message[200];
+        PyOS_snprintf(message, sizeof(message),
+                      "compiletime version %s of module '%.100s' "
+                      "does not match runtime version %s",
+                      ctversion, __Pyx_MODULE_NAME, rtversion);
+        #if PY_VERSION_HEX < 0x02050000
+        return PyErr_Warn(NULL, message);
+        #else
+        return PyErr_WarnEx(NULL, message, 1);
+        #endif
+    }
+    return 0;
+}
+
+static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) {
+    int start = 0, mid = 0, end = count - 1;
+    if (end >= 0 && code_line > entries[end].code_line) {
+        return count;
+    }
+    while (start < end) {
+        mid = (start + end) / 2;
+        if (code_line < entries[mid].code_line) {
+            end = mid;
+        } else if (code_line > entries[mid].code_line) {
+             start = mid + 1;
+        } else {
+            return mid;
+        }
+    }
+    if (code_line <= entries[mid].code_line) {
+        return mid;
+    } else {
+        return mid + 1;
+    }
+}
+static PyCodeObject *__pyx_find_code_object(int code_line) {
+    PyCodeObject* code_object;
+    int pos;
+    if (unlikely(!code_line) || unlikely(!__pyx_code_cache.entries)) {
+        return NULL;
+    }
+    pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line);
+    if (unlikely(pos >= __pyx_code_cache.count) || unlikely(__pyx_code_cache.entries[pos].code_line != code_line)) {
+        return NULL;
+    }
+    code_object = __pyx_code_cache.entries[pos].code_object;
+    Py_INCREF(code_object);
+    return code_object;
+}
+static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) {
+    int pos, i;
+    __Pyx_CodeObjectCacheEntry* entries = __pyx_code_cache.entries;
+    if (unlikely(!code_line)) {
+        return;
+    }
+    if (unlikely(!entries)) {
+        entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Malloc(64*sizeof(__Pyx_CodeObjectCacheEntry));
+        if (likely(entries)) {
+            __pyx_code_cache.entries = entries;
+            __pyx_code_cache.max_count = 64;
+            __pyx_code_cache.count = 1;
+            entries[0].code_line = code_line;
+            entries[0].code_object = code_object;
+            Py_INCREF(code_object);
+        }
+        return;
+    }
+    pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line);
+    if ((pos < __pyx_code_cache.count) && unlikely(__pyx_code_cache.entries[pos].code_line == code_line)) {
+        PyCodeObject* tmp = entries[pos].code_object;
+        entries[pos].code_object = code_object;
+        Py_DECREF(tmp);
+        return;
+    }
+    if (__pyx_code_cache.count == __pyx_code_cache.max_count) {
+        int new_max = __pyx_code_cache.max_count + 64;
+        entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Realloc(
+            __pyx_code_cache.entries, new_max*sizeof(__Pyx_CodeObjectCacheEntry));
+        if (unlikely(!entries)) {
+            return;
+        }
+        __pyx_code_cache.entries = entries;
+        __pyx_code_cache.max_count = new_max;
+    }
+    for (i=__pyx_code_cache.count; i>pos; i--) {
+        entries[i] = entries[i-1];
+    }
+    entries[pos].code_line = code_line;
+    entries[pos].code_object = code_object;
+    __pyx_code_cache.count++;
+    Py_INCREF(code_object);
+}
+
+#include "compile.h"
+#include "frameobject.h"
+#include "traceback.h"
+static PyCodeObject* __Pyx_CreateCodeObjectForTraceback(
+            const char *funcname, int c_line,
+            int py_line, const char *filename) {
+    PyCodeObject *py_code = 0;
+    PyObject *py_srcfile = 0;
+    PyObject *py_funcname = 0;
+    #if PY_MAJOR_VERSION < 3
+    py_srcfile = PyString_FromString(filename);
+    #else
+    py_srcfile = PyUnicode_FromString(filename);
+    #endif
+    if (!py_srcfile) goto bad;
+    if (c_line) {
+        #if PY_MAJOR_VERSION < 3
+        py_funcname = PyString_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line);
+        #else
+        py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line);
+        #endif
+    }
+    else {
+        #if PY_MAJOR_VERSION < 3
+        py_funcname = PyString_FromString(funcname);
+        #else
+        py_funcname = PyUnicode_FromString(funcname);
+        #endif
+    }
+    if (!py_funcname) goto bad;
+    py_code = __Pyx_PyCode_New(
+        0,            /*int argcount,*/
+        0,            /*int kwonlyargcount,*/
+        0,            /*int nlocals,*/
+        0,            /*int stacksize,*/
+        0,            /*int flags,*/
+        __pyx_empty_bytes, /*PyObject *code,*/
+        __pyx_empty_tuple, /*PyObject *consts,*/
+        __pyx_empty_tuple, /*PyObject *names,*/
+        __pyx_empty_tuple, /*PyObject *varnames,*/
+        __pyx_empty_tuple, /*PyObject *freevars,*/
+        __pyx_empty_tuple, /*PyObject *cellvars,*/
+        py_srcfile,   /*PyObject *filename,*/
+        py_funcname,  /*PyObject *name,*/
+        py_line,      /*int firstlineno,*/
+        __pyx_empty_bytes  /*PyObject *lnotab*/
+    );
+    Py_DECREF(py_srcfile);
+    Py_DECREF(py_funcname);
+    return py_code;
+bad:
+    Py_XDECREF(py_srcfile);
+    Py_XDECREF(py_funcname);
+    return NULL;
+}
+static void __Pyx_AddTraceback(const char *funcname, int c_line,
+                               int py_line, const char *filename) {
+    PyCodeObject *py_code = 0;
+    PyObject *py_globals = 0;
+    PyFrameObject *py_frame = 0;
+    py_code = __pyx_find_code_object(c_line ? c_line : py_line);
+    if (!py_code) {
+        py_code = __Pyx_CreateCodeObjectForTraceback(
+            funcname, c_line, py_line, filename);
+        if (!py_code) goto bad;
+        __pyx_insert_code_object(c_line ? c_line : py_line, py_code);
+    }
+    py_globals = PyModule_GetDict(__pyx_m);
+    if (!py_globals) goto bad;
+    py_frame = PyFrame_New(
+        PyThreadState_GET(), /*PyThreadState *tstate,*/
+        py_code,             /*PyCodeObject *code,*/
+        py_globals,          /*PyObject *globals,*/
+        0                    /*PyObject *locals*/
+    );
+    if (!py_frame) goto bad;
+    py_frame->f_lineno = py_line;
+    PyTraceBack_Here(py_frame);
+bad:
+    Py_XDECREF(py_code);
+    Py_XDECREF(py_frame);
+}
+
+static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
+    while (t->p) {
+        #if PY_MAJOR_VERSION < 3
+        if (t->is_unicode) {
+            *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
+        } else if (t->intern) {
+            *t->p = PyString_InternFromString(t->s);
+        } else {
+            *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
+        }
+        #else  /* Python 3+ has unicode identifiers */
+        if (t->is_unicode | t->is_str) {
+            if (t->intern) {
+                *t->p = PyUnicode_InternFromString(t->s);
+            } else if (t->encoding) {
+                *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL);
+            } else {
+                *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
+            }
+        } else {
+            *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
+        }
+        #endif
+        if (!*t->p)
+            return -1;
+        ++t;
+    }
+    return 0;
+}
+
+static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) {
+   int is_true = x == Py_True;
+   if (is_true | (x == Py_False) | (x == Py_None)) return is_true;
+   else return PyObject_IsTrue(x);
+}
+static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x) {
+  PyNumberMethods *m;
+  const char *name = NULL;
+  PyObject *res = NULL;
+#if PY_VERSION_HEX < 0x03000000
+  if (PyInt_Check(x) || PyLong_Check(x))
+#else
+  if (PyLong_Check(x))
+#endif
+    return Py_INCREF(x), x;
+  m = Py_TYPE(x)->tp_as_number;
+#if PY_VERSION_HEX < 0x03000000
+  if (m && m->nb_int) {
+    name = "int";
+    res = PyNumber_Int(x);
+  }
+  else if (m && m->nb_long) {
+    name = "long";
+    res = PyNumber_Long(x);
+  }
+#else
+  if (m && m->nb_int) {
+    name = "int";
+    res = PyNumber_Long(x);
+  }
+#endif
+  if (res) {
+#if PY_VERSION_HEX < 0x03000000
+    if (!PyInt_Check(res) && !PyLong_Check(res)) {
+#else
+    if (!PyLong_Check(res)) {
+#endif
+      PyErr_Format(PyExc_TypeError,
+                   "__%s__ returned non-%s (type %.200s)",
+                   name, name, Py_TYPE(res)->tp_name);
+      Py_DECREF(res);
+      return NULL;
+    }
+  }
+  else if (!PyErr_Occurred()) {
+    PyErr_SetString(PyExc_TypeError,
+                    "an integer is required");
+  }
+  return res;
+}
+static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) {
+  Py_ssize_t ival;
+  PyObject* x = PyNumber_Index(b);
+  if (!x) return -1;
+  ival = PyInt_AsSsize_t(x);
+  Py_DECREF(x);
+  return ival;
+}
+static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) {
+#if PY_VERSION_HEX < 0x02050000
+   if (ival <= LONG_MAX)
+       return PyInt_FromLong((long)ival);
+   else {
+       unsigned char *bytes = (unsigned char *) &ival;
+       int one = 1; int little = (int)*(unsigned char*)&one;
+       return _PyLong_FromByteArray(bytes, sizeof(size_t), little, 0);
+   }
+#else
+   return PyInt_FromSize_t(ival);
+#endif
+}
+static CYTHON_INLINE size_t __Pyx_PyInt_AsSize_t(PyObject* x) {
+   unsigned PY_LONG_LONG val = __Pyx_PyInt_AsUnsignedLongLong(x);
+   if (unlikely(val == (unsigned PY_LONG_LONG)-1 && PyErr_Occurred())) {
+       return (size_t)-1;
+   } else if (unlikely(val != (unsigned PY_LONG_LONG)(size_t)val)) {
+       PyErr_SetString(PyExc_OverflowError,
+                       "value too large to convert to size_t");
+       return (size_t)-1;
+   }
+   return (size_t)val;
+}
+
+
+#endif /* Py_PYTHON_H */
diff --git a/lib/bx/bbi/cirtree_file.pxd b/lib/bx/bbi/cirtree_file.pxd
new file mode 100644
index 0000000..f6ef36f
--- /dev/null
+++ b/lib/bx/bbi/cirtree_file.pxd
@@ -0,0 +1,15 @@
+from types cimport *
+
+cdef class CIRTreeFile:
+    cdef object file
+    cdef object reader
+    cdef boolean is_byteswapped
+    cdef bits64 root_offset
+    cdef bits32 block_size
+    cdef bits64 item_count
+    cdef bits32 start_chrom_ix
+    cdef bits32 start_base
+    cdef bits32 end_chrom_ix
+    cdef bits32 end_base
+    cdef bits64 file_size
+    cdef bits32 items_per_slot
diff --git a/lib/bx/bbi/cirtree_file.pyx b/lib/bx/bbi/cirtree_file.pyx
new file mode 100644
index 0000000..8820699
--- /dev/null
+++ b/lib/bx/bbi/cirtree_file.pyx
@@ -0,0 +1,105 @@
+from bx.misc.binary_file import BinaryFileReader
+
+DEF cir_tree_sig = 0x2468ACE0
+
+cdef int ovcmp( bits32 a_hi, bits32 a_lo, bits32 b_hi, bits32 b_lo ):
+    if a_hi < b_hi: 
+        return 1
+    elif a_hi > b_hi:
+        return -1
+    else:
+        if a_lo < b_lo:
+            return 1
+        elif a_lo > b_lo:
+            return -1
+        else:
+            return 0
+
+cdef overlaps( qchrom, qstart, qend, rstartchrom, rstartbase, rendchrom, rendbase ):
+    return ( ovcmp( qchrom, qstart, rendchrom, rendbase ) > 0 ) and \
+           ( ovcmp( qchrom, qend, rstartchrom, rstartbase ) < 0 )
+
+cdef class CIRTreeFile:
+
+    def __init__( self, file=None ):
+        if file is not None:
+            self.attach( file )
+
+    def attach( self, file ):
+        """
+        Attach to an open file
+        """
+        self.file = file
+        self.reader = reader = BinaryFileReader( file, cir_tree_sig )
+        self.is_byteswapped = self.reader.byteswap_needed
+        # Header
+        self.block_size = reader.read_uint32()
+        self.item_count = reader.read_uint64()
+        self.start_chrom_ix  = reader.read_uint32()
+        self.start_base = reader.read_uint32()
+        self.end_chrom_ix = reader.read_uint32()
+        self.end_base = reader.read_uint32()
+        self.file_size = reader.read_uint64()
+        self.items_per_slot = reader.read_uint32()
+        # Skip reserved
+        reader.read_uint32()
+        # Save root
+        self.root_offset = reader.tell()
+
+    def r_find_overlapping( self, int level, bits64 index_file_offset, bits32 chrom_ix, bits32 start, bits32 end, object rval, object reader ):
+        cdef UBYTE is_leaf
+        cdef bits16 child_count
+        reader.seek( index_file_offset )
+        # Block header
+        is_leaf = reader.read_uint8()
+        assert is_leaf == 0 or is_leaf == 1
+        reader.read_uint8()
+        child_count = reader.read_uint16()
+        # Read block
+        if is_leaf:
+            self.r_find_overlapping_leaf( level, chrom_ix, start, end, rval, child_count, reader )
+        else:
+            self.r_find_overlapping_parent( level, chrom_ix, start, end, rval, child_count, reader )
+
+    def r_find_overlapping_leaf( self, int level, bits32 chrom_ix, bits32 start, bits32 end, object rval, 
+                                bits16 child_count, object reader ):
+        cdef bits32 start_chrom_ix, start_base, end_chrom_ix, end_base
+        cdef bits64 offset
+        cdef bits64 size
+        for i from 0 <= i < child_count:
+            start_chrom_ix = reader.read_uint32()
+            start_base = reader.read_uint32()
+            end_chrom_ix = reader.read_uint32()
+            end_base = reader.read_uint32()
+            offset = reader.read_uint64()
+            size = reader.read_uint64()
+            if overlaps( chrom_ix, start, end, start_chrom_ix, start_base, end_chrom_ix, end_base ):
+                rval.append( ( offset, size ) )
+
+    def r_find_overlapping_parent( self, int level, bits32 chrom_ix, bits32 start, bits32 end, object rval, 
+                                  bits16 child_count, object reader ):
+        # Read and cache offsets for all children to avoid excessive seeking
+        ## cdef bits32 start_chrom_ix[child_count], start_base[child_count], end_chrom_ix[child_count], end_base[child_count]
+        ## cdef bits64 offset[child_count]
+        start_chrom_ix = []; start_base = []; end_chrom_ix = []; end_base = []
+        offset = []
+        for i from 0 <= i < child_count:
+            ## start_chrom_ix[i] = reader.read_bits32()
+            ## start_base[i] = reader.read_bits32()
+            ## end_chrom_ix[i] = reader.read_bits32()
+            ## end_base[i] = reader.read_bits32()
+            ## offset[i] = reader.read_bits64()
+            start_chrom_ix.append( reader.read_uint32() )
+            start_base.append( reader.read_uint32() )
+            end_chrom_ix.append( reader.read_uint32() )
+            end_base.append( reader.read_uint32() )
+            offset.append( reader.read_uint64() )
+        # Now recurse
+        for i from 0 <= i < child_count:
+            if overlaps( chrom_ix, start, end, start_chrom_ix[i], start_base[i], end_chrom_ix[i], end_base[i] ):
+                self.r_find_overlapping( level + 1, offset[i], chrom_ix, start, end, rval, reader )
+
+    def find_overlapping_blocks( self, bits32 chrom_ix, bits32 start, bits32 end ):
+        rval = []
+        self.r_find_overlapping( 0, self.root_offset, chrom_ix, start, end, rval, self.reader )
+        return rval
diff --git a/lib/bx/bbi/types.pxd b/lib/bx/bbi/types.pxd
new file mode 100644
index 0000000..8c180be
--- /dev/null
+++ b/lib/bx/bbi/types.pxd
@@ -0,0 +1,12 @@
+ctypedef unsigned char UBYTE 
+ctypedef signed char BYTE 
+ctypedef unsigned short UWORD 
+ctypedef short WORD         
+ctypedef unsigned long long bits64 
+ctypedef unsigned bits32    
+ctypedef unsigned short bits16
+ctypedef unsigned char bits8
+ctypedef int signed32
+
+ctypedef bint boolean
+
diff --git a/lib/bx/binned_array.py b/lib/bx/binned_array.py
new file mode 100644
index 0000000..dfeec4f
--- /dev/null
+++ b/lib/bx/binned_array.py
@@ -0,0 +1,345 @@
+"""
+Numeric arrays stored as individually compressed blocks on disk, allowing
+pseudo-random acccess. 
+
+`BinnedArray` is used to build such an array in memory and save it to disk.
+`BinnedArrayWriter` can instead be used when creating the array sequentially
+(does not require keeping all data in memory). `FileBinnedArray` provides
+read only access to an on disk binned array. 
+"""
+
+from __future__ import division
+
+import math
+
+from numpy import *
+from struct import *
+from bx_extras.lrucache import LRUCache
+
+import sys
+platform_is_little_endian = ( sys.byteorder == 'little' )
+
+MAGIC=0x4AB04612
+
+# Version incremented from version 0 to version 1 by Ian Schenck, June
+# 23, 2006.  Version 1 supports different typecodes, and in doing so
+# breaks the original header format.  The new FileBinnedArray is
+# backwards compatible with version 0.
+
+# Version 1 -> 2 by James Taylor, allow specifying different compression 
+# types.
+
+VERSION=2
+
+# Compression types
+
+comp_types = dict()
+
+comp_types['none'] = ( lambda x: x, lambda x: x )
+
+try:
+    import zlib
+    comp_types['zlib'] = ( zlib.compress, zlib.decompress )
+except:
+    pass
+    
+try:
+    import lzo
+    comp_types['lzo'] = ( lzo.compress, lzo.decompress )
+except:
+    pass
+
+
+MAX=512*1024*1024 
+
+class BinnedArray( object ):
+    def __init__( self, bin_size=512*1024, default=NaN, max_size=MAX, typecode="f" ):
+        self.max_size = max_size
+        self.bin_size = bin_size
+        self.nbins = int( math.ceil( ( max_size / self.bin_size ) ) )
+        self.bins = [ None ] * self.nbins
+        self.default = default
+        self.typecode = typecode
+    def get_bin_offset( self, index ):
+        return index // self.bin_size, index % self.bin_size
+    def init_bin( self, index ):
+        # self.bins[index] = zeros( self.bin_size ) * self.default
+        self.bins[index] = zeros( self.bin_size, self.typecode )
+        self.bins[index][:] = self.default
+    def get( self, key ):
+        bin, offset = self.get_bin_offset( key )
+        if self.bins[bin] is None:
+            return self.default
+        else:
+            return self.bins[bin][offset]
+    def set( self, key, value ):
+        bin, offset = self.get_bin_offset( key )
+        if self.bins[bin] is None: 
+            self.init_bin( bin )
+        self.bins[bin][offset] = value
+    def get_range( self, start, end ):
+        size = end - start
+        assert size >= 0
+        rval = []
+        while size > 0:
+            bin, offset = self.get_bin_offset( start )
+            delta = self.bin_size - offset
+            if self.bins[bin] is None:
+                if delta < size:
+                    rval.append( resize( array(self.default, self.typecode), (delta,) ) )
+                    size -= delta
+                    start += delta
+                else:
+                    rval.append( resize( array(self.default, "f"), (size,) ) )
+                    size = 0
+            else:
+                if delta < size:
+                    rval.append( self.bins[bin][offset:offset+delta] )
+                    size -= delta
+                    start += delta
+                else:
+                    rval.append( self.bins[bin][offset:offset+size] )
+                    size = 0
+        return concatenate( rval )
+    def __getitem__( self, key ):
+        if isinstance( key, slice ):
+            start, stop, stride = key.indices( self.max_size )
+            assert stride == 1, "Slices with strides are not supported"
+            return self.get_range( start, stop )
+        else:
+            return self.get( key )
+    def __setitem__( self, key, value ):
+        return self.set( key, value )
+    def to_file( self, f, comp_type='zlib' ):
+        # Get compress method
+        compress, _ = comp_types[comp_type]
+        # Write header
+        write_packed( f, ">5I", MAGIC, VERSION, self.max_size, self.bin_size, self.nbins )
+        # save type code
+        f.write( pack('c',self.typecode ) )
+        # save compression type
+        f.write( comp_type[0:4].ljust( 4 ) )
+        # write default value
+        a = array( self.default, self.typecode ) 
+        # Struct module can't deal with NaN and endian conversion, we'll hack 
+        # around that by byteswapping the array
+        if platform_is_little_endian: 
+            a = a.byteswap()
+        f.write( a.tostring() )
+        # Save current position (start of bin offsets)
+        index_start_pos = f.tell()
+        # Skip forward to save space for index
+        f.seek( calcsize( ">2I" ) * self.nbins, 1 )
+        bin_pos_and_size = []
+        # Write each bin
+        for bin in self.bins:
+            if bin is None: 
+                bin_pos_and_size.append( ( 0, 0 ) )
+            else:
+                assert bin.dtype.char == self.typecode
+                if platform_is_little_endian:
+                    s = bin.byteswap().tostring()
+                else:
+                    s = bin.tostring()
+                compressed = compress( s )
+                bin_pos_and_size.append( ( f.tell(), len( compressed ) ) )
+                f.write( compressed )
+        # Go back and fill in table
+        f.seek( index_start_pos )
+        for pos, size in bin_pos_and_size:
+            write_packed( f, ">2I", pos, size )
+            
+class FileBinnedArray( object ):
+    def __init__( self, f, cache=32):
+        # If cache=None, then everything is allowed to stay in memory,
+        # this is the default behavior.
+        self.f = f
+        M, V, max_size, bin_size, nbins = read_packed( f, ">5I" )
+        assert M == MAGIC
+        # assert version less than max supported
+        assert V <= VERSION, "File is version %d but I don't know about anything beyond %d" % ( V, VERSION )
+        self.max_size = max_size
+        self.bin_size = bin_size
+        self.nbins = nbins        
+        self.bins = LRUCache(size=cache)
+        # Read typecode
+        if V >= 1:
+            self.typecode = unpack( 'c', f.read(1) )[0]
+        else:
+            self.typecode = 'f'
+        # Read compression type
+        if V >= 2:
+            self.comp_type = f.read( 4 ).strip()
+        else:
+            self.comp_type = 'zlib'
+        self.decompress = comp_types[self.comp_type][1]
+        # Read default value
+        s = f.read( calcsize( self.typecode ) )
+        a = fromstring( s, self.typecode )
+        if platform_is_little_endian: 
+            a = a.byteswap()
+        self.default = a[0]
+        # Read bin sizes and offsets
+        self.bin_pos = []
+        self.bin_sizes = []
+        for i in range( nbins ):
+            pos, size = read_packed( f, ">2I" )
+            self.bin_pos.append( pos )
+            self.bin_sizes.append( size )
+    def get_bin_offset( self, index ):
+        return int( index // self.bin_size ), int( index % self.bin_size )
+    def load_bin( self, index ):
+        assert self.bin_pos[index] != 0
+        self.f.seek( self.bin_pos[index] )
+        raw = self.f.read( self.bin_sizes[index] )
+        a = fromstring( self.decompress( raw ), self.typecode )
+        if platform_is_little_endian:
+            a = a.byteswap()
+        assert len( a ) == self.bin_size
+        self.bins[index] = a
+    def get( self, key ):
+        bin, offset = self.get_bin_offset( key )
+        if bin in self.bins:
+            return self.bins[bin][offset]
+        elif self.bin_pos[bin]:
+            self.load_bin( bin )
+            return self.bins[bin][offset]
+        else:
+            return self.default
+    def get_range( self, start, end ):
+        size = end - start
+        assert size >= 0
+        rval = []
+        while size > 0:
+            bin, offset = self.get_bin_offset( start )
+            delta = self.bin_size - offset
+            if not bin in self.bins and self.bin_pos[bin] != 0:
+                self.load_bin( bin )
+            if self.bins[bin] is None:
+                if delta < size:
+                    rval.append( resize( array(self.default, self.typecode), (delta,) ) )
+                    size -= delta
+                    start += delta
+                else:
+                    rval.append( resize( array(self.default, self.typecode), (size,) ) )
+                    size = 0
+            else:
+                if delta < size:
+                    rval.append( self.bins[bin][offset:offset+delta] )
+                    size -= delta
+                    start += delta
+                else:
+                    rval.append( self.bins[bin][offset:offset+size] )
+                    size = 0
+        return concatenate( rval )
+    def __getitem__( self, key ):
+        if isinstance( key, slice ):
+            start, stop, stride = key.indices( self.max_size )
+            assert stride == 1, "Slices with strides are not supported"
+            return self.get_range( start, stop )
+        else:
+            return self.get( key )
+        
+class BinnedArrayWriter( object ):
+    def __init__( self, f, bin_size=512*1024, default=NaN, max_size=MAX, typecode="f", comp_type='zlib' ):
+        # All parameters in the constructor are immutable after creation
+        self.f = f
+        self.max_size = max_size
+        self.bin_size = bin_size
+        self.nbins = int( math.ceil( ( max_size / self.bin_size ) ) )
+        self.default = default
+        self.typecode = typecode
+        self.bin = 0
+        self.bin_pos = 0
+        self.bin_index = []
+        self.buffer = resize( array(self.default, self.typecode), (self.bin_size,) )
+        self.buffer_contains_values = False
+        self.comp_type = comp_type
+        self.compress = comp_types[comp_type][0]
+        self.write_header()
+        # Start the first bin
+        ## self.bin_index = [ (self.data_offset, 0) ]
+        # Put the fp at the start of the data (we go back and fill in the index at the end)
+        self.f.seek( self.data_offset )
+
+    def write_header( self ):
+        self.f.seek(0)
+        # Write header
+        write_packed( self.f, ">5I", MAGIC, VERSION, self.max_size, self.bin_size, self.nbins )
+        # save type code
+        self.f.write( pack('c',self.typecode ) )
+        # write default value
+        a = array( self.default, self.typecode ) 
+        # write comp type
+        self.f.write( self.comp_type[0:4].ljust(4) )
+        # write default
+        # Struct module can't deal with NaN and endian conversion, we'll hack 
+        # around that by byteswapping the array
+        if platform_is_little_endian: 
+            a = a.byteswap()
+        self.f.write( a.tostring() )
+        # Save current position (start of bin offsets)
+        self.index_pos = self.f.tell()
+        self.data_offset = self.index_pos + (self.nbins * calcsize( ">2I" ))
+        
+    def write_index( self ):
+        self.f.seek(self.index_pos)
+        for pos, size in self.bin_index:
+            write_packed( self.f, ">2I", pos, size )
+
+    def skip( self ):
+        self.bin_pos += 1
+        if self.bin_pos == self.bin_size:
+            self.flush()
+            self.bin_pos = 0
+            self.bin += 1
+            assert self.bin <= self.nbins
+            self.buffer = resize( array(self.default, self.typecode), (self.bin_size,) )
+            self.buffer_contains_values = False
+            ## self.bin_index.append( (self.f.tell(), 0) )
+
+    def write( self, data ):
+        self.buffer[self.bin_pos] = data
+        self.buffer_contains_values = True
+        self.bin_pos += 1
+        if self.bin_pos == self.bin_size:
+            self.flush()
+            self.bin_pos = 0
+            self.bin += 1
+            assert self.bin <= self.nbins
+            self.buffer = resize( array(self.default, self.typecode), (self.bin_size,) )
+            self.buffer_contains_values = False
+            ## self.bin_index.append( (self.f.tell(), 0) )
+
+    def flush( self ):
+        # Flush buffer to file
+        if self.buffer_contains_values:
+            ## pos, size = self.bin_index[self.bin]
+            ## self.f.seek( pos )
+            pos = self.f.tell()
+            if platform_is_little_endian:
+                s = self.buffer.byteswap().tostring()
+            else:
+                s = self.buffer.tostring()
+            compressed = self.compress( s )
+            size = len( compressed )
+            assert len( self.bin_index ) == self.bin
+            self.bin_index.append( ( pos, size ) )
+            self.f.write( compressed )
+        else:
+            assert len( self.bin_index ) == self.bin
+            self.bin_index.append( ( 0, 0 ) )
+
+    def finish( self ):
+        self.flush()
+        self.nbins = self.bin + 1
+        self.write_header()
+        self.write_index()
+
+def write_packed( f, pattern, *vals ):
+    f.write( pack( pattern, *vals ) )
+    
+def read_packed( f, pattern ):
+    rval = unpack( pattern, f.read( calcsize( pattern ) ) )
+    if len( rval ) == 1: return rval[0]
+    return rval
\ No newline at end of file
diff --git a/lib/bx/binned_array_tests.py b/lib/bx/binned_array_tests.py
new file mode 100644
index 0000000..d7eb1c8
--- /dev/null
+++ b/lib/bx/binned_array_tests.py
@@ -0,0 +1,93 @@
+"""
+Tests for `bx.binned_array`.
+"""
+
+from numpy import *
+from binned_array import *
+
+random = random.random
+ 
+# Bigger values take longer, but excercise more bins
+CHUNK_SIZE_RANDOM=945
+CHUNK_SIZE_ZEROS=897
+##CHUNK_SIZE_RANDOM=9456
+##CHUNK_SIZE_ZEROS=8972
+
+source = target = None
+
+def setup():
+    global source
+    global target
+    source = []
+    for i in range( 13 ):
+        if random() < 0.5:
+            source = concatenate( ( source, random( CHUNK_SIZE_RANDOM ) ) )
+        else:
+            source = concatenate( ( source, zeros( CHUNK_SIZE_ZEROS, 'f' ) ) )
+    source = source.astype( 'f' )
+    # Set on target
+    target = BinnedArray( 128, NaN, len( source ) )
+    for i in range( len( source ) ):
+        # if not isNaN( source[i] ):
+            target[i] = source[i]
+    return source, target
+
+def test_simple():
+    # Verify
+    for i in range( len( source ) ):
+        assert source[i] == target[i], "No match, index: %d, source: %f, target: %f, len( source ): %d" % ( i, source[i], target[i], len( source ) )
+    # Verify with slices
+    for i in range( 10 ):
+        a = int( random() * len( source ) )
+        b = int( random() * len( source ) )
+        if b < a: a, b = b, a
+        assert allclose( source[a:b], target[a:b] ), "No match, index: %d:%d, source: %s, target: %s" % \
+            ( a, b, ",".join( map( str, source[a:a+10] ) ), ",".join( map( str, target[a:a+10] ) ) )
+ 
+def test_file():
+    # With a file (zlib)
+    target.to_file( open( "/tmp/foo", "w" ) )
+    target2 = FileBinnedArray( open( "/tmp/foo" ) )
+    for i in range( len( source ) ):
+        assert source[i] == target2[i], "No match, index: %d, source: %d, target: %d" % ( i, source[i], target2[i] )
+    # Verify with slices
+    target2 = FileBinnedArray( open( "/tmp/foo" ) )
+    for i in range( 10 ):
+        a = int( random() * len( source ) )
+        b = int( random() * len( source ) )
+        if b < a: a, b = b, a
+        assert allclose( source[a:b], target[a:b] ), "No match, index: %d:%d, source: %s, target: %s" % \
+            ( a, b, ",".join( map( str, source[a:a+10] ) ), ",".join( map( str, target2[a:a+10] ) ) )
+            
+def test_file_lzo():
+    # With a file (lzo)
+    target.to_file( open( "/tmp/foo3", "w" ), comp_type="lzo" )
+    target3 = FileBinnedArray( open( "/tmp/foo3" ) )
+    # Verify
+    for i in range( len( source ) ):
+        assert source[i] == target3[i], "No match, index: %d, source: %d, target: %d" % ( i, source[i], target3[i] )
+    # Verify with slices
+    target3 = FileBinnedArray( open( "/tmp/foo3" ) )
+    for i in range( 10 ):
+        a = int( random() * len( source ) )
+        b = int( random() * len( source ) )
+        if b < a: a, b = b, a
+        assert allclose( source[a:b], target3[a:b] ), "No match, index: %d:%d, source: %s, target: %s" % \
+            ( a, b, ",".join( map( str, source[a:a+10] ) ), ",".join( map( str, target3[a:a+10] ) ) )
+            
+def test_binned_array_writer():
+    # Test with ba writer
+    o = open( "/tmp/foo4", "w" )
+    w = BinnedArrayWriter( o, 128, comp_type='lzo' )
+    for val in source:
+        w.write( val )
+    w.finish()
+    o.close()
+    # Verify
+    target4 = FileBinnedArray( open( "/tmp/foo4" ) )
+    for i in range( len( source ) ):
+        assert allclose( source[i], target4[i] ), "No match, index: %d, source: %d, target: %d" % ( i, source[i], target4[i] )
+            
+            
+            
+            
diff --git a/lib/bx/bitset.c b/lib/bx/bitset.c
new file mode 100644
index 0000000..fb9c844
--- /dev/null
+++ b/lib/bx/bitset.c
@@ -0,0 +1,5871 @@
+/* Generated by Cython 0.18 on Mon Jul 15 13:25:44 2013 */
+
+#define PY_SSIZE_T_CLEAN
+#include "Python.h"
+#ifndef Py_PYTHON_H
+    #error Python headers needed to compile C extensions, please install development version of Python.
+#elif PY_VERSION_HEX < 0x02040000
+    #error Cython requires Python 2.4+.
+#else
+#include <stddef.h> /* For offsetof */
+#ifndef offsetof
+#define offsetof(type, member) ( (size_t) & ((type*)0) -> member )
+#endif
+#if !defined(WIN32) && !defined(MS_WINDOWS)
+  #ifndef __stdcall
+    #define __stdcall
+  #endif
+  #ifndef __cdecl
+    #define __cdecl
+  #endif
+  #ifndef __fastcall
+    #define __fastcall
+  #endif
+#endif
+#ifndef DL_IMPORT
+  #define DL_IMPORT(t) t
+#endif
+#ifndef DL_EXPORT
+  #define DL_EXPORT(t) t
+#endif
+#ifndef PY_LONG_LONG
+  #define PY_LONG_LONG LONG_LONG
+#endif
+#ifndef Py_HUGE_VAL
+  #define Py_HUGE_VAL HUGE_VAL
+#endif
+#ifdef PYPY_VERSION
+#define CYTHON_COMPILING_IN_PYPY 1
+#define CYTHON_COMPILING_IN_CPYTHON 0
+#else
+#define CYTHON_COMPILING_IN_PYPY 0
+#define CYTHON_COMPILING_IN_CPYTHON 1
+#endif
+#if PY_VERSION_HEX < 0x02050000
+  typedef int Py_ssize_t;
+  #define PY_SSIZE_T_MAX INT_MAX
+  #define PY_SSIZE_T_MIN INT_MIN
+  #define PY_FORMAT_SIZE_T ""
+  #define CYTHON_FORMAT_SSIZE_T ""
+  #define PyInt_FromSsize_t(z) PyInt_FromLong(z)
+  #define PyInt_AsSsize_t(o)   __Pyx_PyInt_AsInt(o)
+  #define PyNumber_Index(o)    ((PyNumber_Check(o) && !PyFloat_Check(o)) ? PyNumber_Int(o) : \
+                                (PyErr_Format(PyExc_TypeError, \
+                                              "expected index value, got %.200s", Py_TYPE(o)->tp_name), \
+                                 (PyObject*)0))
+  #define __Pyx_PyIndex_Check(o) (PyNumber_Check(o) && !PyFloat_Check(o) && \
+                                  !PyComplex_Check(o))
+  #define PyIndex_Check __Pyx_PyIndex_Check
+  #define PyErr_WarnEx(category, message, stacklevel) PyErr_Warn(category, message)
+  #define __PYX_BUILD_PY_SSIZE_T "i"
+#else
+  #define __PYX_BUILD_PY_SSIZE_T "n"
+  #define CYTHON_FORMAT_SSIZE_T "z"
+  #define __Pyx_PyIndex_Check PyIndex_Check
+#endif
+#if PY_VERSION_HEX < 0x02060000
+  #define Py_REFCNT(ob) (((PyObject*)(ob))->ob_refcnt)
+  #define Py_TYPE(ob)   (((PyObject*)(ob))->ob_type)
+  #define Py_SIZE(ob)   (((PyVarObject*)(ob))->ob_size)
+  #define PyVarObject_HEAD_INIT(type, size) \
+          PyObject_HEAD_INIT(type) size,
+  #define PyType_Modified(t)
+  typedef struct {
+     void *buf;
+     PyObject *obj;
+     Py_ssize_t len;
+     Py_ssize_t itemsize;
+     int readonly;
+     int ndim;
+     char *format;
+     Py_ssize_t *shape;
+     Py_ssize_t *strides;
+     Py_ssize_t *suboffsets;
+     void *internal;
+  } Py_buffer;
+  #define PyBUF_SIMPLE 0
+  #define PyBUF_WRITABLE 0x0001
+  #define PyBUF_FORMAT 0x0004
+  #define PyBUF_ND 0x0008
+  #define PyBUF_STRIDES (0x0010 | PyBUF_ND)
+  #define PyBUF_C_CONTIGUOUS (0x0020 | PyBUF_STRIDES)
+  #define PyBUF_F_CONTIGUOUS (0x0040 | PyBUF_STRIDES)
+  #define PyBUF_ANY_CONTIGUOUS (0x0080 | PyBUF_STRIDES)
+  #define PyBUF_INDIRECT (0x0100 | PyBUF_STRIDES)
+  #define PyBUF_RECORDS (PyBUF_STRIDES | PyBUF_FORMAT | PyBUF_WRITABLE)
+  #define PyBUF_FULL (PyBUF_INDIRECT | PyBUF_FORMAT | PyBUF_WRITABLE)
+  typedef int (*getbufferproc)(PyObject *, Py_buffer *, int);
+  typedef void (*releasebufferproc)(PyObject *, Py_buffer *);
+#endif
+#if PY_MAJOR_VERSION < 3
+  #define __Pyx_BUILTIN_MODULE_NAME "__builtin__"
+  #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \
+          PyCode_New(a, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
+#else
+  #define __Pyx_BUILTIN_MODULE_NAME "builtins"
+  #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \
+          PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
+#endif
+#if PY_MAJOR_VERSION < 3 && PY_MINOR_VERSION < 6
+  #define PyUnicode_FromString(s) PyUnicode_Decode(s, strlen(s), "UTF-8", "strict")
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define Py_TPFLAGS_CHECKTYPES 0
+  #define Py_TPFLAGS_HAVE_INDEX 0
+#endif
+#if (PY_VERSION_HEX < 0x02060000) || (PY_MAJOR_VERSION >= 3)
+  #define Py_TPFLAGS_HAVE_NEWBUFFER 0
+#endif
+#if PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND)
+  #define CYTHON_PEP393_ENABLED 1
+  #define __Pyx_PyUnicode_READY(op)       (likely(PyUnicode_IS_READY(op)) ? \
+                                              0 : _PyUnicode_Ready((PyObject *)(op)))
+  #define __Pyx_PyUnicode_GET_LENGTH(u)   PyUnicode_GET_LENGTH(u)
+  #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_READ_CHAR(u, i)
+  #define __Pyx_PyUnicode_READ(k, d, i)   PyUnicode_READ(k, d, i)
+#else
+  #define CYTHON_PEP393_ENABLED 0
+  #define __Pyx_PyUnicode_READY(op)       (0)
+  #define __Pyx_PyUnicode_GET_LENGTH(u)   PyUnicode_GET_SIZE(u)
+  #define __Pyx_PyUnicode_READ_CHAR(u, i) ((Py_UCS4)(PyUnicode_AS_UNICODE(u)[i]))
+  #define __Pyx_PyUnicode_READ(k, d, i)   ((k=k), (Py_UCS4)(((Py_UNICODE*)d)[i]))
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define PyBaseString_Type            PyUnicode_Type
+  #define PyStringObject               PyUnicodeObject
+  #define PyString_Type                PyUnicode_Type
+  #define PyString_Check               PyUnicode_Check
+  #define PyString_CheckExact          PyUnicode_CheckExact
+#endif
+#if PY_VERSION_HEX < 0x02060000
+  #define PyBytesObject                PyStringObject
+  #define PyBytes_Type                 PyString_Type
+  #define PyBytes_Check                PyString_Check
+  #define PyBytes_CheckExact           PyString_CheckExact
+  #define PyBytes_FromString           PyString_FromString
+  #define PyBytes_FromStringAndSize    PyString_FromStringAndSize
+  #define PyBytes_FromFormat           PyString_FromFormat
+  #define PyBytes_DecodeEscape         PyString_DecodeEscape
+  #define PyBytes_AsString             PyString_AsString
+  #define PyBytes_AsStringAndSize      PyString_AsStringAndSize
+  #define PyBytes_Size                 PyString_Size
+  #define PyBytes_AS_STRING            PyString_AS_STRING
+  #define PyBytes_GET_SIZE             PyString_GET_SIZE
+  #define PyBytes_Repr                 PyString_Repr
+  #define PyBytes_Concat               PyString_Concat
+  #define PyBytes_ConcatAndDel         PyString_ConcatAndDel
+#endif
+#if PY_VERSION_HEX < 0x02060000
+  #define PySet_Check(obj)             PyObject_TypeCheck(obj, &PySet_Type)
+  #define PyFrozenSet_Check(obj)       PyObject_TypeCheck(obj, &PyFrozenSet_Type)
+#endif
+#ifndef PySet_CheckExact
+  #define PySet_CheckExact(obj)        (Py_TYPE(obj) == &PySet_Type)
+#endif
+#define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type)
+#if PY_MAJOR_VERSION >= 3
+  #define PyIntObject                  PyLongObject
+  #define PyInt_Type                   PyLong_Type
+  #define PyInt_Check(op)              PyLong_Check(op)
+  #define PyInt_CheckExact(op)         PyLong_CheckExact(op)
+  #define PyInt_FromString             PyLong_FromString
+  #define PyInt_FromUnicode            PyLong_FromUnicode
+  #define PyInt_FromLong               PyLong_FromLong
+  #define PyInt_FromSize_t             PyLong_FromSize_t
+  #define PyInt_FromSsize_t            PyLong_FromSsize_t
+  #define PyInt_AsLong                 PyLong_AsLong
+  #define PyInt_AS_LONG                PyLong_AS_LONG
+  #define PyInt_AsSsize_t              PyLong_AsSsize_t
+  #define PyInt_AsUnsignedLongMask     PyLong_AsUnsignedLongMask
+  #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define PyBoolObject                 PyLongObject
+#endif
+#if PY_VERSION_HEX < 0x03020000
+  typedef long Py_hash_t;
+  #define __Pyx_PyInt_FromHash_t PyInt_FromLong
+  #define __Pyx_PyInt_AsHash_t   PyInt_AsLong
+#else
+  #define __Pyx_PyInt_FromHash_t PyInt_FromSsize_t
+  #define __Pyx_PyInt_AsHash_t   PyInt_AsSsize_t
+#endif
+#if (PY_MAJOR_VERSION < 3) || (PY_VERSION_HEX >= 0x03010300)
+  #define __Pyx_PySequence_GetSlice(obj, a, b) PySequence_GetSlice(obj, a, b)
+  #define __Pyx_PySequence_SetSlice(obj, a, b, value) PySequence_SetSlice(obj, a, b, value)
+  #define __Pyx_PySequence_DelSlice(obj, a, b) PySequence_DelSlice(obj, a, b)
+#else
+  #define __Pyx_PySequence_GetSlice(obj, a, b) (unlikely(!(obj)) ? \
+        (PyErr_SetString(PyExc_SystemError, "null argument to internal routine"), (PyObject*)0) : \
+        (likely((obj)->ob_type->tp_as_mapping) ? (PySequence_GetSlice(obj, a, b)) : \
+            (PyErr_Format(PyExc_TypeError, "'%.200s' object is unsliceable", (obj)->ob_type->tp_name), (PyObject*)0)))
+  #define __Pyx_PySequence_SetSlice(obj, a, b, value) (unlikely(!(obj)) ? \
+        (PyErr_SetString(PyExc_SystemError, "null argument to internal routine"), -1) : \
+        (likely((obj)->ob_type->tp_as_mapping) ? (PySequence_SetSlice(obj, a, b, value)) : \
+            (PyErr_Format(PyExc_TypeError, "'%.200s' object doesn't support slice assignment", (obj)->ob_type->tp_name), -1)))
+  #define __Pyx_PySequence_DelSlice(obj, a, b) (unlikely(!(obj)) ? \
+        (PyErr_SetString(PyExc_SystemError, "null argument to internal routine"), -1) : \
+        (likely((obj)->ob_type->tp_as_mapping) ? (PySequence_DelSlice(obj, a, b)) : \
+            (PyErr_Format(PyExc_TypeError, "'%.200s' object doesn't support slice deletion", (obj)->ob_type->tp_name), -1)))
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define PyMethod_New(func, self, klass) ((self) ? PyMethod_New(func, self) : PyInstanceMethod_New(func))
+#endif
+#if PY_VERSION_HEX < 0x02050000
+  #define __Pyx_GetAttrString(o,n)   PyObject_GetAttrString((o),((char *)(n)))
+  #define __Pyx_SetAttrString(o,n,a) PyObject_SetAttrString((o),((char *)(n)),(a))
+  #define __Pyx_DelAttrString(o,n)   PyObject_DelAttrString((o),((char *)(n)))
+#else
+  #define __Pyx_GetAttrString(o,n)   PyObject_GetAttrString((o),(n))
+  #define __Pyx_SetAttrString(o,n,a) PyObject_SetAttrString((o),(n),(a))
+  #define __Pyx_DelAttrString(o,n)   PyObject_DelAttrString((o),(n))
+#endif
+#if PY_VERSION_HEX < 0x02050000
+  #define __Pyx_NAMESTR(n) ((char *)(n))
+  #define __Pyx_DOCSTR(n)  ((char *)(n))
+#else
+  #define __Pyx_NAMESTR(n) (n)
+  #define __Pyx_DOCSTR(n)  (n)
+#endif
+
+
+#if PY_MAJOR_VERSION >= 3
+  #define __Pyx_PyNumber_Divide(x,y)         PyNumber_TrueDivide(x,y)
+  #define __Pyx_PyNumber_InPlaceDivide(x,y)  PyNumber_InPlaceTrueDivide(x,y)
+#else
+  #define __Pyx_PyNumber_Divide(x,y)         PyNumber_Divide(x,y)
+  #define __Pyx_PyNumber_InPlaceDivide(x,y)  PyNumber_InPlaceDivide(x,y)
+#endif
+
+#ifndef __PYX_EXTERN_C
+  #ifdef __cplusplus
+    #define __PYX_EXTERN_C extern "C"
+  #else
+    #define __PYX_EXTERN_C extern
+  #endif
+#endif
+
+#if defined(WIN32) || defined(MS_WINDOWS)
+#define _USE_MATH_DEFINES
+#endif
+#include <math.h>
+#define __PYX_HAVE__bx__bitset
+#define __PYX_HAVE_API__bx__bitset
+#include "common.h"
+#include "bits.h"
+#include "binBits.h"
+#ifdef _OPENMP
+#include <omp.h>
+#endif /* _OPENMP */
+
+#ifdef PYREX_WITHOUT_ASSERTIONS
+#define CYTHON_WITHOUT_ASSERTIONS
+#endif
+
+#ifndef CYTHON_INLINE
+  #if defined(__GNUC__)
+    #define CYTHON_INLINE __inline__
+  #elif defined(_MSC_VER)
+    #define CYTHON_INLINE __inline
+  #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+    #define CYTHON_INLINE inline
+  #else
+    #define CYTHON_INLINE
+  #endif
+#endif
+#ifndef CYTHON_UNUSED
+# if defined(__GNUC__)
+#   if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
+#     define CYTHON_UNUSED __attribute__ ((__unused__))
+#   else
+#     define CYTHON_UNUSED
+#   endif
+# elif defined(__ICC) || (defined(__INTEL_COMPILER) && !defined(_MSC_VER))
+#   define CYTHON_UNUSED __attribute__ ((__unused__))
+# else
+#   define CYTHON_UNUSED
+# endif
+#endif
+typedef struct {PyObject **p; char *s; const long n; const char* encoding; const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry; /*proto*/
+
+#define __Pyx_PyBytes_FromUString(s) PyBytes_FromString((char*)s)
+#define __Pyx_PyBytes_AsUString(s)   ((unsigned char*) PyBytes_AsString(s))
+#define __Pyx_Owned_Py_None(b) (Py_INCREF(Py_None), Py_None)
+#define __Pyx_PyBool_FromLong(b) ((b) ? (Py_INCREF(Py_True), Py_True) : (Py_INCREF(Py_False), Py_False))
+static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*);
+static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x);
+static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*);
+static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t);
+static CYTHON_INLINE size_t __Pyx_PyInt_AsSize_t(PyObject*);
+#if CYTHON_COMPILING_IN_CPYTHON
+#define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x))
+#else
+#define __pyx_PyFloat_AsDouble(x) PyFloat_AsDouble(x)
+#endif
+#define __pyx_PyFloat_AsFloat(x) ((float) __pyx_PyFloat_AsDouble(x))
+
+
+#ifdef __GNUC__
+  /* Test for GCC > 2.95 */
+  #if __GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))
+    #define likely(x)   __builtin_expect(!!(x), 1)
+    #define unlikely(x) __builtin_expect(!!(x), 0)
+  #else /* __GNUC__ > 2 ... */
+    #define likely(x)   (x)
+    #define unlikely(x) (x)
+  #endif /* __GNUC__ > 2 ... */
+#else /* __GNUC__ */
+  #define likely(x)   (x)
+  #define unlikely(x) (x)
+#endif /* __GNUC__ */
+    
+static PyObject *__pyx_m;
+static PyObject *__pyx_b;
+static PyObject *__pyx_empty_tuple;
+static PyObject *__pyx_empty_bytes;
+static int __pyx_lineno;
+static int __pyx_clineno = 0;
+static const char * __pyx_cfilenm= __FILE__;
+static const char *__pyx_filename;
+
+
+static const char *__pyx_f[] = {
+  "bitset.pyx",
+};
+
+/*--- Type declarations ---*/
+struct __pyx_obj_2bx_6bitset_BinnedBitSet;
+struct __pyx_obj_2bx_6bitset_BitSet;
+
+/* "bx/bitset.pyx":73
+ * 
+ * cdef class BitSet
+ * cdef class BinnedBitSet             # <<<<<<<<<<<<<<
+ * 
+ * ## ---- BitSet bounds checking ----------------------------------------------
+ */
+struct __pyx_obj_2bx_6bitset_BinnedBitSet {
+  PyObject_HEAD
+  struct BinBits *bb;
+};
+
+
+/* "bx/bitset.pyx":72
+ * ## ---- Forward declerations ------------------------------------------------
+ * 
+ * cdef class BitSet             # <<<<<<<<<<<<<<
+ * cdef class BinnedBitSet
+ * 
+ */
+struct __pyx_obj_2bx_6bitset_BitSet {
+  PyObject_HEAD
+  Bits *bits;
+  int bitCount;
+};
+
+#ifndef CYTHON_REFNANNY
+  #define CYTHON_REFNANNY 0
+#endif
+#if CYTHON_REFNANNY
+  typedef struct {
+    void (*INCREF)(void*, PyObject*, int);
+    void (*DECREF)(void*, PyObject*, int);
+    void (*GOTREF)(void*, PyObject*, int);
+    void (*GIVEREF)(void*, PyObject*, int);
+    void* (*SetupContext)(const char*, int, const char*);
+    void (*FinishContext)(void**);
+  } __Pyx_RefNannyAPIStruct;
+  static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL;
+  static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname); /*proto*/
+  #define __Pyx_RefNannyDeclarations void *__pyx_refnanny = NULL;
+#ifdef WITH_THREAD
+  #define __Pyx_RefNannySetupContext(name, acquire_gil) \
+          if (acquire_gil) { \
+              PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure(); \
+              __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__); \
+              PyGILState_Release(__pyx_gilstate_save); \
+          } else { \
+              __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__); \
+          }
+#else
+  #define __Pyx_RefNannySetupContext(name, acquire_gil) \
+          __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__)
+#endif
+  #define __Pyx_RefNannyFinishContext() \
+          __Pyx_RefNanny->FinishContext(&__pyx_refnanny)
+  #define __Pyx_INCREF(r)  __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_DECREF(r)  __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_GOTREF(r)  __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_XINCREF(r)  do { if((r) != NULL) {__Pyx_INCREF(r); }} while(0)
+  #define __Pyx_XDECREF(r)  do { if((r) != NULL) {__Pyx_DECREF(r); }} while(0)
+  #define __Pyx_XGOTREF(r)  do { if((r) != NULL) {__Pyx_GOTREF(r); }} while(0)
+  #define __Pyx_XGIVEREF(r) do { if((r) != NULL) {__Pyx_GIVEREF(r);}} while(0)
+#else
+  #define __Pyx_RefNannyDeclarations
+  #define __Pyx_RefNannySetupContext(name, acquire_gil)
+  #define __Pyx_RefNannyFinishContext()
+  #define __Pyx_INCREF(r) Py_INCREF(r)
+  #define __Pyx_DECREF(r) Py_DECREF(r)
+  #define __Pyx_GOTREF(r)
+  #define __Pyx_GIVEREF(r)
+  #define __Pyx_XINCREF(r) Py_XINCREF(r)
+  #define __Pyx_XDECREF(r) Py_XDECREF(r)
+  #define __Pyx_XGOTREF(r)
+  #define __Pyx_XGIVEREF(r)
+#endif /* CYTHON_REFNANNY */
+#define __Pyx_CLEAR(r)    do { PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);} while(0)
+#define __Pyx_XCLEAR(r)   do { if((r) != NULL) {PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);}} while(0)
+
+static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/
+
+static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
+static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
+
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause); /*proto*/
+
+static void __Pyx_RaiseDoubleKeywordsError(const char* func_name, PyObject* kw_name); /*proto*/
+
+static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
+    PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
+    const char* function_name); /*proto*/
+
+static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
+    Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/
+
+static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
+    const char *name, int exact); /*proto*/
+
+static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level); /*proto*/
+
+static CYTHON_INLINE unsigned char __Pyx_PyInt_AsUnsignedChar(PyObject *);
+
+static CYTHON_INLINE unsigned short __Pyx_PyInt_AsUnsignedShort(PyObject *);
+
+static CYTHON_INLINE unsigned int __Pyx_PyInt_AsUnsignedInt(PyObject *);
+
+static CYTHON_INLINE char __Pyx_PyInt_AsChar(PyObject *);
+
+static CYTHON_INLINE short __Pyx_PyInt_AsShort(PyObject *);
+
+static CYTHON_INLINE int __Pyx_PyInt_AsInt(PyObject *);
+
+static CYTHON_INLINE signed char __Pyx_PyInt_AsSignedChar(PyObject *);
+
+static CYTHON_INLINE signed short __Pyx_PyInt_AsSignedShort(PyObject *);
+
+static CYTHON_INLINE signed int __Pyx_PyInt_AsSignedInt(PyObject *);
+
+static CYTHON_INLINE int __Pyx_PyInt_AsLongDouble(PyObject *);
+
+static CYTHON_INLINE unsigned long __Pyx_PyInt_AsUnsignedLong(PyObject *);
+
+static CYTHON_INLINE unsigned PY_LONG_LONG __Pyx_PyInt_AsUnsignedLongLong(PyObject *);
+
+static CYTHON_INLINE long __Pyx_PyInt_AsLong(PyObject *);
+
+static CYTHON_INLINE PY_LONG_LONG __Pyx_PyInt_AsLongLong(PyObject *);
+
+static CYTHON_INLINE signed long __Pyx_PyInt_AsSignedLong(PyObject *);
+
+static CYTHON_INLINE signed PY_LONG_LONG __Pyx_PyInt_AsSignedLongLong(PyObject *);
+
+static int __Pyx_check_binary_version(void);
+
+typedef struct {
+    int code_line;
+    PyCodeObject* code_object;
+} __Pyx_CodeObjectCacheEntry;
+struct __Pyx_CodeObjectCache {
+    int count;
+    int max_count;
+    __Pyx_CodeObjectCacheEntry* entries;
+};
+static struct __Pyx_CodeObjectCache __pyx_code_cache = {0,0,NULL};
+static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line);
+static PyCodeObject *__pyx_find_code_object(int code_line);
+static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object);
+
+static void __Pyx_AddTraceback(const char *funcname, int c_line,
+                               int py_line, const char *filename); /*proto*/
+
+static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
+
+
+/* Module declarations from 'bx.bitset' */
+static PyTypeObject *__pyx_ptype_2bx_6bitset_BitSet = 0;
+static PyTypeObject *__pyx_ptype_2bx_6bitset_BinnedBitSet = 0;
+static int __pyx_v_2bx_6bitset_MAX_INT;
+static CYTHON_INLINE PyObject *__pyx_f_2bx_6bitset_b_check_index(struct __pyx_obj_2bx_6bitset_BitSet *, PyObject *); /*proto*/
+static CYTHON_INLINE PyObject *__pyx_f_2bx_6bitset_b_check_range(struct __pyx_obj_2bx_6bitset_BitSet *, PyObject *, PyObject *); /*proto*/
+static CYTHON_INLINE PyObject *__pyx_f_2bx_6bitset_b_check_range_count(struct __pyx_obj_2bx_6bitset_BitSet *, PyObject *, PyObject *); /*proto*/
+static CYTHON_INLINE PyObject *__pyx_f_2bx_6bitset_b_check_same_size(struct __pyx_obj_2bx_6bitset_BitSet *, struct __pyx_obj_2bx_6bitset_BitSet *); /*proto*/
+static CYTHON_INLINE PyObject *__pyx_f_2bx_6bitset_bb_check_index(struct __pyx_obj_2bx_6bitset_BinnedBitSet *, PyObject *); /*proto*/
+static CYTHON_INLINE PyObject *__pyx_f_2bx_6bitset_bb_check_start(struct __pyx_obj_2bx_6bitset_BinnedBitSet *, PyObject *); /*proto*/
+static CYTHON_INLINE PyObject *__pyx_f_2bx_6bitset_bb_check_range_count(struct __pyx_obj_2bx_6bitset_BinnedBitSet *, PyObject *, PyObject *); /*proto*/
+static CYTHON_INLINE PyObject *__pyx_f_2bx_6bitset_bb_check_same_size(struct __pyx_obj_2bx_6bitset_BinnedBitSet *, struct __pyx_obj_2bx_6bitset_BinnedBitSet *); /*proto*/
+#define __Pyx_MODULE_NAME "bx.bitset"
+int __pyx_module_is_main_bx__bitset = 0;
+
+/* Implementation of 'bx.bitset' */
+static PyObject *__pyx_builtin_IndexError;
+static PyObject *__pyx_builtin_ValueError;
+static int __pyx_pf_2bx_6bitset_6BitSet___cinit__(struct __pyx_obj_2bx_6bitset_BitSet *__pyx_v_self, PyObject *__pyx_v_bitCount); /* proto */
+static void __pyx_pf_2bx_6bitset_6BitSet_2__dealloc__(struct __pyx_obj_2bx_6bitset_BitSet *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_2bx_6bitset_6BitSet_4size___get__(struct __pyx_obj_2bx_6bitset_BitSet *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_2bx_6bitset_6BitSet_4set(struct __pyx_obj_2bx_6bitset_BitSet *__pyx_v_self, PyObject *__pyx_v_index); /* proto */
+static PyObject *__pyx_pf_2bx_6bitset_6BitSet_6clear(struct __pyx_obj_2bx_6bitset_BitSet *__pyx_v_self, PyObject *__pyx_v_index); /* proto */
+static PyObject *__pyx_pf_2bx_6bitset_6BitSet_8clone(struct __pyx_obj_2bx_6bitset_BitSet *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_2bx_6bitset_6BitSet_10set_range(struct __pyx_obj_2bx_6bitset_BitSet *__pyx_v_self, PyObject *__pyx_v_start, PyObject *__pyx_v_count); /* proto */
+static PyObject *__pyx_pf_2bx_6bitset_6BitSet_12get(struct __pyx_obj_2bx_6bitset_BitSet *__pyx_v_self, PyObject *__pyx_v_index); /* proto */
+static PyObject *__pyx_pf_2bx_6bitset_6BitSet_14count_range(struct __pyx_obj_2bx_6bitset_BitSet *__pyx_v_self, PyObject *__pyx_v_start, PyObject *__pyx_v_count); /* proto */
+static PyObject *__pyx_pf_2bx_6bitset_6BitSet_16next_set(struct __pyx_obj_2bx_6bitset_BitSet *__pyx_v_self, PyObject *__pyx_v_start, PyObject *__pyx_v_end); /* proto */
+static PyObject *__pyx_pf_2bx_6bitset_6BitSet_18next_clear(struct __pyx_obj_2bx_6bitset_BitSet *__pyx_v_self, PyObject *__pyx_v_start, PyObject *__pyx_v_end); /* proto */
+static PyObject *__pyx_pf_2bx_6bitset_6BitSet_20iand(struct __pyx_obj_2bx_6bitset_BitSet *__pyx_v_self, struct __pyx_obj_2bx_6bitset_BitSet *__pyx_v_other); /* proto */
+static PyObject *__pyx_pf_2bx_6bitset_6BitSet_22ior(struct __pyx_obj_2bx_6bitset_BitSet *__pyx_v_self, struct __pyx_obj_2bx_6bitset_BitSet *__pyx_v_other); /* proto */
+static PyObject *__pyx_pf_2bx_6bitset_6BitSet_24ixor(struct __pyx_obj_2bx_6bitset_BitSet *__pyx_v_self, struct __pyx_obj_2bx_6bitset_BitSet *__pyx_v_other); /* proto */
+static PyObject *__pyx_pf_2bx_6bitset_6BitSet_26invert(struct __pyx_obj_2bx_6bitset_BitSet *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_2bx_6bitset_6BitSet_28__getitem__(struct __pyx_obj_2bx_6bitset_BitSet *__pyx_v_self, PyObject *__pyx_v_index); /* proto */
+static PyObject *__pyx_pf_2bx_6bitset_6BitSet_30__iand__(struct __pyx_obj_2bx_6bitset_BitSet *__pyx_v_self, PyObject *__pyx_v_other); /* proto */
+static PyObject *__pyx_pf_2bx_6bitset_6BitSet_32__ior__(struct __pyx_obj_2bx_6bitset_BitSet *__pyx_v_self, PyObject *__pyx_v_other); /* proto */
+static PyObject *__pyx_pf_2bx_6bitset_6BitSet_34__invert__(struct __pyx_obj_2bx_6bitset_BitSet *__pyx_v_self); /* proto */
+static int __pyx_pf_2bx_6bitset_12BinnedBitSet___cinit__(struct __pyx_obj_2bx_6bitset_BinnedBitSet *__pyx_v_self, PyObject *__pyx_v_size, PyObject *__pyx_v_granularity); /* proto */
+static void __pyx_pf_2bx_6bitset_12BinnedBitSet_2__dealloc__(struct __pyx_obj_2bx_6bitset_BinnedBitSet *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_2bx_6bitset_12BinnedBitSet_4__getitem__(struct __pyx_obj_2bx_6bitset_BinnedBitSet *__pyx_v_self, PyObject *__pyx_v_index); /* proto */
+static PyObject *__pyx_pf_2bx_6bitset_12BinnedBitSet_6set(struct __pyx_obj_2bx_6bitset_BinnedBitSet *__pyx_v_self, PyObject *__pyx_v_index); /* proto */
+static PyObject *__pyx_pf_2bx_6bitset_12BinnedBitSet_8clear(struct __pyx_obj_2bx_6bitset_BinnedBitSet *__pyx_v_self, PyObject *__pyx_v_index); /* proto */
+static PyObject *__pyx_pf_2bx_6bitset_12BinnedBitSet_10set_range(struct __pyx_obj_2bx_6bitset_BinnedBitSet *__pyx_v_self, int __pyx_v_start, PyObject *__pyx_v_count); /* proto */
+static PyObject *__pyx_pf_2bx_6bitset_12BinnedBitSet_12count_range(struct __pyx_obj_2bx_6bitset_BinnedBitSet *__pyx_v_self, PyObject *__pyx_v_start, PyObject *__pyx_v_count); /* proto */
+static PyObject *__pyx_pf_2bx_6bitset_12BinnedBitSet_14next_set(struct __pyx_obj_2bx_6bitset_BinnedBitSet *__pyx_v_self, PyObject *__pyx_v_start); /* proto */
+static PyObject *__pyx_pf_2bx_6bitset_12BinnedBitSet_16next_clear(struct __pyx_obj_2bx_6bitset_BinnedBitSet *__pyx_v_self, PyObject *__pyx_v_start); /* proto */
+static PyObject *__pyx_pf_2bx_6bitset_12BinnedBitSet_4size___get__(struct __pyx_obj_2bx_6bitset_BinnedBitSet *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_2bx_6bitset_12BinnedBitSet_8bin_size___get__(struct __pyx_obj_2bx_6bitset_BinnedBitSet *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_2bx_6bitset_12BinnedBitSet_18iand(struct __pyx_obj_2bx_6bitset_BinnedBitSet *__pyx_v_self, struct __pyx_obj_2bx_6bitset_BinnedBitSet *__pyx_v_other); /* proto */
+static PyObject *__pyx_pf_2bx_6bitset_12BinnedBitSet_20ior(struct __pyx_obj_2bx_6bitset_BinnedBitSet *__pyx_v_self, struct __pyx_obj_2bx_6bitset_BinnedBitSet *__pyx_v_other); /* proto */
+static PyObject *__pyx_pf_2bx_6bitset_12BinnedBitSet_22invert(struct __pyx_obj_2bx_6bitset_BinnedBitSet *__pyx_v_self); /* proto */
+static char __pyx_k_1[] = "BitSet index (%d) must be non-negative.";
+static char __pyx_k_2[] = "%d is larger than the size of this BitSet (%d).";
+static char __pyx_k_3[] = "Range end (%d) must be greater than range start(%d).";
+static char __pyx_k_4[] = "End %d is larger than the size of this BitSet (%d).";
+static char __pyx_k_5[] = "Count (%d) must be non-negative.";
+static char __pyx_k_6[] = "BitSets must have the same size";
+static char __pyx_k_8[] = "%d is larger than the maximum BitSet size of %d.";
+static char __pyx_k_9[] = "End (%d) is larger than the size of this BinnedBitSet (%d).";
+static char __pyx_k_12[] = "%d is larger than the maximum BinnedBitSet size of %d.";
+static char __pyx_k_13[] = "\nCompact mutable sequences of bits (vectors of 0s and 1s) supporting various\nboolean operations, and a \"binned\" variation which stores long runs of \nidentical bits compactly.\n\nBecause the binned implementation avoids a lot of memory allocation and access\nwhen working with either small subregions of the total interval or setting /\ntesting spans larger than the bin size, it can be much faster.\n";
+static char __pyx_k__MAX[] = "MAX";
+static char __pyx_k__end[] = "end";
+static char __pyx_k__get[] = "get";
+static char __pyx_k__ior[] = "ior";
+static char __pyx_k__sys[] = "sys";
+static char __pyx_k__iand[] = "iand";
+static char __pyx_k__size[] = "size";
+static char __pyx_k__count[] = "count";
+static char __pyx_k__start[] = "start";
+static char __pyx_k__invert[] = "invert";
+static char __pyx_k____main__[] = "__main__";
+static char __pyx_k____test__[] = "__test__";
+static char __pyx_k__bitCount[] = "bitCount";
+static char __pyx_k__IndexError[] = "IndexError";
+static char __pyx_k__ValueError[] = "ValueError";
+static char __pyx_k__granularity[] = "granularity";
+static PyObject *__pyx_kp_s_1;
+static PyObject *__pyx_kp_s_12;
+static PyObject *__pyx_kp_s_2;
+static PyObject *__pyx_kp_s_3;
+static PyObject *__pyx_kp_s_4;
+static PyObject *__pyx_kp_s_5;
+static PyObject *__pyx_kp_s_6;
+static PyObject *__pyx_kp_s_8;
+static PyObject *__pyx_kp_s_9;
+static PyObject *__pyx_n_s__IndexError;
+static PyObject *__pyx_n_s__MAX;
+static PyObject *__pyx_n_s__ValueError;
+static PyObject *__pyx_n_s____main__;
+static PyObject *__pyx_n_s____test__;
+static PyObject *__pyx_n_s__bitCount;
+static PyObject *__pyx_n_s__count;
+static PyObject *__pyx_n_s__end;
+static PyObject *__pyx_n_s__get;
+static PyObject *__pyx_n_s__granularity;
+static PyObject *__pyx_n_s__iand;
+static PyObject *__pyx_n_s__invert;
+static PyObject *__pyx_n_s__ior;
+static PyObject *__pyx_n_s__size;
+static PyObject *__pyx_n_s__start;
+static PyObject *__pyx_n_s__sys;
+static PyObject *__pyx_int_0;
+static PyObject *__pyx_int_1024;
+static PyObject *__pyx_int_536870912;
+static PyObject *__pyx_k_11;
+static PyObject *__pyx_k_tuple_7;
+static PyObject *__pyx_k_tuple_10;
+
+/* "bx/bitset.pyx":77
+ * ## ---- BitSet bounds checking ----------------------------------------------
+ * 
+ * cdef inline b_check_index( BitSet b, index ):             # <<<<<<<<<<<<<<
+ *     if index < 0:
+ *         raise IndexError( "BitSet index (%d) must be non-negative." % index )
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_2bx_6bitset_b_check_index(struct __pyx_obj_2bx_6bitset_BitSet *__pyx_v_b, PyObject *__pyx_v_index) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_t_2;
+  PyObject *__pyx_t_3 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("b_check_index", 0);
+
+  /* "bx/bitset.pyx":78
+ * 
+ * cdef inline b_check_index( BitSet b, index ):
+ *     if index < 0:             # <<<<<<<<<<<<<<
+ *         raise IndexError( "BitSet index (%d) must be non-negative." % index )
+ *     if index >= b.bitCount:
+ */
+  __pyx_t_1 = PyObject_RichCompare(__pyx_v_index, __pyx_int_0, Py_LT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 78; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 78; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  if (__pyx_t_2) {
+
+    /* "bx/bitset.pyx":79
+ * cdef inline b_check_index( BitSet b, index ):
+ *     if index < 0:
+ *         raise IndexError( "BitSet index (%d) must be non-negative." % index )             # <<<<<<<<<<<<<<
+ *     if index >= b.bitCount:
+ *         raise IndexError( "%d is larger than the size of this BitSet (%d)." % ( index, b.bitCount ) )
+ */
+    __pyx_t_1 = PyNumber_Remainder(((PyObject *)__pyx_kp_s_1), __pyx_v_index); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 79; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(((PyObject *)__pyx_t_1));
+    __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 79; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    PyTuple_SET_ITEM(__pyx_t_3, 0, ((PyObject *)__pyx_t_1));
+    __Pyx_GIVEREF(((PyObject *)__pyx_t_1));
+    __pyx_t_1 = 0;
+    __pyx_t_1 = PyObject_Call(__pyx_builtin_IndexError, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 79; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
+    __Pyx_Raise(__pyx_t_1, 0, 0, 0);
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 79; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  /* "bx/bitset.pyx":80
+ *     if index < 0:
+ *         raise IndexError( "BitSet index (%d) must be non-negative." % index )
+ *     if index >= b.bitCount:             # <<<<<<<<<<<<<<
+ *         raise IndexError( "%d is larger than the size of this BitSet (%d)." % ( index, b.bitCount ) )
+ * 
+ */
+  __pyx_t_1 = PyInt_FromLong(__pyx_v_b->bitCount); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 80; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_3 = PyObject_RichCompare(__pyx_v_index, __pyx_t_1, Py_GE); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 80; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 80; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  if (__pyx_t_2) {
+
+    /* "bx/bitset.pyx":81
+ *         raise IndexError( "BitSet index (%d) must be non-negative." % index )
+ *     if index >= b.bitCount:
+ *         raise IndexError( "%d is larger than the size of this BitSet (%d)." % ( index, b.bitCount ) )             # <<<<<<<<<<<<<<
+ * 
+ * cdef inline b_check_range( BitSet b, start, end ):
+ */
+    __pyx_t_3 = PyInt_FromLong(__pyx_v_b->bitCount); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 81; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 81; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __Pyx_INCREF(__pyx_v_index);
+    PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_index);
+    __Pyx_GIVEREF(__pyx_v_index);
+    PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_t_3);
+    __Pyx_GIVEREF(__pyx_t_3);
+    __pyx_t_3 = 0;
+    __pyx_t_3 = PyNumber_Remainder(((PyObject *)__pyx_kp_s_2), ((PyObject *)__pyx_t_1)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 81; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(((PyObject *)__pyx_t_3));
+    __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+    __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 81; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    PyTuple_SET_ITEM(__pyx_t_1, 0, ((PyObject *)__pyx_t_3));
+    __Pyx_GIVEREF(((PyObject *)__pyx_t_3));
+    __pyx_t_3 = 0;
+    __pyx_t_3 = PyObject_Call(__pyx_builtin_IndexError, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 81; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+    __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 81; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    goto __pyx_L4;
+  }
+  __pyx_L4:;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_AddTraceback("bx.bitset.b_check_index", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bitset.pyx":83
+ *         raise IndexError( "%d is larger than the size of this BitSet (%d)." % ( index, b.bitCount ) )
+ * 
+ * cdef inline b_check_range( BitSet b, start, end ):             # <<<<<<<<<<<<<<
+ *     b_check_index( b, start )
+ *     if end < start:
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_2bx_6bitset_b_check_range(struct __pyx_obj_2bx_6bitset_BitSet *__pyx_v_b, PyObject *__pyx_v_start, PyObject *__pyx_v_end) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_t_2;
+  PyObject *__pyx_t_3 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("b_check_range", 0);
+
+  /* "bx/bitset.pyx":84
+ * 
+ * cdef inline b_check_range( BitSet b, start, end ):
+ *     b_check_index( b, start )             # <<<<<<<<<<<<<<
+ *     if end < start:
+ *         raise IndexError( "Range end (%d) must be greater than range start(%d)." % ( end, start ) )
+ */
+  __pyx_t_1 = __pyx_f_2bx_6bitset_b_check_index(__pyx_v_b, __pyx_v_start); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 84; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "bx/bitset.pyx":85
+ * cdef inline b_check_range( BitSet b, start, end ):
+ *     b_check_index( b, start )
+ *     if end < start:             # <<<<<<<<<<<<<<
+ *         raise IndexError( "Range end (%d) must be greater than range start(%d)." % ( end, start ) )
+ *     if end > b.bitCount:
+ */
+  __pyx_t_1 = PyObject_RichCompare(__pyx_v_end, __pyx_v_start, Py_LT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 85; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 85; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  if (__pyx_t_2) {
+
+    /* "bx/bitset.pyx":86
+ *     b_check_index( b, start )
+ *     if end < start:
+ *         raise IndexError( "Range end (%d) must be greater than range start(%d)." % ( end, start ) )             # <<<<<<<<<<<<<<
+ *     if end > b.bitCount:
+ *         raise IndexError( "End %d is larger than the size of this BitSet (%d)." % ( end, b.bitCount ) )
+ */
+    __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 86; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __Pyx_INCREF(__pyx_v_end);
+    PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_end);
+    __Pyx_GIVEREF(__pyx_v_end);
+    __Pyx_INCREF(__pyx_v_start);
+    PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_v_start);
+    __Pyx_GIVEREF(__pyx_v_start);
+    __pyx_t_3 = PyNumber_Remainder(((PyObject *)__pyx_kp_s_3), ((PyObject *)__pyx_t_1)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 86; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(((PyObject *)__pyx_t_3));
+    __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+    __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 86; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    PyTuple_SET_ITEM(__pyx_t_1, 0, ((PyObject *)__pyx_t_3));
+    __Pyx_GIVEREF(((PyObject *)__pyx_t_3));
+    __pyx_t_3 = 0;
+    __pyx_t_3 = PyObject_Call(__pyx_builtin_IndexError, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 86; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+    __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 86; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  /* "bx/bitset.pyx":87
+ *     if end < start:
+ *         raise IndexError( "Range end (%d) must be greater than range start(%d)." % ( end, start ) )
+ *     if end > b.bitCount:             # <<<<<<<<<<<<<<
+ *         raise IndexError( "End %d is larger than the size of this BitSet (%d)." % ( end, b.bitCount ) )
+ * 
+ */
+  __pyx_t_3 = PyInt_FromLong(__pyx_v_b->bitCount); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 87; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_1 = PyObject_RichCompare(__pyx_v_end, __pyx_t_3, Py_GT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 87; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 87; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  if (__pyx_t_2) {
+
+    /* "bx/bitset.pyx":88
+ *         raise IndexError( "Range end (%d) must be greater than range start(%d)." % ( end, start ) )
+ *     if end > b.bitCount:
+ *         raise IndexError( "End %d is larger than the size of this BitSet (%d)." % ( end, b.bitCount ) )             # <<<<<<<<<<<<<<
+ * 
+ * cdef inline b_check_range_count( BitSet b, start, count ):
+ */
+    __pyx_t_1 = PyInt_FromLong(__pyx_v_b->bitCount); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 88; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 88; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_INCREF(__pyx_v_end);
+    PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_end);
+    __Pyx_GIVEREF(__pyx_v_end);
+    PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_1);
+    __Pyx_GIVEREF(__pyx_t_1);
+    __pyx_t_1 = 0;
+    __pyx_t_1 = PyNumber_Remainder(((PyObject *)__pyx_kp_s_4), ((PyObject *)__pyx_t_3)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 88; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(((PyObject *)__pyx_t_1));
+    __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
+    __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 88; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    PyTuple_SET_ITEM(__pyx_t_3, 0, ((PyObject *)__pyx_t_1));
+    __Pyx_GIVEREF(((PyObject *)__pyx_t_1));
+    __pyx_t_1 = 0;
+    __pyx_t_1 = PyObject_Call(__pyx_builtin_IndexError, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 88; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
+    __Pyx_Raise(__pyx_t_1, 0, 0, 0);
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 88; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    goto __pyx_L4;
+  }
+  __pyx_L4:;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_AddTraceback("bx.bitset.b_check_range", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bitset.pyx":90
+ *         raise IndexError( "End %d is larger than the size of this BitSet (%d)." % ( end, b.bitCount ) )
+ * 
+ * cdef inline b_check_range_count( BitSet b, start, count ):             # <<<<<<<<<<<<<<
+ *     b_check_index( b, start )
+ *     if count < 0:
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_2bx_6bitset_b_check_range_count(struct __pyx_obj_2bx_6bitset_BitSet *__pyx_v_b, PyObject *__pyx_v_start, PyObject *__pyx_v_count) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_t_2;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("b_check_range_count", 0);
+
+  /* "bx/bitset.pyx":91
+ * 
+ * cdef inline b_check_range_count( BitSet b, start, count ):
+ *     b_check_index( b, start )             # <<<<<<<<<<<<<<
+ *     if count < 0:
+ *         raise IndexError( "Count (%d) must be non-negative." % count )
+ */
+  __pyx_t_1 = __pyx_f_2bx_6bitset_b_check_index(__pyx_v_b, __pyx_v_start); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 91; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "bx/bitset.pyx":92
+ * cdef inline b_check_range_count( BitSet b, start, count ):
+ *     b_check_index( b, start )
+ *     if count < 0:             # <<<<<<<<<<<<<<
+ *         raise IndexError( "Count (%d) must be non-negative." % count )
+ *     if start + count > b.bitCount:
+ */
+  __pyx_t_1 = PyObject_RichCompare(__pyx_v_count, __pyx_int_0, Py_LT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 92; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 92; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  if (__pyx_t_2) {
+
+    /* "bx/bitset.pyx":93
+ *     b_check_index( b, start )
+ *     if count < 0:
+ *         raise IndexError( "Count (%d) must be non-negative." % count )             # <<<<<<<<<<<<<<
+ *     if start + count > b.bitCount:
+ *         raise IndexError( "End %d is larger than the size of this BitSet (%d)." % ( start + count, b.bitCount ) )
+ */
+    __pyx_t_1 = PyNumber_Remainder(((PyObject *)__pyx_kp_s_5), __pyx_v_count); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 93; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(((PyObject *)__pyx_t_1));
+    __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 93; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    PyTuple_SET_ITEM(__pyx_t_3, 0, ((PyObject *)__pyx_t_1));
+    __Pyx_GIVEREF(((PyObject *)__pyx_t_1));
+    __pyx_t_1 = 0;
+    __pyx_t_1 = PyObject_Call(__pyx_builtin_IndexError, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 93; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
+    __Pyx_Raise(__pyx_t_1, 0, 0, 0);
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 93; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  /* "bx/bitset.pyx":94
+ *     if count < 0:
+ *         raise IndexError( "Count (%d) must be non-negative." % count )
+ *     if start + count > b.bitCount:             # <<<<<<<<<<<<<<
+ *         raise IndexError( "End %d is larger than the size of this BitSet (%d)." % ( start + count, b.bitCount ) )
+ * 
+ */
+  __pyx_t_1 = PyNumber_Add(__pyx_v_start, __pyx_v_count); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 94; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_3 = PyInt_FromLong(__pyx_v_b->bitCount); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 94; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_4 = PyObject_RichCompare(__pyx_t_1, __pyx_t_3, Py_GT); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 94; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 94; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  if (__pyx_t_2) {
+
+    /* "bx/bitset.pyx":95
+ *         raise IndexError( "Count (%d) must be non-negative." % count )
+ *     if start + count > b.bitCount:
+ *         raise IndexError( "End %d is larger than the size of this BitSet (%d)." % ( start + count, b.bitCount ) )             # <<<<<<<<<<<<<<
+ * 
+ * cdef inline b_check_same_size( BitSet b, BitSet other ):
+ */
+    __pyx_t_4 = PyNumber_Add(__pyx_v_start, __pyx_v_count); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 95; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    __pyx_t_3 = PyInt_FromLong(__pyx_v_b->bitCount); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 95; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 95; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_4);
+    __Pyx_GIVEREF(__pyx_t_4);
+    PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_t_3);
+    __Pyx_GIVEREF(__pyx_t_3);
+    __pyx_t_4 = 0;
+    __pyx_t_3 = 0;
+    __pyx_t_3 = PyNumber_Remainder(((PyObject *)__pyx_kp_s_4), ((PyObject *)__pyx_t_1)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 95; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(((PyObject *)__pyx_t_3));
+    __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+    __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 95; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    PyTuple_SET_ITEM(__pyx_t_1, 0, ((PyObject *)__pyx_t_3));
+    __Pyx_GIVEREF(((PyObject *)__pyx_t_3));
+    __pyx_t_3 = 0;
+    __pyx_t_3 = PyObject_Call(__pyx_builtin_IndexError, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 95; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+    __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 95; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    goto __pyx_L4;
+  }
+  __pyx_L4:;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_AddTraceback("bx.bitset.b_check_range_count", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bitset.pyx":97
+ *         raise IndexError( "End %d is larger than the size of this BitSet (%d)." % ( start + count, b.bitCount ) )
+ * 
+ * cdef inline b_check_same_size( BitSet b, BitSet other ):             # <<<<<<<<<<<<<<
+ *     if b.bitCount != other.bitCount:
+ *         raise ValueError( "BitSets must have the same size" )
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_2bx_6bitset_b_check_same_size(struct __pyx_obj_2bx_6bitset_BitSet *__pyx_v_b, struct __pyx_obj_2bx_6bitset_BitSet *__pyx_v_other) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("b_check_same_size", 0);
+
+  /* "bx/bitset.pyx":98
+ * 
+ * cdef inline b_check_same_size( BitSet b, BitSet other ):
+ *     if b.bitCount != other.bitCount:             # <<<<<<<<<<<<<<
+ *         raise ValueError( "BitSets must have the same size" )
+ * 
+ */
+  __pyx_t_1 = (__pyx_v_b->bitCount != __pyx_v_other->bitCount);
+  if (__pyx_t_1) {
+
+    /* "bx/bitset.pyx":99
+ * cdef inline b_check_same_size( BitSet b, BitSet other ):
+ *     if b.bitCount != other.bitCount:
+ *         raise ValueError( "BitSets must have the same size" )             # <<<<<<<<<<<<<<
+ * 
+ * ## ---- BitSet --------------------------------------------------------------
+ */
+    __pyx_t_2 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_k_tuple_7), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 99; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __Pyx_Raise(__pyx_t_2, 0, 0, 0);
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 99; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_AddTraceback("bx.bitset.b_check_same_size", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_2bx_6bitset_6BitSet_1__cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static int __pyx_pw_2bx_6bitset_6BitSet_1__cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_bitCount = 0;
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__cinit__ (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__bitCount,0};
+    PyObject* values[1] = {0};
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__bitCount)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__cinit__") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 109; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else if (PyTuple_GET_SIZE(__pyx_args) != 1) {
+      goto __pyx_L5_argtuple_error;
+    } else {
+      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+    }
+    __pyx_v_bitCount = values[0];
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("__cinit__", 1, 1, 1, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 109; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.bitset.BitSet.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return -1;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_6bitset_6BitSet___cinit__(((struct __pyx_obj_2bx_6bitset_BitSet *)__pyx_v_self), __pyx_v_bitCount);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bitset.pyx":109
+ *     cdef Bits * bits
+ *     cdef int bitCount
+ *     def __cinit__( self, bitCount ):             # <<<<<<<<<<<<<<
+ *         if bitCount > MAX_INT:
+ *             raise ValueError( "%d is larger than the maximum BitSet size of %d." % ( bitCount, MAX_INT ) )
+ */
+
+static int __pyx_pf_2bx_6bitset_6BitSet___cinit__(struct __pyx_obj_2bx_6bitset_BitSet *__pyx_v_self, PyObject *__pyx_v_bitCount) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  int __pyx_t_3;
+  int __pyx_t_4;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__cinit__", 0);
+
+  /* "bx/bitset.pyx":110
+ *     cdef int bitCount
+ *     def __cinit__( self, bitCount ):
+ *         if bitCount > MAX_INT:             # <<<<<<<<<<<<<<
+ *             raise ValueError( "%d is larger than the maximum BitSet size of %d." % ( bitCount, MAX_INT ) )
+ *         self.bitCount = bitCount
+ */
+  __pyx_t_1 = PyInt_FromLong(__pyx_v_2bx_6bitset_MAX_INT); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = PyObject_RichCompare(__pyx_v_bitCount, __pyx_t_1, Py_GT); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  if (__pyx_t_3) {
+
+    /* "bx/bitset.pyx":111
+ *     def __cinit__( self, bitCount ):
+ *         if bitCount > MAX_INT:
+ *             raise ValueError( "%d is larger than the maximum BitSet size of %d." % ( bitCount, MAX_INT ) )             # <<<<<<<<<<<<<<
+ *         self.bitCount = bitCount
+ *         self.bits = bitAlloc( bitCount )
+ */
+    __pyx_t_2 = PyInt_FromLong(__pyx_v_2bx_6bitset_MAX_INT); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 111; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 111; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __Pyx_INCREF(__pyx_v_bitCount);
+    PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_bitCount);
+    __Pyx_GIVEREF(__pyx_v_bitCount);
+    PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_t_2);
+    __Pyx_GIVEREF(__pyx_t_2);
+    __pyx_t_2 = 0;
+    __pyx_t_2 = PyNumber_Remainder(((PyObject *)__pyx_kp_s_8), ((PyObject *)__pyx_t_1)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 111; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(((PyObject *)__pyx_t_2));
+    __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+    __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 111; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    PyTuple_SET_ITEM(__pyx_t_1, 0, ((PyObject *)__pyx_t_2));
+    __Pyx_GIVEREF(((PyObject *)__pyx_t_2));
+    __pyx_t_2 = 0;
+    __pyx_t_2 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 111; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+    __Pyx_Raise(__pyx_t_2, 0, 0, 0);
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 111; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  /* "bx/bitset.pyx":112
+ *         if bitCount > MAX_INT:
+ *             raise ValueError( "%d is larger than the maximum BitSet size of %d." % ( bitCount, MAX_INT ) )
+ *         self.bitCount = bitCount             # <<<<<<<<<<<<<<
+ *         self.bits = bitAlloc( bitCount )
+ *     def __dealloc__( self ):
+ */
+  __pyx_t_4 = __Pyx_PyInt_AsInt(__pyx_v_bitCount); if (unlikely((__pyx_t_4 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 112; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_v_self->bitCount = __pyx_t_4;
+
+  /* "bx/bitset.pyx":113
+ *             raise ValueError( "%d is larger than the maximum BitSet size of %d." % ( bitCount, MAX_INT ) )
+ *         self.bitCount = bitCount
+ *         self.bits = bitAlloc( bitCount )             # <<<<<<<<<<<<<<
+ *     def __dealloc__( self ):
+ *         if self.bits:
+ */
+  __pyx_t_4 = __Pyx_PyInt_AsInt(__pyx_v_bitCount); if (unlikely((__pyx_t_4 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_v_self->bits = bitAlloc(__pyx_t_4);
+
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_AddTraceback("bx.bitset.BitSet.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = -1;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static void __pyx_pw_2bx_6bitset_6BitSet_3__dealloc__(PyObject *__pyx_v_self); /*proto*/
+static void __pyx_pw_2bx_6bitset_6BitSet_3__dealloc__(PyObject *__pyx_v_self) {
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__dealloc__ (wrapper)", 0);
+  __pyx_pf_2bx_6bitset_6BitSet_2__dealloc__(((struct __pyx_obj_2bx_6bitset_BitSet *)__pyx_v_self));
+  __Pyx_RefNannyFinishContext();
+}
+
+/* "bx/bitset.pyx":114
+ *         self.bitCount = bitCount
+ *         self.bits = bitAlloc( bitCount )
+ *     def __dealloc__( self ):             # <<<<<<<<<<<<<<
+ *         if self.bits:
+ *             bitFree( & self.bits )
+ */
+
+static void __pyx_pf_2bx_6bitset_6BitSet_2__dealloc__(struct __pyx_obj_2bx_6bitset_BitSet *__pyx_v_self) {
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("__dealloc__", 0);
+
+  /* "bx/bitset.pyx":115
+ *         self.bits = bitAlloc( bitCount )
+ *     def __dealloc__( self ):
+ *         if self.bits:             # <<<<<<<<<<<<<<
+ *             bitFree( & self.bits )
+ *     property size:
+ */
+  __pyx_t_1 = (__pyx_v_self->bits != 0);
+  if (__pyx_t_1) {
+
+    /* "bx/bitset.pyx":116
+ *     def __dealloc__( self ):
+ *         if self.bits:
+ *             bitFree( & self.bits )             # <<<<<<<<<<<<<<
+ *     property size:
+ *         def __get__( self ):
+ */
+    bitFree((&__pyx_v_self->bits));
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  __Pyx_RefNannyFinishContext();
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_6bitset_6BitSet_4size_1__get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_2bx_6bitset_6BitSet_4size_1__get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_6bitset_6BitSet_4size___get__(((struct __pyx_obj_2bx_6bitset_BitSet *)__pyx_v_self));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bitset.pyx":118
+ *             bitFree( & self.bits )
+ *     property size:
+ *         def __get__( self ):             # <<<<<<<<<<<<<<
+ *             return self.bitCount
+ *     def set( self, index ):
+ */
+
+static PyObject *__pyx_pf_2bx_6bitset_6BitSet_4size___get__(struct __pyx_obj_2bx_6bitset_BitSet *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__get__", 0);
+
+  /* "bx/bitset.pyx":119
+ *     property size:
+ *         def __get__( self ):
+ *             return self.bitCount             # <<<<<<<<<<<<<<
+ *     def set( self, index ):
+ *         b_check_index( self, index )
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = PyInt_FromLong(__pyx_v_self->bitCount); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("bx.bitset.BitSet.size.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_6bitset_6BitSet_5set(PyObject *__pyx_v_self, PyObject *__pyx_v_index); /*proto*/
+static PyObject *__pyx_pw_2bx_6bitset_6BitSet_5set(PyObject *__pyx_v_self, PyObject *__pyx_v_index) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("set (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_6bitset_6BitSet_4set(((struct __pyx_obj_2bx_6bitset_BitSet *)__pyx_v_self), ((PyObject *)__pyx_v_index));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bitset.pyx":120
+ *         def __get__( self ):
+ *             return self.bitCount
+ *     def set( self, index ):             # <<<<<<<<<<<<<<
+ *         b_check_index( self, index )
+ *         bitSetOne( self.bits, index )
+ */
+
+static PyObject *__pyx_pf_2bx_6bitset_6BitSet_4set(struct __pyx_obj_2bx_6bitset_BitSet *__pyx_v_self, PyObject *__pyx_v_index) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_t_2;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("set", 0);
+
+  /* "bx/bitset.pyx":121
+ *             return self.bitCount
+ *     def set( self, index ):
+ *         b_check_index( self, index )             # <<<<<<<<<<<<<<
+ *         bitSetOne( self.bits, index )
+ *     def clear( self, index ):
+ */
+  __pyx_t_1 = __pyx_f_2bx_6bitset_b_check_index(__pyx_v_self, __pyx_v_index); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 121; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "bx/bitset.pyx":122
+ *     def set( self, index ):
+ *         b_check_index( self, index )
+ *         bitSetOne( self.bits, index )             # <<<<<<<<<<<<<<
+ *     def clear( self, index ):
+ *         b_check_index( self, index )
+ */
+  __pyx_t_2 = __Pyx_PyInt_AsInt(__pyx_v_index); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 122; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  bitSetOne(__pyx_v_self->bits, __pyx_t_2);
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("bx.bitset.BitSet.set", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_6bitset_6BitSet_7clear(PyObject *__pyx_v_self, PyObject *__pyx_v_index); /*proto*/
+static PyObject *__pyx_pw_2bx_6bitset_6BitSet_7clear(PyObject *__pyx_v_self, PyObject *__pyx_v_index) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("clear (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_6bitset_6BitSet_6clear(((struct __pyx_obj_2bx_6bitset_BitSet *)__pyx_v_self), ((PyObject *)__pyx_v_index));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bitset.pyx":123
+ *         b_check_index( self, index )
+ *         bitSetOne( self.bits, index )
+ *     def clear( self, index ):             # <<<<<<<<<<<<<<
+ *         b_check_index( self, index )
+ *         bitClearOne( self.bits, index )
+ */
+
+static PyObject *__pyx_pf_2bx_6bitset_6BitSet_6clear(struct __pyx_obj_2bx_6bitset_BitSet *__pyx_v_self, PyObject *__pyx_v_index) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_t_2;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("clear", 0);
+
+  /* "bx/bitset.pyx":124
+ *         bitSetOne( self.bits, index )
+ *     def clear( self, index ):
+ *         b_check_index( self, index )             # <<<<<<<<<<<<<<
+ *         bitClearOne( self.bits, index )
+ *     def clone( self ):
+ */
+  __pyx_t_1 = __pyx_f_2bx_6bitset_b_check_index(__pyx_v_self, __pyx_v_index); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 124; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "bx/bitset.pyx":125
+ *     def clear( self, index ):
+ *         b_check_index( self, index )
+ *         bitClearOne( self.bits, index )             # <<<<<<<<<<<<<<
+ *     def clone( self ):
+ *         other = BitSet( self.bitCount )
+ */
+  __pyx_t_2 = __Pyx_PyInt_AsInt(__pyx_v_index); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  bitClearOne(__pyx_v_self->bits, __pyx_t_2);
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("bx.bitset.BitSet.clear", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_6bitset_6BitSet_9clone(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static PyObject *__pyx_pw_2bx_6bitset_6BitSet_9clone(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("clone (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_6bitset_6BitSet_8clone(((struct __pyx_obj_2bx_6bitset_BitSet *)__pyx_v_self));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bitset.pyx":126
+ *         b_check_index( self, index )
+ *         bitClearOne( self.bits, index )
+ *     def clone( self ):             # <<<<<<<<<<<<<<
+ *         other = BitSet( self.bitCount )
+ *         other.ior( self )
+ */
+
+static PyObject *__pyx_pf_2bx_6bitset_6BitSet_8clone(struct __pyx_obj_2bx_6bitset_BitSet *__pyx_v_self) {
+  struct __pyx_obj_2bx_6bitset_BitSet *__pyx_v_other = NULL;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("clone", 0);
+
+  /* "bx/bitset.pyx":127
+ *         bitClearOne( self.bits, index )
+ *     def clone( self ):
+ *         other = BitSet( self.bitCount )             # <<<<<<<<<<<<<<
+ *         other.ior( self )
+ *         return other
+ */
+  __pyx_t_1 = PyInt_FromLong(__pyx_v_self->bitCount); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
+  __Pyx_GIVEREF(__pyx_t_1);
+  __pyx_t_1 = 0;
+  __pyx_t_1 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_2bx_6bitset_BitSet)), ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
+  __pyx_v_other = ((struct __pyx_obj_2bx_6bitset_BitSet *)__pyx_t_1);
+  __pyx_t_1 = 0;
+
+  /* "bx/bitset.pyx":128
+ *     def clone( self ):
+ *         other = BitSet( self.bitCount )
+ *         other.ior( self )             # <<<<<<<<<<<<<<
+ *         return other
+ *     def set_range( self, start, count ):
+ */
+  __pyx_t_1 = PyObject_GetAttr(((PyObject *)__pyx_v_other), __pyx_n_s__ior); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 128; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 128; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_INCREF(((PyObject *)__pyx_v_self));
+  PyTuple_SET_ITEM(__pyx_t_2, 0, ((PyObject *)__pyx_v_self));
+  __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
+  __pyx_t_3 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 128; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+  /* "bx/bitset.pyx":129
+ *         other = BitSet( self.bitCount )
+ *         other.ior( self )
+ *         return other             # <<<<<<<<<<<<<<
+ *     def set_range( self, start, count ):
+ *         b_check_range_count( self, start, count )
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __Pyx_INCREF(((PyObject *)__pyx_v_other));
+  __pyx_r = ((PyObject *)__pyx_v_other);
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_AddTraceback("bx.bitset.BitSet.clone", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XDECREF((PyObject *)__pyx_v_other);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_6bitset_6BitSet_11set_range(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyObject *__pyx_pw_2bx_6bitset_6BitSet_11set_range(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_start = 0;
+  PyObject *__pyx_v_count = 0;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("set_range (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__start,&__pyx_n_s__count,0};
+    PyObject* values[2] = {0,0};
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__start)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__count)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("set_range", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 130; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "set_range") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 130; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
+      goto __pyx_L5_argtuple_error;
+    } else {
+      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+    }
+    __pyx_v_start = values[0];
+    __pyx_v_count = values[1];
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("set_range", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 130; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.bitset.BitSet.set_range", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_6bitset_6BitSet_10set_range(((struct __pyx_obj_2bx_6bitset_BitSet *)__pyx_v_self), __pyx_v_start, __pyx_v_count);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bitset.pyx":130
+ *         other.ior( self )
+ *         return other
+ *     def set_range( self, start, count ):             # <<<<<<<<<<<<<<
+ *         b_check_range_count( self, start, count )
+ *         bitSetRange( self.bits, start, count )
+ */
+
+static PyObject *__pyx_pf_2bx_6bitset_6BitSet_10set_range(struct __pyx_obj_2bx_6bitset_BitSet *__pyx_v_self, PyObject *__pyx_v_start, PyObject *__pyx_v_count) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_t_2;
+  int __pyx_t_3;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("set_range", 0);
+
+  /* "bx/bitset.pyx":131
+ *         return other
+ *     def set_range( self, start, count ):
+ *         b_check_range_count( self, start, count )             # <<<<<<<<<<<<<<
+ *         bitSetRange( self.bits, start, count )
+ *     def get( self, index ):
+ */
+  __pyx_t_1 = __pyx_f_2bx_6bitset_b_check_range_count(__pyx_v_self, __pyx_v_start, __pyx_v_count); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 131; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "bx/bitset.pyx":132
+ *     def set_range( self, start, count ):
+ *         b_check_range_count( self, start, count )
+ *         bitSetRange( self.bits, start, count )             # <<<<<<<<<<<<<<
+ *     def get( self, index ):
+ *         b_check_index( self, index )
+ */
+  __pyx_t_2 = __Pyx_PyInt_AsInt(__pyx_v_start); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = __Pyx_PyInt_AsInt(__pyx_v_count); if (unlikely((__pyx_t_3 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  bitSetRange(__pyx_v_self->bits, __pyx_t_2, __pyx_t_3);
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("bx.bitset.BitSet.set_range", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_6bitset_6BitSet_13get(PyObject *__pyx_v_self, PyObject *__pyx_v_index); /*proto*/
+static PyObject *__pyx_pw_2bx_6bitset_6BitSet_13get(PyObject *__pyx_v_self, PyObject *__pyx_v_index) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("get (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_6bitset_6BitSet_12get(((struct __pyx_obj_2bx_6bitset_BitSet *)__pyx_v_self), ((PyObject *)__pyx_v_index));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bitset.pyx":133
+ *         b_check_range_count( self, start, count )
+ *         bitSetRange( self.bits, start, count )
+ *     def get( self, index ):             # <<<<<<<<<<<<<<
+ *         b_check_index( self, index )
+ *         return bitReadOne( self.bits, index );
+ */
+
+static PyObject *__pyx_pf_2bx_6bitset_6BitSet_12get(struct __pyx_obj_2bx_6bitset_BitSet *__pyx_v_self, PyObject *__pyx_v_index) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_t_2;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("get", 0);
+
+  /* "bx/bitset.pyx":134
+ *         bitSetRange( self.bits, start, count )
+ *     def get( self, index ):
+ *         b_check_index( self, index )             # <<<<<<<<<<<<<<
+ *         return bitReadOne( self.bits, index );
+ *     def count_range( self, start=0, count=None ):
+ */
+  __pyx_t_1 = __pyx_f_2bx_6bitset_b_check_index(__pyx_v_self, __pyx_v_index); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 134; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "bx/bitset.pyx":135
+ *     def get( self, index ):
+ *         b_check_index( self, index )
+ *         return bitReadOne( self.bits, index );             # <<<<<<<<<<<<<<
+ *     def count_range( self, start=0, count=None ):
+ *         if count == None:
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_2 = __Pyx_PyInt_AsInt(__pyx_v_index); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 135; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyInt_FromLong(bitReadOne(__pyx_v_self->bits, __pyx_t_2)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 135; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("bx.bitset.BitSet.get", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_6bitset_6BitSet_15count_range(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyObject *__pyx_pw_2bx_6bitset_6BitSet_15count_range(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_start = 0;
+  PyObject *__pyx_v_count = 0;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("count_range (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__start,&__pyx_n_s__count,0};
+    PyObject* values[2] = {0,0};
+    values[0] = ((PyObject *)__pyx_int_0);
+
+    /* "bx/bitset.pyx":136
+ *         b_check_index( self, index )
+ *         return bitReadOne( self.bits, index );
+ *     def count_range( self, start=0, count=None ):             # <<<<<<<<<<<<<<
+ *         if count == None:
+ *             count = self.bitCount - start
+ */
+    values[1] = ((PyObject *)Py_None);
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s__start);
+          if (value) { values[0] = value; kw_args--; }
+        }
+        case  1:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s__count);
+          if (value) { values[1] = value; kw_args--; }
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "count_range") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 136; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else {
+      switch (PyTuple_GET_SIZE(__pyx_args)) {
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+    }
+    __pyx_v_start = values[0];
+    __pyx_v_count = values[1];
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("count_range", 0, 0, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 136; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.bitset.BitSet.count_range", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_6bitset_6BitSet_14count_range(((struct __pyx_obj_2bx_6bitset_BitSet *)__pyx_v_self), __pyx_v_start, __pyx_v_count);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_2bx_6bitset_6BitSet_14count_range(struct __pyx_obj_2bx_6bitset_BitSet *__pyx_v_self, PyObject *__pyx_v_start, PyObject *__pyx_v_count) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_t_2;
+  PyObject *__pyx_t_3 = NULL;
+  int __pyx_t_4;
+  int __pyx_t_5;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("count_range", 0);
+  __Pyx_INCREF(__pyx_v_count);
+
+  /* "bx/bitset.pyx":137
+ *         return bitReadOne( self.bits, index );
+ *     def count_range( self, start=0, count=None ):
+ *         if count == None:             # <<<<<<<<<<<<<<
+ *             count = self.bitCount - start
+ *         b_check_range_count( self, start, count )
+ */
+  __pyx_t_1 = PyObject_RichCompare(__pyx_v_count, Py_None, Py_EQ); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 137; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 137; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  if (__pyx_t_2) {
+
+    /* "bx/bitset.pyx":138
+ *     def count_range( self, start=0, count=None ):
+ *         if count == None:
+ *             count = self.bitCount - start             # <<<<<<<<<<<<<<
+ *         b_check_range_count( self, start, count )
+ *         return bitCountRange( self.bits, start, count )
+ */
+    __pyx_t_1 = PyInt_FromLong(__pyx_v_self->bitCount); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 138; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __pyx_t_3 = PyNumber_Subtract(__pyx_t_1, __pyx_v_start); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 138; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    __Pyx_DECREF(__pyx_v_count);
+    __pyx_v_count = __pyx_t_3;
+    __pyx_t_3 = 0;
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  /* "bx/bitset.pyx":139
+ *         if count == None:
+ *             count = self.bitCount - start
+ *         b_check_range_count( self, start, count )             # <<<<<<<<<<<<<<
+ *         return bitCountRange( self.bits, start, count )
+ *     def next_set( self, start, end=None ):
+ */
+  __pyx_t_3 = __pyx_f_2bx_6bitset_b_check_range_count(__pyx_v_self, __pyx_v_start, __pyx_v_count); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 139; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+  /* "bx/bitset.pyx":140
+ *             count = self.bitCount - start
+ *         b_check_range_count( self, start, count )
+ *         return bitCountRange( self.bits, start, count )             # <<<<<<<<<<<<<<
+ *     def next_set( self, start, end=None ):
+ *         if end == None:
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_4 = __Pyx_PyInt_AsInt(__pyx_v_start); if (unlikely((__pyx_t_4 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 140; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_5 = __Pyx_PyInt_AsInt(__pyx_v_count); if (unlikely((__pyx_t_5 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 140; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = PyInt_FromLong(bitCountRange(__pyx_v_self->bits, __pyx_t_4, __pyx_t_5)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 140; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_r = __pyx_t_3;
+  __pyx_t_3 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_AddTraceback("bx.bitset.BitSet.count_range", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_count);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_6bitset_6BitSet_17next_set(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyObject *__pyx_pw_2bx_6bitset_6BitSet_17next_set(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_start = 0;
+  PyObject *__pyx_v_end = 0;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("next_set (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__start,&__pyx_n_s__end,0};
+    PyObject* values[2] = {0,0};
+
+    /* "bx/bitset.pyx":141
+ *         b_check_range_count( self, start, count )
+ *         return bitCountRange( self.bits, start, count )
+ *     def next_set( self, start, end=None ):             # <<<<<<<<<<<<<<
+ *         if end == None:
+ *             end = self.bitCount
+ */
+    values[1] = ((PyObject *)Py_None);
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__start)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s__end);
+          if (value) { values[1] = value; kw_args--; }
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "next_set") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 141; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else {
+      switch (PyTuple_GET_SIZE(__pyx_args)) {
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+    }
+    __pyx_v_start = values[0];
+    __pyx_v_end = values[1];
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("next_set", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 141; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.bitset.BitSet.next_set", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_6bitset_6BitSet_16next_set(((struct __pyx_obj_2bx_6bitset_BitSet *)__pyx_v_self), __pyx_v_start, __pyx_v_end);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_2bx_6bitset_6BitSet_16next_set(struct __pyx_obj_2bx_6bitset_BitSet *__pyx_v_self, PyObject *__pyx_v_start, PyObject *__pyx_v_end) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_t_2;
+  int __pyx_t_3;
+  int __pyx_t_4;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("next_set", 0);
+  __Pyx_INCREF(__pyx_v_end);
+
+  /* "bx/bitset.pyx":142
+ *         return bitCountRange( self.bits, start, count )
+ *     def next_set( self, start, end=None ):
+ *         if end == None:             # <<<<<<<<<<<<<<
+ *             end = self.bitCount
+ *         b_check_range( self, start, end )
+ */
+  __pyx_t_1 = PyObject_RichCompare(__pyx_v_end, Py_None, Py_EQ); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  if (__pyx_t_2) {
+
+    /* "bx/bitset.pyx":143
+ *     def next_set( self, start, end=None ):
+ *         if end == None:
+ *             end = self.bitCount             # <<<<<<<<<<<<<<
+ *         b_check_range( self, start, end )
+ *         return bitFindSet( self.bits, start, end )
+ */
+    __pyx_t_1 = PyInt_FromLong(__pyx_v_self->bitCount); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __Pyx_DECREF(__pyx_v_end);
+    __pyx_v_end = __pyx_t_1;
+    __pyx_t_1 = 0;
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  /* "bx/bitset.pyx":144
+ *         if end == None:
+ *             end = self.bitCount
+ *         b_check_range( self, start, end )             # <<<<<<<<<<<<<<
+ *         return bitFindSet( self.bits, start, end )
+ *     def next_clear( self, start, end=None ):
+ */
+  __pyx_t_1 = __pyx_f_2bx_6bitset_b_check_range(__pyx_v_self, __pyx_v_start, __pyx_v_end); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 144; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "bx/bitset.pyx":145
+ *             end = self.bitCount
+ *         b_check_range( self, start, end )
+ *         return bitFindSet( self.bits, start, end )             # <<<<<<<<<<<<<<
+ *     def next_clear( self, start, end=None ):
+ *         if end == None:
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_3 = __Pyx_PyInt_AsInt(__pyx_v_start); if (unlikely((__pyx_t_3 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_4 = __Pyx_PyInt_AsInt(__pyx_v_end); if (unlikely((__pyx_t_4 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyInt_FromLong(bitFindSet(__pyx_v_self->bits, __pyx_t_3, __pyx_t_4)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("bx.bitset.BitSet.next_set", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_end);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_6bitset_6BitSet_19next_clear(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyObject *__pyx_pw_2bx_6bitset_6BitSet_19next_clear(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_start = 0;
+  PyObject *__pyx_v_end = 0;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("next_clear (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__start,&__pyx_n_s__end,0};
+    PyObject* values[2] = {0,0};
+
+    /* "bx/bitset.pyx":146
+ *         b_check_range( self, start, end )
+ *         return bitFindSet( self.bits, start, end )
+ *     def next_clear( self, start, end=None ):             # <<<<<<<<<<<<<<
+ *         if end == None:
+ *             end = self.bitCount
+ */
+    values[1] = ((PyObject *)Py_None);
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__start)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s__end);
+          if (value) { values[1] = value; kw_args--; }
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "next_clear") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 146; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else {
+      switch (PyTuple_GET_SIZE(__pyx_args)) {
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+    }
+    __pyx_v_start = values[0];
+    __pyx_v_end = values[1];
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("next_clear", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 146; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.bitset.BitSet.next_clear", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_6bitset_6BitSet_18next_clear(((struct __pyx_obj_2bx_6bitset_BitSet *)__pyx_v_self), __pyx_v_start, __pyx_v_end);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_2bx_6bitset_6BitSet_18next_clear(struct __pyx_obj_2bx_6bitset_BitSet *__pyx_v_self, PyObject *__pyx_v_start, PyObject *__pyx_v_end) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_t_2;
+  int __pyx_t_3;
+  int __pyx_t_4;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("next_clear", 0);
+  __Pyx_INCREF(__pyx_v_end);
+
+  /* "bx/bitset.pyx":147
+ *         return bitFindSet( self.bits, start, end )
+ *     def next_clear( self, start, end=None ):
+ *         if end == None:             # <<<<<<<<<<<<<<
+ *             end = self.bitCount
+ *         b_check_range( self, start, end )
+ */
+  __pyx_t_1 = PyObject_RichCompare(__pyx_v_end, Py_None, Py_EQ); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  if (__pyx_t_2) {
+
+    /* "bx/bitset.pyx":148
+ *     def next_clear( self, start, end=None ):
+ *         if end == None:
+ *             end = self.bitCount             # <<<<<<<<<<<<<<
+ *         b_check_range( self, start, end )
+ *         return bitFindClear( self.bits, start, end )
+ */
+    __pyx_t_1 = PyInt_FromLong(__pyx_v_self->bitCount); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 148; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __Pyx_DECREF(__pyx_v_end);
+    __pyx_v_end = __pyx_t_1;
+    __pyx_t_1 = 0;
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  /* "bx/bitset.pyx":149
+ *         if end == None:
+ *             end = self.bitCount
+ *         b_check_range( self, start, end )             # <<<<<<<<<<<<<<
+ *         return bitFindClear( self.bits, start, end )
+ *     def iand( self, BitSet other ):
+ */
+  __pyx_t_1 = __pyx_f_2bx_6bitset_b_check_range(__pyx_v_self, __pyx_v_start, __pyx_v_end); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 149; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "bx/bitset.pyx":150
+ *             end = self.bitCount
+ *         b_check_range( self, start, end )
+ *         return bitFindClear( self.bits, start, end )             # <<<<<<<<<<<<<<
+ *     def iand( self, BitSet other ):
+ *         b_check_same_size( self, other )
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_3 = __Pyx_PyInt_AsInt(__pyx_v_start); if (unlikely((__pyx_t_3 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 150; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_4 = __Pyx_PyInt_AsInt(__pyx_v_end); if (unlikely((__pyx_t_4 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 150; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyInt_FromLong(bitFindClear(__pyx_v_self->bits, __pyx_t_3, __pyx_t_4)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 150; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("bx.bitset.BitSet.next_clear", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_end);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_6bitset_6BitSet_21iand(PyObject *__pyx_v_self, PyObject *__pyx_v_other); /*proto*/
+static PyObject *__pyx_pw_2bx_6bitset_6BitSet_21iand(PyObject *__pyx_v_self, PyObject *__pyx_v_other) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("iand (wrapper)", 0);
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_other), __pyx_ptype_2bx_6bitset_BitSet, 1, "other", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 151; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_r = __pyx_pf_2bx_6bitset_6BitSet_20iand(((struct __pyx_obj_2bx_6bitset_BitSet *)__pyx_v_self), ((struct __pyx_obj_2bx_6bitset_BitSet *)__pyx_v_other));
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bitset.pyx":151
+ *         b_check_range( self, start, end )
+ *         return bitFindClear( self.bits, start, end )
+ *     def iand( self, BitSet other ):             # <<<<<<<<<<<<<<
+ *         b_check_same_size( self, other )
+ *         bitAnd( self.bits, other.bits, self.bitCount )
+ */
+
+static PyObject *__pyx_pf_2bx_6bitset_6BitSet_20iand(struct __pyx_obj_2bx_6bitset_BitSet *__pyx_v_self, struct __pyx_obj_2bx_6bitset_BitSet *__pyx_v_other) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("iand", 0);
+
+  /* "bx/bitset.pyx":152
+ *         return bitFindClear( self.bits, start, end )
+ *     def iand( self, BitSet other ):
+ *         b_check_same_size( self, other )             # <<<<<<<<<<<<<<
+ *         bitAnd( self.bits, other.bits, self.bitCount )
+ *     def ior( self, BitSet other ):
+ */
+  __pyx_t_1 = __pyx_f_2bx_6bitset_b_check_same_size(__pyx_v_self, __pyx_v_other); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 152; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "bx/bitset.pyx":153
+ *     def iand( self, BitSet other ):
+ *         b_check_same_size( self, other )
+ *         bitAnd( self.bits, other.bits, self.bitCount )             # <<<<<<<<<<<<<<
+ *     def ior( self, BitSet other ):
+ *         b_check_same_size( self, other )
+ */
+  bitAnd(__pyx_v_self->bits, __pyx_v_other->bits, __pyx_v_self->bitCount);
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("bx.bitset.BitSet.iand", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_6bitset_6BitSet_23ior(PyObject *__pyx_v_self, PyObject *__pyx_v_other); /*proto*/
+static PyObject *__pyx_pw_2bx_6bitset_6BitSet_23ior(PyObject *__pyx_v_self, PyObject *__pyx_v_other) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("ior (wrapper)", 0);
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_other), __pyx_ptype_2bx_6bitset_BitSet, 1, "other", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 154; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_r = __pyx_pf_2bx_6bitset_6BitSet_22ior(((struct __pyx_obj_2bx_6bitset_BitSet *)__pyx_v_self), ((struct __pyx_obj_2bx_6bitset_BitSet *)__pyx_v_other));
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bitset.pyx":154
+ *         b_check_same_size( self, other )
+ *         bitAnd( self.bits, other.bits, self.bitCount )
+ *     def ior( self, BitSet other ):             # <<<<<<<<<<<<<<
+ *         b_check_same_size( self, other )
+ *         bitOr( self.bits, other.bits, self.bitCount )
+ */
+
+static PyObject *__pyx_pf_2bx_6bitset_6BitSet_22ior(struct __pyx_obj_2bx_6bitset_BitSet *__pyx_v_self, struct __pyx_obj_2bx_6bitset_BitSet *__pyx_v_other) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("ior", 0);
+
+  /* "bx/bitset.pyx":155
+ *         bitAnd( self.bits, other.bits, self.bitCount )
+ *     def ior( self, BitSet other ):
+ *         b_check_same_size( self, other )             # <<<<<<<<<<<<<<
+ *         bitOr( self.bits, other.bits, self.bitCount )
+ *     def ixor( self, BitSet other ):
+ */
+  __pyx_t_1 = __pyx_f_2bx_6bitset_b_check_same_size(__pyx_v_self, __pyx_v_other); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 155; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "bx/bitset.pyx":156
+ *     def ior( self, BitSet other ):
+ *         b_check_same_size( self, other )
+ *         bitOr( self.bits, other.bits, self.bitCount )             # <<<<<<<<<<<<<<
+ *     def ixor( self, BitSet other ):
+ *         b_check_same_size( self, other )
+ */
+  bitOr(__pyx_v_self->bits, __pyx_v_other->bits, __pyx_v_self->bitCount);
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("bx.bitset.BitSet.ior", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_6bitset_6BitSet_25ixor(PyObject *__pyx_v_self, PyObject *__pyx_v_other); /*proto*/
+static PyObject *__pyx_pw_2bx_6bitset_6BitSet_25ixor(PyObject *__pyx_v_self, PyObject *__pyx_v_other) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("ixor (wrapper)", 0);
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_other), __pyx_ptype_2bx_6bitset_BitSet, 1, "other", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 157; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_r = __pyx_pf_2bx_6bitset_6BitSet_24ixor(((struct __pyx_obj_2bx_6bitset_BitSet *)__pyx_v_self), ((struct __pyx_obj_2bx_6bitset_BitSet *)__pyx_v_other));
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bitset.pyx":157
+ *         b_check_same_size( self, other )
+ *         bitOr( self.bits, other.bits, self.bitCount )
+ *     def ixor( self, BitSet other ):             # <<<<<<<<<<<<<<
+ *         b_check_same_size( self, other )
+ *         bitXor( self.bits, other.bits, self.bitCount )
+ */
+
+static PyObject *__pyx_pf_2bx_6bitset_6BitSet_24ixor(struct __pyx_obj_2bx_6bitset_BitSet *__pyx_v_self, struct __pyx_obj_2bx_6bitset_BitSet *__pyx_v_other) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("ixor", 0);
+
+  /* "bx/bitset.pyx":158
+ *         bitOr( self.bits, other.bits, self.bitCount )
+ *     def ixor( self, BitSet other ):
+ *         b_check_same_size( self, other )             # <<<<<<<<<<<<<<
+ *         bitXor( self.bits, other.bits, self.bitCount )
+ *     def invert( self ):
+ */
+  __pyx_t_1 = __pyx_f_2bx_6bitset_b_check_same_size(__pyx_v_self, __pyx_v_other); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "bx/bitset.pyx":159
+ *     def ixor( self, BitSet other ):
+ *         b_check_same_size( self, other )
+ *         bitXor( self.bits, other.bits, self.bitCount )             # <<<<<<<<<<<<<<
+ *     def invert( self ):
+ *         bitNot( self.bits, self.bitCount)
+ */
+  bitXor(__pyx_v_self->bits, __pyx_v_other->bits, __pyx_v_self->bitCount);
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("bx.bitset.BitSet.ixor", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_6bitset_6BitSet_27invert(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static PyObject *__pyx_pw_2bx_6bitset_6BitSet_27invert(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("invert (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_6bitset_6BitSet_26invert(((struct __pyx_obj_2bx_6bitset_BitSet *)__pyx_v_self));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bitset.pyx":160
+ *         b_check_same_size( self, other )
+ *         bitXor( self.bits, other.bits, self.bitCount )
+ *     def invert( self ):             # <<<<<<<<<<<<<<
+ *         bitNot( self.bits, self.bitCount)
+ *     def __getitem__( self, index ):
+ */
+
+static PyObject *__pyx_pf_2bx_6bitset_6BitSet_26invert(struct __pyx_obj_2bx_6bitset_BitSet *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("invert", 0);
+
+  /* "bx/bitset.pyx":161
+ *         bitXor( self.bits, other.bits, self.bitCount )
+ *     def invert( self ):
+ *         bitNot( self.bits, self.bitCount)             # <<<<<<<<<<<<<<
+ *     def __getitem__( self, index ):
+ *         return self.get( index )
+ */
+  bitNot(__pyx_v_self->bits, __pyx_v_self->bitCount);
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_6bitset_6BitSet_29__getitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_index); /*proto*/
+static PyObject *__pyx_pw_2bx_6bitset_6BitSet_29__getitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_index) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__getitem__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_6bitset_6BitSet_28__getitem__(((struct __pyx_obj_2bx_6bitset_BitSet *)__pyx_v_self), ((PyObject *)__pyx_v_index));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bitset.pyx":162
+ *     def invert( self ):
+ *         bitNot( self.bits, self.bitCount)
+ *     def __getitem__( self, index ):             # <<<<<<<<<<<<<<
+ *         return self.get( index )
+ *     def __iand__( self, other ):
+ */
+
+static PyObject *__pyx_pf_2bx_6bitset_6BitSet_28__getitem__(struct __pyx_obj_2bx_6bitset_BitSet *__pyx_v_self, PyObject *__pyx_v_index) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__getitem__", 0);
+
+  /* "bx/bitset.pyx":163
+ *         bitNot( self.bits, self.bitCount)
+ *     def __getitem__( self, index ):
+ *         return self.get( index )             # <<<<<<<<<<<<<<
+ *     def __iand__( self, other ):
+ *         self.iand( other )
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = PyObject_GetAttr(((PyObject *)__pyx_v_self), __pyx_n_s__get); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 163; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 163; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_INCREF(__pyx_v_index);
+  PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_index);
+  __Pyx_GIVEREF(__pyx_v_index);
+  __pyx_t_3 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 163; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
+  __pyx_r = __pyx_t_3;
+  __pyx_t_3 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_AddTraceback("bx.bitset.BitSet.__getitem__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_6bitset_6BitSet_31__iand__(PyObject *__pyx_v_self, PyObject *__pyx_v_other); /*proto*/
+static PyObject *__pyx_pw_2bx_6bitset_6BitSet_31__iand__(PyObject *__pyx_v_self, PyObject *__pyx_v_other) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__iand__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_6bitset_6BitSet_30__iand__(((struct __pyx_obj_2bx_6bitset_BitSet *)__pyx_v_self), ((PyObject *)__pyx_v_other));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bitset.pyx":164
+ *     def __getitem__( self, index ):
+ *         return self.get( index )
+ *     def __iand__( self, other ):             # <<<<<<<<<<<<<<
+ *         self.iand( other )
+ *         return self
+ */
+
+static PyObject *__pyx_pf_2bx_6bitset_6BitSet_30__iand__(struct __pyx_obj_2bx_6bitset_BitSet *__pyx_v_self, PyObject *__pyx_v_other) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__iand__", 0);
+
+  /* "bx/bitset.pyx":165
+ *         return self.get( index )
+ *     def __iand__( self, other ):
+ *         self.iand( other )             # <<<<<<<<<<<<<<
+ *         return self
+ *     def __ior__( self, other ):
+ */
+  __pyx_t_1 = PyObject_GetAttr(((PyObject *)__pyx_v_self), __pyx_n_s__iand); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 165; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 165; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_INCREF(__pyx_v_other);
+  PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_other);
+  __Pyx_GIVEREF(__pyx_v_other);
+  __pyx_t_3 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 165; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+  /* "bx/bitset.pyx":166
+ *     def __iand__( self, other ):
+ *         self.iand( other )
+ *         return self             # <<<<<<<<<<<<<<
+ *     def __ior__( self, other ):
+ *         self.ior( other )
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __Pyx_INCREF(((PyObject *)__pyx_v_self));
+  __pyx_r = ((PyObject *)__pyx_v_self);
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_AddTraceback("bx.bitset.BitSet.__iand__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_6bitset_6BitSet_33__ior__(PyObject *__pyx_v_self, PyObject *__pyx_v_other); /*proto*/
+static PyObject *__pyx_pw_2bx_6bitset_6BitSet_33__ior__(PyObject *__pyx_v_self, PyObject *__pyx_v_other) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__ior__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_6bitset_6BitSet_32__ior__(((struct __pyx_obj_2bx_6bitset_BitSet *)__pyx_v_self), ((PyObject *)__pyx_v_other));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bitset.pyx":167
+ *         self.iand( other )
+ *         return self
+ *     def __ior__( self, other ):             # <<<<<<<<<<<<<<
+ *         self.ior( other )
+ *         return self
+ */
+
+static PyObject *__pyx_pf_2bx_6bitset_6BitSet_32__ior__(struct __pyx_obj_2bx_6bitset_BitSet *__pyx_v_self, PyObject *__pyx_v_other) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__ior__", 0);
+
+  /* "bx/bitset.pyx":168
+ *         return self
+ *     def __ior__( self, other ):
+ *         self.ior( other )             # <<<<<<<<<<<<<<
+ *         return self
+ *     def __invert__( self ):
+ */
+  __pyx_t_1 = PyObject_GetAttr(((PyObject *)__pyx_v_self), __pyx_n_s__ior); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 168; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 168; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_INCREF(__pyx_v_other);
+  PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_other);
+  __Pyx_GIVEREF(__pyx_v_other);
+  __pyx_t_3 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 168; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+  /* "bx/bitset.pyx":169
+ *     def __ior__( self, other ):
+ *         self.ior( other )
+ *         return self             # <<<<<<<<<<<<<<
+ *     def __invert__( self ):
+ *         self.invert()
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __Pyx_INCREF(((PyObject *)__pyx_v_self));
+  __pyx_r = ((PyObject *)__pyx_v_self);
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_AddTraceback("bx.bitset.BitSet.__ior__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_6bitset_6BitSet_35__invert__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_2bx_6bitset_6BitSet_35__invert__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__invert__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_6bitset_6BitSet_34__invert__(((struct __pyx_obj_2bx_6bitset_BitSet *)__pyx_v_self));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bitset.pyx":170
+ *         self.ior( other )
+ *         return self
+ *     def __invert__( self ):             # <<<<<<<<<<<<<<
+ *         self.invert()
+ *         return self
+ */
+
+static PyObject *__pyx_pf_2bx_6bitset_6BitSet_34__invert__(struct __pyx_obj_2bx_6bitset_BitSet *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__invert__", 0);
+
+  /* "bx/bitset.pyx":171
+ *         return self
+ *     def __invert__( self ):
+ *         self.invert()             # <<<<<<<<<<<<<<
+ *         return self
+ * 
+ */
+  __pyx_t_1 = PyObject_GetAttr(((PyObject *)__pyx_v_self), __pyx_n_s__invert); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 171; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 171; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+  /* "bx/bitset.pyx":172
+ *     def __invert__( self ):
+ *         self.invert()
+ *         return self             # <<<<<<<<<<<<<<
+ * 
+ * ## ---- BinnedBitSet bounds checking ----------------------------------------
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __Pyx_INCREF(((PyObject *)__pyx_v_self));
+  __pyx_r = ((PyObject *)__pyx_v_self);
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_AddTraceback("bx.bitset.BitSet.__invert__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bitset.pyx":176
+ * ## ---- BinnedBitSet bounds checking ----------------------------------------
+ * 
+ * cdef inline bb_check_index( BinnedBitSet bb, index ):             # <<<<<<<<<<<<<<
+ *     if index < 0:
+ *         raise IndexError( "BitSet index (%d) must be non-negative." % index )
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_2bx_6bitset_bb_check_index(struct __pyx_obj_2bx_6bitset_BinnedBitSet *__pyx_v_bb, PyObject *__pyx_v_index) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_t_2;
+  PyObject *__pyx_t_3 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("bb_check_index", 0);
+
+  /* "bx/bitset.pyx":177
+ * 
+ * cdef inline bb_check_index( BinnedBitSet bb, index ):
+ *     if index < 0:             # <<<<<<<<<<<<<<
+ *         raise IndexError( "BitSet index (%d) must be non-negative." % index )
+ *     if index >= bb.bb.size:
+ */
+  __pyx_t_1 = PyObject_RichCompare(__pyx_v_index, __pyx_int_0, Py_LT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 177; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 177; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  if (__pyx_t_2) {
+
+    /* "bx/bitset.pyx":178
+ * cdef inline bb_check_index( BinnedBitSet bb, index ):
+ *     if index < 0:
+ *         raise IndexError( "BitSet index (%d) must be non-negative." % index )             # <<<<<<<<<<<<<<
+ *     if index >= bb.bb.size:
+ *         raise IndexError( "%d is larger than the size of this BitSet (%d)." % ( index, bb.bb.size ) )
+ */
+    __pyx_t_1 = PyNumber_Remainder(((PyObject *)__pyx_kp_s_1), __pyx_v_index); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 178; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(((PyObject *)__pyx_t_1));
+    __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 178; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    PyTuple_SET_ITEM(__pyx_t_3, 0, ((PyObject *)__pyx_t_1));
+    __Pyx_GIVEREF(((PyObject *)__pyx_t_1));
+    __pyx_t_1 = 0;
+    __pyx_t_1 = PyObject_Call(__pyx_builtin_IndexError, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 178; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
+    __Pyx_Raise(__pyx_t_1, 0, 0, 0);
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 178; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  /* "bx/bitset.pyx":179
+ *     if index < 0:
+ *         raise IndexError( "BitSet index (%d) must be non-negative." % index )
+ *     if index >= bb.bb.size:             # <<<<<<<<<<<<<<
+ *         raise IndexError( "%d is larger than the size of this BitSet (%d)." % ( index, bb.bb.size ) )
+ * cdef inline bb_check_start( BinnedBitSet bb, start ):
+ */
+  __pyx_t_1 = PyInt_FromLong(__pyx_v_bb->bb->size); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 179; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_3 = PyObject_RichCompare(__pyx_v_index, __pyx_t_1, Py_GE); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 179; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 179; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  if (__pyx_t_2) {
+
+    /* "bx/bitset.pyx":180
+ *         raise IndexError( "BitSet index (%d) must be non-negative." % index )
+ *     if index >= bb.bb.size:
+ *         raise IndexError( "%d is larger than the size of this BitSet (%d)." % ( index, bb.bb.size ) )             # <<<<<<<<<<<<<<
+ * cdef inline bb_check_start( BinnedBitSet bb, start ):
+ *     bb_check_index( bb, start )
+ */
+    __pyx_t_3 = PyInt_FromLong(__pyx_v_bb->bb->size); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 180; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 180; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __Pyx_INCREF(__pyx_v_index);
+    PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_index);
+    __Pyx_GIVEREF(__pyx_v_index);
+    PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_t_3);
+    __Pyx_GIVEREF(__pyx_t_3);
+    __pyx_t_3 = 0;
+    __pyx_t_3 = PyNumber_Remainder(((PyObject *)__pyx_kp_s_2), ((PyObject *)__pyx_t_1)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 180; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(((PyObject *)__pyx_t_3));
+    __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+    __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 180; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    PyTuple_SET_ITEM(__pyx_t_1, 0, ((PyObject *)__pyx_t_3));
+    __Pyx_GIVEREF(((PyObject *)__pyx_t_3));
+    __pyx_t_3 = 0;
+    __pyx_t_3 = PyObject_Call(__pyx_builtin_IndexError, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 180; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+    __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 180; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    goto __pyx_L4;
+  }
+  __pyx_L4:;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_AddTraceback("bx.bitset.bb_check_index", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bitset.pyx":181
+ *     if index >= bb.bb.size:
+ *         raise IndexError( "%d is larger than the size of this BitSet (%d)." % ( index, bb.bb.size ) )
+ * cdef inline bb_check_start( BinnedBitSet bb, start ):             # <<<<<<<<<<<<<<
+ *     bb_check_index( bb, start )
+ * cdef inline bb_check_range_count( BinnedBitSet bb, start, count ):
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_2bx_6bitset_bb_check_start(struct __pyx_obj_2bx_6bitset_BinnedBitSet *__pyx_v_bb, PyObject *__pyx_v_start) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("bb_check_start", 0);
+
+  /* "bx/bitset.pyx":182
+ *         raise IndexError( "%d is larger than the size of this BitSet (%d)." % ( index, bb.bb.size ) )
+ * cdef inline bb_check_start( BinnedBitSet bb, start ):
+ *     bb_check_index( bb, start )             # <<<<<<<<<<<<<<
+ * cdef inline bb_check_range_count( BinnedBitSet bb, start, count ):
+ *     bb_check_index( bb, start )
+ */
+  __pyx_t_1 = __pyx_f_2bx_6bitset_bb_check_index(__pyx_v_bb, __pyx_v_start); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 182; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("bx.bitset.bb_check_start", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bitset.pyx":183
+ * cdef inline bb_check_start( BinnedBitSet bb, start ):
+ *     bb_check_index( bb, start )
+ * cdef inline bb_check_range_count( BinnedBitSet bb, start, count ):             # <<<<<<<<<<<<<<
+ *     bb_check_index( bb, start )
+ *     if count < 0:
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_2bx_6bitset_bb_check_range_count(struct __pyx_obj_2bx_6bitset_BinnedBitSet *__pyx_v_bb, PyObject *__pyx_v_start, PyObject *__pyx_v_count) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_t_2;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("bb_check_range_count", 0);
+
+  /* "bx/bitset.pyx":184
+ *     bb_check_index( bb, start )
+ * cdef inline bb_check_range_count( BinnedBitSet bb, start, count ):
+ *     bb_check_index( bb, start )             # <<<<<<<<<<<<<<
+ *     if count < 0:
+ *         raise IndexError( "Count (%d) must be non-negative." % count )
+ */
+  __pyx_t_1 = __pyx_f_2bx_6bitset_bb_check_index(__pyx_v_bb, __pyx_v_start); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 184; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "bx/bitset.pyx":185
+ * cdef inline bb_check_range_count( BinnedBitSet bb, start, count ):
+ *     bb_check_index( bb, start )
+ *     if count < 0:             # <<<<<<<<<<<<<<
+ *         raise IndexError( "Count (%d) must be non-negative." % count )
+ *     if start + count > bb.bb.size:
+ */
+  __pyx_t_1 = PyObject_RichCompare(__pyx_v_count, __pyx_int_0, Py_LT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 185; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 185; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  if (__pyx_t_2) {
+
+    /* "bx/bitset.pyx":186
+ *     bb_check_index( bb, start )
+ *     if count < 0:
+ *         raise IndexError( "Count (%d) must be non-negative." % count )             # <<<<<<<<<<<<<<
+ *     if start + count > bb.bb.size:
+ *         raise IndexError( "End (%d) is larger than the size of this BinnedBitSet (%d)." % ( start + count, bb.bb.size ) )
+ */
+    __pyx_t_1 = PyNumber_Remainder(((PyObject *)__pyx_kp_s_5), __pyx_v_count); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 186; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(((PyObject *)__pyx_t_1));
+    __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 186; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    PyTuple_SET_ITEM(__pyx_t_3, 0, ((PyObject *)__pyx_t_1));
+    __Pyx_GIVEREF(((PyObject *)__pyx_t_1));
+    __pyx_t_1 = 0;
+    __pyx_t_1 = PyObject_Call(__pyx_builtin_IndexError, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 186; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
+    __Pyx_Raise(__pyx_t_1, 0, 0, 0);
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 186; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  /* "bx/bitset.pyx":187
+ *     if count < 0:
+ *         raise IndexError( "Count (%d) must be non-negative." % count )
+ *     if start + count > bb.bb.size:             # <<<<<<<<<<<<<<
+ *         raise IndexError( "End (%d) is larger than the size of this BinnedBitSet (%d)." % ( start + count, bb.bb.size ) )
+ * cdef inline bb_check_same_size( BinnedBitSet bb, BinnedBitSet other ):
+ */
+  __pyx_t_1 = PyNumber_Add(__pyx_v_start, __pyx_v_count); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_3 = PyInt_FromLong(__pyx_v_bb->bb->size); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_4 = PyObject_RichCompare(__pyx_t_1, __pyx_t_3, Py_GT); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  if (__pyx_t_2) {
+
+    /* "bx/bitset.pyx":188
+ *         raise IndexError( "Count (%d) must be non-negative." % count )
+ *     if start + count > bb.bb.size:
+ *         raise IndexError( "End (%d) is larger than the size of this BinnedBitSet (%d)." % ( start + count, bb.bb.size ) )             # <<<<<<<<<<<<<<
+ * cdef inline bb_check_same_size( BinnedBitSet bb, BinnedBitSet other ):
+ *     if bb.bb.size != other.bb.size:
+ */
+    __pyx_t_4 = PyNumber_Add(__pyx_v_start, __pyx_v_count); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 188; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    __pyx_t_3 = PyInt_FromLong(__pyx_v_bb->bb->size); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 188; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 188; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_4);
+    __Pyx_GIVEREF(__pyx_t_4);
+    PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_t_3);
+    __Pyx_GIVEREF(__pyx_t_3);
+    __pyx_t_4 = 0;
+    __pyx_t_3 = 0;
+    __pyx_t_3 = PyNumber_Remainder(((PyObject *)__pyx_kp_s_9), ((PyObject *)__pyx_t_1)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 188; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(((PyObject *)__pyx_t_3));
+    __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+    __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 188; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    PyTuple_SET_ITEM(__pyx_t_1, 0, ((PyObject *)__pyx_t_3));
+    __Pyx_GIVEREF(((PyObject *)__pyx_t_3));
+    __pyx_t_3 = 0;
+    __pyx_t_3 = PyObject_Call(__pyx_builtin_IndexError, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 188; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+    __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 188; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    goto __pyx_L4;
+  }
+  __pyx_L4:;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_AddTraceback("bx.bitset.bb_check_range_count", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bitset.pyx":189
+ *     if start + count > bb.bb.size:
+ *         raise IndexError( "End (%d) is larger than the size of this BinnedBitSet (%d)." % ( start + count, bb.bb.size ) )
+ * cdef inline bb_check_same_size( BinnedBitSet bb, BinnedBitSet other ):             # <<<<<<<<<<<<<<
+ *     if bb.bb.size != other.bb.size:
+ *         raise ValueError( "BitSets must have the same size" )
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_2bx_6bitset_bb_check_same_size(struct __pyx_obj_2bx_6bitset_BinnedBitSet *__pyx_v_bb, struct __pyx_obj_2bx_6bitset_BinnedBitSet *__pyx_v_other) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("bb_check_same_size", 0);
+
+  /* "bx/bitset.pyx":190
+ *         raise IndexError( "End (%d) is larger than the size of this BinnedBitSet (%d)." % ( start + count, bb.bb.size ) )
+ * cdef inline bb_check_same_size( BinnedBitSet bb, BinnedBitSet other ):
+ *     if bb.bb.size != other.bb.size:             # <<<<<<<<<<<<<<
+ *         raise ValueError( "BitSets must have the same size" )
+ * 
+ */
+  __pyx_t_1 = (__pyx_v_bb->bb->size != __pyx_v_other->bb->size);
+  if (__pyx_t_1) {
+
+    /* "bx/bitset.pyx":191
+ * cdef inline bb_check_same_size( BinnedBitSet bb, BinnedBitSet other ):
+ *     if bb.bb.size != other.bb.size:
+ *         raise ValueError( "BitSets must have the same size" )             # <<<<<<<<<<<<<<
+ * 
+ * ## ---- BinnedBitSet --------------------------------------------------------
+ */
+    __pyx_t_2 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_k_tuple_10), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 191; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __Pyx_Raise(__pyx_t_2, 0, 0, 0);
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 191; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_AddTraceback("bx.bitset.bb_check_same_size", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_2bx_6bitset_12BinnedBitSet_1__cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static int __pyx_pw_2bx_6bitset_12BinnedBitSet_1__cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_size = 0;
+  PyObject *__pyx_v_granularity = 0;
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__cinit__ (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__size,&__pyx_n_s__granularity,0};
+    PyObject* values[2] = {0,0};
+    values[0] = __pyx_k_11;
+    values[1] = ((PyObject *)__pyx_int_1024);
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s__size);
+          if (value) { values[0] = value; kw_args--; }
+        }
+        case  1:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s__granularity);
+          if (value) { values[1] = value; kw_args--; }
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__cinit__") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 199; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else {
+      switch (PyTuple_GET_SIZE(__pyx_args)) {
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+    }
+    __pyx_v_size = values[0];
+    __pyx_v_granularity = values[1];
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 0, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 199; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.bitset.BinnedBitSet.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return -1;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_6bitset_12BinnedBitSet___cinit__(((struct __pyx_obj_2bx_6bitset_BinnedBitSet *)__pyx_v_self), __pyx_v_size, __pyx_v_granularity);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bitset.pyx":199
+ * cdef class BinnedBitSet:
+ *     cdef BinBits * bb
+ *     def __cinit__( self, size=MAX, granularity=1024 ):             # <<<<<<<<<<<<<<
+ *         if size > MAX_INT:
+ *             raise ValueError( "%d is larger than the maximum BinnedBitSet size of %d." % ( size, MAX_INT ) )
+ */
+
+static int __pyx_pf_2bx_6bitset_12BinnedBitSet___cinit__(struct __pyx_obj_2bx_6bitset_BinnedBitSet *__pyx_v_self, PyObject *__pyx_v_size, PyObject *__pyx_v_granularity) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  int __pyx_t_3;
+  int __pyx_t_4;
+  int __pyx_t_5;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__cinit__", 0);
+
+  /* "bx/bitset.pyx":200
+ *     cdef BinBits * bb
+ *     def __cinit__( self, size=MAX, granularity=1024 ):
+ *         if size > MAX_INT:             # <<<<<<<<<<<<<<
+ *             raise ValueError( "%d is larger than the maximum BinnedBitSet size of %d." % ( size, MAX_INT ) )
+ *         self.bb = binBitsAlloc( size, granularity )
+ */
+  __pyx_t_1 = PyInt_FromLong(__pyx_v_2bx_6bitset_MAX_INT); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 200; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = PyObject_RichCompare(__pyx_v_size, __pyx_t_1, Py_GT); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 200; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 200; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  if (__pyx_t_3) {
+
+    /* "bx/bitset.pyx":201
+ *     def __cinit__( self, size=MAX, granularity=1024 ):
+ *         if size > MAX_INT:
+ *             raise ValueError( "%d is larger than the maximum BinnedBitSet size of %d." % ( size, MAX_INT ) )             # <<<<<<<<<<<<<<
+ *         self.bb = binBitsAlloc( size, granularity )
+ *     def __dealloc__( self ):
+ */
+    __pyx_t_2 = PyInt_FromLong(__pyx_v_2bx_6bitset_MAX_INT); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 201; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 201; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __Pyx_INCREF(__pyx_v_size);
+    PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_size);
+    __Pyx_GIVEREF(__pyx_v_size);
+    PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_t_2);
+    __Pyx_GIVEREF(__pyx_t_2);
+    __pyx_t_2 = 0;
+    __pyx_t_2 = PyNumber_Remainder(((PyObject *)__pyx_kp_s_12), ((PyObject *)__pyx_t_1)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 201; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(((PyObject *)__pyx_t_2));
+    __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+    __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 201; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    PyTuple_SET_ITEM(__pyx_t_1, 0, ((PyObject *)__pyx_t_2));
+    __Pyx_GIVEREF(((PyObject *)__pyx_t_2));
+    __pyx_t_2 = 0;
+    __pyx_t_2 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 201; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+    __Pyx_Raise(__pyx_t_2, 0, 0, 0);
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 201; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  /* "bx/bitset.pyx":202
+ *         if size > MAX_INT:
+ *             raise ValueError( "%d is larger than the maximum BinnedBitSet size of %d." % ( size, MAX_INT ) )
+ *         self.bb = binBitsAlloc( size, granularity )             # <<<<<<<<<<<<<<
+ *     def __dealloc__( self ):
+ *         if self.bb:
+ */
+  __pyx_t_4 = __Pyx_PyInt_AsInt(__pyx_v_size); if (unlikely((__pyx_t_4 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 202; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_5 = __Pyx_PyInt_AsInt(__pyx_v_granularity); if (unlikely((__pyx_t_5 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 202; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_v_self->bb = binBitsAlloc(__pyx_t_4, __pyx_t_5);
+
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_AddTraceback("bx.bitset.BinnedBitSet.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = -1;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static void __pyx_pw_2bx_6bitset_12BinnedBitSet_3__dealloc__(PyObject *__pyx_v_self); /*proto*/
+static void __pyx_pw_2bx_6bitset_12BinnedBitSet_3__dealloc__(PyObject *__pyx_v_self) {
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__dealloc__ (wrapper)", 0);
+  __pyx_pf_2bx_6bitset_12BinnedBitSet_2__dealloc__(((struct __pyx_obj_2bx_6bitset_BinnedBitSet *)__pyx_v_self));
+  __Pyx_RefNannyFinishContext();
+}
+
+/* "bx/bitset.pyx":203
+ *             raise ValueError( "%d is larger than the maximum BinnedBitSet size of %d." % ( size, MAX_INT ) )
+ *         self.bb = binBitsAlloc( size, granularity )
+ *     def __dealloc__( self ):             # <<<<<<<<<<<<<<
+ *         if self.bb:
+ *             binBitsFree( self.bb );
+ */
+
+static void __pyx_pf_2bx_6bitset_12BinnedBitSet_2__dealloc__(struct __pyx_obj_2bx_6bitset_BinnedBitSet *__pyx_v_self) {
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("__dealloc__", 0);
+
+  /* "bx/bitset.pyx":204
+ *         self.bb = binBitsAlloc( size, granularity )
+ *     def __dealloc__( self ):
+ *         if self.bb:             # <<<<<<<<<<<<<<
+ *             binBitsFree( self.bb );
+ *     def __getitem__( self, index ):
+ */
+  __pyx_t_1 = (__pyx_v_self->bb != 0);
+  if (__pyx_t_1) {
+
+    /* "bx/bitset.pyx":205
+ *     def __dealloc__( self ):
+ *         if self.bb:
+ *             binBitsFree( self.bb );             # <<<<<<<<<<<<<<
+ *     def __getitem__( self, index ):
+ *         bb_check_index( self, index )
+ */
+    binBitsFree(__pyx_v_self->bb);
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  __Pyx_RefNannyFinishContext();
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_6bitset_12BinnedBitSet_5__getitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_index); /*proto*/
+static PyObject *__pyx_pw_2bx_6bitset_12BinnedBitSet_5__getitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_index) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__getitem__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_6bitset_12BinnedBitSet_4__getitem__(((struct __pyx_obj_2bx_6bitset_BinnedBitSet *)__pyx_v_self), ((PyObject *)__pyx_v_index));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bitset.pyx":206
+ *         if self.bb:
+ *             binBitsFree( self.bb );
+ *     def __getitem__( self, index ):             # <<<<<<<<<<<<<<
+ *         bb_check_index( self, index )
+ *         return binBitsReadOne( self.bb, index )
+ */
+
+static PyObject *__pyx_pf_2bx_6bitset_12BinnedBitSet_4__getitem__(struct __pyx_obj_2bx_6bitset_BinnedBitSet *__pyx_v_self, PyObject *__pyx_v_index) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_t_2;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__getitem__", 0);
+
+  /* "bx/bitset.pyx":207
+ *             binBitsFree( self.bb );
+ *     def __getitem__( self, index ):
+ *         bb_check_index( self, index )             # <<<<<<<<<<<<<<
+ *         return binBitsReadOne( self.bb, index )
+ *     def set( self, index ):
+ */
+  __pyx_t_1 = __pyx_f_2bx_6bitset_bb_check_index(__pyx_v_self, __pyx_v_index); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "bx/bitset.pyx":208
+ *     def __getitem__( self, index ):
+ *         bb_check_index( self, index )
+ *         return binBitsReadOne( self.bb, index )             # <<<<<<<<<<<<<<
+ *     def set( self, index ):
+ *         bb_check_index( self, index )
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_2 = __Pyx_PyInt_AsInt(__pyx_v_index); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 208; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyInt_FromLong(binBitsReadOne(__pyx_v_self->bb, __pyx_t_2)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 208; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("bx.bitset.BinnedBitSet.__getitem__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_6bitset_12BinnedBitSet_7set(PyObject *__pyx_v_self, PyObject *__pyx_v_index); /*proto*/
+static PyObject *__pyx_pw_2bx_6bitset_12BinnedBitSet_7set(PyObject *__pyx_v_self, PyObject *__pyx_v_index) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("set (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_6bitset_12BinnedBitSet_6set(((struct __pyx_obj_2bx_6bitset_BinnedBitSet *)__pyx_v_self), ((PyObject *)__pyx_v_index));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bitset.pyx":209
+ *         bb_check_index( self, index )
+ *         return binBitsReadOne( self.bb, index )
+ *     def set( self, index ):             # <<<<<<<<<<<<<<
+ *         bb_check_index( self, index )
+ *         binBitsSetOne( self.bb, index )
+ */
+
+static PyObject *__pyx_pf_2bx_6bitset_12BinnedBitSet_6set(struct __pyx_obj_2bx_6bitset_BinnedBitSet *__pyx_v_self, PyObject *__pyx_v_index) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_t_2;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("set", 0);
+
+  /* "bx/bitset.pyx":210
+ *         return binBitsReadOne( self.bb, index )
+ *     def set( self, index ):
+ *         bb_check_index( self, index )             # <<<<<<<<<<<<<<
+ *         binBitsSetOne( self.bb, index )
+ *     def clear( self, index ):
+ */
+  __pyx_t_1 = __pyx_f_2bx_6bitset_bb_check_index(__pyx_v_self, __pyx_v_index); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 210; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "bx/bitset.pyx":211
+ *     def set( self, index ):
+ *         bb_check_index( self, index )
+ *         binBitsSetOne( self.bb, index )             # <<<<<<<<<<<<<<
+ *     def clear( self, index ):
+ *         bb_check_index( self, index )
+ */
+  __pyx_t_2 = __Pyx_PyInt_AsInt(__pyx_v_index); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 211; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  binBitsSetOne(__pyx_v_self->bb, __pyx_t_2);
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("bx.bitset.BinnedBitSet.set", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_6bitset_12BinnedBitSet_9clear(PyObject *__pyx_v_self, PyObject *__pyx_v_index); /*proto*/
+static PyObject *__pyx_pw_2bx_6bitset_12BinnedBitSet_9clear(PyObject *__pyx_v_self, PyObject *__pyx_v_index) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("clear (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_6bitset_12BinnedBitSet_8clear(((struct __pyx_obj_2bx_6bitset_BinnedBitSet *)__pyx_v_self), ((PyObject *)__pyx_v_index));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bitset.pyx":212
+ *         bb_check_index( self, index )
+ *         binBitsSetOne( self.bb, index )
+ *     def clear( self, index ):             # <<<<<<<<<<<<<<
+ *         bb_check_index( self, index )
+ *         binBitsClearOne( self.bb, index )
+ */
+
+static PyObject *__pyx_pf_2bx_6bitset_12BinnedBitSet_8clear(struct __pyx_obj_2bx_6bitset_BinnedBitSet *__pyx_v_self, PyObject *__pyx_v_index) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_t_2;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("clear", 0);
+
+  /* "bx/bitset.pyx":213
+ *         binBitsSetOne( self.bb, index )
+ *     def clear( self, index ):
+ *         bb_check_index( self, index )             # <<<<<<<<<<<<<<
+ *         binBitsClearOne( self.bb, index )
+ *     def set_range( self, int start, count ):
+ */
+  __pyx_t_1 = __pyx_f_2bx_6bitset_bb_check_index(__pyx_v_self, __pyx_v_index); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 213; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "bx/bitset.pyx":214
+ *     def clear( self, index ):
+ *         bb_check_index( self, index )
+ *         binBitsClearOne( self.bb, index )             # <<<<<<<<<<<<<<
+ *     def set_range( self, int start, count ):
+ *         bb_check_range_count( self, start, count )
+ */
+  __pyx_t_2 = __Pyx_PyInt_AsInt(__pyx_v_index); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 214; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  binBitsClearOne(__pyx_v_self->bb, __pyx_t_2);
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("bx.bitset.BinnedBitSet.clear", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_6bitset_12BinnedBitSet_11set_range(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyObject *__pyx_pw_2bx_6bitset_12BinnedBitSet_11set_range(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  int __pyx_v_start;
+  PyObject *__pyx_v_count = 0;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("set_range (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__start,&__pyx_n_s__count,0};
+    PyObject* values[2] = {0,0};
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__start)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__count)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("set_range", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 215; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "set_range") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 215; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
+      goto __pyx_L5_argtuple_error;
+    } else {
+      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+    }
+    __pyx_v_start = __Pyx_PyInt_AsInt(values[0]); if (unlikely((__pyx_v_start == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 215; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_count = values[1];
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("set_range", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 215; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.bitset.BinnedBitSet.set_range", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_6bitset_12BinnedBitSet_10set_range(((struct __pyx_obj_2bx_6bitset_BinnedBitSet *)__pyx_v_self), __pyx_v_start, __pyx_v_count);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bitset.pyx":215
+ *         bb_check_index( self, index )
+ *         binBitsClearOne( self.bb, index )
+ *     def set_range( self, int start, count ):             # <<<<<<<<<<<<<<
+ *         bb_check_range_count( self, start, count )
+ *         binBitsSetRange( self.bb, start, count )
+ */
+
+static PyObject *__pyx_pf_2bx_6bitset_12BinnedBitSet_10set_range(struct __pyx_obj_2bx_6bitset_BinnedBitSet *__pyx_v_self, int __pyx_v_start, PyObject *__pyx_v_count) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  int __pyx_t_3;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("set_range", 0);
+
+  /* "bx/bitset.pyx":216
+ *         binBitsClearOne( self.bb, index )
+ *     def set_range( self, int start, count ):
+ *         bb_check_range_count( self, start, count )             # <<<<<<<<<<<<<<
+ *         binBitsSetRange( self.bb, start, count )
+ *     def count_range( self, start, count ):
+ */
+  __pyx_t_1 = PyInt_FromLong(__pyx_v_start); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 216; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = __pyx_f_2bx_6bitset_bb_check_range_count(__pyx_v_self, __pyx_t_1, __pyx_v_count); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 216; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+  /* "bx/bitset.pyx":217
+ *     def set_range( self, int start, count ):
+ *         bb_check_range_count( self, start, count )
+ *         binBitsSetRange( self.bb, start, count )             # <<<<<<<<<<<<<<
+ *     def count_range( self, start, count ):
+ *         bb_check_range_count( self, start, count )
+ */
+  __pyx_t_3 = __Pyx_PyInt_AsInt(__pyx_v_count); if (unlikely((__pyx_t_3 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 217; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  binBitsSetRange(__pyx_v_self->bb, __pyx_v_start, __pyx_t_3);
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_AddTraceback("bx.bitset.BinnedBitSet.set_range", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_6bitset_12BinnedBitSet_13count_range(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyObject *__pyx_pw_2bx_6bitset_12BinnedBitSet_13count_range(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_start = 0;
+  PyObject *__pyx_v_count = 0;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("count_range (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__start,&__pyx_n_s__count,0};
+    PyObject* values[2] = {0,0};
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__start)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__count)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("count_range", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 218; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "count_range") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 218; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
+      goto __pyx_L5_argtuple_error;
+    } else {
+      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+    }
+    __pyx_v_start = values[0];
+    __pyx_v_count = values[1];
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("count_range", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 218; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.bitset.BinnedBitSet.count_range", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_6bitset_12BinnedBitSet_12count_range(((struct __pyx_obj_2bx_6bitset_BinnedBitSet *)__pyx_v_self), __pyx_v_start, __pyx_v_count);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bitset.pyx":218
+ *         bb_check_range_count( self, start, count )
+ *         binBitsSetRange( self.bb, start, count )
+ *     def count_range( self, start, count ):             # <<<<<<<<<<<<<<
+ *         bb_check_range_count( self, start, count )
+ *         return binBitsCountRange( self.bb, start, count )
+ */
+
+static PyObject *__pyx_pf_2bx_6bitset_12BinnedBitSet_12count_range(struct __pyx_obj_2bx_6bitset_BinnedBitSet *__pyx_v_self, PyObject *__pyx_v_start, PyObject *__pyx_v_count) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_t_2;
+  int __pyx_t_3;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("count_range", 0);
+
+  /* "bx/bitset.pyx":219
+ *         binBitsSetRange( self.bb, start, count )
+ *     def count_range( self, start, count ):
+ *         bb_check_range_count( self, start, count )             # <<<<<<<<<<<<<<
+ *         return binBitsCountRange( self.bb, start, count )
+ *     def next_set( self, start ):
+ */
+  __pyx_t_1 = __pyx_f_2bx_6bitset_bb_check_range_count(__pyx_v_self, __pyx_v_start, __pyx_v_count); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 219; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "bx/bitset.pyx":220
+ *     def count_range( self, start, count ):
+ *         bb_check_range_count( self, start, count )
+ *         return binBitsCountRange( self.bb, start, count )             # <<<<<<<<<<<<<<
+ *     def next_set( self, start ):
+ *         bb_check_start( self, start )
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_2 = __Pyx_PyInt_AsInt(__pyx_v_start); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 220; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = __Pyx_PyInt_AsInt(__pyx_v_count); if (unlikely((__pyx_t_3 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 220; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyInt_FromLong(binBitsCountRange(__pyx_v_self->bb, __pyx_t_2, __pyx_t_3)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 220; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("bx.bitset.BinnedBitSet.count_range", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_6bitset_12BinnedBitSet_15next_set(PyObject *__pyx_v_self, PyObject *__pyx_v_start); /*proto*/
+static PyObject *__pyx_pw_2bx_6bitset_12BinnedBitSet_15next_set(PyObject *__pyx_v_self, PyObject *__pyx_v_start) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("next_set (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_6bitset_12BinnedBitSet_14next_set(((struct __pyx_obj_2bx_6bitset_BinnedBitSet *)__pyx_v_self), ((PyObject *)__pyx_v_start));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bitset.pyx":221
+ *         bb_check_range_count( self, start, count )
+ *         return binBitsCountRange( self.bb, start, count )
+ *     def next_set( self, start ):             # <<<<<<<<<<<<<<
+ *         bb_check_start( self, start )
+ *         return binBitsFindSet( self.bb, start )
+ */
+
+static PyObject *__pyx_pf_2bx_6bitset_12BinnedBitSet_14next_set(struct __pyx_obj_2bx_6bitset_BinnedBitSet *__pyx_v_self, PyObject *__pyx_v_start) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_t_2;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("next_set", 0);
+
+  /* "bx/bitset.pyx":222
+ *         return binBitsCountRange( self.bb, start, count )
+ *     def next_set( self, start ):
+ *         bb_check_start( self, start )             # <<<<<<<<<<<<<<
+ *         return binBitsFindSet( self.bb, start )
+ *     def next_clear( self, start ):
+ */
+  __pyx_t_1 = __pyx_f_2bx_6bitset_bb_check_start(__pyx_v_self, __pyx_v_start); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 222; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "bx/bitset.pyx":223
+ *     def next_set( self, start ):
+ *         bb_check_start( self, start )
+ *         return binBitsFindSet( self.bb, start )             # <<<<<<<<<<<<<<
+ *     def next_clear( self, start ):
+ *         bb_check_start( self, start )
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_2 = __Pyx_PyInt_AsInt(__pyx_v_start); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 223; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyInt_FromLong(binBitsFindSet(__pyx_v_self->bb, __pyx_t_2)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 223; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("bx.bitset.BinnedBitSet.next_set", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_6bitset_12BinnedBitSet_17next_clear(PyObject *__pyx_v_self, PyObject *__pyx_v_start); /*proto*/
+static PyObject *__pyx_pw_2bx_6bitset_12BinnedBitSet_17next_clear(PyObject *__pyx_v_self, PyObject *__pyx_v_start) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("next_clear (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_6bitset_12BinnedBitSet_16next_clear(((struct __pyx_obj_2bx_6bitset_BinnedBitSet *)__pyx_v_self), ((PyObject *)__pyx_v_start));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bitset.pyx":224
+ *         bb_check_start( self, start )
+ *         return binBitsFindSet( self.bb, start )
+ *     def next_clear( self, start ):             # <<<<<<<<<<<<<<
+ *         bb_check_start( self, start )
+ *         return binBitsFindClear( self.bb, start )
+ */
+
+static PyObject *__pyx_pf_2bx_6bitset_12BinnedBitSet_16next_clear(struct __pyx_obj_2bx_6bitset_BinnedBitSet *__pyx_v_self, PyObject *__pyx_v_start) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_t_2;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("next_clear", 0);
+
+  /* "bx/bitset.pyx":225
+ *         return binBitsFindSet( self.bb, start )
+ *     def next_clear( self, start ):
+ *         bb_check_start( self, start )             # <<<<<<<<<<<<<<
+ *         return binBitsFindClear( self.bb, start )
+ *     property size:
+ */
+  __pyx_t_1 = __pyx_f_2bx_6bitset_bb_check_start(__pyx_v_self, __pyx_v_start); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 225; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "bx/bitset.pyx":226
+ *     def next_clear( self, start ):
+ *         bb_check_start( self, start )
+ *         return binBitsFindClear( self.bb, start )             # <<<<<<<<<<<<<<
+ *     property size:
+ *         def __get__( self ):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_2 = __Pyx_PyInt_AsInt(__pyx_v_start); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 226; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyInt_FromLong(binBitsFindClear(__pyx_v_self->bb, __pyx_t_2)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 226; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("bx.bitset.BinnedBitSet.next_clear", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_6bitset_12BinnedBitSet_4size_1__get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_2bx_6bitset_12BinnedBitSet_4size_1__get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_6bitset_12BinnedBitSet_4size___get__(((struct __pyx_obj_2bx_6bitset_BinnedBitSet *)__pyx_v_self));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bitset.pyx":228
+ *         return binBitsFindClear( self.bb, start )
+ *     property size:
+ *         def __get__( self ):             # <<<<<<<<<<<<<<
+ *             return self.bb.size
+ *     property bin_size:
+ */
+
+static PyObject *__pyx_pf_2bx_6bitset_12BinnedBitSet_4size___get__(struct __pyx_obj_2bx_6bitset_BinnedBitSet *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__get__", 0);
+
+  /* "bx/bitset.pyx":229
+ *     property size:
+ *         def __get__( self ):
+ *             return self.bb.size             # <<<<<<<<<<<<<<
+ *     property bin_size:
+ *         def __get__( self ):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = PyInt_FromLong(__pyx_v_self->bb->size); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 229; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("bx.bitset.BinnedBitSet.size.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_6bitset_12BinnedBitSet_8bin_size_1__get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_2bx_6bitset_12BinnedBitSet_8bin_size_1__get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_6bitset_12BinnedBitSet_8bin_size___get__(((struct __pyx_obj_2bx_6bitset_BinnedBitSet *)__pyx_v_self));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bitset.pyx":231
+ *             return self.bb.size
+ *     property bin_size:
+ *         def __get__( self ):             # <<<<<<<<<<<<<<
+ *             return self.bb.bin_size
+ *     def iand( self, BinnedBitSet other ):
+ */
+
+static PyObject *__pyx_pf_2bx_6bitset_12BinnedBitSet_8bin_size___get__(struct __pyx_obj_2bx_6bitset_BinnedBitSet *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__get__", 0);
+
+  /* "bx/bitset.pyx":232
+ *     property bin_size:
+ *         def __get__( self ):
+ *             return self.bb.bin_size             # <<<<<<<<<<<<<<
+ *     def iand( self, BinnedBitSet other ):
+ *         bb_check_same_size( self, other )
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = PyInt_FromLong(__pyx_v_self->bb->bin_size); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 232; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("bx.bitset.BinnedBitSet.bin_size.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_6bitset_12BinnedBitSet_19iand(PyObject *__pyx_v_self, PyObject *__pyx_v_other); /*proto*/
+static PyObject *__pyx_pw_2bx_6bitset_12BinnedBitSet_19iand(PyObject *__pyx_v_self, PyObject *__pyx_v_other) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("iand (wrapper)", 0);
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_other), __pyx_ptype_2bx_6bitset_BinnedBitSet, 1, "other", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 233; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_r = __pyx_pf_2bx_6bitset_12BinnedBitSet_18iand(((struct __pyx_obj_2bx_6bitset_BinnedBitSet *)__pyx_v_self), ((struct __pyx_obj_2bx_6bitset_BinnedBitSet *)__pyx_v_other));
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bitset.pyx":233
+ *         def __get__( self ):
+ *             return self.bb.bin_size
+ *     def iand( self, BinnedBitSet other ):             # <<<<<<<<<<<<<<
+ *         bb_check_same_size( self, other )
+ *         binBitsAnd( self.bb, other.bb )
+ */
+
+static PyObject *__pyx_pf_2bx_6bitset_12BinnedBitSet_18iand(struct __pyx_obj_2bx_6bitset_BinnedBitSet *__pyx_v_self, struct __pyx_obj_2bx_6bitset_BinnedBitSet *__pyx_v_other) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("iand", 0);
+
+  /* "bx/bitset.pyx":234
+ *             return self.bb.bin_size
+ *     def iand( self, BinnedBitSet other ):
+ *         bb_check_same_size( self, other )             # <<<<<<<<<<<<<<
+ *         binBitsAnd( self.bb, other.bb )
+ *     def ior( self, BinnedBitSet other ):
+ */
+  __pyx_t_1 = __pyx_f_2bx_6bitset_bb_check_same_size(__pyx_v_self, __pyx_v_other); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 234; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "bx/bitset.pyx":235
+ *     def iand( self, BinnedBitSet other ):
+ *         bb_check_same_size( self, other )
+ *         binBitsAnd( self.bb, other.bb )             # <<<<<<<<<<<<<<
+ *     def ior( self, BinnedBitSet other ):
+ *         bb_check_same_size( self, other )
+ */
+  binBitsAnd(__pyx_v_self->bb, __pyx_v_other->bb);
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("bx.bitset.BinnedBitSet.iand", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_6bitset_12BinnedBitSet_21ior(PyObject *__pyx_v_self, PyObject *__pyx_v_other); /*proto*/
+static PyObject *__pyx_pw_2bx_6bitset_12BinnedBitSet_21ior(PyObject *__pyx_v_self, PyObject *__pyx_v_other) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("ior (wrapper)", 0);
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_other), __pyx_ptype_2bx_6bitset_BinnedBitSet, 1, "other", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 236; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_r = __pyx_pf_2bx_6bitset_12BinnedBitSet_20ior(((struct __pyx_obj_2bx_6bitset_BinnedBitSet *)__pyx_v_self), ((struct __pyx_obj_2bx_6bitset_BinnedBitSet *)__pyx_v_other));
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bitset.pyx":236
+ *         bb_check_same_size( self, other )
+ *         binBitsAnd( self.bb, other.bb )
+ *     def ior( self, BinnedBitSet other ):             # <<<<<<<<<<<<<<
+ *         bb_check_same_size( self, other )
+ *         binBitsOr( self.bb, other.bb )
+ */
+
+static PyObject *__pyx_pf_2bx_6bitset_12BinnedBitSet_20ior(struct __pyx_obj_2bx_6bitset_BinnedBitSet *__pyx_v_self, struct __pyx_obj_2bx_6bitset_BinnedBitSet *__pyx_v_other) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("ior", 0);
+
+  /* "bx/bitset.pyx":237
+ *         binBitsAnd( self.bb, other.bb )
+ *     def ior( self, BinnedBitSet other ):
+ *         bb_check_same_size( self, other )             # <<<<<<<<<<<<<<
+ *         binBitsOr( self.bb, other.bb )
+ *     def invert( self ):
+ */
+  __pyx_t_1 = __pyx_f_2bx_6bitset_bb_check_same_size(__pyx_v_self, __pyx_v_other); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 237; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "bx/bitset.pyx":238
+ *     def ior( self, BinnedBitSet other ):
+ *         bb_check_same_size( self, other )
+ *         binBitsOr( self.bb, other.bb )             # <<<<<<<<<<<<<<
+ *     def invert( self ):
+ *         binBitsNot( self.bb )
+ */
+  binBitsOr(__pyx_v_self->bb, __pyx_v_other->bb);
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("bx.bitset.BinnedBitSet.ior", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_6bitset_12BinnedBitSet_23invert(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static PyObject *__pyx_pw_2bx_6bitset_12BinnedBitSet_23invert(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("invert (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_6bitset_12BinnedBitSet_22invert(((struct __pyx_obj_2bx_6bitset_BinnedBitSet *)__pyx_v_self));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/bitset.pyx":239
+ *         bb_check_same_size( self, other )
+ *         binBitsOr( self.bb, other.bb )
+ *     def invert( self ):             # <<<<<<<<<<<<<<
+ *         binBitsNot( self.bb )
+ */
+
+static PyObject *__pyx_pf_2bx_6bitset_12BinnedBitSet_22invert(struct __pyx_obj_2bx_6bitset_BinnedBitSet *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("invert", 0);
+
+  /* "bx/bitset.pyx":240
+ *         binBitsOr( self.bb, other.bb )
+ *     def invert( self ):
+ *         binBitsNot( self.bb )             # <<<<<<<<<<<<<<
+ */
+  binBitsNot(__pyx_v_self->bb);
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_tp_new_2bx_6bitset_BitSet(PyTypeObject *t, PyObject *a, PyObject *k) {
+  PyObject *o = (*t->tp_alloc)(t, 0);
+  if (!o) return 0;
+  if (__pyx_pw_2bx_6bitset_6BitSet_1__cinit__(o, a, k) < 0) {
+    Py_DECREF(o); o = 0;
+  }
+  return o;
+}
+
+static void __pyx_tp_dealloc_2bx_6bitset_BitSet(PyObject *o) {
+  {
+    PyObject *etype, *eval, *etb;
+    PyErr_Fetch(&etype, &eval, &etb);
+    ++Py_REFCNT(o);
+    __pyx_pw_2bx_6bitset_6BitSet_3__dealloc__(o);
+    if (PyErr_Occurred()) PyErr_WriteUnraisable(o);
+    --Py_REFCNT(o);
+    PyErr_Restore(etype, eval, etb);
+  }
+  (*Py_TYPE(o)->tp_free)(o);
+}
+static PyObject *__pyx_sq_item_2bx_6bitset_BitSet(PyObject *o, Py_ssize_t i) {
+  PyObject *r;
+  PyObject *x = PyInt_FromSsize_t(i); if(!x) return 0;
+  r = Py_TYPE(o)->tp_as_mapping->mp_subscript(o, x);
+  Py_DECREF(x);
+  return r;
+}
+
+static PyObject *__pyx_getprop_2bx_6bitset_6BitSet_size(PyObject *o, CYTHON_UNUSED void *x) {
+  return __pyx_pw_2bx_6bitset_6BitSet_4size_1__get__(o);
+}
+
+static PyMethodDef __pyx_methods_2bx_6bitset_BitSet[] = {
+  {__Pyx_NAMESTR("set"), (PyCFunction)__pyx_pw_2bx_6bitset_6BitSet_5set, METH_O, __Pyx_DOCSTR(0)},
+  {__Pyx_NAMESTR("clear"), (PyCFunction)__pyx_pw_2bx_6bitset_6BitSet_7clear, METH_O, __Pyx_DOCSTR(0)},
+  {__Pyx_NAMESTR("clone"), (PyCFunction)__pyx_pw_2bx_6bitset_6BitSet_9clone, METH_NOARGS, __Pyx_DOCSTR(0)},
+  {__Pyx_NAMESTR("set_range"), (PyCFunction)__pyx_pw_2bx_6bitset_6BitSet_11set_range, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(0)},
+  {__Pyx_NAMESTR("get"), (PyCFunction)__pyx_pw_2bx_6bitset_6BitSet_13get, METH_O, __Pyx_DOCSTR(0)},
+  {__Pyx_NAMESTR("count_range"), (PyCFunction)__pyx_pw_2bx_6bitset_6BitSet_15count_range, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(0)},
+  {__Pyx_NAMESTR("next_set"), (PyCFunction)__pyx_pw_2bx_6bitset_6BitSet_17next_set, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(0)},
+  {__Pyx_NAMESTR("next_clear"), (PyCFunction)__pyx_pw_2bx_6bitset_6BitSet_19next_clear, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(0)},
+  {__Pyx_NAMESTR("iand"), (PyCFunction)__pyx_pw_2bx_6bitset_6BitSet_21iand, METH_O, __Pyx_DOCSTR(0)},
+  {__Pyx_NAMESTR("ior"), (PyCFunction)__pyx_pw_2bx_6bitset_6BitSet_23ior, METH_O, __Pyx_DOCSTR(0)},
+  {__Pyx_NAMESTR("ixor"), (PyCFunction)__pyx_pw_2bx_6bitset_6BitSet_25ixor, METH_O, __Pyx_DOCSTR(0)},
+  {__Pyx_NAMESTR("invert"), (PyCFunction)__pyx_pw_2bx_6bitset_6BitSet_27invert, METH_NOARGS, __Pyx_DOCSTR(0)},
+  {0, 0, 0, 0}
+};
+
+static struct PyGetSetDef __pyx_getsets_2bx_6bitset_BitSet[] = {
+  {(char *)"size", __pyx_getprop_2bx_6bitset_6BitSet_size, 0, 0, 0},
+  {0, 0, 0, 0, 0}
+};
+
+static PyNumberMethods __pyx_tp_as_number_BitSet = {
+  0, /*nb_add*/
+  0, /*nb_subtract*/
+  0, /*nb_multiply*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_divide*/
+  #endif
+  0, /*nb_remainder*/
+  0, /*nb_divmod*/
+  0, /*nb_power*/
+  0, /*nb_negative*/
+  0, /*nb_positive*/
+  0, /*nb_absolute*/
+  0, /*nb_nonzero*/
+  __pyx_pw_2bx_6bitset_6BitSet_35__invert__, /*nb_invert*/
+  0, /*nb_lshift*/
+  0, /*nb_rshift*/
+  0, /*nb_and*/
+  0, /*nb_xor*/
+  0, /*nb_or*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_coerce*/
+  #endif
+  0, /*nb_int*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_long*/
+  #else
+  0, /*reserved*/
+  #endif
+  0, /*nb_float*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_oct*/
+  #endif
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_hex*/
+  #endif
+  0, /*nb_inplace_add*/
+  0, /*nb_inplace_subtract*/
+  0, /*nb_inplace_multiply*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_inplace_divide*/
+  #endif
+  0, /*nb_inplace_remainder*/
+  0, /*nb_inplace_power*/
+  0, /*nb_inplace_lshift*/
+  0, /*nb_inplace_rshift*/
+  __pyx_pw_2bx_6bitset_6BitSet_31__iand__, /*nb_inplace_and*/
+  0, /*nb_inplace_xor*/
+  __pyx_pw_2bx_6bitset_6BitSet_33__ior__, /*nb_inplace_or*/
+  0, /*nb_floor_divide*/
+  0, /*nb_true_divide*/
+  0, /*nb_inplace_floor_divide*/
+  0, /*nb_inplace_true_divide*/
+  #if PY_VERSION_HEX >= 0x02050000
+  0, /*nb_index*/
+  #endif
+};
+
+static PySequenceMethods __pyx_tp_as_sequence_BitSet = {
+  0, /*sq_length*/
+  0, /*sq_concat*/
+  0, /*sq_repeat*/
+  __pyx_sq_item_2bx_6bitset_BitSet, /*sq_item*/
+  0, /*sq_slice*/
+  0, /*sq_ass_item*/
+  0, /*sq_ass_slice*/
+  0, /*sq_contains*/
+  0, /*sq_inplace_concat*/
+  0, /*sq_inplace_repeat*/
+};
+
+static PyMappingMethods __pyx_tp_as_mapping_BitSet = {
+  0, /*mp_length*/
+  __pyx_pw_2bx_6bitset_6BitSet_29__getitem__, /*mp_subscript*/
+  0, /*mp_ass_subscript*/
+};
+
+static PyBufferProcs __pyx_tp_as_buffer_BitSet = {
+  #if PY_MAJOR_VERSION < 3
+  0, /*bf_getreadbuffer*/
+  #endif
+  #if PY_MAJOR_VERSION < 3
+  0, /*bf_getwritebuffer*/
+  #endif
+  #if PY_MAJOR_VERSION < 3
+  0, /*bf_getsegcount*/
+  #endif
+  #if PY_MAJOR_VERSION < 3
+  0, /*bf_getcharbuffer*/
+  #endif
+  #if PY_VERSION_HEX >= 0x02060000
+  0, /*bf_getbuffer*/
+  #endif
+  #if PY_VERSION_HEX >= 0x02060000
+  0, /*bf_releasebuffer*/
+  #endif
+};
+
+static PyTypeObject __pyx_type_2bx_6bitset_BitSet = {
+  PyVarObject_HEAD_INIT(0, 0)
+  __Pyx_NAMESTR("bx.bitset.BitSet"), /*tp_name*/
+  sizeof(struct __pyx_obj_2bx_6bitset_BitSet), /*tp_basicsize*/
+  0, /*tp_itemsize*/
+  __pyx_tp_dealloc_2bx_6bitset_BitSet, /*tp_dealloc*/
+  0, /*tp_print*/
+  0, /*tp_getattr*/
+  0, /*tp_setattr*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*tp_compare*/
+  #else
+  0, /*reserved*/
+  #endif
+  0, /*tp_repr*/
+  &__pyx_tp_as_number_BitSet, /*tp_as_number*/
+  &__pyx_tp_as_sequence_BitSet, /*tp_as_sequence*/
+  &__pyx_tp_as_mapping_BitSet, /*tp_as_mapping*/
+  0, /*tp_hash*/
+  0, /*tp_call*/
+  0, /*tp_str*/
+  0, /*tp_getattro*/
+  0, /*tp_setattro*/
+  &__pyx_tp_as_buffer_BitSet, /*tp_as_buffer*/
+  Py_TPFLAGS_DEFAULT|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE, /*tp_flags*/
+  0, /*tp_doc*/
+  0, /*tp_traverse*/
+  0, /*tp_clear*/
+  0, /*tp_richcompare*/
+  0, /*tp_weaklistoffset*/
+  0, /*tp_iter*/
+  0, /*tp_iternext*/
+  __pyx_methods_2bx_6bitset_BitSet, /*tp_methods*/
+  0, /*tp_members*/
+  __pyx_getsets_2bx_6bitset_BitSet, /*tp_getset*/
+  0, /*tp_base*/
+  0, /*tp_dict*/
+  0, /*tp_descr_get*/
+  0, /*tp_descr_set*/
+  0, /*tp_dictoffset*/
+  0, /*tp_init*/
+  0, /*tp_alloc*/
+  __pyx_tp_new_2bx_6bitset_BitSet, /*tp_new*/
+  0, /*tp_free*/
+  0, /*tp_is_gc*/
+  0, /*tp_bases*/
+  0, /*tp_mro*/
+  0, /*tp_cache*/
+  0, /*tp_subclasses*/
+  0, /*tp_weaklist*/
+  0, /*tp_del*/
+  #if PY_VERSION_HEX >= 0x02060000
+  0, /*tp_version_tag*/
+  #endif
+};
+
+static PyObject *__pyx_tp_new_2bx_6bitset_BinnedBitSet(PyTypeObject *t, PyObject *a, PyObject *k) {
+  PyObject *o = (*t->tp_alloc)(t, 0);
+  if (!o) return 0;
+  if (__pyx_pw_2bx_6bitset_12BinnedBitSet_1__cinit__(o, a, k) < 0) {
+    Py_DECREF(o); o = 0;
+  }
+  return o;
+}
+
+static void __pyx_tp_dealloc_2bx_6bitset_BinnedBitSet(PyObject *o) {
+  {
+    PyObject *etype, *eval, *etb;
+    PyErr_Fetch(&etype, &eval, &etb);
+    ++Py_REFCNT(o);
+    __pyx_pw_2bx_6bitset_12BinnedBitSet_3__dealloc__(o);
+    if (PyErr_Occurred()) PyErr_WriteUnraisable(o);
+    --Py_REFCNT(o);
+    PyErr_Restore(etype, eval, etb);
+  }
+  (*Py_TYPE(o)->tp_free)(o);
+}
+static PyObject *__pyx_sq_item_2bx_6bitset_BinnedBitSet(PyObject *o, Py_ssize_t i) {
+  PyObject *r;
+  PyObject *x = PyInt_FromSsize_t(i); if(!x) return 0;
+  r = Py_TYPE(o)->tp_as_mapping->mp_subscript(o, x);
+  Py_DECREF(x);
+  return r;
+}
+
+static PyObject *__pyx_getprop_2bx_6bitset_12BinnedBitSet_size(PyObject *o, CYTHON_UNUSED void *x) {
+  return __pyx_pw_2bx_6bitset_12BinnedBitSet_4size_1__get__(o);
+}
+
+static PyObject *__pyx_getprop_2bx_6bitset_12BinnedBitSet_bin_size(PyObject *o, CYTHON_UNUSED void *x) {
+  return __pyx_pw_2bx_6bitset_12BinnedBitSet_8bin_size_1__get__(o);
+}
+
+static PyMethodDef __pyx_methods_2bx_6bitset_BinnedBitSet[] = {
+  {__Pyx_NAMESTR("set"), (PyCFunction)__pyx_pw_2bx_6bitset_12BinnedBitSet_7set, METH_O, __Pyx_DOCSTR(0)},
+  {__Pyx_NAMESTR("clear"), (PyCFunction)__pyx_pw_2bx_6bitset_12BinnedBitSet_9clear, METH_O, __Pyx_DOCSTR(0)},
+  {__Pyx_NAMESTR("set_range"), (PyCFunction)__pyx_pw_2bx_6bitset_12BinnedBitSet_11set_range, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(0)},
+  {__Pyx_NAMESTR("count_range"), (PyCFunction)__pyx_pw_2bx_6bitset_12BinnedBitSet_13count_range, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(0)},
+  {__Pyx_NAMESTR("next_set"), (PyCFunction)__pyx_pw_2bx_6bitset_12BinnedBitSet_15next_set, METH_O, __Pyx_DOCSTR(0)},
+  {__Pyx_NAMESTR("next_clear"), (PyCFunction)__pyx_pw_2bx_6bitset_12BinnedBitSet_17next_clear, METH_O, __Pyx_DOCSTR(0)},
+  {__Pyx_NAMESTR("iand"), (PyCFunction)__pyx_pw_2bx_6bitset_12BinnedBitSet_19iand, METH_O, __Pyx_DOCSTR(0)},
+  {__Pyx_NAMESTR("ior"), (PyCFunction)__pyx_pw_2bx_6bitset_12BinnedBitSet_21ior, METH_O, __Pyx_DOCSTR(0)},
+  {__Pyx_NAMESTR("invert"), (PyCFunction)__pyx_pw_2bx_6bitset_12BinnedBitSet_23invert, METH_NOARGS, __Pyx_DOCSTR(0)},
+  {0, 0, 0, 0}
+};
+
+static struct PyGetSetDef __pyx_getsets_2bx_6bitset_BinnedBitSet[] = {
+  {(char *)"size", __pyx_getprop_2bx_6bitset_12BinnedBitSet_size, 0, 0, 0},
+  {(char *)"bin_size", __pyx_getprop_2bx_6bitset_12BinnedBitSet_bin_size, 0, 0, 0},
+  {0, 0, 0, 0, 0}
+};
+
+static PyNumberMethods __pyx_tp_as_number_BinnedBitSet = {
+  0, /*nb_add*/
+  0, /*nb_subtract*/
+  0, /*nb_multiply*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_divide*/
+  #endif
+  0, /*nb_remainder*/
+  0, /*nb_divmod*/
+  0, /*nb_power*/
+  0, /*nb_negative*/
+  0, /*nb_positive*/
+  0, /*nb_absolute*/
+  0, /*nb_nonzero*/
+  0, /*nb_invert*/
+  0, /*nb_lshift*/
+  0, /*nb_rshift*/
+  0, /*nb_and*/
+  0, /*nb_xor*/
+  0, /*nb_or*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_coerce*/
+  #endif
+  0, /*nb_int*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_long*/
+  #else
+  0, /*reserved*/
+  #endif
+  0, /*nb_float*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_oct*/
+  #endif
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_hex*/
+  #endif
+  0, /*nb_inplace_add*/
+  0, /*nb_inplace_subtract*/
+  0, /*nb_inplace_multiply*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_inplace_divide*/
+  #endif
+  0, /*nb_inplace_remainder*/
+  0, /*nb_inplace_power*/
+  0, /*nb_inplace_lshift*/
+  0, /*nb_inplace_rshift*/
+  0, /*nb_inplace_and*/
+  0, /*nb_inplace_xor*/
+  0, /*nb_inplace_or*/
+  0, /*nb_floor_divide*/
+  0, /*nb_true_divide*/
+  0, /*nb_inplace_floor_divide*/
+  0, /*nb_inplace_true_divide*/
+  #if PY_VERSION_HEX >= 0x02050000
+  0, /*nb_index*/
+  #endif
+};
+
+static PySequenceMethods __pyx_tp_as_sequence_BinnedBitSet = {
+  0, /*sq_length*/
+  0, /*sq_concat*/
+  0, /*sq_repeat*/
+  __pyx_sq_item_2bx_6bitset_BinnedBitSet, /*sq_item*/
+  0, /*sq_slice*/
+  0, /*sq_ass_item*/
+  0, /*sq_ass_slice*/
+  0, /*sq_contains*/
+  0, /*sq_inplace_concat*/
+  0, /*sq_inplace_repeat*/
+};
+
+static PyMappingMethods __pyx_tp_as_mapping_BinnedBitSet = {
+  0, /*mp_length*/
+  __pyx_pw_2bx_6bitset_12BinnedBitSet_5__getitem__, /*mp_subscript*/
+  0, /*mp_ass_subscript*/
+};
+
+static PyBufferProcs __pyx_tp_as_buffer_BinnedBitSet = {
+  #if PY_MAJOR_VERSION < 3
+  0, /*bf_getreadbuffer*/
+  #endif
+  #if PY_MAJOR_VERSION < 3
+  0, /*bf_getwritebuffer*/
+  #endif
+  #if PY_MAJOR_VERSION < 3
+  0, /*bf_getsegcount*/
+  #endif
+  #if PY_MAJOR_VERSION < 3
+  0, /*bf_getcharbuffer*/
+  #endif
+  #if PY_VERSION_HEX >= 0x02060000
+  0, /*bf_getbuffer*/
+  #endif
+  #if PY_VERSION_HEX >= 0x02060000
+  0, /*bf_releasebuffer*/
+  #endif
+};
+
+static PyTypeObject __pyx_type_2bx_6bitset_BinnedBitSet = {
+  PyVarObject_HEAD_INIT(0, 0)
+  __Pyx_NAMESTR("bx.bitset.BinnedBitSet"), /*tp_name*/
+  sizeof(struct __pyx_obj_2bx_6bitset_BinnedBitSet), /*tp_basicsize*/
+  0, /*tp_itemsize*/
+  __pyx_tp_dealloc_2bx_6bitset_BinnedBitSet, /*tp_dealloc*/
+  0, /*tp_print*/
+  0, /*tp_getattr*/
+  0, /*tp_setattr*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*tp_compare*/
+  #else
+  0, /*reserved*/
+  #endif
+  0, /*tp_repr*/
+  &__pyx_tp_as_number_BinnedBitSet, /*tp_as_number*/
+  &__pyx_tp_as_sequence_BinnedBitSet, /*tp_as_sequence*/
+  &__pyx_tp_as_mapping_BinnedBitSet, /*tp_as_mapping*/
+  0, /*tp_hash*/
+  0, /*tp_call*/
+  0, /*tp_str*/
+  0, /*tp_getattro*/
+  0, /*tp_setattro*/
+  &__pyx_tp_as_buffer_BinnedBitSet, /*tp_as_buffer*/
+  Py_TPFLAGS_DEFAULT|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE, /*tp_flags*/
+  0, /*tp_doc*/
+  0, /*tp_traverse*/
+  0, /*tp_clear*/
+  0, /*tp_richcompare*/
+  0, /*tp_weaklistoffset*/
+  0, /*tp_iter*/
+  0, /*tp_iternext*/
+  __pyx_methods_2bx_6bitset_BinnedBitSet, /*tp_methods*/
+  0, /*tp_members*/
+  __pyx_getsets_2bx_6bitset_BinnedBitSet, /*tp_getset*/
+  0, /*tp_base*/
+  0, /*tp_dict*/
+  0, /*tp_descr_get*/
+  0, /*tp_descr_set*/
+  0, /*tp_dictoffset*/
+  0, /*tp_init*/
+  0, /*tp_alloc*/
+  __pyx_tp_new_2bx_6bitset_BinnedBitSet, /*tp_new*/
+  0, /*tp_free*/
+  0, /*tp_is_gc*/
+  0, /*tp_bases*/
+  0, /*tp_mro*/
+  0, /*tp_cache*/
+  0, /*tp_subclasses*/
+  0, /*tp_weaklist*/
+  0, /*tp_del*/
+  #if PY_VERSION_HEX >= 0x02060000
+  0, /*tp_version_tag*/
+  #endif
+};
+
+static PyMethodDef __pyx_methods[] = {
+  {0, 0, 0, 0}
+};
+
+#if PY_MAJOR_VERSION >= 3
+static struct PyModuleDef __pyx_moduledef = {
+  #if PY_VERSION_HEX < 0x03020000
+    { PyObject_HEAD_INIT(NULL) NULL, 0, NULL },
+  #else
+    PyModuleDef_HEAD_INIT,
+  #endif
+    __Pyx_NAMESTR("bitset"),
+    __Pyx_DOCSTR(__pyx_k_13), /* m_doc */
+    -1, /* m_size */
+    __pyx_methods /* m_methods */,
+    NULL, /* m_reload */
+    NULL, /* m_traverse */
+    NULL, /* m_clear */
+    NULL /* m_free */
+};
+#endif
+
+static __Pyx_StringTabEntry __pyx_string_tab[] = {
+  {&__pyx_kp_s_1, __pyx_k_1, sizeof(__pyx_k_1), 0, 0, 1, 0},
+  {&__pyx_kp_s_12, __pyx_k_12, sizeof(__pyx_k_12), 0, 0, 1, 0},
+  {&__pyx_kp_s_2, __pyx_k_2, sizeof(__pyx_k_2), 0, 0, 1, 0},
+  {&__pyx_kp_s_3, __pyx_k_3, sizeof(__pyx_k_3), 0, 0, 1, 0},
+  {&__pyx_kp_s_4, __pyx_k_4, sizeof(__pyx_k_4), 0, 0, 1, 0},
+  {&__pyx_kp_s_5, __pyx_k_5, sizeof(__pyx_k_5), 0, 0, 1, 0},
+  {&__pyx_kp_s_6, __pyx_k_6, sizeof(__pyx_k_6), 0, 0, 1, 0},
+  {&__pyx_kp_s_8, __pyx_k_8, sizeof(__pyx_k_8), 0, 0, 1, 0},
+  {&__pyx_kp_s_9, __pyx_k_9, sizeof(__pyx_k_9), 0, 0, 1, 0},
+  {&__pyx_n_s__IndexError, __pyx_k__IndexError, sizeof(__pyx_k__IndexError), 0, 0, 1, 1},
+  {&__pyx_n_s__MAX, __pyx_k__MAX, sizeof(__pyx_k__MAX), 0, 0, 1, 1},
+  {&__pyx_n_s__ValueError, __pyx_k__ValueError, sizeof(__pyx_k__ValueError), 0, 0, 1, 1},
+  {&__pyx_n_s____main__, __pyx_k____main__, sizeof(__pyx_k____main__), 0, 0, 1, 1},
+  {&__pyx_n_s____test__, __pyx_k____test__, sizeof(__pyx_k____test__), 0, 0, 1, 1},
+  {&__pyx_n_s__bitCount, __pyx_k__bitCount, sizeof(__pyx_k__bitCount), 0, 0, 1, 1},
+  {&__pyx_n_s__count, __pyx_k__count, sizeof(__pyx_k__count), 0, 0, 1, 1},
+  {&__pyx_n_s__end, __pyx_k__end, sizeof(__pyx_k__end), 0, 0, 1, 1},
+  {&__pyx_n_s__get, __pyx_k__get, sizeof(__pyx_k__get), 0, 0, 1, 1},
+  {&__pyx_n_s__granularity, __pyx_k__granularity, sizeof(__pyx_k__granularity), 0, 0, 1, 1},
+  {&__pyx_n_s__iand, __pyx_k__iand, sizeof(__pyx_k__iand), 0, 0, 1, 1},
+  {&__pyx_n_s__invert, __pyx_k__invert, sizeof(__pyx_k__invert), 0, 0, 1, 1},
+  {&__pyx_n_s__ior, __pyx_k__ior, sizeof(__pyx_k__ior), 0, 0, 1, 1},
+  {&__pyx_n_s__size, __pyx_k__size, sizeof(__pyx_k__size), 0, 0, 1, 1},
+  {&__pyx_n_s__start, __pyx_k__start, sizeof(__pyx_k__start), 0, 0, 1, 1},
+  {&__pyx_n_s__sys, __pyx_k__sys, sizeof(__pyx_k__sys), 0, 0, 1, 1},
+  {0, 0, 0, 0, 0, 0, 0}
+};
+static int __Pyx_InitCachedBuiltins(void) {
+  __pyx_builtin_IndexError = __Pyx_GetName(__pyx_b, __pyx_n_s__IndexError); if (!__pyx_builtin_IndexError) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 79; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_builtin_ValueError = __Pyx_GetName(__pyx_b, __pyx_n_s__ValueError); if (!__pyx_builtin_ValueError) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 99; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  return 0;
+  __pyx_L1_error:;
+  return -1;
+}
+
+static int __Pyx_InitCachedConstants(void) {
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0);
+
+  /* "bx/bitset.pyx":99
+ * cdef inline b_check_same_size( BitSet b, BitSet other ):
+ *     if b.bitCount != other.bitCount:
+ *         raise ValueError( "BitSets must have the same size" )             # <<<<<<<<<<<<<<
+ * 
+ * ## ---- BitSet --------------------------------------------------------------
+ */
+  __pyx_k_tuple_7 = PyTuple_Pack(1, ((PyObject *)__pyx_kp_s_6)); if (unlikely(!__pyx_k_tuple_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 99; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_k_tuple_7);
+  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_7));
+
+  /* "bx/bitset.pyx":191
+ * cdef inline bb_check_same_size( BinnedBitSet bb, BinnedBitSet other ):
+ *     if bb.bb.size != other.bb.size:
+ *         raise ValueError( "BitSets must have the same size" )             # <<<<<<<<<<<<<<
+ * 
+ * ## ---- BinnedBitSet --------------------------------------------------------
+ */
+  __pyx_k_tuple_10 = PyTuple_Pack(1, ((PyObject *)__pyx_kp_s_6)); if (unlikely(!__pyx_k_tuple_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 191; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_k_tuple_10);
+  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_10));
+  __Pyx_RefNannyFinishContext();
+  return 0;
+  __pyx_L1_error:;
+  __Pyx_RefNannyFinishContext();
+  return -1;
+}
+
+static int __Pyx_InitGlobals(void) {
+  if (__Pyx_InitStrings(__pyx_string_tab) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  __pyx_int_0 = PyInt_FromLong(0); if (unlikely(!__pyx_int_0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  __pyx_int_1024 = PyInt_FromLong(1024); if (unlikely(!__pyx_int_1024)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  __pyx_int_536870912 = PyInt_FromLong(536870912); if (unlikely(!__pyx_int_536870912)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  return 0;
+  __pyx_L1_error:;
+  return -1;
+}
+
+#if PY_MAJOR_VERSION < 3
+PyMODINIT_FUNC initbitset(void); /*proto*/
+PyMODINIT_FUNC initbitset(void)
+#else
+PyMODINIT_FUNC PyInit_bitset(void); /*proto*/
+PyMODINIT_FUNC PyInit_bitset(void)
+#endif
+{
+  PyObject *__pyx_t_1 = NULL;
+  __Pyx_RefNannyDeclarations
+  #if CYTHON_REFNANNY
+  __Pyx_RefNanny = __Pyx_RefNannyImportAPI("refnanny");
+  if (!__Pyx_RefNanny) {
+      PyErr_Clear();
+      __Pyx_RefNanny = __Pyx_RefNannyImportAPI("Cython.Runtime.refnanny");
+      if (!__Pyx_RefNanny)
+          Py_FatalError("failed to import 'refnanny' module");
+  }
+  #endif
+  __Pyx_RefNannySetupContext("PyMODINIT_FUNC PyInit_bitset(void)", 0);
+  if ( __Pyx_check_binary_version() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_bytes)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #ifdef __Pyx_CyFunction_USED
+  if (__Pyx_CyFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #endif
+  #ifdef __Pyx_FusedFunction_USED
+  if (__pyx_FusedFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #endif
+  #ifdef __Pyx_Generator_USED
+  if (__pyx_Generator_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #endif
+  /*--- Library function declarations ---*/
+  /*--- Threads initialization code ---*/
+  #if defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS
+  #ifdef WITH_THREAD /* Python build with threading support? */
+  PyEval_InitThreads();
+  #endif
+  #endif
+  /*--- Module creation code ---*/
+  #if PY_MAJOR_VERSION < 3
+  __pyx_m = Py_InitModule4(__Pyx_NAMESTR("bitset"), __pyx_methods, __Pyx_DOCSTR(__pyx_k_13), 0, PYTHON_API_VERSION); Py_XINCREF(__pyx_m);
+  #else
+  __pyx_m = PyModule_Create(&__pyx_moduledef);
+  #endif
+  if (unlikely(!__pyx_m)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #if PY_MAJOR_VERSION >= 3
+  {
+    PyObject *modules = PyImport_GetModuleDict(); if (unlikely(!modules)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (!PyDict_GetItemString(modules, "bx.bitset")) {
+      if (unlikely(PyDict_SetItemString(modules, "bx.bitset", __pyx_m) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+  }
+  #endif
+  __pyx_b = PyImport_AddModule(__Pyx_NAMESTR(__Pyx_BUILTIN_MODULE_NAME)); if (unlikely(!__pyx_b)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #if CYTHON_COMPILING_IN_PYPY
+  Py_INCREF(__pyx_b);
+  #endif
+  if (__Pyx_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  /*--- Initialize various global constants etc. ---*/
+  if (unlikely(__Pyx_InitGlobals() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (__pyx_module_is_main_bx__bitset) {
+    if (__Pyx_SetAttrString(__pyx_m, "__name__", __pyx_n_s____main__) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  }
+  /*--- Builtin init code ---*/
+  if (unlikely(__Pyx_InitCachedBuiltins() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  /*--- Constants init code ---*/
+  if (unlikely(__Pyx_InitCachedConstants() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  /*--- Global init code ---*/
+  /*--- Variable export code ---*/
+  /*--- Function export code ---*/
+  /*--- Type init code ---*/
+  if (PyType_Ready(&__pyx_type_2bx_6bitset_BitSet) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 106; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (__Pyx_SetAttrString(__pyx_m, "BitSet", (PyObject *)&__pyx_type_2bx_6bitset_BitSet) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 106; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_2bx_6bitset_BitSet = &__pyx_type_2bx_6bitset_BitSet;
+  if (PyType_Ready(&__pyx_type_2bx_6bitset_BinnedBitSet) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 197; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (__Pyx_SetAttrString(__pyx_m, "BinnedBitSet", (PyObject *)&__pyx_type_2bx_6bitset_BinnedBitSet) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 197; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_2bx_6bitset_BinnedBitSet = &__pyx_type_2bx_6bitset_BinnedBitSet;
+  /*--- Type import code ---*/
+  /*--- Variable import code ---*/
+  /*--- Function import code ---*/
+  /*--- Execution code ---*/
+
+  /* "bx/bitset.pyx":11
+ * """
+ * 
+ * import sys             # <<<<<<<<<<<<<<
+ * 
+ * cdef extern from "common.h":
+ */
+  __pyx_t_1 = __Pyx_Import(((PyObject *)__pyx_n_s__sys), 0, -1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 11; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s__sys, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 11; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "bx/bitset.pyx":104
+ * 
+ * # Maximum value of a signed 32 bit integer ( 2**31 - 1 )
+ * cdef int MAX_INT = 2147483647             # <<<<<<<<<<<<<<
+ * 
+ * cdef class BitSet:
+ */
+  __pyx_v_2bx_6bitset_MAX_INT = 2147483647;
+
+  /* "bx/bitset.pyx":195
+ * ## ---- BinnedBitSet --------------------------------------------------------
+ * 
+ * MAX=512*1024*1024             # <<<<<<<<<<<<<<
+ * 
+ * cdef class BinnedBitSet:
+ */
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s__MAX, __pyx_int_536870912) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 195; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "bx/bitset.pyx":199
+ * cdef class BinnedBitSet:
+ *     cdef BinBits * bb
+ *     def __cinit__( self, size=MAX, granularity=1024 ):             # <<<<<<<<<<<<<<
+ *         if size > MAX_INT:
+ *             raise ValueError( "%d is larger than the maximum BinnedBitSet size of %d." % ( size, MAX_INT ) )
+ */
+  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__MAX); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 199; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_k_11 = __pyx_t_1;
+  __Pyx_GIVEREF(__pyx_t_1);
+  __pyx_t_1 = 0;
+
+  /* "bx/bitset.pyx":1
+ * """             # <<<<<<<<<<<<<<
+ * Compact mutable sequences of bits (vectors of 0s and 1s) supporting various
+ * boolean operations, and a "binned" variation which stores long runs of
+ */
+  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(((PyObject *)__pyx_t_1));
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s____test__, ((PyObject *)__pyx_t_1)) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  if (__pyx_m) {
+    __Pyx_AddTraceback("init bx.bitset", __pyx_clineno, __pyx_lineno, __pyx_filename);
+    Py_DECREF(__pyx_m); __pyx_m = 0;
+  } else if (!PyErr_Occurred()) {
+    PyErr_SetString(PyExc_ImportError, "init bx.bitset");
+  }
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  #if PY_MAJOR_VERSION < 3
+  return;
+  #else
+  return __pyx_m;
+  #endif
+}
+
+/* Runtime support code */
+#if CYTHON_REFNANNY
+static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) {
+    PyObject *m = NULL, *p = NULL;
+    void *r = NULL;
+    m = PyImport_ImportModule((char *)modname);
+    if (!m) goto end;
+    p = PyObject_GetAttrString(m, (char *)"RefNannyAPI");
+    if (!p) goto end;
+    r = PyLong_AsVoidPtr(p);
+end:
+    Py_XDECREF(p);
+    Py_XDECREF(m);
+    return (__Pyx_RefNannyAPIStruct *)r;
+}
+#endif /* CYTHON_REFNANNY */
+
+static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name) {
+    PyObject *result;
+    result = PyObject_GetAttr(dict, name);
+    if (!result) {
+        if (dict != __pyx_b) {
+            PyErr_Clear();
+            result = PyObject_GetAttr(__pyx_b, name);
+        }
+        if (!result) {
+            PyErr_SetObject(PyExc_NameError, name);
+        }
+    }
+    return result;
+}
+
+static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    PyObject *tmp_type, *tmp_value, *tmp_tb;
+    PyThreadState *tstate = PyThreadState_GET();
+    tmp_type = tstate->curexc_type;
+    tmp_value = tstate->curexc_value;
+    tmp_tb = tstate->curexc_traceback;
+    tstate->curexc_type = type;
+    tstate->curexc_value = value;
+    tstate->curexc_traceback = tb;
+    Py_XDECREF(tmp_type);
+    Py_XDECREF(tmp_value);
+    Py_XDECREF(tmp_tb);
+#else
+    PyErr_Restore(type, value, tb);
+#endif
+}
+static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    PyThreadState *tstate = PyThreadState_GET();
+    *type = tstate->curexc_type;
+    *value = tstate->curexc_value;
+    *tb = tstate->curexc_traceback;
+    tstate->curexc_type = 0;
+    tstate->curexc_value = 0;
+    tstate->curexc_traceback = 0;
+#else
+    PyErr_Fetch(type, value, tb);
+#endif
+}
+
+#if PY_MAJOR_VERSION < 3
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb,
+                        CYTHON_UNUSED PyObject *cause) {
+    Py_XINCREF(type);
+    if (!value || value == Py_None)
+        value = NULL;
+    else
+        Py_INCREF(value);
+    if (!tb || tb == Py_None)
+        tb = NULL;
+    else {
+        Py_INCREF(tb);
+        if (!PyTraceBack_Check(tb)) {
+            PyErr_SetString(PyExc_TypeError,
+                "raise: arg 3 must be a traceback or None");
+            goto raise_error;
+        }
+    }
+    #if PY_VERSION_HEX < 0x02050000
+    if (PyClass_Check(type)) {
+    #else
+    if (PyType_Check(type)) {
+    #endif
+#if CYTHON_COMPILING_IN_PYPY
+        if (!value) {
+            Py_INCREF(Py_None);
+            value = Py_None;
+        }
+#endif
+        PyErr_NormalizeException(&type, &value, &tb);
+    } else {
+        if (value) {
+            PyErr_SetString(PyExc_TypeError,
+                "instance exception may not have a separate value");
+            goto raise_error;
+        }
+        value = type;
+        #if PY_VERSION_HEX < 0x02050000
+            if (PyInstance_Check(type)) {
+                type = (PyObject*) ((PyInstanceObject*)type)->in_class;
+                Py_INCREF(type);
+            }
+            else {
+                type = 0;
+                PyErr_SetString(PyExc_TypeError,
+                    "raise: exception must be an old-style class or instance");
+                goto raise_error;
+            }
+        #else
+            type = (PyObject*) Py_TYPE(type);
+            Py_INCREF(type);
+            if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
+                PyErr_SetString(PyExc_TypeError,
+                    "raise: exception class must be a subclass of BaseException");
+                goto raise_error;
+            }
+        #endif
+    }
+    __Pyx_ErrRestore(type, value, tb);
+    return;
+raise_error:
+    Py_XDECREF(value);
+    Py_XDECREF(type);
+    Py_XDECREF(tb);
+    return;
+}
+#else /* Python 3+ */
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause) {
+    PyObject* owned_instance = NULL;
+    if (tb == Py_None) {
+        tb = 0;
+    } else if (tb && !PyTraceBack_Check(tb)) {
+        PyErr_SetString(PyExc_TypeError,
+            "raise: arg 3 must be a traceback or None");
+        goto bad;
+    }
+    if (value == Py_None)
+        value = 0;
+    if (PyExceptionInstance_Check(type)) {
+        if (value) {
+            PyErr_SetString(PyExc_TypeError,
+                "instance exception may not have a separate value");
+            goto bad;
+        }
+        value = type;
+        type = (PyObject*) Py_TYPE(value);
+    } else if (PyExceptionClass_Check(type)) {
+        PyObject *args;
+        if (!value)
+            args = PyTuple_New(0);
+        else if (PyTuple_Check(value)) {
+            Py_INCREF(value);
+            args = value;
+        }
+        else
+            args = PyTuple_Pack(1, value);
+        if (!args)
+            goto bad;
+        owned_instance = PyEval_CallObject(type, args);
+        Py_DECREF(args);
+        if (!owned_instance)
+            goto bad;
+        value = owned_instance;
+        if (!PyExceptionInstance_Check(value)) {
+            PyErr_Format(PyExc_TypeError,
+                         "calling %R should have returned an instance of "
+                         "BaseException, not %R",
+                         type, Py_TYPE(value));
+            goto bad;
+        }
+    } else {
+        PyErr_SetString(PyExc_TypeError,
+            "raise: exception class must be a subclass of BaseException");
+        goto bad;
+    }
+    if (cause && cause != Py_None) {
+        PyObject *fixed_cause;
+        if (PyExceptionClass_Check(cause)) {
+            fixed_cause = PyObject_CallObject(cause, NULL);
+            if (fixed_cause == NULL)
+                goto bad;
+        }
+        else if (PyExceptionInstance_Check(cause)) {
+            fixed_cause = cause;
+            Py_INCREF(fixed_cause);
+        }
+        else {
+            PyErr_SetString(PyExc_TypeError,
+                            "exception causes must derive from "
+                            "BaseException");
+            goto bad;
+        }
+        PyException_SetCause(value, fixed_cause);
+    }
+    PyErr_SetObject(type, value);
+    if (tb) {
+        PyThreadState *tstate = PyThreadState_GET();
+        PyObject* tmp_tb = tstate->curexc_traceback;
+        if (tb != tmp_tb) {
+            Py_INCREF(tb);
+            tstate->curexc_traceback = tb;
+            Py_XDECREF(tmp_tb);
+        }
+    }
+bad:
+    Py_XDECREF(owned_instance);
+    return;
+}
+#endif
+
+static void __Pyx_RaiseDoubleKeywordsError(
+    const char* func_name,
+    PyObject* kw_name)
+{
+    PyErr_Format(PyExc_TypeError,
+        #if PY_MAJOR_VERSION >= 3
+        "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
+        #else
+        "%s() got multiple values for keyword argument '%s'", func_name,
+        PyString_AsString(kw_name));
+        #endif
+}
+
+static int __Pyx_ParseOptionalKeywords(
+    PyObject *kwds,
+    PyObject **argnames[],
+    PyObject *kwds2,
+    PyObject *values[],
+    Py_ssize_t num_pos_args,
+    const char* function_name)
+{
+    PyObject *key = 0, *value = 0;
+    Py_ssize_t pos = 0;
+    PyObject*** name;
+    PyObject*** first_kw_arg = argnames + num_pos_args;
+    while (PyDict_Next(kwds, &pos, &key, &value)) {
+        name = first_kw_arg;
+        while (*name && (**name != key)) name++;
+        if (*name) {
+            values[name-argnames] = value;
+            continue;
+        }
+        name = first_kw_arg;
+        #if PY_MAJOR_VERSION < 3
+        if (likely(PyString_CheckExact(key)) || likely(PyString_Check(key))) {
+            while (*name) {
+                if ((CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**name) == PyString_GET_SIZE(key))
+                        && _PyString_Eq(**name, key)) {
+                    values[name-argnames] = value;
+                    break;
+                }
+                name++;
+            }
+            if (*name) continue;
+            else {
+                PyObject*** argname = argnames;
+                while (argname != first_kw_arg) {
+                    if ((**argname == key) || (
+                            (CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**argname) == PyString_GET_SIZE(key))
+                             && _PyString_Eq(**argname, key))) {
+                        goto arg_passed_twice;
+                    }
+                    argname++;
+                }
+            }
+        } else
+        #endif
+        if (likely(PyUnicode_Check(key))) {
+            while (*name) {
+                int cmp = (**name == key) ? 0 :
+                #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3
+                    (PyUnicode_GET_SIZE(**name) != PyUnicode_GET_SIZE(key)) ? 1 :
+                #endif
+                    PyUnicode_Compare(**name, key);
+                if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad;
+                if (cmp == 0) {
+                    values[name-argnames] = value;
+                    break;
+                }
+                name++;
+            }
+            if (*name) continue;
+            else {
+                PyObject*** argname = argnames;
+                while (argname != first_kw_arg) {
+                    int cmp = (**argname == key) ? 0 :
+                    #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3
+                        (PyUnicode_GET_SIZE(**argname) != PyUnicode_GET_SIZE(key)) ? 1 :
+                    #endif
+                        PyUnicode_Compare(**argname, key);
+                    if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad;
+                    if (cmp == 0) goto arg_passed_twice;
+                    argname++;
+                }
+            }
+        } else
+            goto invalid_keyword_type;
+        if (kwds2) {
+            if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
+        } else {
+            goto invalid_keyword;
+        }
+    }
+    return 0;
+arg_passed_twice:
+    __Pyx_RaiseDoubleKeywordsError(function_name, key);
+    goto bad;
+invalid_keyword_type:
+    PyErr_Format(PyExc_TypeError,
+        "%s() keywords must be strings", function_name);
+    goto bad;
+invalid_keyword:
+    PyErr_Format(PyExc_TypeError,
+    #if PY_MAJOR_VERSION < 3
+        "%s() got an unexpected keyword argument '%s'",
+        function_name, PyString_AsString(key));
+    #else
+        "%s() got an unexpected keyword argument '%U'",
+        function_name, key);
+    #endif
+bad:
+    return -1;
+}
+
+static void __Pyx_RaiseArgtupleInvalid(
+    const char* func_name,
+    int exact,
+    Py_ssize_t num_min,
+    Py_ssize_t num_max,
+    Py_ssize_t num_found)
+{
+    Py_ssize_t num_expected;
+    const char *more_or_less;
+    if (num_found < num_min) {
+        num_expected = num_min;
+        more_or_less = "at least";
+    } else {
+        num_expected = num_max;
+        more_or_less = "at most";
+    }
+    if (exact) {
+        more_or_less = "exactly";
+    }
+    PyErr_Format(PyExc_TypeError,
+                 "%s() takes %s %" CYTHON_FORMAT_SSIZE_T "d positional argument%s (%" CYTHON_FORMAT_SSIZE_T "d given)",
+                 func_name, more_or_less, num_expected,
+                 (num_expected == 1) ? "" : "s", num_found);
+}
+
+static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
+    const char *name, int exact)
+{
+    if (!type) {
+        PyErr_Format(PyExc_SystemError, "Missing type object");
+        return 0;
+    }
+    if (none_allowed && obj == Py_None) return 1;
+    else if (exact) {
+        if (Py_TYPE(obj) == type) return 1;
+    }
+    else {
+        if (PyObject_TypeCheck(obj, type)) return 1;
+    }
+    PyErr_Format(PyExc_TypeError,
+        "Argument '%s' has incorrect type (expected %s, got %s)",
+        name, type->tp_name, Py_TYPE(obj)->tp_name);
+    return 0;
+}
+
+static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level) {
+    PyObject *empty_list = 0;
+    PyObject *module = 0;
+    PyObject *global_dict = 0;
+    PyObject *empty_dict = 0;
+    PyObject *list;
+    #if PY_VERSION_HEX < 0x03030000
+    PyObject *py_import = 0;
+    py_import = __Pyx_GetAttrString(__pyx_b, "__import__");
+    if (!py_import)
+        goto bad;
+    #endif
+    if (from_list)
+        list = from_list;
+    else {
+        empty_list = PyList_New(0);
+        if (!empty_list)
+            goto bad;
+        list = empty_list;
+    }
+    global_dict = PyModule_GetDict(__pyx_m);
+    if (!global_dict)
+        goto bad;
+    empty_dict = PyDict_New();
+    if (!empty_dict)
+        goto bad;
+    #if PY_VERSION_HEX >= 0x02050000
+    {
+        #if PY_MAJOR_VERSION >= 3
+        if (level == -1) {
+            if (strchr(__Pyx_MODULE_NAME, '.')) {
+                #if PY_VERSION_HEX < 0x03030000
+                PyObject *py_level = PyInt_FromLong(1);
+                if (!py_level)
+                    goto bad;
+                module = PyObject_CallFunctionObjArgs(py_import,
+                    name, global_dict, empty_dict, list, py_level, NULL);
+                Py_DECREF(py_level);
+                #else
+                module = PyImport_ImportModuleLevelObject(
+                    name, global_dict, empty_dict, list, 1);
+                #endif
+                if (!module) {
+                    if (!PyErr_ExceptionMatches(PyExc_ImportError))
+                        goto bad;
+                    PyErr_Clear();
+                }
+            }
+            level = 0; /* try absolute import on failure */
+        }
+        #endif
+        if (!module) {
+            #if PY_VERSION_HEX < 0x03030000
+            PyObject *py_level = PyInt_FromLong(level);
+            if (!py_level)
+                goto bad;
+            module = PyObject_CallFunctionObjArgs(py_import,
+                name, global_dict, empty_dict, list, py_level, NULL);
+            Py_DECREF(py_level);
+            #else
+            module = PyImport_ImportModuleLevelObject(
+                name, global_dict, empty_dict, list, level);
+            #endif
+        }
+    }
+    #else
+    if (level>0) {
+        PyErr_SetString(PyExc_RuntimeError, "Relative import is not supported for Python <=2.4.");
+        goto bad;
+    }
+    module = PyObject_CallFunctionObjArgs(py_import,
+        name, global_dict, empty_dict, list, NULL);
+    #endif
+bad:
+    #if PY_VERSION_HEX < 0x03030000
+    Py_XDECREF(py_import);
+    #endif
+    Py_XDECREF(empty_list);
+    Py_XDECREF(empty_dict);
+    return module;
+}
+
+static CYTHON_INLINE unsigned char __Pyx_PyInt_AsUnsignedChar(PyObject* x) {
+    const unsigned char neg_one = (unsigned char)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(unsigned char) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(unsigned char)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to unsigned char" :
+                    "value too large to convert to unsigned char");
+            }
+            return (unsigned char)-1;
+        }
+        return (unsigned char)val;
+    }
+    return (unsigned char)__Pyx_PyInt_AsUnsignedLong(x);
+}
+
+static CYTHON_INLINE unsigned short __Pyx_PyInt_AsUnsignedShort(PyObject* x) {
+    const unsigned short neg_one = (unsigned short)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(unsigned short) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(unsigned short)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to unsigned short" :
+                    "value too large to convert to unsigned short");
+            }
+            return (unsigned short)-1;
+        }
+        return (unsigned short)val;
+    }
+    return (unsigned short)__Pyx_PyInt_AsUnsignedLong(x);
+}
+
+static CYTHON_INLINE unsigned int __Pyx_PyInt_AsUnsignedInt(PyObject* x) {
+    const unsigned int neg_one = (unsigned int)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(unsigned int) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(unsigned int)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to unsigned int" :
+                    "value too large to convert to unsigned int");
+            }
+            return (unsigned int)-1;
+        }
+        return (unsigned int)val;
+    }
+    return (unsigned int)__Pyx_PyInt_AsUnsignedLong(x);
+}
+
+static CYTHON_INLINE char __Pyx_PyInt_AsChar(PyObject* x) {
+    const char neg_one = (char)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(char) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(char)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to char" :
+                    "value too large to convert to char");
+            }
+            return (char)-1;
+        }
+        return (char)val;
+    }
+    return (char)__Pyx_PyInt_AsLong(x);
+}
+
+static CYTHON_INLINE short __Pyx_PyInt_AsShort(PyObject* x) {
+    const short neg_one = (short)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(short) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(short)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to short" :
+                    "value too large to convert to short");
+            }
+            return (short)-1;
+        }
+        return (short)val;
+    }
+    return (short)__Pyx_PyInt_AsLong(x);
+}
+
+static CYTHON_INLINE int __Pyx_PyInt_AsInt(PyObject* x) {
+    const int neg_one = (int)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(int) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(int)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to int" :
+                    "value too large to convert to int");
+            }
+            return (int)-1;
+        }
+        return (int)val;
+    }
+    return (int)__Pyx_PyInt_AsLong(x);
+}
+
+static CYTHON_INLINE signed char __Pyx_PyInt_AsSignedChar(PyObject* x) {
+    const signed char neg_one = (signed char)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(signed char) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(signed char)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to signed char" :
+                    "value too large to convert to signed char");
+            }
+            return (signed char)-1;
+        }
+        return (signed char)val;
+    }
+    return (signed char)__Pyx_PyInt_AsSignedLong(x);
+}
+
+static CYTHON_INLINE signed short __Pyx_PyInt_AsSignedShort(PyObject* x) {
+    const signed short neg_one = (signed short)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(signed short) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(signed short)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to signed short" :
+                    "value too large to convert to signed short");
+            }
+            return (signed short)-1;
+        }
+        return (signed short)val;
+    }
+    return (signed short)__Pyx_PyInt_AsSignedLong(x);
+}
+
+static CYTHON_INLINE signed int __Pyx_PyInt_AsSignedInt(PyObject* x) {
+    const signed int neg_one = (signed int)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(signed int) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(signed int)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to signed int" :
+                    "value too large to convert to signed int");
+            }
+            return (signed int)-1;
+        }
+        return (signed int)val;
+    }
+    return (signed int)__Pyx_PyInt_AsSignedLong(x);
+}
+
+static CYTHON_INLINE int __Pyx_PyInt_AsLongDouble(PyObject* x) {
+    const int neg_one = (int)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(int) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(int)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to int" :
+                    "value too large to convert to int");
+            }
+            return (int)-1;
+        }
+        return (int)val;
+    }
+    return (int)__Pyx_PyInt_AsLong(x);
+}
+
+static CYTHON_INLINE unsigned long __Pyx_PyInt_AsUnsignedLong(PyObject* x) {
+    const unsigned long neg_one = (unsigned long)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to unsigned long");
+            return (unsigned long)-1;
+        }
+        return (unsigned long)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to unsigned long");
+                return (unsigned long)-1;
+            }
+            return (unsigned long)PyLong_AsUnsignedLong(x);
+        } else {
+            return (unsigned long)PyLong_AsLong(x);
+        }
+    } else {
+        unsigned long val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (unsigned long)-1;
+        val = __Pyx_PyInt_AsUnsignedLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE unsigned PY_LONG_LONG __Pyx_PyInt_AsUnsignedLongLong(PyObject* x) {
+    const unsigned PY_LONG_LONG neg_one = (unsigned PY_LONG_LONG)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to unsigned PY_LONG_LONG");
+            return (unsigned PY_LONG_LONG)-1;
+        }
+        return (unsigned PY_LONG_LONG)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to unsigned PY_LONG_LONG");
+                return (unsigned PY_LONG_LONG)-1;
+            }
+            return (unsigned PY_LONG_LONG)PyLong_AsUnsignedLongLong(x);
+        } else {
+            return (unsigned PY_LONG_LONG)PyLong_AsLongLong(x);
+        }
+    } else {
+        unsigned PY_LONG_LONG val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (unsigned PY_LONG_LONG)-1;
+        val = __Pyx_PyInt_AsUnsignedLongLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE long __Pyx_PyInt_AsLong(PyObject* x) {
+    const long neg_one = (long)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to long");
+            return (long)-1;
+        }
+        return (long)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to long");
+                return (long)-1;
+            }
+            return (long)PyLong_AsUnsignedLong(x);
+        } else {
+            return (long)PyLong_AsLong(x);
+        }
+    } else {
+        long val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (long)-1;
+        val = __Pyx_PyInt_AsLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE PY_LONG_LONG __Pyx_PyInt_AsLongLong(PyObject* x) {
+    const PY_LONG_LONG neg_one = (PY_LONG_LONG)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to PY_LONG_LONG");
+            return (PY_LONG_LONG)-1;
+        }
+        return (PY_LONG_LONG)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to PY_LONG_LONG");
+                return (PY_LONG_LONG)-1;
+            }
+            return (PY_LONG_LONG)PyLong_AsUnsignedLongLong(x);
+        } else {
+            return (PY_LONG_LONG)PyLong_AsLongLong(x);
+        }
+    } else {
+        PY_LONG_LONG val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (PY_LONG_LONG)-1;
+        val = __Pyx_PyInt_AsLongLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE signed long __Pyx_PyInt_AsSignedLong(PyObject* x) {
+    const signed long neg_one = (signed long)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to signed long");
+            return (signed long)-1;
+        }
+        return (signed long)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to signed long");
+                return (signed long)-1;
+            }
+            return (signed long)PyLong_AsUnsignedLong(x);
+        } else {
+            return (signed long)PyLong_AsLong(x);
+        }
+    } else {
+        signed long val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (signed long)-1;
+        val = __Pyx_PyInt_AsSignedLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE signed PY_LONG_LONG __Pyx_PyInt_AsSignedLongLong(PyObject* x) {
+    const signed PY_LONG_LONG neg_one = (signed PY_LONG_LONG)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to signed PY_LONG_LONG");
+            return (signed PY_LONG_LONG)-1;
+        }
+        return (signed PY_LONG_LONG)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to signed PY_LONG_LONG");
+                return (signed PY_LONG_LONG)-1;
+            }
+            return (signed PY_LONG_LONG)PyLong_AsUnsignedLongLong(x);
+        } else {
+            return (signed PY_LONG_LONG)PyLong_AsLongLong(x);
+        }
+    } else {
+        signed PY_LONG_LONG val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (signed PY_LONG_LONG)-1;
+        val = __Pyx_PyInt_AsSignedLongLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static int __Pyx_check_binary_version(void) {
+    char ctversion[4], rtversion[4];
+    PyOS_snprintf(ctversion, 4, "%d.%d", PY_MAJOR_VERSION, PY_MINOR_VERSION);
+    PyOS_snprintf(rtversion, 4, "%s", Py_GetVersion());
+    if (ctversion[0] != rtversion[0] || ctversion[2] != rtversion[2]) {
+        char message[200];
+        PyOS_snprintf(message, sizeof(message),
+                      "compiletime version %s of module '%.100s' "
+                      "does not match runtime version %s",
+                      ctversion, __Pyx_MODULE_NAME, rtversion);
+        #if PY_VERSION_HEX < 0x02050000
+        return PyErr_Warn(NULL, message);
+        #else
+        return PyErr_WarnEx(NULL, message, 1);
+        #endif
+    }
+    return 0;
+}
+
+static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) {
+    int start = 0, mid = 0, end = count - 1;
+    if (end >= 0 && code_line > entries[end].code_line) {
+        return count;
+    }
+    while (start < end) {
+        mid = (start + end) / 2;
+        if (code_line < entries[mid].code_line) {
+            end = mid;
+        } else if (code_line > entries[mid].code_line) {
+             start = mid + 1;
+        } else {
+            return mid;
+        }
+    }
+    if (code_line <= entries[mid].code_line) {
+        return mid;
+    } else {
+        return mid + 1;
+    }
+}
+static PyCodeObject *__pyx_find_code_object(int code_line) {
+    PyCodeObject* code_object;
+    int pos;
+    if (unlikely(!code_line) || unlikely(!__pyx_code_cache.entries)) {
+        return NULL;
+    }
+    pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line);
+    if (unlikely(pos >= __pyx_code_cache.count) || unlikely(__pyx_code_cache.entries[pos].code_line != code_line)) {
+        return NULL;
+    }
+    code_object = __pyx_code_cache.entries[pos].code_object;
+    Py_INCREF(code_object);
+    return code_object;
+}
+static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) {
+    int pos, i;
+    __Pyx_CodeObjectCacheEntry* entries = __pyx_code_cache.entries;
+    if (unlikely(!code_line)) {
+        return;
+    }
+    if (unlikely(!entries)) {
+        entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Malloc(64*sizeof(__Pyx_CodeObjectCacheEntry));
+        if (likely(entries)) {
+            __pyx_code_cache.entries = entries;
+            __pyx_code_cache.max_count = 64;
+            __pyx_code_cache.count = 1;
+            entries[0].code_line = code_line;
+            entries[0].code_object = code_object;
+            Py_INCREF(code_object);
+        }
+        return;
+    }
+    pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line);
+    if ((pos < __pyx_code_cache.count) && unlikely(__pyx_code_cache.entries[pos].code_line == code_line)) {
+        PyCodeObject* tmp = entries[pos].code_object;
+        entries[pos].code_object = code_object;
+        Py_DECREF(tmp);
+        return;
+    }
+    if (__pyx_code_cache.count == __pyx_code_cache.max_count) {
+        int new_max = __pyx_code_cache.max_count + 64;
+        entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Realloc(
+            __pyx_code_cache.entries, new_max*sizeof(__Pyx_CodeObjectCacheEntry));
+        if (unlikely(!entries)) {
+            return;
+        }
+        __pyx_code_cache.entries = entries;
+        __pyx_code_cache.max_count = new_max;
+    }
+    for (i=__pyx_code_cache.count; i>pos; i--) {
+        entries[i] = entries[i-1];
+    }
+    entries[pos].code_line = code_line;
+    entries[pos].code_object = code_object;
+    __pyx_code_cache.count++;
+    Py_INCREF(code_object);
+}
+
+#include "compile.h"
+#include "frameobject.h"
+#include "traceback.h"
+static PyCodeObject* __Pyx_CreateCodeObjectForTraceback(
+            const char *funcname, int c_line,
+            int py_line, const char *filename) {
+    PyCodeObject *py_code = 0;
+    PyObject *py_srcfile = 0;
+    PyObject *py_funcname = 0;
+    #if PY_MAJOR_VERSION < 3
+    py_srcfile = PyString_FromString(filename);
+    #else
+    py_srcfile = PyUnicode_FromString(filename);
+    #endif
+    if (!py_srcfile) goto bad;
+    if (c_line) {
+        #if PY_MAJOR_VERSION < 3
+        py_funcname = PyString_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line);
+        #else
+        py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line);
+        #endif
+    }
+    else {
+        #if PY_MAJOR_VERSION < 3
+        py_funcname = PyString_FromString(funcname);
+        #else
+        py_funcname = PyUnicode_FromString(funcname);
+        #endif
+    }
+    if (!py_funcname) goto bad;
+    py_code = __Pyx_PyCode_New(
+        0,            /*int argcount,*/
+        0,            /*int kwonlyargcount,*/
+        0,            /*int nlocals,*/
+        0,            /*int stacksize,*/
+        0,            /*int flags,*/
+        __pyx_empty_bytes, /*PyObject *code,*/
+        __pyx_empty_tuple, /*PyObject *consts,*/
+        __pyx_empty_tuple, /*PyObject *names,*/
+        __pyx_empty_tuple, /*PyObject *varnames,*/
+        __pyx_empty_tuple, /*PyObject *freevars,*/
+        __pyx_empty_tuple, /*PyObject *cellvars,*/
+        py_srcfile,   /*PyObject *filename,*/
+        py_funcname,  /*PyObject *name,*/
+        py_line,      /*int firstlineno,*/
+        __pyx_empty_bytes  /*PyObject *lnotab*/
+    );
+    Py_DECREF(py_srcfile);
+    Py_DECREF(py_funcname);
+    return py_code;
+bad:
+    Py_XDECREF(py_srcfile);
+    Py_XDECREF(py_funcname);
+    return NULL;
+}
+static void __Pyx_AddTraceback(const char *funcname, int c_line,
+                               int py_line, const char *filename) {
+    PyCodeObject *py_code = 0;
+    PyObject *py_globals = 0;
+    PyFrameObject *py_frame = 0;
+    py_code = __pyx_find_code_object(c_line ? c_line : py_line);
+    if (!py_code) {
+        py_code = __Pyx_CreateCodeObjectForTraceback(
+            funcname, c_line, py_line, filename);
+        if (!py_code) goto bad;
+        __pyx_insert_code_object(c_line ? c_line : py_line, py_code);
+    }
+    py_globals = PyModule_GetDict(__pyx_m);
+    if (!py_globals) goto bad;
+    py_frame = PyFrame_New(
+        PyThreadState_GET(), /*PyThreadState *tstate,*/
+        py_code,             /*PyCodeObject *code,*/
+        py_globals,          /*PyObject *globals,*/
+        0                    /*PyObject *locals*/
+    );
+    if (!py_frame) goto bad;
+    py_frame->f_lineno = py_line;
+    PyTraceBack_Here(py_frame);
+bad:
+    Py_XDECREF(py_code);
+    Py_XDECREF(py_frame);
+}
+
+static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
+    while (t->p) {
+        #if PY_MAJOR_VERSION < 3
+        if (t->is_unicode) {
+            *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
+        } else if (t->intern) {
+            *t->p = PyString_InternFromString(t->s);
+        } else {
+            *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
+        }
+        #else  /* Python 3+ has unicode identifiers */
+        if (t->is_unicode | t->is_str) {
+            if (t->intern) {
+                *t->p = PyUnicode_InternFromString(t->s);
+            } else if (t->encoding) {
+                *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL);
+            } else {
+                *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
+            }
+        } else {
+            *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
+        }
+        #endif
+        if (!*t->p)
+            return -1;
+        ++t;
+    }
+    return 0;
+}
+
+static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) {
+   int is_true = x == Py_True;
+   if (is_true | (x == Py_False) | (x == Py_None)) return is_true;
+   else return PyObject_IsTrue(x);
+}
+static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x) {
+  PyNumberMethods *m;
+  const char *name = NULL;
+  PyObject *res = NULL;
+#if PY_VERSION_HEX < 0x03000000
+  if (PyInt_Check(x) || PyLong_Check(x))
+#else
+  if (PyLong_Check(x))
+#endif
+    return Py_INCREF(x), x;
+  m = Py_TYPE(x)->tp_as_number;
+#if PY_VERSION_HEX < 0x03000000
+  if (m && m->nb_int) {
+    name = "int";
+    res = PyNumber_Int(x);
+  }
+  else if (m && m->nb_long) {
+    name = "long";
+    res = PyNumber_Long(x);
+  }
+#else
+  if (m && m->nb_int) {
+    name = "int";
+    res = PyNumber_Long(x);
+  }
+#endif
+  if (res) {
+#if PY_VERSION_HEX < 0x03000000
+    if (!PyInt_Check(res) && !PyLong_Check(res)) {
+#else
+    if (!PyLong_Check(res)) {
+#endif
+      PyErr_Format(PyExc_TypeError,
+                   "__%s__ returned non-%s (type %.200s)",
+                   name, name, Py_TYPE(res)->tp_name);
+      Py_DECREF(res);
+      return NULL;
+    }
+  }
+  else if (!PyErr_Occurred()) {
+    PyErr_SetString(PyExc_TypeError,
+                    "an integer is required");
+  }
+  return res;
+}
+static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) {
+  Py_ssize_t ival;
+  PyObject* x = PyNumber_Index(b);
+  if (!x) return -1;
+  ival = PyInt_AsSsize_t(x);
+  Py_DECREF(x);
+  return ival;
+}
+static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) {
+#if PY_VERSION_HEX < 0x02050000
+   if (ival <= LONG_MAX)
+       return PyInt_FromLong((long)ival);
+   else {
+       unsigned char *bytes = (unsigned char *) &ival;
+       int one = 1; int little = (int)*(unsigned char*)&one;
+       return _PyLong_FromByteArray(bytes, sizeof(size_t), little, 0);
+   }
+#else
+   return PyInt_FromSize_t(ival);
+#endif
+}
+static CYTHON_INLINE size_t __Pyx_PyInt_AsSize_t(PyObject* x) {
+   unsigned PY_LONG_LONG val = __Pyx_PyInt_AsUnsignedLongLong(x);
+   if (unlikely(val == (unsigned PY_LONG_LONG)-1 && PyErr_Occurred())) {
+       return (size_t)-1;
+   } else if (unlikely(val != (unsigned PY_LONG_LONG)(size_t)val)) {
+       PyErr_SetString(PyExc_OverflowError,
+                       "value too large to convert to size_t");
+       return (size_t)-1;
+   }
+   return (size_t)val;
+}
+
+
+#endif /* Py_PYTHON_H */
diff --git a/lib/bx/bitset.pyx b/lib/bx/bitset.pyx
new file mode 100644
index 0000000..6a68ec9
--- /dev/null
+++ b/lib/bx/bitset.pyx
@@ -0,0 +1,240 @@
+"""
+Compact mutable sequences of bits (vectors of 0s and 1s) supporting various
+boolean operations, and a "binned" variation which stores long runs of 
+identical bits compactly.
+
+Because the binned implementation avoids a lot of memory allocation and access
+when working with either small subregions of the total interval or setting /
+testing spans larger than the bin size, it can be much faster.
+"""
+
+import sys
+
+cdef extern from "common.h":
+    ctypedef int boolean
+
+cdef extern from "bits.h":
+    ctypedef unsigned char Bits
+    # Allocate bits. 
+    Bits * bitAlloc( int bitCount )
+    # Clone bits. 
+    Bits * bitClone(Bits* orig, int bitCount )
+    # Free bits. 
+    void bitFree(Bits **pB)
+    # Set a single bit. 
+    void bitSetOne(Bits *b, int bitIx)
+    # Clear a single bit. 
+    void bitClearOne(Bits *b, int bitIx)
+    # Set a range of bits. 
+    void bitSetRange(Bits *b, int startIx, int bitCount)
+    # Read a single bit. 
+    int bitReadOne(Bits *b, int bitIx)
+    # Count number of bits set in range. 
+    int bitCountRange(Bits *b, int startIx, int bitCount)
+    # Find the index of the the next set bit. 
+    int bitFindSet(Bits *b, int startIx, int bitCount)
+    # Find the index of the the next clear bit. 
+    int bitFindClear(Bits *b, int startIx, int bitCount)
+    # Clear many bits. 
+    void bitClear(Bits *b, int bitCount)
+    # And two bitmaps.  Put result in a. 
+    void bitAnd(Bits *a, Bits *b, int bitCount)
+    # Or two bitmaps.  Put result in a. 
+    void bitOr(Bits *a, Bits *b, int bitCount)
+    # Xor two bitmaps.  Put result in a. 
+    void bitXor(Bits *a, Bits *b, int bitCount)
+    # Flip all bits in a. 
+    void bitNot(Bits *a, int bitCount)
+    ## # Print part or all of bit map as a string of 0s and 1s.  Mostly useful for
+    ## void bitPrint(Bits *a, int startIx, int bitCount, FILE* out)
+
+cdef extern from "binBits.h":
+    struct BinBits:
+        int size
+        int bin_size
+        int nbins
+        Bits ** bins
+    BinBits* binBitsAlloc( int size, int granularity )
+    void binBitsFree( BinBits * bb )
+    int binBitsReadOne( BinBits * bb, int pos )
+    void binBitsSetOne( BinBits * bb, int pos )
+    void binBitsClearOne( BinBits * bb, int pos )
+    void binBitsSetRange( BinBits *bb, int start, int size )
+    int binBitsCountRange( BinBits *bb, int start, int size )
+    int binBitsFindSet( BinBits *bb, int start )
+    int binBitsFindClear( BinBits *bb, int start )
+    void binBitsAnd( BinBits *bb1, BinBits *bb2 )
+    void binBitsOr( BinBits *bb1, BinBits *bb2 )
+    void binBitsNot( BinBits *bb )
+
+## ---- Forward declerations ------------------------------------------------
+
+cdef class BitSet
+cdef class BinnedBitSet
+
+## ---- BitSet bounds checking ----------------------------------------------
+    
+cdef inline b_check_index( BitSet b, index ):
+    if index < 0:
+        raise IndexError( "BitSet index (%d) must be non-negative." % index )
+    if index >= b.bitCount:
+        raise IndexError( "%d is larger than the size of this BitSet (%d)." % ( index, b.bitCount ) )
+    
+cdef inline b_check_range( BitSet b, start, end ):
+    b_check_index( b, start )
+    if end < start:
+        raise IndexError( "Range end (%d) must be greater than range start(%d)." % ( end, start ) )
+    if end > b.bitCount:
+        raise IndexError( "End %d is larger than the size of this BitSet (%d)." % ( end, b.bitCount ) )
+        
+cdef inline b_check_range_count( BitSet b, start, count ):
+    b_check_index( b, start )
+    if count < 0:
+        raise IndexError( "Count (%d) must be non-negative." % count )
+    if start + count > b.bitCount:
+        raise IndexError( "End %d is larger than the size of this BitSet (%d)." % ( start + count, b.bitCount ) )
+
+cdef inline b_check_same_size( BitSet b, BitSet other ):
+    if b.bitCount != other.bitCount:
+        raise ValueError( "BitSets must have the same size" )
+
+## ---- BitSet --------------------------------------------------------------
+
+# Maximum value of a signed 32 bit integer ( 2**31 - 1 )
+cdef int MAX_INT = 2147483647
+
+cdef class BitSet:
+    cdef Bits * bits
+    cdef int bitCount
+    def __cinit__( self, bitCount ):
+        if bitCount > MAX_INT:
+            raise ValueError( "%d is larger than the maximum BitSet size of %d." % ( bitCount, MAX_INT ) )
+        self.bitCount = bitCount
+        self.bits = bitAlloc( bitCount )
+    def __dealloc__( self ):
+        if self.bits:
+            bitFree( & self.bits )
+    property size:
+        def __get__( self ):
+            return self.bitCount
+    def set( self, index ):
+        b_check_index( self, index )
+        bitSetOne( self.bits, index )
+    def clear( self, index ):
+        b_check_index( self, index )
+        bitClearOne( self.bits, index )
+    def clone( self ):
+        other = BitSet( self.bitCount )
+        other.ior( self )
+        return other
+    def set_range( self, start, count ):
+        b_check_range_count( self, start, count )
+        bitSetRange( self.bits, start, count )
+    def get( self, index ):
+        b_check_index( self, index )
+        return bitReadOne( self.bits, index );
+    def count_range( self, start=0, count=None ):
+        if count == None: 
+            count = self.bitCount - start
+        b_check_range_count( self, start, count )
+        return bitCountRange( self.bits, start, count )
+    def next_set( self, start, end=None ):
+        if end == None: 
+            end = self.bitCount
+        b_check_range( self, start, end )
+        return bitFindSet( self.bits, start, end )
+    def next_clear( self, start, end=None ):
+        if end == None: 
+            end = self.bitCount
+        b_check_range( self, start, end )
+        return bitFindClear( self.bits, start, end )
+    def iand( self, BitSet other ):
+        b_check_same_size( self, other )
+        bitAnd( self.bits, other.bits, self.bitCount )
+    def ior( self, BitSet other ): 
+        b_check_same_size( self, other )
+        bitOr( self.bits, other.bits, self.bitCount )
+    def ixor( self, BitSet other ): 
+        b_check_same_size( self, other )
+        bitXor( self.bits, other.bits, self.bitCount )
+    def invert( self ):
+        bitNot( self.bits, self.bitCount)
+    def __getitem__( self, index ):
+        return self.get( index )
+    def __iand__( self, other ):
+        self.iand( other )
+        return self
+    def __ior__( self, other ):
+        self.ior( other )
+        return self
+    def __invert__( self ):
+        self.invert()
+        return self
+
+## ---- BinnedBitSet bounds checking ----------------------------------------
+
+cdef inline bb_check_index( BinnedBitSet bb, index ):
+    if index < 0:
+        raise IndexError( "BitSet index (%d) must be non-negative." % index )
+    if index >= bb.bb.size:
+        raise IndexError( "%d is larger than the size of this BitSet (%d)." % ( index, bb.bb.size ) )        
+cdef inline bb_check_start( BinnedBitSet bb, start ):
+    bb_check_index( bb, start )
+cdef inline bb_check_range_count( BinnedBitSet bb, start, count ):
+    bb_check_index( bb, start )
+    if count < 0:
+        raise IndexError( "Count (%d) must be non-negative." % count )
+    if start + count > bb.bb.size:
+        raise IndexError( "End (%d) is larger than the size of this BinnedBitSet (%d)." % ( start + count, bb.bb.size ) )
+cdef inline bb_check_same_size( BinnedBitSet bb, BinnedBitSet other ):
+    if bb.bb.size != other.bb.size:
+        raise ValueError( "BitSets must have the same size" )
+
+## ---- BinnedBitSet --------------------------------------------------------
+
+MAX=512*1024*1024 
+
+cdef class BinnedBitSet:
+    cdef BinBits * bb
+    def __cinit__( self, size=MAX, granularity=1024 ):
+        if size > MAX_INT:
+            raise ValueError( "%d is larger than the maximum BinnedBitSet size of %d." % ( size, MAX_INT ) )
+        self.bb = binBitsAlloc( size, granularity )
+    def __dealloc__( self ):
+        if self.bb:
+            binBitsFree( self.bb );
+    def __getitem__( self, index ):
+        bb_check_index( self, index )
+        return binBitsReadOne( self.bb, index )
+    def set( self, index ):
+        bb_check_index( self, index )
+        binBitsSetOne( self.bb, index )
+    def clear( self, index ):
+        bb_check_index( self, index )
+        binBitsClearOne( self.bb, index )
+    def set_range( self, int start, count ):
+        bb_check_range_count( self, start, count )
+        binBitsSetRange( self.bb, start, count )
+    def count_range( self, start, count ):
+        bb_check_range_count( self, start, count )
+        return binBitsCountRange( self.bb, start, count )
+    def next_set( self, start ):
+        bb_check_start( self, start )
+        return binBitsFindSet( self.bb, start )
+    def next_clear( self, start ):
+        bb_check_start( self, start )
+        return binBitsFindClear( self.bb, start )
+    property size:
+        def __get__( self ):
+            return self.bb.size
+    property bin_size:
+        def __get__( self ):
+            return self.bb.bin_size
+    def iand( self, BinnedBitSet other ):
+        bb_check_same_size( self, other )
+        binBitsAnd( self.bb, other.bb )
+    def ior( self, BinnedBitSet other ):
+        bb_check_same_size( self, other )
+        binBitsOr( self.bb, other.bb )
+    def invert( self ):
+        binBitsNot( self.bb )
diff --git a/lib/bx/bitset_builders.py b/lib/bx/bitset_builders.py
new file mode 100644
index 0000000..47bb9d9
--- /dev/null
+++ b/lib/bx/bitset_builders.py
@@ -0,0 +1,155 @@
+"""
+Support for creating dictionaries of `Bitset`s / `BinnedBitset`s from text
+files containg sets of "covered" intervals in sequences (e.g. `BED`_ files).
+
+.. BED: http://genome.ucsc.edu/FAQ/FAQformat.html#format1
+"""
+
+from warnings import warn
+from bx.bitset import *
+import re
+
+def binned_bitsets_from_file( f, chrom_col=0, start_col=1, end_col=2, strand_col=5, upstream_pad=0, downstream_pad=0, lens={} ):
+    """
+    Read a file into a dictionary of bitsets. The defaults arguments 
+    
+    - 'f' should be a file like object (or any iterable containing strings)
+    - 'chrom_col', 'start_col', and 'end_col' must exist in each line. 
+    - 'strand_col' is optional, any line without it will be assumed to be '+'
+    - if 'lens' is provided bitset sizes will be looked up from it, otherwise
+      chromosomes will be assumed to be the maximum size
+    """
+    last_chrom = None
+    last_bitset = None
+    bitsets = dict() 
+    for line in f:
+        if line.startswith("#") or line.isspace():
+            continue
+        fields = line.split()
+        strand = "+"
+        if len(fields) > strand_col:
+            if fields[strand_col] == "-": strand = "-"
+        chrom = fields[chrom_col]
+        if chrom != last_chrom:
+            if chrom not in bitsets:
+                if chrom in lens:
+                    size = lens[chrom]
+                else:
+                    size = MAX
+                bitsets[chrom] = BinnedBitSet( size ) 
+            last_chrom = chrom
+            last_bitset = bitsets[chrom]
+        start, end = int( fields[start_col] ), int( fields[end_col] )
+        if upstream_pad: start = max( 0, start - upstream_pad )
+        if downstream_pad: end = min( size, end + downstream_pad )
+        if start > end: warn( "Interval start after end!" )
+        last_bitset.set_range( start, end-start )
+    return bitsets
+
+def binned_bitsets_from_bed_file( f, chrom_col=0, start_col=1, end_col=2, strand_col=5, upstream_pad=0, downstream_pad=0, lens={} ):
+    """
+    Read a file into a dictionary of bitsets. The defaults arguments 
+    
+    - 'f' should be a file like object (or any iterable containing strings)
+    - 'chrom_col', 'start_col', and 'end_col' must exist in each line. 
+    - 'strand_col' is optional, any line without it will be assumed to be '+'
+    - if 'lens' is provided bitset sizes will be looked up from it, otherwise
+      chromosomes will be assumed to be the maximum size
+    """
+    last_chrom = None
+    last_bitset = None
+    bitsets = dict() 
+    offset = 0
+    for line in f:
+        if line.startswith("#") or line.isspace():
+            continue
+        # Ignore browser lines completely
+        if line.startswith( "browser" ):
+            continue
+        # Need to check track lines due to the offset 
+        if line.startswith( "track" ):
+            m = re.search( "offset=(\d+)", line )
+            if m and m.group( 1 ):
+                offset = int( m.group(1) )
+            continue
+        fields = line.split()
+        strand = "+"
+        if len(fields) > strand_col:
+            if fields[strand_col] == "-": strand = "-"
+        chrom = fields[chrom_col]
+        if chrom != last_chrom:
+            if chrom not in bitsets:
+                if chrom in lens:
+                    size = lens[chrom]
+                else:
+                    size = MAX
+                bitsets[chrom] = BinnedBitSet( size ) 
+            last_chrom = chrom
+            last_bitset = bitsets[chrom]
+        start, end = int( fields[start_col] ) + offset, int( fields[end_col] ) + offset
+        ## # Switch to '+' strand coordinates if not already
+        ## if strand == '-':
+        ##     start = size - end
+        ##     end = size - start
+        if upstream_pad: start = max( 0, start - upstream_pad )
+        if downstream_pad: end = min( size, end + downstream_pad )
+        if start > end: warn( "Interval start after end!" )
+        last_bitset.set_range( start, end-start )
+    return bitsets
+
+def binned_bitsets_proximity( f, chrom_col=0, start_col=1, end_col=2, strand_col=5, upstream=0, downstream=0 ):
+    """Read a file into a dictionary of bitsets"""
+    last_chrom = None
+    last_bitset = None
+    bitsets = dict()
+    for line in f:
+        if line.startswith("#"): continue
+#        print "input=%s" % ( line ),
+        fields = line.split()
+        strand = "+"
+        if len(fields) >= strand_col + 1:
+            if fields[strand_col] == "-": strand = "-"
+        chrom = fields[chrom_col]
+        if chrom != last_chrom:
+            if chrom not in bitsets:
+                bitsets[chrom] = BinnedBitSet( MAX )
+            last_chrom = chrom
+            last_bitset = bitsets[chrom]
+        start, end = int( fields[start_col] ), int( fields[end_col] )
+        if strand == "+":
+            if upstream: start = max( 0, start - upstream )
+            if downstream: end = min( MAX, end + downstream )
+        if strand == "-":
+            if upstream: end = min( MAX, end + upstream )
+            if downstream: start = max( 0, start - downstream )
+#        print "set: start=%d\tend=%d" % ( start, end )
+        if end-start > 0:
+            last_bitset.set_range( start, end-start )
+    return bitsets
+
+def binned_bitsets_from_list( list=[] ):
+    """Read a list into a dictionary of bitsets"""
+    last_chrom = None
+    last_bitset = None
+    bitsets = dict()
+    for l in list:
+        chrom = l[0]
+        if chrom != last_chrom:
+            if chrom not in bitsets:
+                bitsets[chrom] = BinnedBitSet(MAX)
+            last_chrom = chrom
+            last_bitset = bitsets[chrom]
+        start, end = int( l[1] ), int( l[2] )
+        last_bitset.set_range( start, end - start )
+    return bitsets
+
+def binned_bitsets_by_chrom( f, chrom, chrom_col=0, start_col=1, end_col=2):
+    """Read a file by chrom name into a bitset"""
+    bitset = BinnedBitSet( MAX )
+    for line in f:
+        if line.startswith("#"): continue
+        fields = line.split()
+        if fields[chrom_col] == chrom:
+            start, end = int( fields[start_col] ), int( fields[end_col] )
+            bitset.set_range( start, end-start )
+    return bitset
diff --git a/lib/bx/bitset_tests.py b/lib/bx/bitset_tests.py
new file mode 100644
index 0000000..9413fe2
--- /dev/null
+++ b/lib/bx/bitset_tests.py
@@ -0,0 +1,112 @@
+"""
+Tests for `bx.bitset`.
+"""
+
+import bx.bitset
+import unittest
+
+class AbstractTests( object ):
+
+    def assert_bits( self, bits, list ):
+        assert bits.size == len( list ), "Bitset size and verification list size do not match"
+        for i in range( bits.size ):
+            self.assertEquals( bits[i], list[i] )
+
+    def test_overflow_create( self ):
+        self.assertRaises( ValueError, self.new_bits, 4000000000 )
+        
+    def test_overflow_access( self ):
+        bits = self.new_bits( 100 )
+        self.assertRaises( IndexError, bits.set, -5 )
+        self.assertRaises( IndexError, bits.set, 110 )
+
+    def test_access( self ):
+        # Create and assert empty
+        bits = self.new_bits( 100 )
+        l = [ 0 ] * 100
+        self.assert_bits( bits, l )
+        # Set some positions
+        for pos in ( 11, 14, 70, 16 ):
+            bits.set( pos )
+            l[ pos ] = 1
+        # Clear some positions
+        for pos in ( 14, 80, 16 ):
+            bits.clear( pos )
+            l[ pos ] = 0
+        self.assert_bits( bits, l )
+
+    def test_range_access( self ):
+        # Create and assert empty
+        bits = self.new_bits( 100 )
+        l = [ 0 ] * 100
+        self.assert_bits( bits, l )
+        # Set some positions
+        for b, e in ( ( 11, 14 ), (20,75), (90,99) ):
+            bits.set_range( b, e-b)
+            for pos in range( b, e ): l[ pos ] = 1
+        self.assert_bits( bits, l )
+
+    def test_count( self ):
+        # Create and assert empty
+        bits = self.new_bits( 100 )
+        # Set some positions
+        for b, e in ( ( 11, 14 ), (20,75), (90,100) ):
+            bits.set_range( b, e-b)
+        self.assertEquals( bits.count_range( 0, 0 ), 0 )
+        self.assertEquals( bits.count_range( 0, 20 ), 3 )
+        self.assertEquals( bits.count_range( 25, 25 ), 25 )
+        self.assertEquals( bits.count_range( 80, 20 ), 10 )
+        self.assertEquals( bits.count_range( 0, 100 ), 68 )
+
+    def test_find( self ):
+        # Create and assert empty
+        bits = self.new_bits( 100 )
+        # Set some positions
+        for b, e in ( ( 11, 14 ), (20,75), (90,100) ):
+            bits.set_range( b, e-b)
+        # Next set
+        self.assertEquals( bits.next_set( 0 ), 11 )
+        self.assertEquals( bits.next_set( 13 ), 13 )
+        self.assertEquals( bits.next_set( 15 ), 20 )
+        # Next clear
+        self.assertEquals( bits.next_clear( 0 ), 0 )
+        self.assertEquals( bits.next_clear( 11 ), 14 )
+        self.assertEquals( bits.next_clear( 20 ), 75 )
+        self.assertEquals( bits.next_clear( 92 ), 100 )
+
+    def test_and( self ):
+        bits1 = self.new_bits( 100 )
+        bits2 = self.new_bits( 100 )
+        bits1.set_range( 20, 40 )
+        bits2.set_range( 50, 25 )
+        bits1.iand( bits2 )
+        l = [0]*100
+        for i in range( 50, 60 ): l[i] = 1
+        self.assert_bits( bits1, l )
+    
+    def test_or( self ):
+        bits1 = self.new_bits( 100 )
+        bits2 = self.new_bits( 100 )
+        bits1.set_range( 20, 40 )
+        bits2.set_range( 50, 25 )
+        bits1.ior( bits2 )
+        l = [0]*100
+        for i in range( 20, 75 ): l[i] = 1
+        self.assert_bits( bits1, l )
+        
+    def test_not( self ):
+        bits = self.new_bits( 100 )
+        bits.set_range( 20, 40 )
+        bits.invert()
+        l = [1]*100
+        for i in range( 20, 60 ): l[i] = 0
+        self.assert_bits( bits, l )
+        
+class BitSetTests( AbstractTests, unittest.TestCase ):
+    def new_bits( self, size ):
+        return bx.bitset.BitSet( size ) 
+
+class BinnedBitSetTests( AbstractTests, unittest.TestCase ):
+    def new_bits( self, size ):
+        granularity = size % 11 
+        return bx.bitset.BinnedBitSet( size, granularity ) 
\ No newline at end of file
diff --git a/lib/bx/bitset_utils.py b/lib/bx/bitset_utils.py
new file mode 100644
index 0000000..104dc53
--- /dev/null
+++ b/lib/bx/bitset_utils.py
@@ -0,0 +1,74 @@
+"""
+Utility functions for working with `Bitset`s and treating lists of (start,end)
+as `Bitset`s.
+"""
+
+from bx.bitset import *
+
+def bitset_intersect( ex1, ex2 ):
+    bits1 = list2bits( ex1 )
+    bits2 = list2bits( ex2 )
+    bits1.iand( bits2 )
+    return bits2list( bits1 )
+
+def bitset_subtract( ex1, ex2 ):
+    bits1 = list2bits( ex1 )
+    bits2 = list2bits( ex2 )
+    bits2.invert()
+    bits1.iand( bits2 )
+    return bits2list( bits1 )
+
+def list2bits( ex ):
+    bits = BinnedBitSet(MAX)
+    for start,end  in ex:
+        bits.set_range( start, end - start )
+    return bits
+
+def bits2list( bits ):
+    ex = []
+    end = 0
+    while 1:
+        start = bits.next_set( end )
+        if start == bits.size: break
+        end = bits.next_clear( start )
+        ex.append( (start, end) )
+    return ex
+
+def bitset_complement( exons ):
+    bits = BinnedBitSet(MAX)
+    introns = []
+    for start, end in exons:
+        bits.set_range( start, end - start )
+    bits.invert()
+
+    # only complement within the range of the list
+    ex_start = min( [a[0] for a in exons] )
+    ex_end = max( [a[1] for a in exons] )
+    end = ex_start
+    len = ex_end
+    while 1:
+            start = bits.next_set( end )
+            if start == bits.size: break
+            end = bits.next_clear( start )
+            if end > len: end = len
+            if start != end:
+                introns.append( (start,end ) )
+            if end == len: break
+    return introns 
+
+def bitset_interval_intersect( bits, istart, iend ):
+    rval = []
+    end = istart
+    len = iend
+    while 1:
+        start = bits.next_set( end )
+        if start >= len: break
+        end = bits.next_clear( start )
+        if start != end:
+            rval.append( (start,end) )
+        if end >= len: break
+    return rval
+
+def bitset_union( exons ):
+    bits = list2bits( exons )
+    return bits2list( bits )
diff --git a/lib/bx/cookbook/__init__.py b/lib/bx/cookbook/__init__.py
new file mode 100644
index 0000000..3d79703
--- /dev/null
+++ b/lib/bx/cookbook/__init__.py
@@ -0,0 +1,98 @@
+"""
+Various useful utilities, mostly taken from the ASPN Python cookbook.
+"""
+
+seq_types = type( () ), type( [] )
+
+def flatten( *args ):
+    for arg in args:
+        if type( arg ) in seq_types:
+            for elem in arg:
+                for f in flatten( elem ): 
+                    yield f
+        else:
+            yield arg
+
+def cross_lists(*sets):
+    """Return the cross product of the arguments"""
+    wheels = map(iter, sets) 
+    digits = [it.next() for it in wheels]
+    while True:
+        yield digits[:]
+        for i in range(len(digits)-1, -1, -1):
+            try:
+                digits[i] = wheels[i].next()
+                break
+            except StopIteration:
+                wheels[i] = iter(sets[i])
+                digits[i] = wheels[i].next()
+        else:
+            break
+
+# Cached / memoized methods
+
+import types
+
+def cachedmethod(function):
+    return types.MethodType(Memoize(function), None)
+
+
+class Memoize:
+    def __init__(self,function):
+        self._cache = {}
+        self._callable = function
+            
+    def __call__(self, *args, **kwds):
+        cache = self._cache
+        key = self._getKey(*args,**kwds)
+        try: return cache[key]
+        except KeyError:
+            cachedValue = cache[key] = self._callable(*args,**kwds)
+            return cachedValue
+    
+    def _getKey(self,*args,**kwds):
+        return kwds and (args, ImmutableDict(kwds)) or args    
+
+
+class memoized(object):
+   """Decorator that caches a function's return value each time it is called.
+   If called later with the same arguments, the cached value is returned, and
+   not re-evaluated.
+   """
+   def __init__(self, func):
+      self.func = func
+      self.cache = {}
+   def __call__(self, *args):
+      try:
+         return self.cache[args]
+      except KeyError:
+         self.cache[args] = value = self.func(*args)
+         return value
+      except TypeError:
+         # uncachable -- for instance, passing a list as an argument.
+         # Better to not cache than to blow up entirely.
+         return self.func(*args)
+   def __repr__(self):
+      """Return the function's docstring."""
+      return self.func.__doc__
+
+
+class ImmutableDict(dict):
+    '''A hashable dict.'''
+
+    def __init__(self,*args,**kwds):
+        dict.__init__(self,*args,**kwds)
+    def __setitem__(self,key,value):
+        raise NotImplementedError, "dict is immutable"
+    def __delitem__(self,key):
+        raise NotImplementedError, "dict is immutable"
+    def clear(self):
+        raise NotImplementedError, "dict is immutable"
+    def setdefault(self,k,default=None):
+        raise NotImplementedError, "dict is immutable"
+    def popitem(self):
+        raise NotImplementedError, "dict is immutable"
+    def update(self,other):
+        raise NotImplementedError, "dict is immutable"
+    def __hash__(self):
+        return hash(tuple(self.iteritems()))
diff --git a/lib/bx/cookbook/argparse.py b/lib/bx/cookbook/argparse.py
new file mode 100644
index 0000000..32d948c
--- /dev/null
+++ b/lib/bx/cookbook/argparse.py
@@ -0,0 +1,2362 @@
+# Author: Steven J. Bethard <steven.bethard at gmail.com>.
+
+"""Command-line parsing library
+
+This module is an optparse-inspired command-line parsing library that:
+
+    - handles both optional and positional arguments
+    - produces highly informative usage messages
+    - supports parsers that dispatch to sub-parsers
+
+The following is a simple usage example that sums integers from the
+command-line and writes the result to a file::
+
+    parser = argparse.ArgumentParser(
+        description='sum the integers at the command line')
+    parser.add_argument(
+        'integers', metavar='int', nargs='+', type=int,
+        help='an integer to be summed')
+    parser.add_argument(
+        '--log', default=sys.stdout, type=argparse.FileType('w'),
+        help='the file where the sum should be written')
+    args = parser.parse_args()
+    args.log.write('%s' % sum(args.integers))
+    args.log.close()
+
+The module contains the following public classes:
+
+    - ArgumentParser -- The main entry point for command-line parsing. As the
+        example above shows, the add_argument() method is used to populate
+        the parser with actions for optional and positional arguments. Then
+        the parse_args() method is invoked to convert the args at the
+        command-line into an object with attributes.
+
+    - ArgumentError -- The exception raised by ArgumentParser objects when
+        there are errors with the parser's actions. Errors raised while
+        parsing the command-line are caught by ArgumentParser and emitted
+        as command-line messages.
+
+    - FileType -- A factory for defining types of files to be created. As the
+        example above shows, instances of FileType are typically passed as
+        the type= argument of add_argument() calls.
+
+    - Action -- The base class for parser actions. Typically actions are
+        selected by passing strings like 'store_true' or 'append_const' to
+        the action= argument of add_argument(). However, for greater
+        customization of ArgumentParser actions, subclasses of Action may
+        be defined and passed as the action= argument.
+
+    - HelpFormatter, RawDescriptionHelpFormatter, RawTextHelpFormatter,
+        ArgumentDefaultsHelpFormatter -- Formatter classes which
+        may be passed as the formatter_class= argument to the
+        ArgumentParser constructor. HelpFormatter is the default,
+        RawDescriptionHelpFormatter and RawTextHelpFormatter tell the parser
+        not to change the formatting for help text, and
+        ArgumentDefaultsHelpFormatter adds information about argument defaults
+        to the help.
+
+All other classes in this module are considered implementation details.
+(Also note that HelpFormatter and RawDescriptionHelpFormatter are only
+considered public as object names -- the API of the formatter objects is
+still considered an implementation detail.)
+"""
+
+__version__ = '1.2.1'
+__all__ = [
+    'ArgumentParser',
+    'ArgumentError',
+    'ArgumentTypeError',
+    'FileType',
+    'HelpFormatter',
+    'ArgumentDefaultsHelpFormatter',
+    'RawDescriptionHelpFormatter',
+    'RawTextHelpFormatter',
+    'Namespace',
+    'Action',
+    'ONE_OR_MORE',
+    'OPTIONAL',
+    'PARSER',
+    'REMAINDER',
+    'SUPPRESS',
+    'ZERO_OR_MORE',
+]
+
+
+import copy as _copy
+import os as _os
+import re as _re
+import sys as _sys
+import textwrap as _textwrap
+
+from gettext import gettext as _
+
+try:
+    set
+except NameError:
+    # for python < 2.4 compatibility (sets module is there since 2.3):
+    from sets import Set as set
+
+try:
+    basestring
+except NameError:
+    basestring = str
+
+try:
+    sorted
+except NameError:
+    # for python < 2.4 compatibility:
+    def sorted(iterable, reverse=False):
+        result = list(iterable)
+        result.sort()
+        if reverse:
+            result.reverse()
+        return result
+
+
+def _callable(obj):
+    return hasattr(obj, '__call__') or hasattr(obj, '__bases__')
+
+
+SUPPRESS = '==SUPPRESS=='
+
+OPTIONAL = '?'
+ZERO_OR_MORE = '*'
+ONE_OR_MORE = '+'
+PARSER = 'A...'
+REMAINDER = '...'
+_UNRECOGNIZED_ARGS_ATTR = '_unrecognized_args'
+
+# =============================
+# Utility functions and classes
+# =============================
+
+class _AttributeHolder(object):
+    """Abstract base class that provides __repr__.
+
+    The __repr__ method returns a string in the format::
+        ClassName(attr=name, attr=name, ...)
+    The attributes are determined either by a class-level attribute,
+    '_kwarg_names', or by inspecting the instance __dict__.
+    """
+
+    def __repr__(self):
+        type_name = type(self).__name__
+        arg_strings = []
+        for arg in self._get_args():
+            arg_strings.append(repr(arg))
+        for name, value in self._get_kwargs():
+            arg_strings.append('%s=%r' % (name, value))
+        return '%s(%s)' % (type_name, ', '.join(arg_strings))
+
+    def _get_kwargs(self):
+        return sorted(self.__dict__.items())
+
+    def _get_args(self):
+        return []
+
+
+def _ensure_value(namespace, name, value):
+    if getattr(namespace, name, None) is None:
+        setattr(namespace, name, value)
+    return getattr(namespace, name)
+
+
+# ===============
+# Formatting Help
+# ===============
+
+class HelpFormatter(object):
+    """Formatter for generating usage messages and argument help strings.
+
+    Only the name of this class is considered a public API. All the methods
+    provided by the class are considered an implementation detail.
+    """
+
+    def __init__(self,
+                 prog,
+                 indent_increment=2,
+                 max_help_position=24,
+                 width=None):
+
+        # default setting for width
+        if width is None:
+            try:
+                width = int(_os.environ['COLUMNS'])
+            except (KeyError, ValueError):
+                width = 80
+            width -= 2
+
+        self._prog = prog
+        self._indent_increment = indent_increment
+        self._max_help_position = max_help_position
+        self._width = width
+
+        self._current_indent = 0
+        self._level = 0
+        self._action_max_length = 0
+
+        self._root_section = self._Section(self, None)
+        self._current_section = self._root_section
+
+        self._whitespace_matcher = _re.compile(r'\s+')
+        self._long_break_matcher = _re.compile(r'\n\n\n+')
+
+    # ===============================
+    # Section and indentation methods
+    # ===============================
+    def _indent(self):
+        self._current_indent += self._indent_increment
+        self._level += 1
+
+    def _dedent(self):
+        self._current_indent -= self._indent_increment
+        assert self._current_indent >= 0, 'Indent decreased below 0.'
+        self._level -= 1
+
+    class _Section(object):
+
+        def __init__(self, formatter, parent, heading=None):
+            self.formatter = formatter
+            self.parent = parent
+            self.heading = heading
+            self.items = []
+
+        def format_help(self):
+            # format the indented section
+            if self.parent is not None:
+                self.formatter._indent()
+            join = self.formatter._join_parts
+            for func, args in self.items:
+                func(*args)
+            item_help = join([func(*args) for func, args in self.items])
+            if self.parent is not None:
+                self.formatter._dedent()
+
+            # return nothing if the section was empty
+            if not item_help:
+                return ''
+
+            # add the heading if the section was non-empty
+            if self.heading is not SUPPRESS and self.heading is not None:
+                current_indent = self.formatter._current_indent
+                heading = '%*s%s:\n' % (current_indent, '', self.heading)
+            else:
+                heading = ''
+
+            # join the section-initial newline, the heading and the help
+            return join(['\n', heading, item_help, '\n'])
+
+    def _add_item(self, func, args):
+        self._current_section.items.append((func, args))
+
+    # ========================
+    # Message building methods
+    # ========================
+    def start_section(self, heading):
+        self._indent()
+        section = self._Section(self, self._current_section, heading)
+        self._add_item(section.format_help, [])
+        self._current_section = section
+
+    def end_section(self):
+        self._current_section = self._current_section.parent
+        self._dedent()
+
+    def add_text(self, text):
+        if text is not SUPPRESS and text is not None:
+            self._add_item(self._format_text, [text])
+
+    def add_usage(self, usage, actions, groups, prefix=None):
+        if usage is not SUPPRESS:
+            args = usage, actions, groups, prefix
+            self._add_item(self._format_usage, args)
+
+    def add_argument(self, action):
+        if action.help is not SUPPRESS:
+
+            # find all invocations
+            get_invocation = self._format_action_invocation
+            invocations = [get_invocation(action)]
+            for subaction in self._iter_indented_subactions(action):
+                invocations.append(get_invocation(subaction))
+
+            # update the maximum item length
+            invocation_length = max([len(s) for s in invocations])
+            action_length = invocation_length + self._current_indent
+            self._action_max_length = max(self._action_max_length,
+                                          action_length)
+
+            # add the item to the list
+            self._add_item(self._format_action, [action])
+
+    def add_arguments(self, actions):
+        for action in actions:
+            self.add_argument(action)
+
+    # =======================
+    # Help-formatting methods
+    # =======================
+    def format_help(self):
+        help = self._root_section.format_help()
+        if help:
+            help = self._long_break_matcher.sub('\n\n', help)
+            help = help.strip('\n') + '\n'
+        return help
+
+    def _join_parts(self, part_strings):
+        return ''.join([part
+                        for part in part_strings
+                        if part and part is not SUPPRESS])
+
+    def _format_usage(self, usage, actions, groups, prefix):
+        if prefix is None:
+            prefix = _('usage: ')
+
+        # if usage is specified, use that
+        if usage is not None:
+            usage = usage % dict(prog=self._prog)
+
+        # if no optionals or positionals are available, usage is just prog
+        elif usage is None and not actions:
+            usage = '%(prog)s' % dict(prog=self._prog)
+
+        # if optionals and positionals are available, calculate usage
+        elif usage is None:
+            prog = '%(prog)s' % dict(prog=self._prog)
+
+            # split optionals from positionals
+            optionals = []
+            positionals = []
+            for action in actions:
+                if action.option_strings:
+                    optionals.append(action)
+                else:
+                    positionals.append(action)
+
+            # build full usage string
+            format = self._format_actions_usage
+            action_usage = format(optionals + positionals, groups)
+            usage = ' '.join([s for s in [prog, action_usage] if s])
+
+            # wrap the usage parts if it's too long
+            text_width = self._width - self._current_indent
+            if len(prefix) + len(usage) > text_width:
+
+                # break usage into wrappable parts
+                part_regexp = r'\(.*?\)+|\[.*?\]+|\S+'
+                opt_usage = format(optionals, groups)
+                pos_usage = format(positionals, groups)
+                opt_parts = _re.findall(part_regexp, opt_usage)
+                pos_parts = _re.findall(part_regexp, pos_usage)
+                assert ' '.join(opt_parts) == opt_usage
+                assert ' '.join(pos_parts) == pos_usage
+
+                # helper for wrapping lines
+                def get_lines(parts, indent, prefix=None):
+                    lines = []
+                    line = []
+                    if prefix is not None:
+                        line_len = len(prefix) - 1
+                    else:
+                        line_len = len(indent) - 1
+                    for part in parts:
+                        if line_len + 1 + len(part) > text_width:
+                            lines.append(indent + ' '.join(line))
+                            line = []
+                            line_len = len(indent) - 1
+                        line.append(part)
+                        line_len += len(part) + 1
+                    if line:
+                        lines.append(indent + ' '.join(line))
+                    if prefix is not None:
+                        lines[0] = lines[0][len(indent):]
+                    return lines
+
+                # if prog is short, follow it with optionals or positionals
+                if len(prefix) + len(prog) <= 0.75 * text_width:
+                    indent = ' ' * (len(prefix) + len(prog) + 1)
+                    if opt_parts:
+                        lines = get_lines([prog] + opt_parts, indent, prefix)
+                        lines.extend(get_lines(pos_parts, indent))
+                    elif pos_parts:
+                        lines = get_lines([prog] + pos_parts, indent, prefix)
+                    else:
+                        lines = [prog]
+
+                # if prog is long, put it on its own line
+                else:
+                    indent = ' ' * len(prefix)
+                    parts = opt_parts + pos_parts
+                    lines = get_lines(parts, indent)
+                    if len(lines) > 1:
+                        lines = []
+                        lines.extend(get_lines(opt_parts, indent))
+                        lines.extend(get_lines(pos_parts, indent))
+                    lines = [prog] + lines
+
+                # join lines into usage
+                usage = '\n'.join(lines)
+
+        # prefix with 'usage:'
+        return '%s%s\n\n' % (prefix, usage)
+
+    def _format_actions_usage(self, actions, groups):
+        # find group indices and identify actions in groups
+        group_actions = set()
+        inserts = {}
+        for group in groups:
+            try:
+                start = actions.index(group._group_actions[0])
+            except ValueError:
+                continue
+            else:
+                end = start + len(group._group_actions)
+                if actions[start:end] == group._group_actions:
+                    for action in group._group_actions:
+                        group_actions.add(action)
+                    if not group.required:
+                        if start in inserts:
+                            inserts[start] += ' ['
+                        else:
+                            inserts[start] = '['
+                        inserts[end] = ']'
+                    else:
+                        if start in inserts:
+                            inserts[start] += ' ('
+                        else:
+                            inserts[start] = '('
+                        inserts[end] = ')'
+                    for i in range(start + 1, end):
+                        inserts[i] = '|'
+
+        # collect all actions format strings
+        parts = []
+        for i, action in enumerate(actions):
+
+            # suppressed arguments are marked with None
+            # remove | separators for suppressed arguments
+            if action.help is SUPPRESS:
+                parts.append(None)
+                if inserts.get(i) == '|':
+                    inserts.pop(i)
+                elif inserts.get(i + 1) == '|':
+                    inserts.pop(i + 1)
+
+            # produce all arg strings
+            elif not action.option_strings:
+                part = self._format_args(action, action.dest)
+
+                # if it's in a group, strip the outer []
+                if action in group_actions:
+                    if part[0] == '[' and part[-1] == ']':
+                        part = part[1:-1]
+
+                # add the action string to the list
+                parts.append(part)
+
+            # produce the first way to invoke the option in brackets
+            else:
+                option_string = action.option_strings[0]
+
+                # if the Optional doesn't take a value, format is:
+                #    -s or --long
+                if action.nargs == 0:
+                    part = '%s' % option_string
+
+                # if the Optional takes a value, format is:
+                #    -s ARGS or --long ARGS
+                else:
+                    default = action.dest.upper()
+                    args_string = self._format_args(action, default)
+                    part = '%s %s' % (option_string, args_string)
+
+                # make it look optional if it's not required or in a group
+                if not action.required and action not in group_actions:
+                    part = '[%s]' % part
+
+                # add the action string to the list
+                parts.append(part)
+
+        # insert things at the necessary indices
+        for i in sorted(inserts, reverse=True):
+            parts[i:i] = [inserts[i]]
+
+        # join all the action items with spaces
+        text = ' '.join([item for item in parts if item is not None])
+
+        # clean up separators for mutually exclusive groups
+        open = r'[\[(]'
+        close = r'[\])]'
+        text = _re.sub(r'(%s) ' % open, r'\1', text)
+        text = _re.sub(r' (%s)' % close, r'\1', text)
+        text = _re.sub(r'%s *%s' % (open, close), r'', text)
+        text = _re.sub(r'\(([^|]*)\)', r'\1', text)
+        text = text.strip()
+
+        # return the text
+        return text
+
+    def _format_text(self, text):
+        if '%(prog)' in text:
+            text = text % dict(prog=self._prog)
+        text_width = self._width - self._current_indent
+        indent = ' ' * self._current_indent
+        return self._fill_text(text, text_width, indent) + '\n\n'
+
+    def _format_action(self, action):
+        # determine the required width and the entry label
+        help_position = min(self._action_max_length + 2,
+                            self._max_help_position)
+        help_width = self._width - help_position
+        action_width = help_position - self._current_indent - 2
+        action_header = self._format_action_invocation(action)
+
+        # ho nelp; start on same line and add a final newline
+        if not action.help:
+            tup = self._current_indent, '', action_header
+            action_header = '%*s%s\n' % tup
+
+        # short action name; start on the same line and pad two spaces
+        elif len(action_header) <= action_width:
+            tup = self._current_indent, '', action_width, action_header
+            action_header = '%*s%-*s  ' % tup
+            indent_first = 0
+
+        # long action name; start on the next line
+        else:
+            tup = self._current_indent, '', action_header
+            action_header = '%*s%s\n' % tup
+            indent_first = help_position
+
+        # collect the pieces of the action help
+        parts = [action_header]
+
+        # if there was help for the action, add lines of help text
+        if action.help:
+            help_text = self._expand_help(action)
+            help_lines = self._split_lines(help_text, help_width)
+            parts.append('%*s%s\n' % (indent_first, '', help_lines[0]))
+            for line in help_lines[1:]:
+                parts.append('%*s%s\n' % (help_position, '', line))
+
+        # or add a newline if the description doesn't end with one
+        elif not action_header.endswith('\n'):
+            parts.append('\n')
+
+        # if there are any sub-actions, add their help as well
+        for subaction in self._iter_indented_subactions(action):
+            parts.append(self._format_action(subaction))
+
+        # return a single string
+        return self._join_parts(parts)
+
+    def _format_action_invocation(self, action):
+        if not action.option_strings:
+            metavar, = self._metavar_formatter(action, action.dest)(1)
+            return metavar
+
+        else:
+            parts = []
+
+            # if the Optional doesn't take a value, format is:
+            #    -s, --long
+            if action.nargs == 0:
+                parts.extend(action.option_strings)
+
+            # if the Optional takes a value, format is:
+            #    -s ARGS, --long ARGS
+            else:
+                default = action.dest.upper()
+                args_string = self._format_args(action, default)
+                for option_string in action.option_strings:
+                    parts.append('%s %s' % (option_string, args_string))
+
+            return ', '.join(parts)
+
+    def _metavar_formatter(self, action, default_metavar):
+        if action.metavar is not None:
+            result = action.metavar
+        elif action.choices is not None:
+            choice_strs = [str(choice) for choice in action.choices]
+            result = '{%s}' % ','.join(choice_strs)
+        else:
+            result = default_metavar
+
+        def format(tuple_size):
+            if isinstance(result, tuple):
+                return result
+            else:
+                return (result, ) * tuple_size
+        return format
+
+    def _format_args(self, action, default_metavar):
+        get_metavar = self._metavar_formatter(action, default_metavar)
+        if action.nargs is None:
+            result = '%s' % get_metavar(1)
+        elif action.nargs == OPTIONAL:
+            result = '[%s]' % get_metavar(1)
+        elif action.nargs == ZERO_OR_MORE:
+            result = '[%s [%s ...]]' % get_metavar(2)
+        elif action.nargs == ONE_OR_MORE:
+            result = '%s [%s ...]' % get_metavar(2)
+        elif action.nargs == REMAINDER:
+            result = '...'
+        elif action.nargs == PARSER:
+            result = '%s ...' % get_metavar(1)
+        else:
+            formats = ['%s' for _ in range(action.nargs)]
+            result = ' '.join(formats) % get_metavar(action.nargs)
+        return result
+
+    def _expand_help(self, action):
+        params = dict(vars(action), prog=self._prog)
+        for name in list(params):
+            if params[name] is SUPPRESS:
+                del params[name]
+        for name in list(params):
+            if hasattr(params[name], '__name__'):
+                params[name] = params[name].__name__
+        if params.get('choices') is not None:
+            choices_str = ', '.join([str(c) for c in params['choices']])
+            params['choices'] = choices_str
+        return self._get_help_string(action) % params
+
+    def _iter_indented_subactions(self, action):
+        try:
+            get_subactions = action._get_subactions
+        except AttributeError:
+            pass
+        else:
+            self._indent()
+            for subaction in get_subactions():
+                yield subaction
+            self._dedent()
+
+    def _split_lines(self, text, width):
+        text = self._whitespace_matcher.sub(' ', text).strip()
+        return _textwrap.wrap(text, width)
+
+    def _fill_text(self, text, width, indent):
+        text = self._whitespace_matcher.sub(' ', text).strip()
+        return _textwrap.fill(text, width, initial_indent=indent,
+                                           subsequent_indent=indent)
+
+    def _get_help_string(self, action):
+        return action.help
+
+
+class RawDescriptionHelpFormatter(HelpFormatter):
+    """Help message formatter which retains any formatting in descriptions.
+
+    Only the name of this class is considered a public API. All the methods
+    provided by the class are considered an implementation detail.
+    """
+
+    def _fill_text(self, text, width, indent):
+        return ''.join([indent + line for line in text.splitlines(True)])
+
+
+class RawTextHelpFormatter(RawDescriptionHelpFormatter):
+    """Help message formatter which retains formatting of all help text.
+
+    Only the name of this class is considered a public API. All the methods
+    provided by the class are considered an implementation detail.
+    """
+
+    def _split_lines(self, text, width):
+        return text.splitlines()
+
+
+class ArgumentDefaultsHelpFormatter(HelpFormatter):
+    """Help message formatter which adds default values to argument help.
+
+    Only the name of this class is considered a public API. All the methods
+    provided by the class are considered an implementation detail.
+    """
+
+    def _get_help_string(self, action):
+        help = action.help
+        if '%(default)' not in action.help:
+            if action.default is not SUPPRESS:
+                defaulting_nargs = [OPTIONAL, ZERO_OR_MORE]
+                if action.option_strings or action.nargs in defaulting_nargs:
+                    help += ' (default: %(default)s)'
+        return help
+
+
+# =====================
+# Options and Arguments
+# =====================
+
+def _get_action_name(argument):
+    if argument is None:
+        return None
+    elif argument.option_strings:
+        return  '/'.join(argument.option_strings)
+    elif argument.metavar not in (None, SUPPRESS):
+        return argument.metavar
+    elif argument.dest not in (None, SUPPRESS):
+        return argument.dest
+    else:
+        return None
+
+
+class ArgumentError(Exception):
+    """An error from creating or using an argument (optional or positional).
+
+    The string value of this exception is the message, augmented with
+    information about the argument that caused it.
+    """
+
+    def __init__(self, argument, message):
+        self.argument_name = _get_action_name(argument)
+        self.message = message
+
+    def __str__(self):
+        if self.argument_name is None:
+            format = '%(message)s'
+        else:
+            format = 'argument %(argument_name)s: %(message)s'
+        return format % dict(message=self.message,
+                             argument_name=self.argument_name)
+
+
+class ArgumentTypeError(Exception):
+    """An error from trying to convert a command line string to a type."""
+    pass
+
+
+# ==============
+# Action classes
+# ==============
+
+class Action(_AttributeHolder):
+    """Information about how to convert command line strings to Python objects.
+
+    Action objects are used by an ArgumentParser to represent the information
+    needed to parse a single argument from one or more strings from the
+    command line. The keyword arguments to the Action constructor are also
+    all attributes of Action instances.
+
+    Keyword Arguments:
+
+        - option_strings -- A list of command-line option strings which
+            should be associated with this action.
+
+        - dest -- The name of the attribute to hold the created object(s)
+
+        - nargs -- The number of command-line arguments that should be
+            consumed. By default, one argument will be consumed and a single
+            value will be produced.  Other values include:
+                - N (an integer) consumes N arguments (and produces a list)
+                - '?' consumes zero or one arguments
+                - '*' consumes zero or more arguments (and produces a list)
+                - '+' consumes one or more arguments (and produces a list)
+            Note that the difference between the default and nargs=1 is that
+            with the default, a single value will be produced, while with
+            nargs=1, a list containing a single value will be produced.
+
+        - const -- The value to be produced if the option is specified and the
+            option uses an action that takes no values.
+
+        - default -- The value to be produced if the option is not specified.
+
+        - type -- The type which the command-line arguments should be converted
+            to, should be one of 'string', 'int', 'float', 'complex' or a
+            callable object that accepts a single string argument. If None,
+            'string' is assumed.
+
+        - choices -- A container of values that should be allowed. If not None,
+            after a command-line argument has been converted to the appropriate
+            type, an exception will be raised if it is not a member of this
+            collection.
+
+        - required -- True if the action must always be specified at the
+            command line. This is only meaningful for optional command-line
+            arguments.
+
+        - help -- The help string describing the argument.
+
+        - metavar -- The name to be used for the option's argument with the
+            help string. If None, the 'dest' value will be used as the name.
+    """
+
+    def __init__(self,
+                 option_strings,
+                 dest,
+                 nargs=None,
+                 const=None,
+                 default=None,
+                 type=None,
+                 choices=None,
+                 required=False,
+                 help=None,
+                 metavar=None):
+        self.option_strings = option_strings
+        self.dest = dest
+        self.nargs = nargs
+        self.const = const
+        self.default = default
+        self.type = type
+        self.choices = choices
+        self.required = required
+        self.help = help
+        self.metavar = metavar
+
+    def _get_kwargs(self):
+        names = [
+            'option_strings',
+            'dest',
+            'nargs',
+            'const',
+            'default',
+            'type',
+            'choices',
+            'help',
+            'metavar',
+        ]
+        return [(name, getattr(self, name)) for name in names]
+
+    def __call__(self, parser, namespace, values, option_string=None):
+        raise NotImplementedError(_('.__call__() not defined'))
+
+
+class _StoreAction(Action):
+
+    def __init__(self,
+                 option_strings,
+                 dest,
+                 nargs=None,
+                 const=None,
+                 default=None,
+                 type=None,
+                 choices=None,
+                 required=False,
+                 help=None,
+                 metavar=None):
+        if nargs == 0:
+            raise ValueError('nargs for store actions must be > 0; if you '
+                             'have nothing to store, actions such as store '
+                             'true or store const may be more appropriate')
+        if const is not None and nargs != OPTIONAL:
+            raise ValueError('nargs must be %r to supply const' % OPTIONAL)
+        super(_StoreAction, self).__init__(
+            option_strings=option_strings,
+            dest=dest,
+            nargs=nargs,
+            const=const,
+            default=default,
+            type=type,
+            choices=choices,
+            required=required,
+            help=help,
+            metavar=metavar)
+
+    def __call__(self, parser, namespace, values, option_string=None):
+        setattr(namespace, self.dest, values)
+
+
+class _StoreConstAction(Action):
+
+    def __init__(self,
+                 option_strings,
+                 dest,
+                 const,
+                 default=None,
+                 required=False,
+                 help=None,
+                 metavar=None):
+        super(_StoreConstAction, self).__init__(
+            option_strings=option_strings,
+            dest=dest,
+            nargs=0,
+            const=const,
+            default=default,
+            required=required,
+            help=help)
+
+    def __call__(self, parser, namespace, values, option_string=None):
+        setattr(namespace, self.dest, self.const)
+
+
+class _StoreTrueAction(_StoreConstAction):
+
+    def __init__(self,
+                 option_strings,
+                 dest,
+                 default=False,
+                 required=False,
+                 help=None):
+        super(_StoreTrueAction, self).__init__(
+            option_strings=option_strings,
+            dest=dest,
+            const=True,
+            default=default,
+            required=required,
+            help=help)
+
+
+class _StoreFalseAction(_StoreConstAction):
+
+    def __init__(self,
+                 option_strings,
+                 dest,
+                 default=True,
+                 required=False,
+                 help=None):
+        super(_StoreFalseAction, self).__init__(
+            option_strings=option_strings,
+            dest=dest,
+            const=False,
+            default=default,
+            required=required,
+            help=help)
+
+
+class _AppendAction(Action):
+
+    def __init__(self,
+                 option_strings,
+                 dest,
+                 nargs=None,
+                 const=None,
+                 default=None,
+                 type=None,
+                 choices=None,
+                 required=False,
+                 help=None,
+                 metavar=None):
+        if nargs == 0:
+            raise ValueError('nargs for append actions must be > 0; if arg '
+                             'strings are not supplying the value to append, '
+                             'the append const action may be more appropriate')
+        if const is not None and nargs != OPTIONAL:
+            raise ValueError('nargs must be %r to supply const' % OPTIONAL)
+        super(_AppendAction, self).__init__(
+            option_strings=option_strings,
+            dest=dest,
+            nargs=nargs,
+            const=const,
+            default=default,
+            type=type,
+            choices=choices,
+            required=required,
+            help=help,
+            metavar=metavar)
+
+    def __call__(self, parser, namespace, values, option_string=None):
+        items = _copy.copy(_ensure_value(namespace, self.dest, []))
+        items.append(values)
+        setattr(namespace, self.dest, items)
+
+
+class _AppendConstAction(Action):
+
+    def __init__(self,
+                 option_strings,
+                 dest,
+                 const,
+                 default=None,
+                 required=False,
+                 help=None,
+                 metavar=None):
+        super(_AppendConstAction, self).__init__(
+            option_strings=option_strings,
+            dest=dest,
+            nargs=0,
+            const=const,
+            default=default,
+            required=required,
+            help=help,
+            metavar=metavar)
+
+    def __call__(self, parser, namespace, values, option_string=None):
+        items = _copy.copy(_ensure_value(namespace, self.dest, []))
+        items.append(self.const)
+        setattr(namespace, self.dest, items)
+
+
+class _CountAction(Action):
+
+    def __init__(self,
+                 option_strings,
+                 dest,
+                 default=None,
+                 required=False,
+                 help=None):
+        super(_CountAction, self).__init__(
+            option_strings=option_strings,
+            dest=dest,
+            nargs=0,
+            default=default,
+            required=required,
+            help=help)
+
+    def __call__(self, parser, namespace, values, option_string=None):
+        new_count = _ensure_value(namespace, self.dest, 0) + 1
+        setattr(namespace, self.dest, new_count)
+
+
+class _HelpAction(Action):
+
+    def __init__(self,
+                 option_strings,
+                 dest=SUPPRESS,
+                 default=SUPPRESS,
+                 help=None):
+        super(_HelpAction, self).__init__(
+            option_strings=option_strings,
+            dest=dest,
+            default=default,
+            nargs=0,
+            help=help)
+
+    def __call__(self, parser, namespace, values, option_string=None):
+        parser.print_help()
+        parser.exit()
+
+
+class _VersionAction(Action):
+
+    def __init__(self,
+                 option_strings,
+                 version=None,
+                 dest=SUPPRESS,
+                 default=SUPPRESS,
+                 help="show program's version number and exit"):
+        super(_VersionAction, self).__init__(
+            option_strings=option_strings,
+            dest=dest,
+            default=default,
+            nargs=0,
+            help=help)
+        self.version = version
+
+    def __call__(self, parser, namespace, values, option_string=None):
+        version = self.version
+        if version is None:
+            version = parser.version
+        formatter = parser._get_formatter()
+        formatter.add_text(version)
+        parser.exit(message=formatter.format_help())
+
+
+class _SubParsersAction(Action):
+
+    class _ChoicesPseudoAction(Action):
+
+        def __init__(self, name, help):
+            sup = super(_SubParsersAction._ChoicesPseudoAction, self)
+            sup.__init__(option_strings=[], dest=name, help=help)
+
+    def __init__(self,
+                 option_strings,
+                 prog,
+                 parser_class,
+                 dest=SUPPRESS,
+                 help=None,
+                 metavar=None):
+
+        self._prog_prefix = prog
+        self._parser_class = parser_class
+        self._name_parser_map = {}
+        self._choices_actions = []
+
+        super(_SubParsersAction, self).__init__(
+            option_strings=option_strings,
+            dest=dest,
+            nargs=PARSER,
+            choices=self._name_parser_map,
+            help=help,
+            metavar=metavar)
+
+    def add_parser(self, name, **kwargs):
+        # set prog from the existing prefix
+        if kwargs.get('prog') is None:
+            kwargs['prog'] = '%s %s' % (self._prog_prefix, name)
+
+        # create a pseudo-action to hold the choice help
+        if 'help' in kwargs:
+            help = kwargs.pop('help')
+            choice_action = self._ChoicesPseudoAction(name, help)
+            self._choices_actions.append(choice_action)
+
+        # create the parser and add it to the map
+        parser = self._parser_class(**kwargs)
+        self._name_parser_map[name] = parser
+        return parser
+
+    def _get_subactions(self):
+        return self._choices_actions
+
+    def __call__(self, parser, namespace, values, option_string=None):
+        parser_name = values[0]
+        arg_strings = values[1:]
+
+        # set the parser name if requested
+        if self.dest is not SUPPRESS:
+            setattr(namespace, self.dest, parser_name)
+
+        # select the parser
+        try:
+            parser = self._name_parser_map[parser_name]
+        except KeyError:
+            tup = parser_name, ', '.join(self._name_parser_map)
+            msg = _('unknown parser %r (choices: %s)' % tup)
+            raise ArgumentError(self, msg)
+
+        # parse all the remaining options into the namespace
+        # store any unrecognized options on the object, so that the top
+        # level parser can decide what to do with them
+        namespace, arg_strings = parser.parse_known_args(arg_strings, namespace)
+        if arg_strings:
+            vars(namespace).setdefault(_UNRECOGNIZED_ARGS_ATTR, [])
+            getattr(namespace, _UNRECOGNIZED_ARGS_ATTR).extend(arg_strings)
+
+
+# ==============
+# Type classes
+# ==============
+
+class FileType(object):
+    """Factory for creating file object types
+
+    Instances of FileType are typically passed as type= arguments to the
+    ArgumentParser add_argument() method.
+
+    Keyword Arguments:
+        - mode -- A string indicating how the file is to be opened. Accepts the
+            same values as the builtin open() function.
+        - bufsize -- The file's desired buffer size. Accepts the same values as
+            the builtin open() function.
+    """
+
+    def __init__(self, mode='r', bufsize=None):
+        self._mode = mode
+        self._bufsize = bufsize
+
+    def __call__(self, string):
+        # the special argument "-" means sys.std{in,out}
+        if string == '-':
+            if 'r' in self._mode:
+                return _sys.stdin
+            elif 'w' in self._mode:
+                return _sys.stdout
+            else:
+                msg = _('argument "-" with mode %r' % self._mode)
+                raise ValueError(msg)
+
+        # all other arguments are used as file names
+        if self._bufsize:
+            return open(string, self._mode, self._bufsize)
+        else:
+            return open(string, self._mode)
+
+    def __repr__(self):
+        args = [self._mode, self._bufsize]
+        args_str = ', '.join([repr(arg) for arg in args if arg is not None])
+        return '%s(%s)' % (type(self).__name__, args_str)
+
+# ===========================
+# Optional and Positional Parsing
+# ===========================
+
+class Namespace(_AttributeHolder):
+    """Simple object for storing attributes.
+
+    Implements equality by attribute names and values, and provides a simple
+    string representation.
+    """
+
+    def __init__(self, **kwargs):
+        for name in kwargs:
+            setattr(self, name, kwargs[name])
+
+    __hash__ = None
+
+    def __eq__(self, other):
+        return vars(self) == vars(other)
+
+    def __ne__(self, other):
+        return not (self == other)
+
+    def __contains__(self, key):
+        return key in self.__dict__
+
+
+class _ActionsContainer(object):
+
+    def __init__(self,
+                 description,
+                 prefix_chars,
+                 argument_default,
+                 conflict_handler):
+        super(_ActionsContainer, self).__init__()
+
+        self.description = description
+        self.argument_default = argument_default
+        self.prefix_chars = prefix_chars
+        self.conflict_handler = conflict_handler
+
+        # set up registries
+        self._registries = {}
+
+        # register actions
+        self.register('action', None, _StoreAction)
+        self.register('action', 'store', _StoreAction)
+        self.register('action', 'store_const', _StoreConstAction)
+        self.register('action', 'store_true', _StoreTrueAction)
+        self.register('action', 'store_false', _StoreFalseAction)
+        self.register('action', 'append', _AppendAction)
+        self.register('action', 'append_const', _AppendConstAction)
+        self.register('action', 'count', _CountAction)
+        self.register('action', 'help', _HelpAction)
+        self.register('action', 'version', _VersionAction)
+        self.register('action', 'parsers', _SubParsersAction)
+
+        # raise an exception if the conflict handler is invalid
+        self._get_handler()
+
+        # action storage
+        self._actions = []
+        self._option_string_actions = {}
+
+        # groups
+        self._action_groups = []
+        self._mutually_exclusive_groups = []
+
+        # defaults storage
+        self._defaults = {}
+
+        # determines whether an "option" looks like a negative number
+        self._negative_number_matcher = _re.compile(r'^-\d+$|^-\d*\.\d+$')
+
+        # whether or not there are any optionals that look like negative
+        # numbers -- uses a list so it can be shared and edited
+        self._has_negative_number_optionals = []
+
+    # ====================
+    # Registration methods
+    # ====================
+    def register(self, registry_name, value, object):
+        registry = self._registries.setdefault(registry_name, {})
+        registry[value] = object
+
+    def _registry_get(self, registry_name, value, default=None):
+        return self._registries[registry_name].get(value, default)
+
+    # ==================================
+    # Namespace default accessor methods
+    # ==================================
+    def set_defaults(self, **kwargs):
+        self._defaults.update(kwargs)
+
+        # if these defaults match any existing arguments, replace
+        # the previous default on the object with the new one
+        for action in self._actions:
+            if action.dest in kwargs:
+                action.default = kwargs[action.dest]
+
+    def get_default(self, dest):
+        for action in self._actions:
+            if action.dest == dest and action.default is not None:
+                return action.default
+        return self._defaults.get(dest, None)
+
+
+    # =======================
+    # Adding argument actions
+    # =======================
+    def add_argument(self, *args, **kwargs):
+        """
+        add_argument(dest, ..., name=value, ...)
+        add_argument(option_string, option_string, ..., name=value, ...)
+        """
+
+        # if no positional args are supplied or only one is supplied and
+        # it doesn't look like an option string, parse a positional
+        # argument
+        chars = self.prefix_chars
+        if not args or len(args) == 1 and args[0][0] not in chars:
+            if args and 'dest' in kwargs:
+                raise ValueError('dest supplied twice for positional argument')
+            kwargs = self._get_positional_kwargs(*args, **kwargs)
+
+        # otherwise, we're adding an optional argument
+        else:
+            kwargs = self._get_optional_kwargs(*args, **kwargs)
+
+        # if no default was supplied, use the parser-level default
+        if 'default' not in kwargs:
+            dest = kwargs['dest']
+            if dest in self._defaults:
+                kwargs['default'] = self._defaults[dest]
+            elif self.argument_default is not None:
+                kwargs['default'] = self.argument_default
+
+        # create the action object, and add it to the parser
+        action_class = self._pop_action_class(kwargs)
+        if not _callable(action_class):
+            raise ValueError('unknown action "%s"' % action_class)
+        action = action_class(**kwargs)
+
+        # raise an error if the action type is not callable
+        type_func = self._registry_get('type', action.type, action.type)
+        if not _callable(type_func):
+            raise ValueError('%r is not callable' % type_func)
+
+        return self._add_action(action)
+
+    def add_argument_group(self, *args, **kwargs):
+        group = _ArgumentGroup(self, *args, **kwargs)
+        self._action_groups.append(group)
+        return group
+
+    def add_mutually_exclusive_group(self, **kwargs):
+        group = _MutuallyExclusiveGroup(self, **kwargs)
+        self._mutually_exclusive_groups.append(group)
+        return group
+
+    def _add_action(self, action):
+        # resolve any conflicts
+        self._check_conflict(action)
+
+        # add to actions list
+        self._actions.append(action)
+        action.container = self
+
+        # index the action by any option strings it has
+        for option_string in action.option_strings:
+            self._option_string_actions[option_string] = action
+
+        # set the flag if any option strings look like negative numbers
+        for option_string in action.option_strings:
+            if self._negative_number_matcher.match(option_string):
+                if not self._has_negative_number_optionals:
+                    self._has_negative_number_optionals.append(True)
+
+        # return the created action
+        return action
+
+    def _remove_action(self, action):
+        self._actions.remove(action)
+
+    def _add_container_actions(self, container):
+        # collect groups by titles
+        title_group_map = {}
+        for group in self._action_groups:
+            if group.title in title_group_map:
+                msg = _('cannot merge actions - two groups are named %r')
+                raise ValueError(msg % (group.title))
+            title_group_map[group.title] = group
+
+        # map each action to its group
+        group_map = {}
+        for group in container._action_groups:
+
+            # if a group with the title exists, use that, otherwise
+            # create a new group matching the container's group
+            if group.title not in title_group_map:
+                title_group_map[group.title] = self.add_argument_group(
+                    title=group.title,
+                    description=group.description,
+                    conflict_handler=group.conflict_handler)
+
+            # map the actions to their new group
+            for action in group._group_actions:
+                group_map[action] = title_group_map[group.title]
+
+        # add container's mutually exclusive groups
+        # NOTE: if add_mutually_exclusive_group ever gains title= and
+        # description= then this code will need to be expanded as above
+        for group in container._mutually_exclusive_groups:
+            mutex_group = self.add_mutually_exclusive_group(
+                required=group.required)
+
+            # map the actions to their new mutex group
+            for action in group._group_actions:
+                group_map[action] = mutex_group
+
+        # add all actions to this container or their group
+        for action in container._actions:
+            group_map.get(action, self)._add_action(action)
+
+    def _get_positional_kwargs(self, dest, **kwargs):
+        # make sure required is not specified
+        if 'required' in kwargs:
+            msg = _("'required' is an invalid argument for positionals")
+            raise TypeError(msg)
+
+        # mark positional arguments as required if at least one is
+        # always required
+        if kwargs.get('nargs') not in [OPTIONAL, ZERO_OR_MORE]:
+            kwargs['required'] = True
+        if kwargs.get('nargs') == ZERO_OR_MORE and 'default' not in kwargs:
+            kwargs['required'] = True
+
+        # return the keyword arguments with no option strings
+        return dict(kwargs, dest=dest, option_strings=[])
+
+    def _get_optional_kwargs(self, *args, **kwargs):
+        # determine short and long option strings
+        option_strings = []
+        long_option_strings = []
+        for option_string in args:
+            # error on strings that don't start with an appropriate prefix
+            if not option_string[0] in self.prefix_chars:
+                msg = _('invalid option string %r: '
+                        'must start with a character %r')
+                tup = option_string, self.prefix_chars
+                raise ValueError(msg % tup)
+
+            # strings starting with two prefix characters are long options
+            option_strings.append(option_string)
+            if option_string[0] in self.prefix_chars:
+                if len(option_string) > 1:
+                    if option_string[1] in self.prefix_chars:
+                        long_option_strings.append(option_string)
+
+        # infer destination, '--foo-bar' -> 'foo_bar' and '-x' -> 'x'
+        dest = kwargs.pop('dest', None)
+        if dest is None:
+            if long_option_strings:
+                dest_option_string = long_option_strings[0]
+            else:
+                dest_option_string = option_strings[0]
+            dest = dest_option_string.lstrip(self.prefix_chars)
+            if not dest:
+                msg = _('dest= is required for options like %r')
+                raise ValueError(msg % option_string)
+            dest = dest.replace('-', '_')
+
+        # return the updated keyword arguments
+        return dict(kwargs, dest=dest, option_strings=option_strings)
+
+    def _pop_action_class(self, kwargs, default=None):
+        action = kwargs.pop('action', default)
+        return self._registry_get('action', action, action)
+
+    def _get_handler(self):
+        # determine function from conflict handler string
+        handler_func_name = '_handle_conflict_%s' % self.conflict_handler
+        try:
+            return getattr(self, handler_func_name)
+        except AttributeError:
+            msg = _('invalid conflict_resolution value: %r')
+            raise ValueError(msg % self.conflict_handler)
+
+    def _check_conflict(self, action):
+
+        # find all options that conflict with this option
+        confl_optionals = []
+        for option_string in action.option_strings:
+            if option_string in self._option_string_actions:
+                confl_optional = self._option_string_actions[option_string]
+                confl_optionals.append((option_string, confl_optional))
+
+        # resolve any conflicts
+        if confl_optionals:
+            conflict_handler = self._get_handler()
+            conflict_handler(action, confl_optionals)
+
+    def _handle_conflict_error(self, action, conflicting_actions):
+        message = _('conflicting option string(s): %s')
+        conflict_string = ', '.join([option_string
+                                     for option_string, action
+                                     in conflicting_actions])
+        raise ArgumentError(action, message % conflict_string)
+
+    def _handle_conflict_resolve(self, action, conflicting_actions):
+
+        # remove all conflicting options
+        for option_string, action in conflicting_actions:
+
+            # remove the conflicting option
+            action.option_strings.remove(option_string)
+            self._option_string_actions.pop(option_string, None)
+
+            # if the option now has no option string, remove it from the
+            # container holding it
+            if not action.option_strings:
+                action.container._remove_action(action)
+
+
+class _ArgumentGroup(_ActionsContainer):
+
+    def __init__(self, container, title=None, description=None, **kwargs):
+        # add any missing keyword arguments by checking the container
+        update = kwargs.setdefault
+        update('conflict_handler', container.conflict_handler)
+        update('prefix_chars', container.prefix_chars)
+        update('argument_default', container.argument_default)
+        super_init = super(_ArgumentGroup, self).__init__
+        super_init(description=description, **kwargs)
+
+        # group attributes
+        self.title = title
+        self._group_actions = []
+
+        # share most attributes with the container
+        self._registries = container._registries
+        self._actions = container._actions
+        self._option_string_actions = container._option_string_actions
+        self._defaults = container._defaults
+        self._has_negative_number_optionals = \
+            container._has_negative_number_optionals
+
+    def _add_action(self, action):
+        action = super(_ArgumentGroup, self)._add_action(action)
+        self._group_actions.append(action)
+        return action
+
+    def _remove_action(self, action):
+        super(_ArgumentGroup, self)._remove_action(action)
+        self._group_actions.remove(action)
+
+
+class _MutuallyExclusiveGroup(_ArgumentGroup):
+
+    def __init__(self, container, required=False):
+        super(_MutuallyExclusiveGroup, self).__init__(container)
+        self.required = required
+        self._container = container
+
+    def _add_action(self, action):
+        if action.required:
+            msg = _('mutually exclusive arguments must be optional')
+            raise ValueError(msg)
+        action = self._container._add_action(action)
+        self._group_actions.append(action)
+        return action
+
+    def _remove_action(self, action):
+        self._container._remove_action(action)
+        self._group_actions.remove(action)
+
+
+class ArgumentParser(_AttributeHolder, _ActionsContainer):
+    """Object for parsing command line strings into Python objects.
+
+    Keyword Arguments:
+        - prog -- The name of the program (default: sys.argv[0])
+        - usage -- A usage message (default: auto-generated from arguments)
+        - description -- A description of what the program does
+        - epilog -- Text following the argument descriptions
+        - parents -- Parsers whose arguments should be copied into this one
+        - formatter_class -- HelpFormatter class for printing help messages
+        - prefix_chars -- Characters that prefix optional arguments
+        - fromfile_prefix_chars -- Characters that prefix files containing
+            additional arguments
+        - argument_default -- The default value for all arguments
+        - conflict_handler -- String indicating how to handle conflicts
+        - add_help -- Add a -h/-help option
+    """
+
+    def __init__(self,
+                 prog=None,
+                 usage=None,
+                 description=None,
+                 epilog=None,
+                 version=None,
+                 parents=[],
+                 formatter_class=HelpFormatter,
+                 prefix_chars='-',
+                 fromfile_prefix_chars=None,
+                 argument_default=None,
+                 conflict_handler='error',
+                 add_help=True):
+
+        if version is not None:
+            import warnings
+            warnings.warn(
+                """The "version" argument to ArgumentParser is deprecated. """
+                """Please use """
+                """"add_argument(..., action='version', version="N", ...)" """
+                """instead""", DeprecationWarning)
+
+        superinit = super(ArgumentParser, self).__init__
+        superinit(description=description,
+                  prefix_chars=prefix_chars,
+                  argument_default=argument_default,
+                  conflict_handler=conflict_handler)
+
+        # default setting for prog
+        if prog is None:
+            prog = _os.path.basename(_sys.argv[0])
+
+        self.prog = prog
+        self.usage = usage
+        self.epilog = epilog
+        self.version = version
+        self.formatter_class = formatter_class
+        self.fromfile_prefix_chars = fromfile_prefix_chars
+        self.add_help = add_help
+
+        add_group = self.add_argument_group
+        self._positionals = add_group(_('positional arguments'))
+        self._optionals = add_group(_('optional arguments'))
+        self._subparsers = None
+
+        # register types
+        def identity(string):
+            return string
+        self.register('type', None, identity)
+
+        # add help and version arguments if necessary
+        # (using explicit default to override global argument_default)
+        if '-' in prefix_chars:
+            default_prefix = '-'
+        else:
+            default_prefix = prefix_chars[0]
+        if self.add_help:
+            self.add_argument(
+                default_prefix+'h', default_prefix*2+'help',
+                action='help', default=SUPPRESS,
+                help=_('show this help message and exit'))
+        if self.version:
+            self.add_argument(
+                default_prefix+'v', default_prefix*2+'version',
+                action='version', default=SUPPRESS,
+                version=self.version,
+                help=_("show program's version number and exit"))
+
+        # add parent arguments and defaults
+        for parent in parents:
+            self._add_container_actions(parent)
+            try:
+                defaults = parent._defaults
+            except AttributeError:
+                pass
+            else:
+                self._defaults.update(defaults)
+
+    # =======================
+    # Pretty __repr__ methods
+    # =======================
+    def _get_kwargs(self):
+        names = [
+            'prog',
+            'usage',
+            'description',
+            'version',
+            'formatter_class',
+            'conflict_handler',
+            'add_help',
+        ]
+        return [(name, getattr(self, name)) for name in names]
+
+    # ==================================
+    # Optional/Positional adding methods
+    # ==================================
+    def add_subparsers(self, **kwargs):
+        if self._subparsers is not None:
+            self.error(_('cannot have multiple subparser arguments'))
+
+        # add the parser class to the arguments if it's not present
+        kwargs.setdefault('parser_class', type(self))
+
+        if 'title' in kwargs or 'description' in kwargs:
+            title = _(kwargs.pop('title', 'subcommands'))
+            description = _(kwargs.pop('description', None))
+            self._subparsers = self.add_argument_group(title, description)
+        else:
+            self._subparsers = self._positionals
+
+        # prog defaults to the usage message of this parser, skipping
+        # optional arguments and with no "usage:" prefix
+        if kwargs.get('prog') is None:
+            formatter = self._get_formatter()
+            positionals = self._get_positional_actions()
+            groups = self._mutually_exclusive_groups
+            formatter.add_usage(self.usage, positionals, groups, '')
+            kwargs['prog'] = formatter.format_help().strip()
+
+        # create the parsers action and add it to the positionals list
+        parsers_class = self._pop_action_class(kwargs, 'parsers')
+        action = parsers_class(option_strings=[], **kwargs)
+        self._subparsers._add_action(action)
+
+        # return the created parsers action
+        return action
+
+    def _add_action(self, action):
+        if action.option_strings:
+            self._optionals._add_action(action)
+        else:
+            self._positionals._add_action(action)
+        return action
+
+    def _get_optional_actions(self):
+        return [action
+                for action in self._actions
+                if action.option_strings]
+
+    def _get_positional_actions(self):
+        return [action
+                for action in self._actions
+                if not action.option_strings]
+
+    # =====================================
+    # Command line argument parsing methods
+    # =====================================
+    def parse_args(self, args=None, namespace=None):
+        args, argv = self.parse_known_args(args, namespace)
+        if argv:
+            msg = _('unrecognized arguments: %s')
+            self.error(msg % ' '.join(argv))
+        return args
+
+    def parse_known_args(self, args=None, namespace=None):
+        # args default to the system args
+        if args is None:
+            args = _sys.argv[1:]
+
+        # default Namespace built from parser defaults
+        if namespace is None:
+            namespace = Namespace()
+
+        # add any action defaults that aren't present
+        for action in self._actions:
+            if action.dest is not SUPPRESS:
+                if not hasattr(namespace, action.dest):
+                    if action.default is not SUPPRESS:
+                        default = action.default
+                        if isinstance(action.default, basestring):
+                            default = self._get_value(action, default)
+                        setattr(namespace, action.dest, default)
+
+        # add any parser defaults that aren't present
+        for dest in self._defaults:
+            if not hasattr(namespace, dest):
+                setattr(namespace, dest, self._defaults[dest])
+
+        # parse the arguments and exit if there are any errors
+        try:
+            namespace, args = self._parse_known_args(args, namespace)
+            if hasattr(namespace, _UNRECOGNIZED_ARGS_ATTR):
+                args.extend(getattr(namespace, _UNRECOGNIZED_ARGS_ATTR))
+                delattr(namespace, _UNRECOGNIZED_ARGS_ATTR)
+            return namespace, args
+        except ArgumentError:
+            err = _sys.exc_info()[1]
+            self.error(str(err))
+
+    def _parse_known_args(self, arg_strings, namespace):
+        # replace arg strings that are file references
+        if self.fromfile_prefix_chars is not None:
+            arg_strings = self._read_args_from_files(arg_strings)
+
+        # map all mutually exclusive arguments to the other arguments
+        # they can't occur with
+        action_conflicts = {}
+        for mutex_group in self._mutually_exclusive_groups:
+            group_actions = mutex_group._group_actions
+            for i, mutex_action in enumerate(mutex_group._group_actions):
+                conflicts = action_conflicts.setdefault(mutex_action, [])
+                conflicts.extend(group_actions[:i])
+                conflicts.extend(group_actions[i + 1:])
+
+        # find all option indices, and determine the arg_string_pattern
+        # which has an 'O' if there is an option at an index,
+        # an 'A' if there is an argument, or a '-' if there is a '--'
+        option_string_indices = {}
+        arg_string_pattern_parts = []
+        arg_strings_iter = iter(arg_strings)
+        for i, arg_string in enumerate(arg_strings_iter):
+
+            # all args after -- are non-options
+            if arg_string == '--':
+                arg_string_pattern_parts.append('-')
+                for arg_string in arg_strings_iter:
+                    arg_string_pattern_parts.append('A')
+
+            # otherwise, add the arg to the arg strings
+            # and note the index if it was an option
+            else:
+                option_tuple = self._parse_optional(arg_string)
+                if option_tuple is None:
+                    pattern = 'A'
+                else:
+                    option_string_indices[i] = option_tuple
+                    pattern = 'O'
+                arg_string_pattern_parts.append(pattern)
+
+        # join the pieces together to form the pattern
+        arg_strings_pattern = ''.join(arg_string_pattern_parts)
+
+        # converts arg strings to the appropriate and then takes the action
+        seen_actions = set()
+        seen_non_default_actions = set()
+
+        def take_action(action, argument_strings, option_string=None):
+            seen_actions.add(action)
+            argument_values = self._get_values(action, argument_strings)
+
+            # error if this argument is not allowed with other previously
+            # seen arguments, assuming that actions that use the default
+            # value don't really count as "present"
+            if argument_values is not action.default:
+                seen_non_default_actions.add(action)
+                for conflict_action in action_conflicts.get(action, []):
+                    if conflict_action in seen_non_default_actions:
+                        msg = _('not allowed with argument %s')
+                        action_name = _get_action_name(conflict_action)
+                        raise ArgumentError(action, msg % action_name)
+
+            # take the action if we didn't receive a SUPPRESS value
+            # (e.g. from a default)
+            if argument_values is not SUPPRESS:
+                action(self, namespace, argument_values, option_string)
+
+        # function to convert arg_strings into an optional action
+        def consume_optional(start_index):
+
+            # get the optional identified at this index
+            option_tuple = option_string_indices[start_index]
+            action, option_string, explicit_arg = option_tuple
+
+            # identify additional optionals in the same arg string
+            # (e.g. -xyz is the same as -x -y -z if no args are required)
+            match_argument = self._match_argument
+            action_tuples = []
+            while True:
+
+                # if we found no optional action, skip it
+                if action is None:
+                    extras.append(arg_strings[start_index])
+                    return start_index + 1
+
+                # if there is an explicit argument, try to match the
+                # optional's string arguments to only this
+                if explicit_arg is not None:
+                    arg_count = match_argument(action, 'A')
+
+                    # if the action is a single-dash option and takes no
+                    # arguments, try to parse more single-dash options out
+                    # of the tail of the option string
+                    chars = self.prefix_chars
+                    if arg_count == 0 and option_string[1] not in chars:
+                        action_tuples.append((action, [], option_string))
+                        char = option_string[0]
+                        option_string = char + explicit_arg[0]
+                        new_explicit_arg = explicit_arg[1:] or None
+                        optionals_map = self._option_string_actions
+                        if option_string in optionals_map:
+                            action = optionals_map[option_string]
+                            explicit_arg = new_explicit_arg
+                        else:
+                            msg = _('ignored explicit argument %r')
+                            raise ArgumentError(action, msg % explicit_arg)
+
+                    # if the action expect exactly one argument, we've
+                    # successfully matched the option; exit the loop
+                    elif arg_count == 1:
+                        stop = start_index + 1
+                        args = [explicit_arg]
+                        action_tuples.append((action, args, option_string))
+                        break
+
+                    # error if a double-dash option did not use the
+                    # explicit argument
+                    else:
+                        msg = _('ignored explicit argument %r')
+                        raise ArgumentError(action, msg % explicit_arg)
+
+                # if there is no explicit argument, try to match the
+                # optional's string arguments with the following strings
+                # if successful, exit the loop
+                else:
+                    start = start_index + 1
+                    selected_patterns = arg_strings_pattern[start:]
+                    arg_count = match_argument(action, selected_patterns)
+                    stop = start + arg_count
+                    args = arg_strings[start:stop]
+                    action_tuples.append((action, args, option_string))
+                    break
+
+            # add the Optional to the list and return the index at which
+            # the Optional's string args stopped
+            assert action_tuples
+            for action, args, option_string in action_tuples:
+                take_action(action, args, option_string)
+            return stop
+
+        # the list of Positionals left to be parsed; this is modified
+        # by consume_positionals()
+        positionals = self._get_positional_actions()
+
+        # function to convert arg_strings into positional actions
+        def consume_positionals(start_index):
+            # match as many Positionals as possible
+            match_partial = self._match_arguments_partial
+            selected_pattern = arg_strings_pattern[start_index:]
+            arg_counts = match_partial(positionals, selected_pattern)
+
+            # slice off the appropriate arg strings for each Positional
+            # and add the Positional and its args to the list
+            for action, arg_count in zip(positionals, arg_counts):
+                args = arg_strings[start_index: start_index + arg_count]
+                start_index += arg_count
+                take_action(action, args)
+
+            # slice off the Positionals that we just parsed and return the
+            # index at which the Positionals' string args stopped
+            positionals[:] = positionals[len(arg_counts):]
+            return start_index
+
+        # consume Positionals and Optionals alternately, until we have
+        # passed the last option string
+        extras = []
+        start_index = 0
+        if option_string_indices:
+            max_option_string_index = max(option_string_indices)
+        else:
+            max_option_string_index = -1
+        while start_index <= max_option_string_index:
+
+            # consume any Positionals preceding the next option
+            next_option_string_index = min([
+                index
+                for index in option_string_indices
+                if index >= start_index])
+            if start_index != next_option_string_index:
+                positionals_end_index = consume_positionals(start_index)
+
+                # only try to parse the next optional if we didn't consume
+                # the option string during the positionals parsing
+                if positionals_end_index > start_index:
+                    start_index = positionals_end_index
+                    continue
+                else:
+                    start_index = positionals_end_index
+
+            # if we consumed all the positionals we could and we're not
+            # at the index of an option string, there were extra arguments
+            if start_index not in option_string_indices:
+                strings = arg_strings[start_index:next_option_string_index]
+                extras.extend(strings)
+                start_index = next_option_string_index
+
+            # consume the next optional and any arguments for it
+            start_index = consume_optional(start_index)
+
+        # consume any positionals following the last Optional
+        stop_index = consume_positionals(start_index)
+
+        # if we didn't consume all the argument strings, there were extras
+        extras.extend(arg_strings[stop_index:])
+
+        # if we didn't use all the Positional objects, there were too few
+        # arg strings supplied.
+        if positionals:
+            self.error(_('too few arguments'))
+
+        # make sure all required actions were present
+        for action in self._actions:
+            if action.required:
+                if action not in seen_actions:
+                    name = _get_action_name(action)
+                    self.error(_('argument %s is required') % name)
+
+        # make sure all required groups had one option present
+        for group in self._mutually_exclusive_groups:
+            if group.required:
+                for action in group._group_actions:
+                    if action in seen_non_default_actions:
+                        break
+
+                # if no actions were used, report the error
+                else:
+                    names = [_get_action_name(action)
+                             for action in group._group_actions
+                             if action.help is not SUPPRESS]
+                    msg = _('one of the arguments %s is required')
+                    self.error(msg % ' '.join(names))
+
+        # return the updated namespace and the extra arguments
+        return namespace, extras
+
+    def _read_args_from_files(self, arg_strings):
+        # expand arguments referencing files
+        new_arg_strings = []
+        for arg_string in arg_strings:
+
+            # for regular arguments, just add them back into the list
+            if arg_string[0] not in self.fromfile_prefix_chars:
+                new_arg_strings.append(arg_string)
+
+            # replace arguments referencing files with the file content
+            else:
+                try:
+                    args_file = open(arg_string[1:])
+                    try:
+                        arg_strings = []
+                        for arg_line in args_file.read().splitlines():
+                            for arg in self.convert_arg_line_to_args(arg_line):
+                                arg_strings.append(arg)
+                        arg_strings = self._read_args_from_files(arg_strings)
+                        new_arg_strings.extend(arg_strings)
+                    finally:
+                        args_file.close()
+                except IOError:
+                    err = _sys.exc_info()[1]
+                    self.error(str(err))
+
+        # return the modified argument list
+        return new_arg_strings
+
+    def convert_arg_line_to_args(self, arg_line):
+        return [arg_line]
+
+    def _match_argument(self, action, arg_strings_pattern):
+        # match the pattern for this action to the arg strings
+        nargs_pattern = self._get_nargs_pattern(action)
+        match = _re.match(nargs_pattern, arg_strings_pattern)
+
+        # raise an exception if we weren't able to find a match
+        if match is None:
+            nargs_errors = {
+                None: _('expected one argument'),
+                OPTIONAL: _('expected at most one argument'),
+                ONE_OR_MORE: _('expected at least one argument'),
+            }
+            default = _('expected %s argument(s)') % action.nargs
+            msg = nargs_errors.get(action.nargs, default)
+            raise ArgumentError(action, msg)
+
+        # return the number of arguments matched
+        return len(match.group(1))
+
+    def _match_arguments_partial(self, actions, arg_strings_pattern):
+        # progressively shorten the actions list by slicing off the
+        # final actions until we find a match
+        result = []
+        for i in range(len(actions), 0, -1):
+            actions_slice = actions[:i]
+            pattern = ''.join([self._get_nargs_pattern(action)
+                               for action in actions_slice])
+            match = _re.match(pattern, arg_strings_pattern)
+            if match is not None:
+                result.extend([len(string) for string in match.groups()])
+                break
+
+        # return the list of arg string counts
+        return result
+
+    def _parse_optional(self, arg_string):
+        # if it's an empty string, it was meant to be a positional
+        if not arg_string:
+            return None
+
+        # if it doesn't start with a prefix, it was meant to be positional
+        if not arg_string[0] in self.prefix_chars:
+            return None
+
+        # if the option string is present in the parser, return the action
+        if arg_string in self._option_string_actions:
+            action = self._option_string_actions[arg_string]
+            return action, arg_string, None
+
+        # if it's just a single character, it was meant to be positional
+        if len(arg_string) == 1:
+            return None
+
+        # if the option string before the "=" is present, return the action
+        if '=' in arg_string:
+            option_string, explicit_arg = arg_string.split('=', 1)
+            if option_string in self._option_string_actions:
+                action = self._option_string_actions[option_string]
+                return action, option_string, explicit_arg
+
+        # search through all possible prefixes of the option string
+        # and all actions in the parser for possible interpretations
+        option_tuples = self._get_option_tuples(arg_string)
+
+        # if multiple actions match, the option string was ambiguous
+        if len(option_tuples) > 1:
+            options = ', '.join([option_string
+                for action, option_string, explicit_arg in option_tuples])
+            tup = arg_string, options
+            self.error(_('ambiguous option: %s could match %s') % tup)
+
+        # if exactly one action matched, this segmentation is good,
+        # so return the parsed action
+        elif len(option_tuples) == 1:
+            option_tuple, = option_tuples
+            return option_tuple
+
+        # if it was not found as an option, but it looks like a negative
+        # number, it was meant to be positional
+        # unless there are negative-number-like options
+        if self._negative_number_matcher.match(arg_string):
+            if not self._has_negative_number_optionals:
+                return None
+
+        # if it contains a space, it was meant to be a positional
+        if ' ' in arg_string:
+            return None
+
+        # it was meant to be an optional but there is no such option
+        # in this parser (though it might be a valid option in a subparser)
+        return None, arg_string, None
+
+    def _get_option_tuples(self, option_string):
+        result = []
+
+        # option strings starting with two prefix characters are only
+        # split at the '='
+        chars = self.prefix_chars
+        if option_string[0] in chars and option_string[1] in chars:
+            if '=' in option_string:
+                option_prefix, explicit_arg = option_string.split('=', 1)
+            else:
+                option_prefix = option_string
+                explicit_arg = None
+            for option_string in self._option_string_actions:
+                if option_string.startswith(option_prefix):
+                    action = self._option_string_actions[option_string]
+                    tup = action, option_string, explicit_arg
+                    result.append(tup)
+
+        # single character options can be concatenated with their arguments
+        # but multiple character options always have to have their argument
+        # separate
+        elif option_string[0] in chars and option_string[1] not in chars:
+            option_prefix = option_string
+            explicit_arg = None
+            short_option_prefix = option_string[:2]
+            short_explicit_arg = option_string[2:]
+
+            for option_string in self._option_string_actions:
+                if option_string == short_option_prefix:
+                    action = self._option_string_actions[option_string]
+                    tup = action, option_string, short_explicit_arg
+                    result.append(tup)
+                elif option_string.startswith(option_prefix):
+                    action = self._option_string_actions[option_string]
+                    tup = action, option_string, explicit_arg
+                    result.append(tup)
+
+        # shouldn't ever get here
+        else:
+            self.error(_('unexpected option string: %s') % option_string)
+
+        # return the collected option tuples
+        return result
+
+    def _get_nargs_pattern(self, action):
+        # in all examples below, we have to allow for '--' args
+        # which are represented as '-' in the pattern
+        nargs = action.nargs
+
+        # the default (None) is assumed to be a single argument
+        if nargs is None:
+            nargs_pattern = '(-*A-*)'
+
+        # allow zero or one arguments
+        elif nargs == OPTIONAL:
+            nargs_pattern = '(-*A?-*)'
+
+        # allow zero or more arguments
+        elif nargs == ZERO_OR_MORE:
+            nargs_pattern = '(-*[A-]*)'
+
+        # allow one or more arguments
+        elif nargs == ONE_OR_MORE:
+            nargs_pattern = '(-*A[A-]*)'
+
+        # allow any number of options or arguments
+        elif nargs == REMAINDER:
+            nargs_pattern = '([-AO]*)'
+
+        # allow one argument followed by any number of options or arguments
+        elif nargs == PARSER:
+            nargs_pattern = '(-*A[-AO]*)'
+
+        # all others should be integers
+        else:
+            nargs_pattern = '(-*%s-*)' % '-*'.join('A' * nargs)
+
+        # if this is an optional action, -- is not allowed
+        if action.option_strings:
+            nargs_pattern = nargs_pattern.replace('-*', '')
+            nargs_pattern = nargs_pattern.replace('-', '')
+
+        # return the pattern
+        return nargs_pattern
+
+    # ========================
+    # Value conversion methods
+    # ========================
+    def _get_values(self, action, arg_strings):
+        # for everything but PARSER args, strip out '--'
+        if action.nargs not in [PARSER, REMAINDER]:
+            arg_strings = [s for s in arg_strings if s != '--']
+
+        # optional argument produces a default when not present
+        if not arg_strings and action.nargs == OPTIONAL:
+            if action.option_strings:
+                value = action.const
+            else:
+                value = action.default
+            if isinstance(value, basestring):
+                value = self._get_value(action, value)
+                self._check_value(action, value)
+
+        # when nargs='*' on a positional, if there were no command-line
+        # args, use the default if it is anything other than None
+        elif (not arg_strings and action.nargs == ZERO_OR_MORE and
+              not action.option_strings):
+            if action.default is not None:
+                value = action.default
+            else:
+                value = arg_strings
+            self._check_value(action, value)
+
+        # single argument or optional argument produces a single value
+        elif len(arg_strings) == 1 and action.nargs in [None, OPTIONAL]:
+            arg_string, = arg_strings
+            value = self._get_value(action, arg_string)
+            self._check_value(action, value)
+
+        # REMAINDER arguments convert all values, checking none
+        elif action.nargs == REMAINDER:
+            value = [self._get_value(action, v) for v in arg_strings]
+
+        # PARSER arguments convert all values, but check only the first
+        elif action.nargs == PARSER:
+            value = [self._get_value(action, v) for v in arg_strings]
+            self._check_value(action, value[0])
+
+        # all other types of nargs produce a list
+        else:
+            value = [self._get_value(action, v) for v in arg_strings]
+            for v in value:
+                self._check_value(action, v)
+
+        # return the converted value
+        return value
+
+    def _get_value(self, action, arg_string):
+        type_func = self._registry_get('type', action.type, action.type)
+        if not _callable(type_func):
+            msg = _('%r is not callable')
+            raise ArgumentError(action, msg % type_func)
+
+        # convert the value to the appropriate type
+        try:
+            result = type_func(arg_string)
+
+        # ArgumentTypeErrors indicate errors
+        except ArgumentTypeError:
+            name = getattr(action.type, '__name__', repr(action.type))
+            msg = str(_sys.exc_info()[1])
+            raise ArgumentError(action, msg)
+
+        # TypeErrors or ValueErrors also indicate errors
+        except (TypeError, ValueError):
+            name = getattr(action.type, '__name__', repr(action.type))
+            msg = _('invalid %s value: %r')
+            raise ArgumentError(action, msg % (name, arg_string))
+
+        # return the converted value
+        return result
+
+    def _check_value(self, action, value):
+        # converted value must be one of the choices (if specified)
+        if action.choices is not None and value not in action.choices:
+            tup = value, ', '.join(map(repr, action.choices))
+            msg = _('invalid choice: %r (choose from %s)') % tup
+            raise ArgumentError(action, msg)
+
+    # =======================
+    # Help-formatting methods
+    # =======================
+    def format_usage(self):
+        formatter = self._get_formatter()
+        formatter.add_usage(self.usage, self._actions,
+                            self._mutually_exclusive_groups)
+        return formatter.format_help()
+
+    def format_help(self):
+        formatter = self._get_formatter()
+
+        # usage
+        formatter.add_usage(self.usage, self._actions,
+                            self._mutually_exclusive_groups)
+
+        # description
+        formatter.add_text(self.description)
+
+        # positionals, optionals and user-defined groups
+        for action_group in self._action_groups:
+            formatter.start_section(action_group.title)
+            formatter.add_text(action_group.description)
+            formatter.add_arguments(action_group._group_actions)
+            formatter.end_section()
+
+        # epilog
+        formatter.add_text(self.epilog)
+
+        # determine help from format above
+        return formatter.format_help()
+
+    def format_version(self):
+        import warnings
+        warnings.warn(
+            'The format_version method is deprecated -- the "version" '
+            'argument to ArgumentParser is no longer supported.',
+            DeprecationWarning)
+        formatter = self._get_formatter()
+        formatter.add_text(self.version)
+        return formatter.format_help()
+
+    def _get_formatter(self):
+        return self.formatter_class(prog=self.prog)
+
+    # =====================
+    # Help-printing methods
+    # =====================
+    def print_usage(self, file=None):
+        if file is None:
+            file = _sys.stdout
+        self._print_message(self.format_usage(), file)
+
+    def print_help(self, file=None):
+        if file is None:
+            file = _sys.stdout
+        self._print_message(self.format_help(), file)
+
+    def print_version(self, file=None):
+        import warnings
+        warnings.warn(
+            'The print_version method is deprecated -- the "version" '
+            'argument to ArgumentParser is no longer supported.',
+            DeprecationWarning)
+        self._print_message(self.format_version(), file)
+
+    def _print_message(self, message, file=None):
+        if message:
+            if file is None:
+                file = _sys.stderr
+            file.write(message)
+
+    # ===============
+    # Exiting methods
+    # ===============
+    def exit(self, status=0, message=None):
+        if message:
+            self._print_message(message, _sys.stderr)
+        _sys.exit(status)
+
+    def error(self, message):
+        """error(message: string)
+
+        Prints a usage message incorporating the message to stderr and
+        exits.
+
+        If you override this in a subclass, it should not return -- it
+        should either exit or raise an exception.
+        """
+        self.print_usage(_sys.stderr)
+        self.exit(2, _('%s: error: %s\n') % (self.prog, message))
diff --git a/lib/bx/cookbook/attribute.py b/lib/bx/cookbook/attribute.py
new file mode 100644
index 0000000..79726c7
--- /dev/null
+++ b/lib/bx/cookbook/attribute.py
@@ -0,0 +1,121 @@
+"""
+Provides functions for creating simple properties.
+
+If, inside a class definition, you write:
+
+    attribute(foo=1, bar=2)
+    
+simple properties named 'foo' and 'bar' are created for this class.
+Also, private instance variables '__foo' and '__bar' will be added 
+to instances of this class.
+
+USEAGE:
+
+# assumes attribute.py is on path 
+from attribute import *
+
+class MyClass(object):
+    readable(foo=1, bar=2) # or, attribute('r', foo=1, bar=2)
+    writable(fro=3, boz=4) # or, attribute('w', fro=3, boz=4)
+    attribute(baz=5)
+
+This is equivalent to the following:
+
+class MyClass(object):
+    def __init__(self): 
+        self.__foo = 1
+        self.__bar = 2
+        self.__fro = 3
+        self.__boz = 4
+        self.__baz = 5
+
+    def get_foo(self): 
+        return self.__foo
+    def get_bar(self): 
+        return self.__bar
+    def set_fro(self, value): 
+        self.__fro = value
+    def set_boz(self, value): 
+        self.__boz = value
+    def get_baz(self):
+        return self.__baz
+    def set_baz(self, value):
+        self.__baz = value
+    def del_baz(self):
+        del self.__baz
+
+    foo = property(fget=get_foo, doc="foo")
+    bar = property(fget=get_bar, doc="bar")
+    fro = property(fset=set_fro, doc="fro")
+    boz = property(fset=set_boz, doc="boz")
+    baz = property(fget=get_baz, fset=set_baz, fdel=del_baz, doc="baz")
+"""
+
+__all__ = ['attribute', 'readable', 'writable']
+__version__ = '3.0'
+__author__ = 'Sean Ross'
+__credits__ = ['Guido van Rossum', 'Garth Kidd']
+__created__ = '10/21/02'
+
+import sys
+
+def mangle(classname, attrname):
+    """mangles name according to python name-mangling 
+       conventions for private variables"""
+    return "_%s__%s" % (classname, attrname)
+
+def class_space(classlevel=3):
+    "returns the calling class' name and dictionary"
+    frame = sys._getframe(classlevel)
+    classname = frame.f_code.co_name
+    classdict = frame.f_locals
+    return classname, classdict
+
+# convenience function
+def readable(**kwds):
+    "returns one read-only property for each (key,value) pair in kwds"
+    return _attribute(permission='r', **kwds)
+
+# convenience function
+def writable(**kwds):
+    "returns one write-only property for each (key,value) pair in kwds"
+    return _attribute(permission='w', **kwds) 
+
+# needed because of the way class_space is resolved in _attribute
+def attribute(permission='rwd', **kwds):
+    """returns one property for each (key,value) pair in kwds;
+       each property provides the specified level of access(permission):
+           'r': readable, 'w':writable, 'd':deletable
+    """
+    return _attribute(permission, **kwds)
+
+# based on code by Guido van Rossum, comp.lang.python 2001-07-31        
+def _attribute(permission='rwd', **kwds):
+    """returns one property for each (key,value) pair in kwds;
+       each property provides the specified level of access(permission):
+           'r': readable, 'w':writable, 'd':deletable
+    """
+    classname, classdict = class_space()
+    def _property(attrname, default):
+        propname, attrname = attrname, mangle(classname, attrname)
+        fget, fset, fdel, doc = None, None, None, propname
+        if 'r' in permission:
+            def fget(self):
+                value = default
+                try: value = getattr(self, attrname)
+                except AttributeError: setattr(self, attrname, default)
+                return value
+        if 'w' in permission:
+            def fset(self, value):
+                setattr(self, attrname, value)
+        if 'd' in permission:
+            def fdel(self): 
+                try: delattr(self, attrname)
+                except AttributeError: pass
+                # calling fget can restore this attribute, so remove property 
+                delattr(self.__class__, propname)
+        return property(fget=fget, fset=fset, fdel=fdel, doc=doc)
+        
+    for attrname, default in kwds.items():
+        classdict[attrname] = _property(attrname, default)
+
diff --git a/lib/bx/cookbook/doc_optparse.py b/lib/bx/cookbook/doc_optparse.py
new file mode 100644
index 0000000..2072d4d
--- /dev/null
+++ b/lib/bx/cookbook/doc_optparse.py
@@ -0,0 +1,86 @@
+"""
+:Author: M. Simionato
+:Date: April 2004
+:Title: A much simplified interface to optparse.
+
+You should use optionparse in your scripts as follows.
+First, write a module level docstring containing something like this
+(this is just an example)::
+
+    '''usage: %prog files [options]
+       -d, --delete: delete all files
+       -e, --erase = ERASE: erase the given file'''
+   
+Then write a main program of this kind:
+
+# sketch of a script to delete files::
+
+    if __name__=='__main__':
+        import optionparse
+        option,args=optionparse.parse(__doc__)
+        if not args and not option: optionparse.exit()
+        elif option.delete: print "Delete all files"
+        elif option.erase: print "Delete the given file"
+
+Notice that ``optionparse`` parses the docstring by looking at the
+characters ",", ":", "=", "\\n", so be careful in using them. If
+the docstring is not correctly formatted you will get a SyntaxError
+or worse, the script will not work as expected.
+"""
+
+import optparse, re, sys, traceback
+
+USAGE = re.compile(r'(?s)\s*usage: (.*?)(\n[ \t]*\n|$)')
+
+def nonzero(self): # will become the nonzero method of optparse.Values       
+    "True if options were given"
+    for v in self.__dict__.itervalues():
+        if v is not None: return True
+    return False
+
+optparse.Values.__nonzero__ = nonzero # dynamically fix optparse.Values
+
+class ParsingError(Exception): pass
+
+optionstring=""
+
+def exception(msg=""):
+    print >> sys.stderr, "Exception while parsing command line:"
+    print >>sys.stderr, traceback.format_exc()
+    exit( msg )
+
+def exit(msg=""):
+    raise SystemExit(msg or optionstring.replace("%prog",sys.argv[0]))
+
+def parse(docstring, arglist=None):
+    global optionstring
+    optionstring = docstring
+    match = USAGE.search(optionstring)
+    if not match: raise ParsingError("Cannot find the option string")
+    optlines = match.group(1).splitlines()
+    try:
+        p = optparse.OptionParser(optlines[0],conflict_handler="resolve")
+        for line in optlines[1:]:
+            opt, help=line.split(':')[:2]
+            # Make both short and long optional (but at least one)
+            ## Old: short,long=opt.split(',')[:2]
+            opt_strings = []
+            action = "store_true"
+            for k in opt.split( ', ' ):
+                k = k.strip()
+                if k.startswith( "--" ) and "=" in k:
+                    action = "store"
+                    k = k.split( "=" )[0]
+                opt_strings.append( k )
+            p.add_option( *opt_strings, **dict( action = action, help = help.strip() ) )
+        helpstring = docstring.replace("%prog",sys.argv[0])
+        # p.add_option( "-h", "--help", action="callback", callback=help_callback, callback_args=(helpstring,) )
+    except (IndexError,ValueError):
+        raise ParsingError("Cannot parse the option string correctly")
+    return p.parse_args(arglist)
+
+def help_callback( option, opt, value, parser, help ):
+    print >> sys.stderr, help
+    sys.exit( 1 )
+    
+    
diff --git a/lib/bx/cookbook/progress_bar.py b/lib/bx/cookbook/progress_bar.py
new file mode 100644
index 0000000..b5c1fb0
--- /dev/null
+++ b/lib/bx/cookbook/progress_bar.py
@@ -0,0 +1,80 @@
+"""
+An ASCII text progress bar. See __main__ for command line use (using \r to 
+move the cursor back to the start of the current line is the key, on
+terminals that do not support this functionality the progress bar will
+not work as well).
+
+http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/168639
+"""
+
+import sys
+
+class ProgressBar:
+    def __init__(self, minValue = 0, maxValue = 10, totalWidth=72):
+        self.progBar = "[]"   # This holds the progress bar string
+        self.min = minValue
+        self.max = maxValue
+        self.span = maxValue - minValue
+        self.width = totalWidth
+        self.amount = 0       # When amount == max, we are 100% done 
+        self.update(0)  # Build progress bar string
+
+    def update(self, newAmount = 0):
+        if newAmount < self.min: newAmount = self.min
+        if newAmount > self.max: newAmount = self.max
+        self.amount = newAmount
+
+        # Figure out the new percent done, round to an integer
+        diffFromMin = float(self.amount - self.min)
+        percentDone = (diffFromMin / float(self.span)) * 100.0
+        percentDone = round(percentDone)
+        percentDone = int(percentDone)
+
+        # Figure out how many hash bars the percentage should be
+        allFull = self.width - 2
+        numHashes = (percentDone / 100.0) * allFull
+        numHashes = int(round(numHashes))
+
+        # build a progress bar with hashes and spaces
+        if allFull == numHashes:
+            self.progBar = "[" + '='*(numHashes) + "]"
+        else:
+            self.progBar = "[" + '='*(numHashes-1) + '>' + ' '*(allFull-numHashes) + "]"
+
+        # figure out where to put the percentage, roughly centered
+        percentPlace = (len(self.progBar) / 2) - len(str(percentDone)) 
+        percentString = str(percentDone) + "%"
+
+        # slice the percentage into the bar
+        self.progBar = self.progBar[0:percentPlace] + percentString + self.progBar[percentPlace+len(percentString):]
+
+    def update_and_print( self, newAmount = 0, f = sys.stdout ):
+        self.update( newAmount )
+        print >> f, "\r", self,
+        f.flush()
+
+
+    def __str__(self):
+        return str(self.progBar)
+
+def iterprogress( sized_iterable ):
+    """
+    Iterate something printing progress bar to stdout
+    """
+    pb = ProgressBar( 0, len( sized_iterable ) )
+    for i, value in enumerate( sized_iterable ):
+        yield value
+        pb.update_and_print( i, sys.stderr )
+
+if __name__ == "__main__":
+    import time
+
+    bar = ProgressBar( 0, 1000, 80 )
+
+    for i in range(1000):
+        bar.update( i )
+        print "\r", bar,
+        sys.stdout.flush()
+        
+
+    print
diff --git a/lib/bx/filter.py b/lib/bx/filter.py
new file mode 100644
index 0000000..cccae4d
--- /dev/null
+++ b/lib/bx/filter.py
@@ -0,0 +1,54 @@
+"""
+Classes for implementing `Pipeline`s composed of `Filter`s (intended to be
+subclassed).
+"""
+
+class Filter( object ):
+    def __init__( self, **kwargs ):
+        raise Exception("AbstractClass")
+    
+    def run( self, reader, writer ):
+        for block in reader:
+            block = self( block )
+            if block: writer( block )
+
+    def step( self, reader, writer ):
+        block = reader.next()
+        if not block: raise StopIteration
+        block = self( block )
+        if block: writer( block )
+        
+    def __call__( self, block ):
+        raise Exception("AbstractMethod")
+
+class Pipeline( Filter ):
+    def __init__( self, **kwargs ):
+        self.pipeline = list()
+
+    def __call__( self, block ):
+        for function in pipeline:
+            if not block: return block
+            try: f = function.__call__
+            except: raise TypeError, "'" + function.__class__.__name__ + "' is not callable."
+            block = f( block )
+        return block
+
+    def append( self, function ):
+        try: f = function.__call__
+        except: raise TypeError, "'" + function.__class__.__name__ + "' is not callable."
+        return self.pipeline.append( function )
+    def remove( self, function ):
+        return self.pipeline.remove( function )
+    def extend( self, pipeline ):
+        for item in pipeline:
+            self.append( item )
+    # Container interface
+    def __len__( self ): return len( self.pipeline )
+    def __getitem__( self, key ): return self.pipeline[key]
+    def __setitem__( self, key, value ):
+        try: f = value.__call__
+        except: raise TypeError, "'" + value.__class__.__name__ + "' is not callable."
+        return self.pipeline.__setitem__( key, value )
+    def __delitem__( self, key ): return self.pipeline.__delitem__( key )
+    def __iter__( self ): return self.pipeline.__iter__()
+    def __contains__( self, item ): return self.pipeline.__contains__( item )
diff --git a/lib/bx/gene_reader.py b/lib/bx/gene_reader.py
new file mode 100644
index 0000000..9ae6e17
--- /dev/null
+++ b/lib/bx/gene_reader.py
@@ -0,0 +1,283 @@
+"""
+Readers extracting gene (exon and intron) information from bed / gtf / gff 
+formats.
+
+ - GeneReader: yields exons
+ - CDSReader: yields cds_exons
+ - FeatureReader: yields cds_exons, introns, exons
+
+For gff/gtf, the start_codon stop_codon line types are merged with CDSs.
+"""
+
+import sys
+from bx.bitset import *
+from bx.bitset_utils import *
+from bx.bitset_builders import *
+
+def GeneReader( fh, format='gff' ):
+    """ yield chrom, strand, gene_exons, name """
+
+    known_formats = ( 'gff', 'gtf', 'bed')
+    if format not in known_formats: 
+        print >>sys.stderr,  '%s format not in %s' % (format, ",".join( known_formats ))
+        raise Exception('?')
+
+    if format == 'bed':
+        for line in fh:    
+            f = line.strip().split()
+            chrom = f[0]
+            chrom_start = int(f[1])
+            name = f[4]
+            strand = f[5]
+            cdsStart = int(f[6])
+            cdsEnd = int(f[7])
+            blockCount = int(f[9])
+            blockSizes = [ int(i) for i in f[10].strip(',').split(',') ]
+            blockStarts = [ chrom_start + int(i) for i in f[11].strip(',').split(',') ]
+
+            # grab cdsStart - cdsEnd
+            gene_exons = []
+            for base,offset in zip( blockStarts, blockSizes ):
+                exon_start = base
+                exon_end = base+offset
+                gene_exons.append( (exon_start, exon_end) )
+            yield chrom, strand, gene_exons, name
+    genelist = {}
+    grouplist = []
+    if format == 'gff' or format == 'gtf':
+        for line in fh:
+            if line.startswith('#'): continue
+            fields = line.strip().split('\t')
+            if len( fields ) < 9: continue
+
+            # fields
+
+            chrom = fields[0]
+            ex_st = int( fields[3] ) - 1 # make zero-centered
+            ex_end = int( fields[4] ) #+ 1 # make exclusive
+            strand = fields[6]
+
+            if format == 'gtf':
+                group = fields[8].split(';')[0]
+            else:
+                group = fields[8]
+
+            if group not in grouplist: grouplist.append( group )
+            if group not in genelist:
+                genelist[group] = (chrom, strand, [])
+            exons_i = 2
+            genelist[group][exons_i].append( ( ex_st, ex_end ) )
+
+        sp = lambda a,b: cmp( a[0], b[0] )
+
+        #for gene in genelist.values():
+        for gene in grouplist:
+            chrom, strand, gene_exons = genelist[ gene ]
+            gene_exons = bitset_union( gene_exons )
+            yield chrom, strand, gene_exons, gene
+
+def CDSReader( fh, format='gff' ):
+    """ yield chrom, strand, cds_exons, name """
+
+    known_formats = ( 'gff', 'gtf', 'bed')
+    if format not in known_formats: 
+        print >>sys.stderr,  '%s format not in %s' % (format, ",".join( known_formats ))
+        raise Exception('?')
+
+    if format == 'bed':
+        for line in fh:    
+            f = line.strip().split()
+            chrom = f[0]
+            chrom_start = int(f[1])
+            name = f[4]
+            strand = f[5]
+            cdsStart = int(f[6])
+            cdsEnd = int(f[7])
+            blockCount = int(f[9])
+            blockSizes = [ int(i) for i in f[10].strip(',').split(',') ]
+            blockStarts = [ chrom_start + int(i) for i in f[11].strip(',').split(',') ]
+
+            # grab cdsStart - cdsEnd
+            cds_exons = []
+            cds_seq = ''
+            genome_seq_index = []
+            for base,offset in zip( blockStarts, blockSizes ):
+                if (base + offset) < cdsStart: continue
+                if base > cdsEnd: continue
+                exon_start = max( base, cdsStart )
+                exon_end = min( base+offset, cdsEnd ) 
+                cds_exons.append( (exon_start, exon_end) )
+            yield chrom, strand, cds_exons, name
+
+    genelist = {}
+    grouplist = []
+    if format == 'gff' or format == 'gtf':
+        for line in fh:
+            if line.startswith('#'): continue
+            fields = line.strip().split('\t')
+            if len( fields ) < 9: continue
+            if fields[2] not in ('CDS', 'stop_codon', 'start_codon'): continue
+
+            # fields
+
+            chrom = fields[0]
+            ex_st = int( fields[3] ) - 1 # make zero-centered
+            ex_end = int( fields[4] ) #+ 1 # make exclusive
+            strand = fields[6]
+
+            if format == 'gtf':
+                group = fields[8].split(';')[0]
+            else:
+                group = fields[8]
+
+            if group not in grouplist: grouplist.append( group )
+            if group not in genelist:
+                genelist[group] = (chrom, strand, [])
+            
+            genelist[group][2].append( ( ex_st, ex_end ) )
+
+        sp = lambda a,b: cmp( a[0], b[0] )
+
+        #for gene in genelist.values():
+        for gene in grouplist:
+            chrom, strand, cds_exons = genelist[ gene ]
+            seqlen = sum([ a[1]-a[0] for a in cds_exons ])
+            overhang = seqlen % 3
+            if overhang > 0:
+                #print >>sys.stderr, "adjusting ", gene  
+                if strand == '+': 
+                    cds_exons[-1] = ( cds_exons[-1][0], cds_exons[-1][1] - overhang )
+                else:
+                    cds_exons[0] = ( cds_exons[0][0] + overhang, cds_exons[0][1] )
+            cds_exons = bitset_union( cds_exons )
+            yield chrom, strand, cds_exons, gene
+
+def FeatureReader( fh, format='gff', alt_introns_subtract="exons", gtf_parse=None):
+    """ 
+    yield chrom, strand, cds_exons, introns, exons, name
+
+    gtf_parse Example:
+    # parse gene_id from transcript_id "AC073130.2-001"; gene_id "TES";
+    gene_name = lambda s: s.split(';')[1].split()[1].strip('"')
+
+    for chrom, strand, cds_exons, introns, exons, name in FeatureReader( sys.stdin, format='gtf', gtf_parse=gene_name )
+    """
+
+    known_formats = ( 'gff', 'gtf', 'bed')
+    if format not in known_formats: 
+        print >>sys.stderr,  '%s format not in %s' % (format, ",".join( known_formats ))
+        raise Exception('?')
+
+    if format == 'bed':
+        for line in fh:    
+            f = line.strip().split()
+            chrom = f[0]
+            chrom_start = int(f[1])
+            name = f[4]
+            strand = f[5]
+            cdsStart = int(f[6])
+            cdsEnd = int(f[7])
+            blockCount = int(f[9])
+            blockSizes = [ int(i) for i in f[10].strip(',').split(',') ]
+            blockStarts = [ chrom_start + int(i) for i in f[11].strip(',').split(',') ]
+
+            # grab cdsStart - cdsEnd
+            cds_exons = []
+            exons = []
+            
+            cds_seq = ''
+            genome_seq_index = []
+            for base,offset in zip( blockStarts, blockSizes ):
+                if (base + offset) < cdsStart: continue
+                if base > cdsEnd: continue
+                # exons
+                exon_start = base
+                exon_end = base+offset
+                exons.append( (exon_start, exon_end) )
+                # cds exons
+                exon_start = max( base, cdsStart )
+                exon_end = min( base+offset, cdsEnd ) 
+                cds_exons.append( (exon_start, exon_end) )
+            cds_exons = bitset_union( cds_exons )
+            exons = bitset_union( exons )
+            introns = bitset_complement( exons )
+            yield chrom, strand, cds_exons, introns, exons, name
+
+    genelist = {}
+    grouplist = []
+    if format == 'gff' or format == 'gtf':
+        for line in fh:
+            if line.startswith('#'): continue
+            fields = line.strip().split('\t')
+            if len( fields ) < 9: continue
+
+            # fields
+
+            chrom = fields[0]
+            ex_st = int( fields[3] ) - 1 # make zero-centered
+            ex_end = int( fields[4] ) #+ 1 # make exclusive
+            strand = fields[6]
+
+            if format == 'gtf':
+                if not gtf_parse:
+                    group = fields[8].split(';')[0]
+                else:
+                    group = gtf_parse( fields[8] )
+            else:
+                group = fields[8]
+
+            # Results are listed in the same order as encountered
+            if group not in grouplist: grouplist.append( group )
+
+            if group not in genelist:
+                # chrom, strand, cds_exons, introns, exons, cds_start, cds_end
+                genelist[group] = [chrom, strand, [], [], [], None, None]
+            
+            if fields[2] == 'exon':
+                genelist[group][4].append( ( ex_st, ex_end ) )
+
+            elif fields[2] in ('CDS', 'stop_codon', 'start_codon'):
+                genelist[group][2].append( ( ex_st, ex_end ) )
+
+                if fields[2] == 'start_codon':
+                    if strand == '+': genelist[group][5] = ex_st
+                    else: genelist[group][5] = ex_end
+                if fields[2] == 'stop_codon':
+                    if strand == '+': genelist[group][5] = ex_end
+                    else: genelist[group][5] = ex_st
+
+            elif fields[2] == 'intron':
+                genelist[group][3].append( ( ex_st, ex_end ) )
+
+        for gene in grouplist:
+            chrom, strand, cds_exons, introns, exons, cds_start, cds_end = genelist[ gene ]
+
+            cds_exons = bitset_union( cds_exons )
+            exons = bitset_union( exons )
+
+            # assure that cds exons were within the cds range
+            if cds_start is not None and cds_end is not None:
+                if strand == '+':
+                    cds_exons = bitset_intersect( cds_exons, [(cds_start,cds_end)] )
+                else:
+                    cds_exons = bitset_intersect( cds_exons, [(cds_end,cds_start)] )
+
+            # assure that introns are non-overlapping with themselves or exons
+            if alt_introns_subtract:
+                if alt_introns_subtract == 'exons':
+                    introns = bitset_subtract( introns, exons )
+                if alt_introns_subtract == 'cds_exons':
+                    introns = bitset_subtract( introns, cds_exons )
+            else: introns = bitset_union( introns )
+
+            # assure CDS is a multiple of 3, trim from last exon if necessary
+            seqlen = sum([ a[1]-a[0] for a in cds_exons ])
+            overhang = seqlen % 3
+            if overhang > 0:
+                if strand == '+': 
+                    cds_exons[-1] = ( cds_exons[-1][0], cds_exons[-1][1] - overhang )
+                else:
+                    cds_exons[0] = ( cds_exons[0][0] + overhang, cds_exons[0][1] )
+
+            yield chrom, strand, cds_exons, introns, exons, gene
+
diff --git a/lib/bx/interval_index_file.py b/lib/bx/interval_index_file.py
new file mode 100644
index 0000000..a6adaa0
--- /dev/null
+++ b/lib/bx/interval_index_file.py
@@ -0,0 +1,503 @@
+"""
+Classes for index files that map genomic intervals to values.
+
+:Authors: James Taylor (james at bx.psu.edu), Bob Harris (rsharris at bx.psu.edu)
+
+An interval index file maps genomic intervals to values.
+
+This implementation writes version 1 file format, and reads versions 0 and 1.
+
+Index File Format
+-----------------
+
+All fields are in big-endian format (most significant byte first).
+
+All intervals are origin-zero, inclusive start, exclusive end.
+
+The file begins with an index file header, then is immediately followed
+by an index table.  The index table points to index headers, and index
+headers point to bins.  Index headers and bins are referenced via pointers
+(file offsets), and can be placed more or less anywhere in the file.
+
+File header
+~~~~~~~~~~~
+
+============ ===========   =================================================
+offset 0x00: 2C FF 80 0A   magic number
+offset 0x04: 00 00 00 01   version (00 00 00 00 is also supported)
+offset 0x08: 00 00 00 2A   (N) number of index sets
+offset 0x0C:  ...          index table
+============ ===========   =================================================
+
+Index table
+~~~~~~~~~~~
+
+The index table is a list of N index headers, packed sequentially and
+sorted by name.  The first begins at offset 0x0C.  Each header describes
+one set of intervals.
+
+============ ===========   =================================================
+offset:      xx xx xx xx   (L) length of index src name
+offset+4:     ...          index src name (e.g. canFam1.chr1)
+offset+4+L:  xx xx xx xx   offset (in this file) to index data
+offset+8+L:  xx xx xx xx   (B) number of bytes in each value;  for version 
+                           0, this field is absent, and B is assumed to be 4
+============ ===========   =================================================
+
+Index data
+~~~~~~~~~~
+
+The index data for (for one index table) consists of the overall range of
+intervals followed by an array of pointers to bins.  The length of the
+array is 1+binForRange(maxEnd-1,maxEnd), where maxEnd is the maximum
+interval end.
+
+============ ===========   =================================================
+offset:      xx xx xx xx   minimum interval start
+offset+4:    xx xx xx xx   maximum interval end
+offset+8:    xx xx xx xx   offset (in this file) to bin 0
+offset+12:   xx xx xx xx   number of intervals in bin 0
+offset+16:   xx xx xx xx   offset (in this file) to bin 1
+offset+20:   xx xx xx xx   number of intervals in bin 1
+...          ...           ...
+============ ===========   =================================================
+
+Bin
+~~~
+
+A bin is an array of (start,end,val), sorted by increasing start (with
+end and val as tiebreakers).  Note that bins may be empty (the number of
+intervals indicated in the index data is zero).  Note that B is determined
+from the appropriate entry in the index table.
+
+============ ===========   =================================================
+offset:      xx xx xx xx   start for interval 1
+offset+4:    xx xx xx xx   end   for interval 1
+offset+8:     ...          (B bytes) value for interval 1
+offset+8+B:  xx xx xx xx   start for interval 2
+offset+12+B: xx xx xx xx   end   for interval 2
+offset+16+B:  ...          (B bytes) value for interval 2
+...          ...           ...
+============ ===========   =================================================
+"""
+
+from bisect import *
+from struct import *
+
+from bx.misc import filecache
+
+try:
+    from bx.misc import seekbzip2
+except:
+    seekbzip2 = None
+    
+try:
+    from bx.misc import seeklzop
+except:
+    seeklzop = None
+
+import os.path
+
+__all__ = [ 'Indexes', 'Index' ]
+
+MAGIC = 0x2cff800a
+VERSION = 2
+
+# These three constants determine the structure of the default binning strategy
+BIN_LEVELS = 6        # Number of levels of bins to build
+BIN_FIRST_SHIFT = 17  # Number of bits for the bottom level bin 
+BIN_NEXT_SHIFT = 3    # Number of bits for each higher level bin
+
+# Build offset and max size arrays for each bin level
+BIN_OFFSETS = [ 1, 0 ]
+BIN_OFFSETS_MAX = [ ( 1 << BIN_FIRST_SHIFT << BIN_NEXT_SHIFT ), ( 1 << BIN_FIRST_SHIFT ) ]
+for i in range( BIN_LEVELS - 2 ):
+    BIN_OFFSETS.insert( 0, ( 2 ** (3*(i+1)) ) + BIN_OFFSETS[0] )
+    BIN_OFFSETS_MAX.insert( 0, ( BIN_OFFSETS_MAX[0] << BIN_NEXT_SHIFT ) )
+# The maximum size for the top bin is actually bigger than the signed integers
+# we use to store positions in the file, so we'll change it to prevent confusion
+BIN_OFFSETS_MAX[ 0 ] = max
+
+# Constants for the minimum and maximum size of the overall interval
+MIN = 0                     
+OLD_MAX = 512*1024*1024     # Maximum size supported by versions < 2 
+DEFAULT_MAX = 512*1024*1024 # Default max size to use when none is passed
+MAX = ( 2 ** 31 )           # Absolute max size (limited by file format)
+
+def offsets_for_max_size( max_size ):
+    """
+    Return the subset of offsets needed to contain intervals over (0,max_size)
+    """
+    for i, max in enumerate( reversed( BIN_OFFSETS_MAX ) ):
+        if max_size < max:
+            break
+    else:
+        raise Exception( "%d is larger than the maximum possible size (%d)" % ( max_size, BIN_OFFSETS_MAX[0] ) )
+    return BIN_OFFSETS[ ( len(BIN_OFFSETS) - i - 1 ) : ]
+
+def bin_for_range( start, end, offsets=None ):
+    """Find the smallest bin that can contain interval (start,end)"""
+    if offsets is None:
+        offsets = BIN_OFFSETS
+    start_bin, end_bin = start, max(start, end - 1)
+    start_bin >>= BIN_FIRST_SHIFT
+    end_bin >>= BIN_FIRST_SHIFT
+    for offset in offsets:
+        if start_bin == end_bin:
+            return offset + start_bin
+        else:
+            start_bin >>= BIN_NEXT_SHIFT
+            end_bin >>= BIN_NEXT_SHIFT
+    raise Exceptionn("Interval (%d,%d) out of range")
+
+class AbstractMultiIndexedAccess( object ):
+    """
+    Allows accessing multiple indexes / files as if they were one
+    """
+    indexed_access_class = None
+    def __init__( self, filenames, index_filenames=None, keep_open=False, use_cache=False, **kwargs ):
+        # TODO: Handle index_filenames argument
+        self.indexes = [ self.new_indexed_access( fname, keep_open=keep_open, use_cache=use_cache, **kwargs ) \
+            for fname in filenames ]
+    def new_indexed_access( self, data_filename, index_filename=None, keep_open=False, **kwargs ):
+        return self.indexed_access_class( data_filename, index_filename, keep_open, **kwargs )
+    def get( self, src, start, end ):
+        return [block for block in self.get_as_iterator( src, start, end )]
+    def get_as_iterator( self, src, start, end ):
+        for block, index, offset in self.get_as_iterator_with_index_and_offset( src, start, end ):
+            yield block
+    def get_as_iterator_with_index_and_offset( self, src, start, end ):
+        for index in self.indexes:
+            for block, idx, offset in index.get_as_iterator_with_index_and_offset( src, start, end ):
+                yield block, idx, offset
+    def close( self ):
+        for index in self.indexes:
+            index.close()
+
+class AbstractIndexedAccess( object ):
+    """Indexed access to a data using overlap queries, requires an index file"""
+
+    def __init__( self, data_filename, index_filename=None, keep_open=False, use_cache=False, **kwargs ):
+        self.data_kwargs = kwargs
+        self.data_filename = data_filename
+        if data_filename.endswith( ".bz2" ):
+            if seekbzip2 is None:
+                raise Exception( "Trying to open .bz2 file but no seekbzip2 module found")
+            table_filename = data_filename + "t"
+            self.table_filename = table_filename
+            if not os.path.exists( table_filename ):
+                raise Exception( "Cannot find bz2t file for: " + data_filename )
+            self.file_type = "bz2t"
+            # Strip .bz2 from the filename before adding ".index"
+            data_filename_root = data_filename[:-4]
+        elif data_filename.endswith( ".lzo" ):
+            if seeklzop is None:
+                raise Exception( "Trying to open .lzo file but no seeklzop module found")
+            table_filename = data_filename + "t"
+            self.table_filename = table_filename
+            if not os.path.exists( table_filename ):
+                raise Exception( "Cannot find lzot file for: " + data_filename )
+            self.file_type = "lzot"
+            # Strip .lzo from the filename before adding ".index"
+            data_filename_root = data_filename[:-4]
+        else:
+            self.file_type = "plain"
+            data_filename_root = data_filename
+        # Open index
+        if index_filename is None: 
+            index_filename = data_filename_root + ".index"
+        self.indexes = Indexes( filename=index_filename )
+        # Use a file cache?
+        self.use_cache = use_cache
+        # Open now?
+        if keep_open: 
+            self.f = self.open_data()
+        else:
+            self.f = None
+
+    def close( self ):
+        if self.f:
+            self.f.close()
+            self.f = None
+
+    def open_data( self ):
+        if self.file_type == "plain":
+            return open( self.data_filename )
+        elif self.file_type == "bz2t":
+            f = seekbzip2.SeekableBzip2File( self.data_filename, self.table_filename )
+            if self.use_cache:
+                return filecache.FileCache( f, f.size )
+            else:
+                return f
+        elif self.file_type == "lzot":
+            if self.use_cache:
+                block_cache_size = 20
+            else:
+                block_cache_size = 0
+            f = seeklzop.SeekableLzopFile( self.data_filename, 
+                                           self.table_filename,
+                                           block_cache_size = block_cache_size )
+            return f
+
+    def get( self, src, start, end ):
+        return [ val for val in self.get_as_iterator( src, start, end ) ]
+    def get_as_iterator( self, src, start, end ):
+        for val, index, offset in self.get_as_iterator_with_index_and_offset( src, start, end ):
+            yield val
+    def get_as_iterator_with_index_and_offset( self, src, start, end ):
+        for val_start, val_end, val in self.indexes.find( src, start, end ):
+            yield self.get_at_offset( val ), self, val
+
+    def get_at_offset( self, offset ):
+        if self.f:
+            self.f.seek( offset )
+            return self.read_at_current_offset( self.f, **self.data_kwargs )
+        else:
+            f = self.open_data()
+            try:
+                f.seek( offset )
+                return self.read_at_current_offset( f, **self.data_kwargs ) 
+            finally:
+                f.close()
+                
+    def read_at_current_offset( self, file, **kwargs ):
+        raise TypeError( "Abstract Method" )
+
+class Indexes:
+    """A set of indexes, each identified by a unique name"""
+
+    def __init__( self, filename=None ):
+        self.indexes = dict()
+        if filename is not None: self.open( filename )
+
+    def add( self, name, start, end, val, max=DEFAULT_MAX ):
+        if name not in self.indexes:
+            self.indexes[name] = Index( max=max )
+        self.indexes[name].add( start, end, val )
+
+    def get( self, name ):
+        if self.indexes[name] is None:
+            offset, value_size = self.offsets[name]
+            self.indexes[name] = Index( filename=self.filename, offset=offset, value_size=value_size, version=self.version )
+        return self.indexes[name]
+
+    def find( self, name, start, end ):
+        if name in self.indexes:
+            return self.get( name ).find( start, end )
+        else:
+            return []
+
+    def open( self, filename ):
+        self.filename = filename
+        self.offsets = dict()  # (will map key to (offset,value_size))
+        f = open( filename )
+        magic, version, length = read_packed( f, ">3I" )
+        if magic != MAGIC:
+            raise Exception("File does not have expected header")
+        if version > VERSION:
+            warn( "File claims version %d, I don't known anything about versions beyond %d. Attempting to continue", version, VERSION )
+        self.version = version
+        for i in range( length ):
+            key_len = read_packed( f, ">I" )
+            key = f.read( key_len )
+            offset = read_packed( f, ">I" )
+            if version == 0:
+                value_size = 4
+            else:
+                value_size = read_packed( f, ">I" )
+                assert value_size % 4 == 0, "unsupported value size: %s" % value_size
+            self.indexes[ key ] = None
+            self.offsets[ key ] = (offset,value_size)
+        f.close()
+
+    def write( self, f ):
+        keys = self.indexes.keys()
+        keys.sort()
+        # First determine the size of the header
+        base = calcsize( ">3I" )
+        for key in keys:
+            key = str( key )
+            base += calcsize( ">I" )
+            base += len( key )
+            base += calcsize( ">2I" )
+        # Now actually write the header
+        write_packed( f, ">3I", MAGIC, VERSION, len( self.indexes ) )
+        # And write the index table
+        for key in keys:
+            key = str( key )
+            # Write the string prefixed by its length (pascal!)
+            write_packed( f, ">I", len( key ) )
+            f.write( key )
+            # Write offset
+            write_packed( f, ">I", base )
+            base += self.indexes[key].bytes_required()
+            # Write value size
+            write_packed( f, ">I", self.indexes[key].value_size )
+        # And finally write each index in order
+        for key in keys:
+            self.indexes[key].write( f )
+
+class Index:
+
+    def __init__( self, min=MIN, max=DEFAULT_MAX, filename=None, offset=0, value_size=None, version=None ):
+        self._value_size = value_size
+        self.max_val = 1   # (1, rather than 0, to force value_size > 0)
+        if filename is None:
+            self.new( min, max )
+        else:
+            self.open( filename, offset, version )
+
+    def get_value_size ( self ):
+        if self._value_size != None:
+            return self._value_size
+        else:
+            return round_up_to_4( bytes_of( self.max_val ) )
+    value_size = property( fget=get_value_size )
+
+    def new( self, min, max ):
+        """Create an empty index for intervals in the range min, max"""
+        # Ensure the range will fit given the shifting strategy
+        assert MIN <= min <= max <= MAX
+        self.min = min
+        self.max = max
+        # Determine offsets to use
+        self.offsets = offsets_for_max_size( max )
+        # Determine the largest bin we will actually use
+        self.bin_count = bin_for_range( max - 1, max, offsets = self.offsets ) + 1
+        # Create empty bins
+        self.bins = [ [] for i in range( self.bin_count ) ]
+
+    def open( self, filename, offset, version ):
+        self.filename = filename
+        self.offset = offset
+        # Open the file and seek to where we expect our header
+        f = open( filename )
+        f.seek( offset )
+        # Read min/max
+        min, max = read_packed( f, ">2I" )
+        self.new( min, max )
+        # Decide how many levels of bins based on 'max'
+        if version < 2:
+            # Prior to version 2 all files used the bins for 512MB
+            self.offsets = offsets_for_max_size( OLD_MAX - 1 )
+        else:
+            self.offsets = offsets_for_max_size( max )
+        # Read bin indexes
+        self.bin_offsets = []
+        self.bin_sizes = []
+        for i in range( self.bin_count ):
+            o, s = read_packed( f, ">2I" )
+            self.bin_offsets.append( o )
+            self.bin_sizes.append( s )
+        # Initialize bins to None, indicating that they need to be loaded
+        self.bins = [ None for i in range( self.bin_count ) ]
+
+    def add( self, start, end, val ):
+        """Add the interval (start,end) with associated value val to the index"""
+        insort( self.bins[ bin_for_range( start, end, offsets=self.offsets ) ], ( start, end, val ) )
+        assert val >= 0
+        self.max_val = max(self.max_val,val)
+
+    def find( self, start, end ):
+        rval = []
+        start_bin = ( max( start, self.min ) ) >> BIN_FIRST_SHIFT
+        end_bin = ( min( end, self.max ) - 1 ) >> BIN_FIRST_SHIFT
+        for offset in self.offsets:
+            for i in range( start_bin + offset, end_bin + offset + 1 ):
+                if self.bins[i] is None: self.load_bin( i )
+                # Iterate over bin and insert any overlapping elements into return value
+                for el_start, el_end, val in self.bins[i]:
+                    if el_start < end and el_end > start:
+                        insort_right( rval, ( el_start, el_end, val ) )
+            start_bin >>= BIN_NEXT_SHIFT
+            end_bin >>= BIN_NEXT_SHIFT
+        return rval
+
+    def iterate( self ):
+        for i in range( self.bin_count ):
+            if self.bins[i] is None: self.load_bin( i )
+            for entry in self.bins[i]:  yield entry
+
+    def load_bin( self, index ):
+        bin = []
+        if self.bin_sizes[index] == 0:
+            self.bins[index] = bin
+            return
+        f = open( self.filename )
+        f.seek( self.bin_offsets[index] )
+        # One big read for happy NFS
+        item_size = self.value_size + calcsize( ">2I" )
+        buffer = f.read( self.bin_sizes[index] * item_size )
+        for i in range( self.bin_sizes[index] ):
+            start, end = unpack( ">2I", buffer[ i*item_size : i*item_size+8 ] )
+            val = unpack_uints( buffer[ i*item_size+8 : (i+1)*item_size ] )
+            bin.append( (start, end, val) )
+        self.bins[index] = bin
+        f.close()
+
+    def write( self, f ):
+        value_size = self.value_size
+        item_size = value_size + calcsize( ">2I" )
+        # Write min/max
+        write_packed( f, ">2I", self.min, self.max )
+        # Write table of bin sizes and offsets
+        base = f.tell() + self.bin_count * calcsize( ">2I" )
+        for bin in self.bins:
+            write_packed( f, ">2I", base, len( bin ) )
+            base += len( bin ) * item_size
+        # Write contents of each bin
+        for bin in self.bins:
+            for start, end, val in bin:
+                write_packed( f, ">2I", start, end )
+                write_packed_uints( f, val, value_size )
+
+    def bytes_required( self ):
+        item_size = self.value_size + calcsize( ">2I" )
+        rval = calcsize( ">2I" )
+        rval += self.bin_count * calcsize( ">2I" )
+        for bin in self.bins:
+            rval += len( bin ) * item_size
+        return rval
+
+def write_packed( f, pattern, *vals ):
+    f.write( pack( pattern, *vals ) )
+
+def read_packed( f, pattern ):
+    rval = unpack( pattern, f.read( calcsize( pattern ) ) )
+    if len( rval ) == 1: return rval[0]
+    return rval
+
+def write_packed_uints( f, v, num_bytes ):
+    if num_bytes < 4:
+        write_packed( f, ">I", v )
+    else:
+        parts = []
+        while num_bytes > 0:
+            parts.append( v & 0xFFFFFFFFL )
+            v >>= 32
+            num_bytes -= 4
+        parts.reverse() # (write most-significant chunk first)
+        write_packed( f, ">%dI" % len( parts ), *parts )
+
+def unpack_uints( parts ):
+    chunks = len( parts )/4
+    vals = unpack( ">%dI" % chunks, parts )
+    val = vals[0]
+    for v in vals[1:]:
+        val = (val << 32) + v
+    return val
+
+def bytes_of( v ):
+    assert v > 0
+    b = 0
+    while v > 0:
+        v >>= 8
+        b += 1
+    return b
+
+def round_up_to_4( v ):
+    if v % 4 == 0:
+        return v
+    else:
+        return v + 4 - (v % 4)
+
diff --git a/lib/bx/interval_index_file_tests.py b/lib/bx/interval_index_file_tests.py
new file mode 100644
index 0000000..f050b7e
--- /dev/null
+++ b/lib/bx/interval_index_file_tests.py
@@ -0,0 +1,50 @@
+import interval_index_file
+from interval_index_file import Indexes
+from tempfile import mktemp
+import random
+
+def test_offsets():
+    assert interval_index_file.offsets_for_max_size( 512*1024*1024  - 1 ) == [ 512 + 64 + 8 + 1, 64 + 8 + 1, 8 + 1, 1, 0 ]
+
+def test_interval_index_file():
+    ix = Indexes()
+    chrs = []
+    for i in range( 5 ):
+        intervals = []
+        name = "seq%d" % i
+        max = random.randint( 0, interval_index_file.MAX )
+        # print name, "size", max
+        for i in range( 500 ):
+            start = random.randint( 0, max )
+            end = random.randint( 0, max )
+            if end < start:
+                end, start = start, end
+            ix.add( name, start, end, i, max=interval_index_file.MAX )
+            intervals.append( ( start, end, i ) )
+        chrs.append( intervals )
+    fname = mktemp()
+    f = open( fname, "w" )
+    ix.write( f )
+    f.close()
+    del ix
+    
+    ix = Indexes( fname )
+    for i in range( 5 ):
+        intervals = chrs[i]
+        name = "seq%d" % i
+        for i in range( 100 ):
+            start = random.randint( 0, max )
+            end = random.randint( 0, max )
+            if end < start:
+                end, start = start, end
+            query_intervals = set()
+            for ( s, e, i ) in intervals:
+                if e > start and s < end:
+                    query_intervals.add( ( s, e, i ) )
+            result = ix.find( name, start, end )
+            for inter in result:
+                assert inter in query_intervals
+
+def test_zero():
+    ix = Indexes()
+    ix.add("t.idx", 0, 0, 1, 123)
diff --git a/lib/bx/intervals/__init__.py b/lib/bx/intervals/__init__.py
new file mode 100644
index 0000000..db8c435
--- /dev/null
+++ b/lib/bx/intervals/__init__.py
@@ -0,0 +1,7 @@
+"""
+Tools and data structures for working with genomic intervals (or sets of 
+regions on a line in general) efficiently.
+"""
+
+# For compatiblity with existing stuff
+from bx.intervals.intersection import *
\ No newline at end of file
diff --git a/lib/bx/intervals/cluster.c b/lib/bx/intervals/cluster.c
new file mode 100644
index 0000000..1feabe2
--- /dev/null
+++ b/lib/bx/intervals/cluster.c
@@ -0,0 +1,2615 @@
+/* Generated by Cython 0.18 on Mon Jul 15 13:25:44 2013 */
+
+#define PY_SSIZE_T_CLEAN
+#include "Python.h"
+#ifndef Py_PYTHON_H
+    #error Python headers needed to compile C extensions, please install development version of Python.
+#elif PY_VERSION_HEX < 0x02040000
+    #error Cython requires Python 2.4+.
+#else
+#include <stddef.h> /* For offsetof */
+#ifndef offsetof
+#define offsetof(type, member) ( (size_t) & ((type*)0) -> member )
+#endif
+#if !defined(WIN32) && !defined(MS_WINDOWS)
+  #ifndef __stdcall
+    #define __stdcall
+  #endif
+  #ifndef __cdecl
+    #define __cdecl
+  #endif
+  #ifndef __fastcall
+    #define __fastcall
+  #endif
+#endif
+#ifndef DL_IMPORT
+  #define DL_IMPORT(t) t
+#endif
+#ifndef DL_EXPORT
+  #define DL_EXPORT(t) t
+#endif
+#ifndef PY_LONG_LONG
+  #define PY_LONG_LONG LONG_LONG
+#endif
+#ifndef Py_HUGE_VAL
+  #define Py_HUGE_VAL HUGE_VAL
+#endif
+#ifdef PYPY_VERSION
+#define CYTHON_COMPILING_IN_PYPY 1
+#define CYTHON_COMPILING_IN_CPYTHON 0
+#else
+#define CYTHON_COMPILING_IN_PYPY 0
+#define CYTHON_COMPILING_IN_CPYTHON 1
+#endif
+#if PY_VERSION_HEX < 0x02050000
+  typedef int Py_ssize_t;
+  #define PY_SSIZE_T_MAX INT_MAX
+  #define PY_SSIZE_T_MIN INT_MIN
+  #define PY_FORMAT_SIZE_T ""
+  #define CYTHON_FORMAT_SSIZE_T ""
+  #define PyInt_FromSsize_t(z) PyInt_FromLong(z)
+  #define PyInt_AsSsize_t(o)   __Pyx_PyInt_AsInt(o)
+  #define PyNumber_Index(o)    ((PyNumber_Check(o) && !PyFloat_Check(o)) ? PyNumber_Int(o) : \
+                                (PyErr_Format(PyExc_TypeError, \
+                                              "expected index value, got %.200s", Py_TYPE(o)->tp_name), \
+                                 (PyObject*)0))
+  #define __Pyx_PyIndex_Check(o) (PyNumber_Check(o) && !PyFloat_Check(o) && \
+                                  !PyComplex_Check(o))
+  #define PyIndex_Check __Pyx_PyIndex_Check
+  #define PyErr_WarnEx(category, message, stacklevel) PyErr_Warn(category, message)
+  #define __PYX_BUILD_PY_SSIZE_T "i"
+#else
+  #define __PYX_BUILD_PY_SSIZE_T "n"
+  #define CYTHON_FORMAT_SSIZE_T "z"
+  #define __Pyx_PyIndex_Check PyIndex_Check
+#endif
+#if PY_VERSION_HEX < 0x02060000
+  #define Py_REFCNT(ob) (((PyObject*)(ob))->ob_refcnt)
+  #define Py_TYPE(ob)   (((PyObject*)(ob))->ob_type)
+  #define Py_SIZE(ob)   (((PyVarObject*)(ob))->ob_size)
+  #define PyVarObject_HEAD_INIT(type, size) \
+          PyObject_HEAD_INIT(type) size,
+  #define PyType_Modified(t)
+  typedef struct {
+     void *buf;
+     PyObject *obj;
+     Py_ssize_t len;
+     Py_ssize_t itemsize;
+     int readonly;
+     int ndim;
+     char *format;
+     Py_ssize_t *shape;
+     Py_ssize_t *strides;
+     Py_ssize_t *suboffsets;
+     void *internal;
+  } Py_buffer;
+  #define PyBUF_SIMPLE 0
+  #define PyBUF_WRITABLE 0x0001
+  #define PyBUF_FORMAT 0x0004
+  #define PyBUF_ND 0x0008
+  #define PyBUF_STRIDES (0x0010 | PyBUF_ND)
+  #define PyBUF_C_CONTIGUOUS (0x0020 | PyBUF_STRIDES)
+  #define PyBUF_F_CONTIGUOUS (0x0040 | PyBUF_STRIDES)
+  #define PyBUF_ANY_CONTIGUOUS (0x0080 | PyBUF_STRIDES)
+  #define PyBUF_INDIRECT (0x0100 | PyBUF_STRIDES)
+  #define PyBUF_RECORDS (PyBUF_STRIDES | PyBUF_FORMAT | PyBUF_WRITABLE)
+  #define PyBUF_FULL (PyBUF_INDIRECT | PyBUF_FORMAT | PyBUF_WRITABLE)
+  typedef int (*getbufferproc)(PyObject *, Py_buffer *, int);
+  typedef void (*releasebufferproc)(PyObject *, Py_buffer *);
+#endif
+#if PY_MAJOR_VERSION < 3
+  #define __Pyx_BUILTIN_MODULE_NAME "__builtin__"
+  #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \
+          PyCode_New(a, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
+#else
+  #define __Pyx_BUILTIN_MODULE_NAME "builtins"
+  #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \
+          PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
+#endif
+#if PY_MAJOR_VERSION < 3 && PY_MINOR_VERSION < 6
+  #define PyUnicode_FromString(s) PyUnicode_Decode(s, strlen(s), "UTF-8", "strict")
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define Py_TPFLAGS_CHECKTYPES 0
+  #define Py_TPFLAGS_HAVE_INDEX 0
+#endif
+#if (PY_VERSION_HEX < 0x02060000) || (PY_MAJOR_VERSION >= 3)
+  #define Py_TPFLAGS_HAVE_NEWBUFFER 0
+#endif
+#if PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND)
+  #define CYTHON_PEP393_ENABLED 1
+  #define __Pyx_PyUnicode_READY(op)       (likely(PyUnicode_IS_READY(op)) ? \
+                                              0 : _PyUnicode_Ready((PyObject *)(op)))
+  #define __Pyx_PyUnicode_GET_LENGTH(u)   PyUnicode_GET_LENGTH(u)
+  #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_READ_CHAR(u, i)
+  #define __Pyx_PyUnicode_READ(k, d, i)   PyUnicode_READ(k, d, i)
+#else
+  #define CYTHON_PEP393_ENABLED 0
+  #define __Pyx_PyUnicode_READY(op)       (0)
+  #define __Pyx_PyUnicode_GET_LENGTH(u)   PyUnicode_GET_SIZE(u)
+  #define __Pyx_PyUnicode_READ_CHAR(u, i) ((Py_UCS4)(PyUnicode_AS_UNICODE(u)[i]))
+  #define __Pyx_PyUnicode_READ(k, d, i)   ((k=k), (Py_UCS4)(((Py_UNICODE*)d)[i]))
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define PyBaseString_Type            PyUnicode_Type
+  #define PyStringObject               PyUnicodeObject
+  #define PyString_Type                PyUnicode_Type
+  #define PyString_Check               PyUnicode_Check
+  #define PyString_CheckExact          PyUnicode_CheckExact
+#endif
+#if PY_VERSION_HEX < 0x02060000
+  #define PyBytesObject                PyStringObject
+  #define PyBytes_Type                 PyString_Type
+  #define PyBytes_Check                PyString_Check
+  #define PyBytes_CheckExact           PyString_CheckExact
+  #define PyBytes_FromString           PyString_FromString
+  #define PyBytes_FromStringAndSize    PyString_FromStringAndSize
+  #define PyBytes_FromFormat           PyString_FromFormat
+  #define PyBytes_DecodeEscape         PyString_DecodeEscape
+  #define PyBytes_AsString             PyString_AsString
+  #define PyBytes_AsStringAndSize      PyString_AsStringAndSize
+  #define PyBytes_Size                 PyString_Size
+  #define PyBytes_AS_STRING            PyString_AS_STRING
+  #define PyBytes_GET_SIZE             PyString_GET_SIZE
+  #define PyBytes_Repr                 PyString_Repr
+  #define PyBytes_Concat               PyString_Concat
+  #define PyBytes_ConcatAndDel         PyString_ConcatAndDel
+#endif
+#if PY_VERSION_HEX < 0x02060000
+  #define PySet_Check(obj)             PyObject_TypeCheck(obj, &PySet_Type)
+  #define PyFrozenSet_Check(obj)       PyObject_TypeCheck(obj, &PyFrozenSet_Type)
+#endif
+#ifndef PySet_CheckExact
+  #define PySet_CheckExact(obj)        (Py_TYPE(obj) == &PySet_Type)
+#endif
+#define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type)
+#if PY_MAJOR_VERSION >= 3
+  #define PyIntObject                  PyLongObject
+  #define PyInt_Type                   PyLong_Type
+  #define PyInt_Check(op)              PyLong_Check(op)
+  #define PyInt_CheckExact(op)         PyLong_CheckExact(op)
+  #define PyInt_FromString             PyLong_FromString
+  #define PyInt_FromUnicode            PyLong_FromUnicode
+  #define PyInt_FromLong               PyLong_FromLong
+  #define PyInt_FromSize_t             PyLong_FromSize_t
+  #define PyInt_FromSsize_t            PyLong_FromSsize_t
+  #define PyInt_AsLong                 PyLong_AsLong
+  #define PyInt_AS_LONG                PyLong_AS_LONG
+  #define PyInt_AsSsize_t              PyLong_AsSsize_t
+  #define PyInt_AsUnsignedLongMask     PyLong_AsUnsignedLongMask
+  #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define PyBoolObject                 PyLongObject
+#endif
+#if PY_VERSION_HEX < 0x03020000
+  typedef long Py_hash_t;
+  #define __Pyx_PyInt_FromHash_t PyInt_FromLong
+  #define __Pyx_PyInt_AsHash_t   PyInt_AsLong
+#else
+  #define __Pyx_PyInt_FromHash_t PyInt_FromSsize_t
+  #define __Pyx_PyInt_AsHash_t   PyInt_AsSsize_t
+#endif
+#if (PY_MAJOR_VERSION < 3) || (PY_VERSION_HEX >= 0x03010300)
+  #define __Pyx_PySequence_GetSlice(obj, a, b) PySequence_GetSlice(obj, a, b)
+  #define __Pyx_PySequence_SetSlice(obj, a, b, value) PySequence_SetSlice(obj, a, b, value)
+  #define __Pyx_PySequence_DelSlice(obj, a, b) PySequence_DelSlice(obj, a, b)
+#else
+  #define __Pyx_PySequence_GetSlice(obj, a, b) (unlikely(!(obj)) ? \
+        (PyErr_SetString(PyExc_SystemError, "null argument to internal routine"), (PyObject*)0) : \
+        (likely((obj)->ob_type->tp_as_mapping) ? (PySequence_GetSlice(obj, a, b)) : \
+            (PyErr_Format(PyExc_TypeError, "'%.200s' object is unsliceable", (obj)->ob_type->tp_name), (PyObject*)0)))
+  #define __Pyx_PySequence_SetSlice(obj, a, b, value) (unlikely(!(obj)) ? \
+        (PyErr_SetString(PyExc_SystemError, "null argument to internal routine"), -1) : \
+        (likely((obj)->ob_type->tp_as_mapping) ? (PySequence_SetSlice(obj, a, b, value)) : \
+            (PyErr_Format(PyExc_TypeError, "'%.200s' object doesn't support slice assignment", (obj)->ob_type->tp_name), -1)))
+  #define __Pyx_PySequence_DelSlice(obj, a, b) (unlikely(!(obj)) ? \
+        (PyErr_SetString(PyExc_SystemError, "null argument to internal routine"), -1) : \
+        (likely((obj)->ob_type->tp_as_mapping) ? (PySequence_DelSlice(obj, a, b)) : \
+            (PyErr_Format(PyExc_TypeError, "'%.200s' object doesn't support slice deletion", (obj)->ob_type->tp_name), -1)))
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define PyMethod_New(func, self, klass) ((self) ? PyMethod_New(func, self) : PyInstanceMethod_New(func))
+#endif
+#if PY_VERSION_HEX < 0x02050000
+  #define __Pyx_GetAttrString(o,n)   PyObject_GetAttrString((o),((char *)(n)))
+  #define __Pyx_SetAttrString(o,n,a) PyObject_SetAttrString((o),((char *)(n)),(a))
+  #define __Pyx_DelAttrString(o,n)   PyObject_DelAttrString((o),((char *)(n)))
+#else
+  #define __Pyx_GetAttrString(o,n)   PyObject_GetAttrString((o),(n))
+  #define __Pyx_SetAttrString(o,n,a) PyObject_SetAttrString((o),(n),(a))
+  #define __Pyx_DelAttrString(o,n)   PyObject_DelAttrString((o),(n))
+#endif
+#if PY_VERSION_HEX < 0x02050000
+  #define __Pyx_NAMESTR(n) ((char *)(n))
+  #define __Pyx_DOCSTR(n)  ((char *)(n))
+#else
+  #define __Pyx_NAMESTR(n) (n)
+  #define __Pyx_DOCSTR(n)  (n)
+#endif
+
+
+#if PY_MAJOR_VERSION >= 3
+  #define __Pyx_PyNumber_Divide(x,y)         PyNumber_TrueDivide(x,y)
+  #define __Pyx_PyNumber_InPlaceDivide(x,y)  PyNumber_InPlaceTrueDivide(x,y)
+#else
+  #define __Pyx_PyNumber_Divide(x,y)         PyNumber_Divide(x,y)
+  #define __Pyx_PyNumber_InPlaceDivide(x,y)  PyNumber_InPlaceDivide(x,y)
+#endif
+
+#ifndef __PYX_EXTERN_C
+  #ifdef __cplusplus
+    #define __PYX_EXTERN_C extern "C"
+  #else
+    #define __PYX_EXTERN_C extern
+  #endif
+#endif
+
+#if defined(WIN32) || defined(MS_WINDOWS)
+#define _USE_MATH_DEFINES
+#endif
+#include <math.h>
+#define __PYX_HAVE__bx__intervals__cluster
+#define __PYX_HAVE_API__bx__intervals__cluster
+#include "cluster.h"
+#ifdef _OPENMP
+#include <omp.h>
+#endif /* _OPENMP */
+
+#ifdef PYREX_WITHOUT_ASSERTIONS
+#define CYTHON_WITHOUT_ASSERTIONS
+#endif
+
+#ifndef CYTHON_INLINE
+  #if defined(__GNUC__)
+    #define CYTHON_INLINE __inline__
+  #elif defined(_MSC_VER)
+    #define CYTHON_INLINE __inline
+  #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+    #define CYTHON_INLINE inline
+  #else
+    #define CYTHON_INLINE
+  #endif
+#endif
+#ifndef CYTHON_UNUSED
+# if defined(__GNUC__)
+#   if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
+#     define CYTHON_UNUSED __attribute__ ((__unused__))
+#   else
+#     define CYTHON_UNUSED
+#   endif
+# elif defined(__ICC) || (defined(__INTEL_COMPILER) && !defined(_MSC_VER))
+#   define CYTHON_UNUSED __attribute__ ((__unused__))
+# else
+#   define CYTHON_UNUSED
+# endif
+#endif
+typedef struct {PyObject **p; char *s; const long n; const char* encoding; const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry; /*proto*/
+
+#define __Pyx_PyBytes_FromUString(s) PyBytes_FromString((char*)s)
+#define __Pyx_PyBytes_AsUString(s)   ((unsigned char*) PyBytes_AsString(s))
+#define __Pyx_Owned_Py_None(b) (Py_INCREF(Py_None), Py_None)
+#define __Pyx_PyBool_FromLong(b) ((b) ? (Py_INCREF(Py_True), Py_True) : (Py_INCREF(Py_False), Py_False))
+static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*);
+static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x);
+static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*);
+static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t);
+static CYTHON_INLINE size_t __Pyx_PyInt_AsSize_t(PyObject*);
+#if CYTHON_COMPILING_IN_CPYTHON
+#define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x))
+#else
+#define __pyx_PyFloat_AsDouble(x) PyFloat_AsDouble(x)
+#endif
+#define __pyx_PyFloat_AsFloat(x) ((float) __pyx_PyFloat_AsDouble(x))
+
+
+#ifdef __GNUC__
+  /* Test for GCC > 2.95 */
+  #if __GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))
+    #define likely(x)   __builtin_expect(!!(x), 1)
+    #define unlikely(x) __builtin_expect(!!(x), 0)
+  #else /* __GNUC__ > 2 ... */
+    #define likely(x)   (x)
+    #define unlikely(x) (x)
+  #endif /* __GNUC__ > 2 ... */
+#else /* __GNUC__ */
+  #define likely(x)   (x)
+  #define unlikely(x) (x)
+#endif /* __GNUC__ */
+    
+static PyObject *__pyx_m;
+static PyObject *__pyx_b;
+static PyObject *__pyx_empty_tuple;
+static PyObject *__pyx_empty_bytes;
+static int __pyx_lineno;
+static int __pyx_clineno = 0;
+static const char * __pyx_cfilenm= __FILE__;
+static const char *__pyx_filename;
+
+
+static const char *__pyx_f[] = {
+  "cluster.pyx",
+};
+
+/*--- Type declarations ---*/
+struct __pyx_obj_2bx_9intervals_7cluster_ClusterTree;
+
+/* "bx/intervals/cluster.pyx":57
+ *     void free_tree(clustertree *tree)
+ * 
+ * cdef class ClusterTree:             # <<<<<<<<<<<<<<
+ *     cdef clustertree *tree
+ *     cdef int mincols
+ */
+struct __pyx_obj_2bx_9intervals_7cluster_ClusterTree {
+  PyObject_HEAD
+  clustertree *tree;
+  int mincols;
+  int minregions;
+};
+
+#ifndef CYTHON_REFNANNY
+  #define CYTHON_REFNANNY 0
+#endif
+#if CYTHON_REFNANNY
+  typedef struct {
+    void (*INCREF)(void*, PyObject*, int);
+    void (*DECREF)(void*, PyObject*, int);
+    void (*GOTREF)(void*, PyObject*, int);
+    void (*GIVEREF)(void*, PyObject*, int);
+    void* (*SetupContext)(const char*, int, const char*);
+    void (*FinishContext)(void**);
+  } __Pyx_RefNannyAPIStruct;
+  static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL;
+  static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname); /*proto*/
+  #define __Pyx_RefNannyDeclarations void *__pyx_refnanny = NULL;
+#ifdef WITH_THREAD
+  #define __Pyx_RefNannySetupContext(name, acquire_gil) \
+          if (acquire_gil) { \
+              PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure(); \
+              __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__); \
+              PyGILState_Release(__pyx_gilstate_save); \
+          } else { \
+              __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__); \
+          }
+#else
+  #define __Pyx_RefNannySetupContext(name, acquire_gil) \
+          __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__)
+#endif
+  #define __Pyx_RefNannyFinishContext() \
+          __Pyx_RefNanny->FinishContext(&__pyx_refnanny)
+  #define __Pyx_INCREF(r)  __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_DECREF(r)  __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_GOTREF(r)  __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_XINCREF(r)  do { if((r) != NULL) {__Pyx_INCREF(r); }} while(0)
+  #define __Pyx_XDECREF(r)  do { if((r) != NULL) {__Pyx_DECREF(r); }} while(0)
+  #define __Pyx_XGOTREF(r)  do { if((r) != NULL) {__Pyx_GOTREF(r); }} while(0)
+  #define __Pyx_XGIVEREF(r) do { if((r) != NULL) {__Pyx_GIVEREF(r);}} while(0)
+#else
+  #define __Pyx_RefNannyDeclarations
+  #define __Pyx_RefNannySetupContext(name, acquire_gil)
+  #define __Pyx_RefNannyFinishContext()
+  #define __Pyx_INCREF(r) Py_INCREF(r)
+  #define __Pyx_DECREF(r) Py_DECREF(r)
+  #define __Pyx_GOTREF(r)
+  #define __Pyx_GIVEREF(r)
+  #define __Pyx_XINCREF(r) Py_XINCREF(r)
+  #define __Pyx_XDECREF(r) Py_XDECREF(r)
+  #define __Pyx_XGOTREF(r)
+  #define __Pyx_XGIVEREF(r)
+#endif /* CYTHON_REFNANNY */
+#define __Pyx_CLEAR(r)    do { PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);} while(0)
+#define __Pyx_XCLEAR(r)   do { if((r) != NULL) {PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);}} while(0)
+
+static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/
+
+static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
+    Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/
+
+static void __Pyx_RaiseDoubleKeywordsError(const char* func_name, PyObject* kw_name); /*proto*/
+
+static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
+    PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
+    const char* function_name); /*proto*/
+
+static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
+static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
+
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause); /*proto*/
+
+static CYTHON_INLINE unsigned char __Pyx_PyInt_AsUnsignedChar(PyObject *);
+
+static CYTHON_INLINE unsigned short __Pyx_PyInt_AsUnsignedShort(PyObject *);
+
+static CYTHON_INLINE unsigned int __Pyx_PyInt_AsUnsignedInt(PyObject *);
+
+static CYTHON_INLINE char __Pyx_PyInt_AsChar(PyObject *);
+
+static CYTHON_INLINE short __Pyx_PyInt_AsShort(PyObject *);
+
+static CYTHON_INLINE int __Pyx_PyInt_AsInt(PyObject *);
+
+static CYTHON_INLINE signed char __Pyx_PyInt_AsSignedChar(PyObject *);
+
+static CYTHON_INLINE signed short __Pyx_PyInt_AsSignedShort(PyObject *);
+
+static CYTHON_INLINE signed int __Pyx_PyInt_AsSignedInt(PyObject *);
+
+static CYTHON_INLINE int __Pyx_PyInt_AsLongDouble(PyObject *);
+
+static CYTHON_INLINE unsigned long __Pyx_PyInt_AsUnsignedLong(PyObject *);
+
+static CYTHON_INLINE unsigned PY_LONG_LONG __Pyx_PyInt_AsUnsignedLongLong(PyObject *);
+
+static CYTHON_INLINE long __Pyx_PyInt_AsLong(PyObject *);
+
+static CYTHON_INLINE PY_LONG_LONG __Pyx_PyInt_AsLongLong(PyObject *);
+
+static CYTHON_INLINE signed long __Pyx_PyInt_AsSignedLong(PyObject *);
+
+static CYTHON_INLINE signed PY_LONG_LONG __Pyx_PyInt_AsSignedLongLong(PyObject *);
+
+static int __Pyx_check_binary_version(void);
+
+typedef struct {
+    int code_line;
+    PyCodeObject* code_object;
+} __Pyx_CodeObjectCacheEntry;
+struct __Pyx_CodeObjectCache {
+    int count;
+    int max_count;
+    __Pyx_CodeObjectCacheEntry* entries;
+};
+static struct __Pyx_CodeObjectCache __pyx_code_cache = {0,0,NULL};
+static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line);
+static PyCodeObject *__pyx_find_code_object(int code_line);
+static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object);
+
+static void __Pyx_AddTraceback(const char *funcname, int c_line,
+                               int py_line, const char *filename); /*proto*/
+
+static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
+
+
+/* Module declarations from 'bx.intervals.cluster' */
+static PyTypeObject *__pyx_ptype_2bx_9intervals_7cluster_ClusterTree = 0;
+#define __Pyx_MODULE_NAME "bx.intervals.cluster"
+int __pyx_module_is_main_bx__intervals__cluster = 0;
+
+/* Implementation of 'bx.intervals.cluster' */
+static PyObject *__pyx_builtin_ValueError;
+static PyObject *__pyx_builtin_sorted;
+static int __pyx_pf_2bx_9intervals_7cluster_11ClusterTree___cinit__(struct __pyx_obj_2bx_9intervals_7cluster_ClusterTree *__pyx_v_self, PyObject *__pyx_v_mincols, PyObject *__pyx_v_minregions); /* proto */
+static void __pyx_pf_2bx_9intervals_7cluster_11ClusterTree_2__dealloc__(struct __pyx_obj_2bx_9intervals_7cluster_ClusterTree *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_2bx_9intervals_7cluster_11ClusterTree_4insert(struct __pyx_obj_2bx_9intervals_7cluster_ClusterTree *__pyx_v_self, PyObject *__pyx_v_s, PyObject *__pyx_v_e, PyObject *__pyx_v_id); /* proto */
+static PyObject *__pyx_pf_2bx_9intervals_7cluster_11ClusterTree_6getregions(struct __pyx_obj_2bx_9intervals_7cluster_ClusterTree *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_2bx_9intervals_7cluster_11ClusterTree_8getlines(struct __pyx_obj_2bx_9intervals_7cluster_ClusterTree *__pyx_v_self); /* proto */
+static char __pyx_k_1[] = "Interval start must be before end";
+static char __pyx_k_3[] = "\nKanwei Li, 2009\nInspired by previous ClusterTree\n\nProvides a ClusterTree data structure that supports efficient finding of \nclusters of intervals that are within a certain distance apart.\n\nThis clustering algorithm uses a binary tree structure. Nodes correspond to \nnon-overlapping intervals, where overlapping means that the distance between\ntwo intervals is less or equal to the max separation.\n\nThe tree self-balances using rotations based on the bin [...]
+static char __pyx_k__e[] = "e";
+static char __pyx_k__s[] = "s";
+static char __pyx_k__id[] = "id";
+static char __pyx_k__extend[] = "extend";
+static char __pyx_k__sorted[] = "sorted";
+static char __pyx_k__mincols[] = "mincols";
+static char __pyx_k____main__[] = "__main__";
+static char __pyx_k____test__[] = "__test__";
+static char __pyx_k__ValueError[] = "ValueError";
+static char __pyx_k__minregions[] = "minregions";
+static PyObject *__pyx_kp_s_1;
+static PyObject *__pyx_n_s__ValueError;
+static PyObject *__pyx_n_s____main__;
+static PyObject *__pyx_n_s____test__;
+static PyObject *__pyx_n_s__e;
+static PyObject *__pyx_n_s__extend;
+static PyObject *__pyx_n_s__id;
+static PyObject *__pyx_n_s__mincols;
+static PyObject *__pyx_n_s__minregions;
+static PyObject *__pyx_n_s__s;
+static PyObject *__pyx_n_s__sorted;
+static PyObject *__pyx_k_tuple_2;
+
+/* Python wrapper */
+static int __pyx_pw_2bx_9intervals_7cluster_11ClusterTree_1__cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static int __pyx_pw_2bx_9intervals_7cluster_11ClusterTree_1__cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_mincols = 0;
+  PyObject *__pyx_v_minregions = 0;
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__cinit__ (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__mincols,&__pyx_n_s__minregions,0};
+    PyObject* values[2] = {0,0};
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__mincols)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__minregions)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("__cinit__", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 62; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__cinit__") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 62; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
+      goto __pyx_L5_argtuple_error;
+    } else {
+      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+    }
+    __pyx_v_mincols = values[0];
+    __pyx_v_minregions = values[1];
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("__cinit__", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 62; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.intervals.cluster.ClusterTree.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return -1;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_9intervals_7cluster_11ClusterTree___cinit__(((struct __pyx_obj_2bx_9intervals_7cluster_ClusterTree *)__pyx_v_self), __pyx_v_mincols, __pyx_v_minregions);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/intervals/cluster.pyx":62
+ *     cdef int minregions
+ * 
+ *     def __cinit__(self, mincols, minregions):             # <<<<<<<<<<<<<<
+ *         self.tree = create_clustertree(mincols, minregions)
+ *         self.mincols = mincols
+ */
+
+static int __pyx_pf_2bx_9intervals_7cluster_11ClusterTree___cinit__(struct __pyx_obj_2bx_9intervals_7cluster_ClusterTree *__pyx_v_self, PyObject *__pyx_v_mincols, PyObject *__pyx_v_minregions) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  int __pyx_t_2;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__cinit__", 0);
+
+  /* "bx/intervals/cluster.pyx":63
+ * 
+ *     def __cinit__(self, mincols, minregions):
+ *         self.tree = create_clustertree(mincols, minregions)             # <<<<<<<<<<<<<<
+ *         self.mincols = mincols
+ *         self.minregions = minregions
+ */
+  __pyx_t_1 = __Pyx_PyInt_AsInt(__pyx_v_mincols); if (unlikely((__pyx_t_1 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 63; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = __Pyx_PyInt_AsInt(__pyx_v_minregions); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 63; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_v_self->tree = create_clustertree(__pyx_t_1, __pyx_t_2);
+
+  /* "bx/intervals/cluster.pyx":64
+ *     def __cinit__(self, mincols, minregions):
+ *         self.tree = create_clustertree(mincols, minregions)
+ *         self.mincols = mincols             # <<<<<<<<<<<<<<
+ *         self.minregions = minregions
+ * 
+ */
+  __pyx_t_2 = __Pyx_PyInt_AsInt(__pyx_v_mincols); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 64; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_v_self->mincols = __pyx_t_2;
+
+  /* "bx/intervals/cluster.pyx":65
+ *         self.tree = create_clustertree(mincols, minregions)
+ *         self.mincols = mincols
+ *         self.minregions = minregions             # <<<<<<<<<<<<<<
+ * 
+ *     def __dealloc__(self):
+ */
+  __pyx_t_2 = __Pyx_PyInt_AsInt(__pyx_v_minregions); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 65; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_v_self->minregions = __pyx_t_2;
+
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_AddTraceback("bx.intervals.cluster.ClusterTree.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = -1;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static void __pyx_pw_2bx_9intervals_7cluster_11ClusterTree_3__dealloc__(PyObject *__pyx_v_self); /*proto*/
+static void __pyx_pw_2bx_9intervals_7cluster_11ClusterTree_3__dealloc__(PyObject *__pyx_v_self) {
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__dealloc__ (wrapper)", 0);
+  __pyx_pf_2bx_9intervals_7cluster_11ClusterTree_2__dealloc__(((struct __pyx_obj_2bx_9intervals_7cluster_ClusterTree *)__pyx_v_self));
+  __Pyx_RefNannyFinishContext();
+}
+
+/* "bx/intervals/cluster.pyx":67
+ *         self.minregions = minregions
+ * 
+ *     def __dealloc__(self):             # <<<<<<<<<<<<<<
+ *         free_tree(self.tree)
+ * 
+ */
+
+static void __pyx_pf_2bx_9intervals_7cluster_11ClusterTree_2__dealloc__(struct __pyx_obj_2bx_9intervals_7cluster_ClusterTree *__pyx_v_self) {
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__dealloc__", 0);
+
+  /* "bx/intervals/cluster.pyx":68
+ * 
+ *     def __dealloc__(self):
+ *         free_tree(self.tree)             # <<<<<<<<<<<<<<
+ * 
+ *     def insert(self, s, e, id):
+ */
+  free_tree(__pyx_v_self->tree);
+
+  __Pyx_RefNannyFinishContext();
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_9intervals_7cluster_11ClusterTree_5insert(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_2bx_9intervals_7cluster_11ClusterTree_4insert[] = " Insert an interval with start, end, id as parameters";
+static PyObject *__pyx_pw_2bx_9intervals_7cluster_11ClusterTree_5insert(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_s = 0;
+  PyObject *__pyx_v_e = 0;
+  PyObject *__pyx_v_id = 0;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("insert (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__s,&__pyx_n_s__e,&__pyx_n_s__id,0};
+    PyObject* values[3] = {0,0,0};
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__s)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__e)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("insert", 1, 3, 3, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 70; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+        case  2:
+        if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__id)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("insert", 1, 3, 3, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 70; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "insert") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 70; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else if (PyTuple_GET_SIZE(__pyx_args) != 3) {
+      goto __pyx_L5_argtuple_error;
+    } else {
+      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+      values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+    }
+    __pyx_v_s = values[0];
+    __pyx_v_e = values[1];
+    __pyx_v_id = values[2];
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("insert", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 70; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.intervals.cluster.ClusterTree.insert", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_9intervals_7cluster_11ClusterTree_4insert(((struct __pyx_obj_2bx_9intervals_7cluster_ClusterTree *)__pyx_v_self), __pyx_v_s, __pyx_v_e, __pyx_v_id);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/intervals/cluster.pyx":70
+ *         free_tree(self.tree)
+ * 
+ *     def insert(self, s, e, id):             # <<<<<<<<<<<<<<
+ *         ''' Insert an interval with start, end, id as parameters'''
+ *         if s > e: raise ValueError("Interval start must be before end")
+ */
+
+static PyObject *__pyx_pf_2bx_9intervals_7cluster_11ClusterTree_4insert(struct __pyx_obj_2bx_9intervals_7cluster_ClusterTree *__pyx_v_self, PyObject *__pyx_v_s, PyObject *__pyx_v_e, PyObject *__pyx_v_id) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_t_2;
+  int __pyx_t_3;
+  int __pyx_t_4;
+  int __pyx_t_5;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("insert", 0);
+
+  /* "bx/intervals/cluster.pyx":72
+ *     def insert(self, s, e, id):
+ *         ''' Insert an interval with start, end, id as parameters'''
+ *         if s > e: raise ValueError("Interval start must be before end")             # <<<<<<<<<<<<<<
+ *         self.tree.root = clusternode_insert(self.tree, self.tree.root, s, e, id)
+ * 
+ */
+  __pyx_t_1 = PyObject_RichCompare(__pyx_v_s, __pyx_v_e, Py_GT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 72; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 72; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  if (__pyx_t_2) {
+    __pyx_t_1 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_k_tuple_2), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 72; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __Pyx_Raise(__pyx_t_1, 0, 0, 0);
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 72; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  /* "bx/intervals/cluster.pyx":73
+ *         ''' Insert an interval with start, end, id as parameters'''
+ *         if s > e: raise ValueError("Interval start must be before end")
+ *         self.tree.root = clusternode_insert(self.tree, self.tree.root, s, e, id)             # <<<<<<<<<<<<<<
+ * 
+ *     def getregions(self):
+ */
+  __pyx_t_3 = __Pyx_PyInt_AsInt(__pyx_v_s); if (unlikely((__pyx_t_3 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 73; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_4 = __Pyx_PyInt_AsInt(__pyx_v_e); if (unlikely((__pyx_t_4 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 73; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_5 = __Pyx_PyInt_AsInt(__pyx_v_id); if (unlikely((__pyx_t_5 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 73; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_v_self->tree->root = clusternode_insert(__pyx_v_self->tree, __pyx_v_self->tree->root, __pyx_t_3, __pyx_t_4, __pyx_t_5);
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("bx.intervals.cluster.ClusterTree.insert", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_9intervals_7cluster_11ClusterTree_7getregions(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_2bx_9intervals_7cluster_11ClusterTree_6getregions[] = " Returns a list clusters in ascending order of starting position.\n            Each cluster is a tuple of (start, end, [sorted ids of intervals in cluster])\n        \n        tree = ClusterTree(0, 0)\n        Insert (6, 7, 1), (1, 2, 3), (9, 10, 2), (3, 4, 0), (3, 8, 4)\n        tree.getregions() returns [(1, 2, [3]), (3, 8, [0, 1, 4]), (9, 10, [2])]\n        ";
+static PyObject *__pyx_pw_2bx_9intervals_7cluster_11ClusterTree_7getregions(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("getregions (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_9intervals_7cluster_11ClusterTree_6getregions(((struct __pyx_obj_2bx_9intervals_7cluster_ClusterTree *)__pyx_v_self));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/intervals/cluster.pyx":75
+ *         self.tree.root = clusternode_insert(self.tree, self.tree.root, s, e, id)
+ * 
+ *     def getregions(self):             # <<<<<<<<<<<<<<
+ *         ''' Returns a list clusters in ascending order of starting position.
+ *             Each cluster is a tuple of (start, end, [sorted ids of intervals in cluster])
+ */
+
+static PyObject *__pyx_pf_2bx_9intervals_7cluster_11ClusterTree_6getregions(struct __pyx_obj_2bx_9intervals_7cluster_ClusterTree *__pyx_v_self) {
+  treeitr *__pyx_v_itr;
+  interval *__pyx_v_ival;
+  PyObject *__pyx_v_regions = NULL;
+  PyObject *__pyx_v_ids = NULL;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_t_2;
+  struct struct_interval *__pyx_t_3;
+  int __pyx_t_4;
+  PyObject *__pyx_t_5 = NULL;
+  PyObject *__pyx_t_6 = NULL;
+  PyObject *__pyx_t_7 = NULL;
+  struct struct_treeitr *__pyx_t_8;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("getregions", 0);
+
+  /* "bx/intervals/cluster.pyx":86
+ *         cdef interval *ival
+ * 
+ *         regions = []             # <<<<<<<<<<<<<<
+ *         itr = clusteritr(self.tree)
+ * 
+ */
+  __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 86; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_v_regions = ((PyObject*)__pyx_t_1);
+  __pyx_t_1 = 0;
+
+  /* "bx/intervals/cluster.pyx":87
+ * 
+ *         regions = []
+ *         itr = clusteritr(self.tree)             # <<<<<<<<<<<<<<
+ * 
+ *         while (itr):
+ */
+  __pyx_v_itr = clusteritr(__pyx_v_self->tree);
+
+  /* "bx/intervals/cluster.pyx":89
+ *         itr = clusteritr(self.tree)
+ * 
+ *         while (itr):             # <<<<<<<<<<<<<<
+ *             ids = []
+ *             ival = itr.node.interval_head
+ */
+  while (1) {
+    __pyx_t_2 = (__pyx_v_itr != 0);
+    if (!__pyx_t_2) break;
+
+    /* "bx/intervals/cluster.pyx":90
+ * 
+ *         while (itr):
+ *             ids = []             # <<<<<<<<<<<<<<
+ *             ival = itr.node.interval_head
+ *             while (ival):
+ */
+    __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 90; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __Pyx_XDECREF(((PyObject *)__pyx_v_ids));
+    __pyx_v_ids = ((PyObject*)__pyx_t_1);
+    __pyx_t_1 = 0;
+
+    /* "bx/intervals/cluster.pyx":91
+ *         while (itr):
+ *             ids = []
+ *             ival = itr.node.interval_head             # <<<<<<<<<<<<<<
+ *             while (ival):
+ *                 ids.append(ival.id)
+ */
+    __pyx_t_3 = __pyx_v_itr->node->interval_head;
+    __pyx_v_ival = __pyx_t_3;
+
+    /* "bx/intervals/cluster.pyx":92
+ *             ids = []
+ *             ival = itr.node.interval_head
+ *             while (ival):             # <<<<<<<<<<<<<<
+ *                 ids.append(ival.id)
+ *                 ival = ival.next
+ */
+    while (1) {
+      __pyx_t_2 = (__pyx_v_ival != 0);
+      if (!__pyx_t_2) break;
+
+      /* "bx/intervals/cluster.pyx":93
+ *             ival = itr.node.interval_head
+ *             while (ival):
+ *                 ids.append(ival.id)             # <<<<<<<<<<<<<<
+ *                 ival = ival.next
+ * 
+ */
+      __pyx_t_1 = PyInt_FromLong(__pyx_v_ival->id); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 93; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_1);
+      __pyx_t_4 = PyList_Append(__pyx_v_ids, __pyx_t_1); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 93; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+      /* "bx/intervals/cluster.pyx":94
+ *             while (ival):
+ *                 ids.append(ival.id)
+ *                 ival = ival.next             # <<<<<<<<<<<<<<
+ * 
+ *             regions.append( (itr.node.start, itr.node.end, sorted(ids)) )
+ */
+      __pyx_t_3 = __pyx_v_ival->next;
+      __pyx_v_ival = __pyx_t_3;
+    }
+
+    /* "bx/intervals/cluster.pyx":96
+ *                 ival = ival.next
+ * 
+ *             regions.append( (itr.node.start, itr.node.end, sorted(ids)) )             # <<<<<<<<<<<<<<
+ *             itr = itr.next
+ *         freeclusteritr(itr)
+ */
+    __pyx_t_1 = PyInt_FromLong(__pyx_v_itr->node->start); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 96; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __pyx_t_5 = PyInt_FromLong(__pyx_v_itr->node->end); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 96; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_5);
+    __pyx_t_6 = PyTuple_New(1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 96; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_6);
+    __Pyx_INCREF(((PyObject *)__pyx_v_ids));
+    PyTuple_SET_ITEM(__pyx_t_6, 0, ((PyObject *)__pyx_v_ids));
+    __Pyx_GIVEREF(((PyObject *)__pyx_v_ids));
+    __pyx_t_7 = PyObject_Call(__pyx_builtin_sorted, ((PyObject *)__pyx_t_6), NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 96; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_7);
+    __Pyx_DECREF(((PyObject *)__pyx_t_6)); __pyx_t_6 = 0;
+    __pyx_t_6 = PyTuple_New(3); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 96; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_6);
+    PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_1);
+    __Pyx_GIVEREF(__pyx_t_1);
+    PyTuple_SET_ITEM(__pyx_t_6, 1, __pyx_t_5);
+    __Pyx_GIVEREF(__pyx_t_5);
+    PyTuple_SET_ITEM(__pyx_t_6, 2, __pyx_t_7);
+    __Pyx_GIVEREF(__pyx_t_7);
+    __pyx_t_1 = 0;
+    __pyx_t_5 = 0;
+    __pyx_t_7 = 0;
+    __pyx_t_4 = PyList_Append(__pyx_v_regions, ((PyObject *)__pyx_t_6)); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 96; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(((PyObject *)__pyx_t_6)); __pyx_t_6 = 0;
+
+    /* "bx/intervals/cluster.pyx":97
+ * 
+ *             regions.append( (itr.node.start, itr.node.end, sorted(ids)) )
+ *             itr = itr.next             # <<<<<<<<<<<<<<
+ *         freeclusteritr(itr)
+ *         return regions
+ */
+    __pyx_t_8 = __pyx_v_itr->next;
+    __pyx_v_itr = __pyx_t_8;
+  }
+
+  /* "bx/intervals/cluster.pyx":98
+ *             regions.append( (itr.node.start, itr.node.end, sorted(ids)) )
+ *             itr = itr.next
+ *         freeclusteritr(itr)             # <<<<<<<<<<<<<<
+ *         return regions
+ * 
+ */
+  freeclusteritr(__pyx_v_itr);
+
+  /* "bx/intervals/cluster.pyx":99
+ *             itr = itr.next
+ *         freeclusteritr(itr)
+ *         return regions             # <<<<<<<<<<<<<<
+ * 
+ *     def getlines(self):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __Pyx_INCREF(((PyObject *)__pyx_v_regions));
+  __pyx_r = ((PyObject *)__pyx_v_regions);
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_5);
+  __Pyx_XDECREF(__pyx_t_6);
+  __Pyx_XDECREF(__pyx_t_7);
+  __Pyx_AddTraceback("bx.intervals.cluster.ClusterTree.getregions", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_regions);
+  __Pyx_XDECREF(__pyx_v_ids);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_9intervals_7cluster_11ClusterTree_9getlines(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_2bx_9intervals_7cluster_11ClusterTree_8getlines[] = " Similar to getregions except it just returns a list of ids of intervals\n            The above example would return [3, 0, 1, 4, 2]\n         ";
+static PyObject *__pyx_pw_2bx_9intervals_7cluster_11ClusterTree_9getlines(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("getlines (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_9intervals_7cluster_11ClusterTree_8getlines(((struct __pyx_obj_2bx_9intervals_7cluster_ClusterTree *)__pyx_v_self));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/intervals/cluster.pyx":101
+ *         return regions
+ * 
+ *     def getlines(self):             # <<<<<<<<<<<<<<
+ *         ''' Similar to getregions except it just returns a list of ids of intervals
+ *             The above example would return [3, 0, 1, 4, 2]
+ */
+
+static PyObject *__pyx_pf_2bx_9intervals_7cluster_11ClusterTree_8getlines(struct __pyx_obj_2bx_9intervals_7cluster_ClusterTree *__pyx_v_self) {
+  treeitr *__pyx_v_itr;
+  interval *__pyx_v_ival;
+  PyObject *__pyx_v_lines = NULL;
+  PyObject *__pyx_v_ids = NULL;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_t_2;
+  struct struct_interval *__pyx_t_3;
+  int __pyx_t_4;
+  PyObject *__pyx_t_5 = NULL;
+  PyObject *__pyx_t_6 = NULL;
+  struct struct_treeitr *__pyx_t_7;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("getlines", 0);
+
+  /* "bx/intervals/cluster.pyx":108
+ *         cdef interval *ival
+ * 
+ *         lines = []             # <<<<<<<<<<<<<<
+ *         itr = clusteritr(self.tree)
+ * 
+ */
+  __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_v_lines = ((PyObject*)__pyx_t_1);
+  __pyx_t_1 = 0;
+
+  /* "bx/intervals/cluster.pyx":109
+ * 
+ *         lines = []
+ *         itr = clusteritr(self.tree)             # <<<<<<<<<<<<<<
+ * 
+ *         while (itr):
+ */
+  __pyx_v_itr = clusteritr(__pyx_v_self->tree);
+
+  /* "bx/intervals/cluster.pyx":111
+ *         itr = clusteritr(self.tree)
+ * 
+ *         while (itr):             # <<<<<<<<<<<<<<
+ *             ids = []
+ *             ival = itr.node.interval_head
+ */
+  while (1) {
+    __pyx_t_2 = (__pyx_v_itr != 0);
+    if (!__pyx_t_2) break;
+
+    /* "bx/intervals/cluster.pyx":112
+ * 
+ *         while (itr):
+ *             ids = []             # <<<<<<<<<<<<<<
+ *             ival = itr.node.interval_head
+ *             while (ival):
+ */
+    __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 112; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __Pyx_XDECREF(((PyObject *)__pyx_v_ids));
+    __pyx_v_ids = ((PyObject*)__pyx_t_1);
+    __pyx_t_1 = 0;
+
+    /* "bx/intervals/cluster.pyx":113
+ *         while (itr):
+ *             ids = []
+ *             ival = itr.node.interval_head             # <<<<<<<<<<<<<<
+ *             while (ival):
+ *                 ids.append(ival.id)
+ */
+    __pyx_t_3 = __pyx_v_itr->node->interval_head;
+    __pyx_v_ival = __pyx_t_3;
+
+    /* "bx/intervals/cluster.pyx":114
+ *             ids = []
+ *             ival = itr.node.interval_head
+ *             while (ival):             # <<<<<<<<<<<<<<
+ *                 ids.append(ival.id)
+ *                 ival = ival.next
+ */
+    while (1) {
+      __pyx_t_2 = (__pyx_v_ival != 0);
+      if (!__pyx_t_2) break;
+
+      /* "bx/intervals/cluster.pyx":115
+ *             ival = itr.node.interval_head
+ *             while (ival):
+ *                 ids.append(ival.id)             # <<<<<<<<<<<<<<
+ *                 ival = ival.next
+ * 
+ */
+      __pyx_t_1 = PyInt_FromLong(__pyx_v_ival->id); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_1);
+      __pyx_t_4 = PyList_Append(__pyx_v_ids, __pyx_t_1); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+      /* "bx/intervals/cluster.pyx":116
+ *             while (ival):
+ *                 ids.append(ival.id)
+ *                 ival = ival.next             # <<<<<<<<<<<<<<
+ * 
+ *             lines.extend(sorted(ids))
+ */
+      __pyx_t_3 = __pyx_v_ival->next;
+      __pyx_v_ival = __pyx_t_3;
+    }
+
+    /* "bx/intervals/cluster.pyx":118
+ *                 ival = ival.next
+ * 
+ *             lines.extend(sorted(ids))             # <<<<<<<<<<<<<<
+ *             itr = itr.next
+ *         freeclusteritr(itr)
+ */
+    __pyx_t_1 = PyObject_GetAttr(((PyObject *)__pyx_v_lines), __pyx_n_s__extend); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 118; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 118; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_5);
+    __Pyx_INCREF(((PyObject *)__pyx_v_ids));
+    PyTuple_SET_ITEM(__pyx_t_5, 0, ((PyObject *)__pyx_v_ids));
+    __Pyx_GIVEREF(((PyObject *)__pyx_v_ids));
+    __pyx_t_6 = PyObject_Call(__pyx_builtin_sorted, ((PyObject *)__pyx_t_5), NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 118; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_6);
+    __Pyx_DECREF(((PyObject *)__pyx_t_5)); __pyx_t_5 = 0;
+    __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 118; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_5);
+    PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_6);
+    __Pyx_GIVEREF(__pyx_t_6);
+    __pyx_t_6 = 0;
+    __pyx_t_6 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_5), NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 118; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_6);
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    __Pyx_DECREF(((PyObject *)__pyx_t_5)); __pyx_t_5 = 0;
+    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+
+    /* "bx/intervals/cluster.pyx":119
+ * 
+ *             lines.extend(sorted(ids))
+ *             itr = itr.next             # <<<<<<<<<<<<<<
+ *         freeclusteritr(itr)
+ *         return lines
+ */
+    __pyx_t_7 = __pyx_v_itr->next;
+    __pyx_v_itr = __pyx_t_7;
+  }
+
+  /* "bx/intervals/cluster.pyx":120
+ *             lines.extend(sorted(ids))
+ *             itr = itr.next
+ *         freeclusteritr(itr)             # <<<<<<<<<<<<<<
+ *         return lines
+ * 
+ */
+  freeclusteritr(__pyx_v_itr);
+
+  /* "bx/intervals/cluster.pyx":121
+ *             itr = itr.next
+ *         freeclusteritr(itr)
+ *         return lines             # <<<<<<<<<<<<<<
+ * 
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __Pyx_INCREF(((PyObject *)__pyx_v_lines));
+  __pyx_r = ((PyObject *)__pyx_v_lines);
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_5);
+  __Pyx_XDECREF(__pyx_t_6);
+  __Pyx_AddTraceback("bx.intervals.cluster.ClusterTree.getlines", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_lines);
+  __Pyx_XDECREF(__pyx_v_ids);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_tp_new_2bx_9intervals_7cluster_ClusterTree(PyTypeObject *t, PyObject *a, PyObject *k) {
+  PyObject *o = (*t->tp_alloc)(t, 0);
+  if (!o) return 0;
+  if (__pyx_pw_2bx_9intervals_7cluster_11ClusterTree_1__cinit__(o, a, k) < 0) {
+    Py_DECREF(o); o = 0;
+  }
+  return o;
+}
+
+static void __pyx_tp_dealloc_2bx_9intervals_7cluster_ClusterTree(PyObject *o) {
+  {
+    PyObject *etype, *eval, *etb;
+    PyErr_Fetch(&etype, &eval, &etb);
+    ++Py_REFCNT(o);
+    __pyx_pw_2bx_9intervals_7cluster_11ClusterTree_3__dealloc__(o);
+    if (PyErr_Occurred()) PyErr_WriteUnraisable(o);
+    --Py_REFCNT(o);
+    PyErr_Restore(etype, eval, etb);
+  }
+  (*Py_TYPE(o)->tp_free)(o);
+}
+
+static PyMethodDef __pyx_methods_2bx_9intervals_7cluster_ClusterTree[] = {
+  {__Pyx_NAMESTR("insert"), (PyCFunction)__pyx_pw_2bx_9intervals_7cluster_11ClusterTree_5insert, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(__pyx_doc_2bx_9intervals_7cluster_11ClusterTree_4insert)},
+  {__Pyx_NAMESTR("getregions"), (PyCFunction)__pyx_pw_2bx_9intervals_7cluster_11ClusterTree_7getregions, METH_NOARGS, __Pyx_DOCSTR(__pyx_doc_2bx_9intervals_7cluster_11ClusterTree_6getregions)},
+  {__Pyx_NAMESTR("getlines"), (PyCFunction)__pyx_pw_2bx_9intervals_7cluster_11ClusterTree_9getlines, METH_NOARGS, __Pyx_DOCSTR(__pyx_doc_2bx_9intervals_7cluster_11ClusterTree_8getlines)},
+  {0, 0, 0, 0}
+};
+
+static PyNumberMethods __pyx_tp_as_number_ClusterTree = {
+  0, /*nb_add*/
+  0, /*nb_subtract*/
+  0, /*nb_multiply*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_divide*/
+  #endif
+  0, /*nb_remainder*/
+  0, /*nb_divmod*/
+  0, /*nb_power*/
+  0, /*nb_negative*/
+  0, /*nb_positive*/
+  0, /*nb_absolute*/
+  0, /*nb_nonzero*/
+  0, /*nb_invert*/
+  0, /*nb_lshift*/
+  0, /*nb_rshift*/
+  0, /*nb_and*/
+  0, /*nb_xor*/
+  0, /*nb_or*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_coerce*/
+  #endif
+  0, /*nb_int*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_long*/
+  #else
+  0, /*reserved*/
+  #endif
+  0, /*nb_float*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_oct*/
+  #endif
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_hex*/
+  #endif
+  0, /*nb_inplace_add*/
+  0, /*nb_inplace_subtract*/
+  0, /*nb_inplace_multiply*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_inplace_divide*/
+  #endif
+  0, /*nb_inplace_remainder*/
+  0, /*nb_inplace_power*/
+  0, /*nb_inplace_lshift*/
+  0, /*nb_inplace_rshift*/
+  0, /*nb_inplace_and*/
+  0, /*nb_inplace_xor*/
+  0, /*nb_inplace_or*/
+  0, /*nb_floor_divide*/
+  0, /*nb_true_divide*/
+  0, /*nb_inplace_floor_divide*/
+  0, /*nb_inplace_true_divide*/
+  #if PY_VERSION_HEX >= 0x02050000
+  0, /*nb_index*/
+  #endif
+};
+
+static PySequenceMethods __pyx_tp_as_sequence_ClusterTree = {
+  0, /*sq_length*/
+  0, /*sq_concat*/
+  0, /*sq_repeat*/
+  0, /*sq_item*/
+  0, /*sq_slice*/
+  0, /*sq_ass_item*/
+  0, /*sq_ass_slice*/
+  0, /*sq_contains*/
+  0, /*sq_inplace_concat*/
+  0, /*sq_inplace_repeat*/
+};
+
+static PyMappingMethods __pyx_tp_as_mapping_ClusterTree = {
+  0, /*mp_length*/
+  0, /*mp_subscript*/
+  0, /*mp_ass_subscript*/
+};
+
+static PyBufferProcs __pyx_tp_as_buffer_ClusterTree = {
+  #if PY_MAJOR_VERSION < 3
+  0, /*bf_getreadbuffer*/
+  #endif
+  #if PY_MAJOR_VERSION < 3
+  0, /*bf_getwritebuffer*/
+  #endif
+  #if PY_MAJOR_VERSION < 3
+  0, /*bf_getsegcount*/
+  #endif
+  #if PY_MAJOR_VERSION < 3
+  0, /*bf_getcharbuffer*/
+  #endif
+  #if PY_VERSION_HEX >= 0x02060000
+  0, /*bf_getbuffer*/
+  #endif
+  #if PY_VERSION_HEX >= 0x02060000
+  0, /*bf_releasebuffer*/
+  #endif
+};
+
+static PyTypeObject __pyx_type_2bx_9intervals_7cluster_ClusterTree = {
+  PyVarObject_HEAD_INIT(0, 0)
+  __Pyx_NAMESTR("bx.intervals.cluster.ClusterTree"), /*tp_name*/
+  sizeof(struct __pyx_obj_2bx_9intervals_7cluster_ClusterTree), /*tp_basicsize*/
+  0, /*tp_itemsize*/
+  __pyx_tp_dealloc_2bx_9intervals_7cluster_ClusterTree, /*tp_dealloc*/
+  0, /*tp_print*/
+  0, /*tp_getattr*/
+  0, /*tp_setattr*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*tp_compare*/
+  #else
+  0, /*reserved*/
+  #endif
+  0, /*tp_repr*/
+  &__pyx_tp_as_number_ClusterTree, /*tp_as_number*/
+  &__pyx_tp_as_sequence_ClusterTree, /*tp_as_sequence*/
+  &__pyx_tp_as_mapping_ClusterTree, /*tp_as_mapping*/
+  0, /*tp_hash*/
+  0, /*tp_call*/
+  0, /*tp_str*/
+  0, /*tp_getattro*/
+  0, /*tp_setattro*/
+  &__pyx_tp_as_buffer_ClusterTree, /*tp_as_buffer*/
+  Py_TPFLAGS_DEFAULT|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE, /*tp_flags*/
+  0, /*tp_doc*/
+  0, /*tp_traverse*/
+  0, /*tp_clear*/
+  0, /*tp_richcompare*/
+  0, /*tp_weaklistoffset*/
+  0, /*tp_iter*/
+  0, /*tp_iternext*/
+  __pyx_methods_2bx_9intervals_7cluster_ClusterTree, /*tp_methods*/
+  0, /*tp_members*/
+  0, /*tp_getset*/
+  0, /*tp_base*/
+  0, /*tp_dict*/
+  0, /*tp_descr_get*/
+  0, /*tp_descr_set*/
+  0, /*tp_dictoffset*/
+  0, /*tp_init*/
+  0, /*tp_alloc*/
+  __pyx_tp_new_2bx_9intervals_7cluster_ClusterTree, /*tp_new*/
+  0, /*tp_free*/
+  0, /*tp_is_gc*/
+  0, /*tp_bases*/
+  0, /*tp_mro*/
+  0, /*tp_cache*/
+  0, /*tp_subclasses*/
+  0, /*tp_weaklist*/
+  0, /*tp_del*/
+  #if PY_VERSION_HEX >= 0x02060000
+  0, /*tp_version_tag*/
+  #endif
+};
+
+static PyMethodDef __pyx_methods[] = {
+  {0, 0, 0, 0}
+};
+
+#if PY_MAJOR_VERSION >= 3
+static struct PyModuleDef __pyx_moduledef = {
+  #if PY_VERSION_HEX < 0x03020000
+    { PyObject_HEAD_INIT(NULL) NULL, 0, NULL },
+  #else
+    PyModuleDef_HEAD_INIT,
+  #endif
+    __Pyx_NAMESTR("cluster"),
+    __Pyx_DOCSTR(__pyx_k_3), /* m_doc */
+    -1, /* m_size */
+    __pyx_methods /* m_methods */,
+    NULL, /* m_reload */
+    NULL, /* m_traverse */
+    NULL, /* m_clear */
+    NULL /* m_free */
+};
+#endif
+
+static __Pyx_StringTabEntry __pyx_string_tab[] = {
+  {&__pyx_kp_s_1, __pyx_k_1, sizeof(__pyx_k_1), 0, 0, 1, 0},
+  {&__pyx_n_s__ValueError, __pyx_k__ValueError, sizeof(__pyx_k__ValueError), 0, 0, 1, 1},
+  {&__pyx_n_s____main__, __pyx_k____main__, sizeof(__pyx_k____main__), 0, 0, 1, 1},
+  {&__pyx_n_s____test__, __pyx_k____test__, sizeof(__pyx_k____test__), 0, 0, 1, 1},
+  {&__pyx_n_s__e, __pyx_k__e, sizeof(__pyx_k__e), 0, 0, 1, 1},
+  {&__pyx_n_s__extend, __pyx_k__extend, sizeof(__pyx_k__extend), 0, 0, 1, 1},
+  {&__pyx_n_s__id, __pyx_k__id, sizeof(__pyx_k__id), 0, 0, 1, 1},
+  {&__pyx_n_s__mincols, __pyx_k__mincols, sizeof(__pyx_k__mincols), 0, 0, 1, 1},
+  {&__pyx_n_s__minregions, __pyx_k__minregions, sizeof(__pyx_k__minregions), 0, 0, 1, 1},
+  {&__pyx_n_s__s, __pyx_k__s, sizeof(__pyx_k__s), 0, 0, 1, 1},
+  {&__pyx_n_s__sorted, __pyx_k__sorted, sizeof(__pyx_k__sorted), 0, 0, 1, 1},
+  {0, 0, 0, 0, 0, 0, 0}
+};
+static int __Pyx_InitCachedBuiltins(void) {
+  __pyx_builtin_ValueError = __Pyx_GetName(__pyx_b, __pyx_n_s__ValueError); if (!__pyx_builtin_ValueError) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 72; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_builtin_sorted = __Pyx_GetName(__pyx_b, __pyx_n_s__sorted); if (!__pyx_builtin_sorted) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 96; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  return 0;
+  __pyx_L1_error:;
+  return -1;
+}
+
+static int __Pyx_InitCachedConstants(void) {
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0);
+
+  /* "bx/intervals/cluster.pyx":72
+ *     def insert(self, s, e, id):
+ *         ''' Insert an interval with start, end, id as parameters'''
+ *         if s > e: raise ValueError("Interval start must be before end")             # <<<<<<<<<<<<<<
+ *         self.tree.root = clusternode_insert(self.tree, self.tree.root, s, e, id)
+ * 
+ */
+  __pyx_k_tuple_2 = PyTuple_Pack(1, ((PyObject *)__pyx_kp_s_1)); if (unlikely(!__pyx_k_tuple_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 72; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_k_tuple_2);
+  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_2));
+  __Pyx_RefNannyFinishContext();
+  return 0;
+  __pyx_L1_error:;
+  __Pyx_RefNannyFinishContext();
+  return -1;
+}
+
+static int __Pyx_InitGlobals(void) {
+  if (__Pyx_InitStrings(__pyx_string_tab) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  return 0;
+  __pyx_L1_error:;
+  return -1;
+}
+
+#if PY_MAJOR_VERSION < 3
+PyMODINIT_FUNC initcluster(void); /*proto*/
+PyMODINIT_FUNC initcluster(void)
+#else
+PyMODINIT_FUNC PyInit_cluster(void); /*proto*/
+PyMODINIT_FUNC PyInit_cluster(void)
+#endif
+{
+  PyObject *__pyx_t_1 = NULL;
+  __Pyx_RefNannyDeclarations
+  #if CYTHON_REFNANNY
+  __Pyx_RefNanny = __Pyx_RefNannyImportAPI("refnanny");
+  if (!__Pyx_RefNanny) {
+      PyErr_Clear();
+      __Pyx_RefNanny = __Pyx_RefNannyImportAPI("Cython.Runtime.refnanny");
+      if (!__Pyx_RefNanny)
+          Py_FatalError("failed to import 'refnanny' module");
+  }
+  #endif
+  __Pyx_RefNannySetupContext("PyMODINIT_FUNC PyInit_cluster(void)", 0);
+  if ( __Pyx_check_binary_version() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_bytes)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #ifdef __Pyx_CyFunction_USED
+  if (__Pyx_CyFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #endif
+  #ifdef __Pyx_FusedFunction_USED
+  if (__pyx_FusedFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #endif
+  #ifdef __Pyx_Generator_USED
+  if (__pyx_Generator_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #endif
+  /*--- Library function declarations ---*/
+  /*--- Threads initialization code ---*/
+  #if defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS
+  #ifdef WITH_THREAD /* Python build with threading support? */
+  PyEval_InitThreads();
+  #endif
+  #endif
+  /*--- Module creation code ---*/
+  #if PY_MAJOR_VERSION < 3
+  __pyx_m = Py_InitModule4(__Pyx_NAMESTR("cluster"), __pyx_methods, __Pyx_DOCSTR(__pyx_k_3), 0, PYTHON_API_VERSION); Py_XINCREF(__pyx_m);
+  #else
+  __pyx_m = PyModule_Create(&__pyx_moduledef);
+  #endif
+  if (unlikely(!__pyx_m)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #if PY_MAJOR_VERSION >= 3
+  {
+    PyObject *modules = PyImport_GetModuleDict(); if (unlikely(!modules)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (!PyDict_GetItemString(modules, "bx.intervals.cluster")) {
+      if (unlikely(PyDict_SetItemString(modules, "bx.intervals.cluster", __pyx_m) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+  }
+  #endif
+  __pyx_b = PyImport_AddModule(__Pyx_NAMESTR(__Pyx_BUILTIN_MODULE_NAME)); if (unlikely(!__pyx_b)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #if CYTHON_COMPILING_IN_PYPY
+  Py_INCREF(__pyx_b);
+  #endif
+  if (__Pyx_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  /*--- Initialize various global constants etc. ---*/
+  if (unlikely(__Pyx_InitGlobals() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (__pyx_module_is_main_bx__intervals__cluster) {
+    if (__Pyx_SetAttrString(__pyx_m, "__name__", __pyx_n_s____main__) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  }
+  /*--- Builtin init code ---*/
+  if (unlikely(__Pyx_InitCachedBuiltins() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  /*--- Constants init code ---*/
+  if (unlikely(__Pyx_InitCachedConstants() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  /*--- Global init code ---*/
+  /*--- Variable export code ---*/
+  /*--- Function export code ---*/
+  /*--- Type init code ---*/
+  if (PyType_Ready(&__pyx_type_2bx_9intervals_7cluster_ClusterTree) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 57; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (__Pyx_SetAttrString(__pyx_m, "ClusterTree", (PyObject *)&__pyx_type_2bx_9intervals_7cluster_ClusterTree) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 57; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_2bx_9intervals_7cluster_ClusterTree = &__pyx_type_2bx_9intervals_7cluster_ClusterTree;
+  /*--- Type import code ---*/
+  /*--- Variable import code ---*/
+  /*--- Function import code ---*/
+  /*--- Execution code ---*/
+
+  /* "bx/intervals/cluster.pyx":1
+ * """             # <<<<<<<<<<<<<<
+ * Kanwei Li, 2009
+ * Inspired by previous ClusterTree
+ */
+  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(((PyObject *)__pyx_t_1));
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s____test__, ((PyObject *)__pyx_t_1)) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  if (__pyx_m) {
+    __Pyx_AddTraceback("init bx.intervals.cluster", __pyx_clineno, __pyx_lineno, __pyx_filename);
+    Py_DECREF(__pyx_m); __pyx_m = 0;
+  } else if (!PyErr_Occurred()) {
+    PyErr_SetString(PyExc_ImportError, "init bx.intervals.cluster");
+  }
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  #if PY_MAJOR_VERSION < 3
+  return;
+  #else
+  return __pyx_m;
+  #endif
+}
+
+/* Runtime support code */
+#if CYTHON_REFNANNY
+static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) {
+    PyObject *m = NULL, *p = NULL;
+    void *r = NULL;
+    m = PyImport_ImportModule((char *)modname);
+    if (!m) goto end;
+    p = PyObject_GetAttrString(m, (char *)"RefNannyAPI");
+    if (!p) goto end;
+    r = PyLong_AsVoidPtr(p);
+end:
+    Py_XDECREF(p);
+    Py_XDECREF(m);
+    return (__Pyx_RefNannyAPIStruct *)r;
+}
+#endif /* CYTHON_REFNANNY */
+
+static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name) {
+    PyObject *result;
+    result = PyObject_GetAttr(dict, name);
+    if (!result) {
+        if (dict != __pyx_b) {
+            PyErr_Clear();
+            result = PyObject_GetAttr(__pyx_b, name);
+        }
+        if (!result) {
+            PyErr_SetObject(PyExc_NameError, name);
+        }
+    }
+    return result;
+}
+
+static void __Pyx_RaiseArgtupleInvalid(
+    const char* func_name,
+    int exact,
+    Py_ssize_t num_min,
+    Py_ssize_t num_max,
+    Py_ssize_t num_found)
+{
+    Py_ssize_t num_expected;
+    const char *more_or_less;
+    if (num_found < num_min) {
+        num_expected = num_min;
+        more_or_less = "at least";
+    } else {
+        num_expected = num_max;
+        more_or_less = "at most";
+    }
+    if (exact) {
+        more_or_less = "exactly";
+    }
+    PyErr_Format(PyExc_TypeError,
+                 "%s() takes %s %" CYTHON_FORMAT_SSIZE_T "d positional argument%s (%" CYTHON_FORMAT_SSIZE_T "d given)",
+                 func_name, more_or_less, num_expected,
+                 (num_expected == 1) ? "" : "s", num_found);
+}
+
+static void __Pyx_RaiseDoubleKeywordsError(
+    const char* func_name,
+    PyObject* kw_name)
+{
+    PyErr_Format(PyExc_TypeError,
+        #if PY_MAJOR_VERSION >= 3
+        "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
+        #else
+        "%s() got multiple values for keyword argument '%s'", func_name,
+        PyString_AsString(kw_name));
+        #endif
+}
+
+static int __Pyx_ParseOptionalKeywords(
+    PyObject *kwds,
+    PyObject **argnames[],
+    PyObject *kwds2,
+    PyObject *values[],
+    Py_ssize_t num_pos_args,
+    const char* function_name)
+{
+    PyObject *key = 0, *value = 0;
+    Py_ssize_t pos = 0;
+    PyObject*** name;
+    PyObject*** first_kw_arg = argnames + num_pos_args;
+    while (PyDict_Next(kwds, &pos, &key, &value)) {
+        name = first_kw_arg;
+        while (*name && (**name != key)) name++;
+        if (*name) {
+            values[name-argnames] = value;
+            continue;
+        }
+        name = first_kw_arg;
+        #if PY_MAJOR_VERSION < 3
+        if (likely(PyString_CheckExact(key)) || likely(PyString_Check(key))) {
+            while (*name) {
+                if ((CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**name) == PyString_GET_SIZE(key))
+                        && _PyString_Eq(**name, key)) {
+                    values[name-argnames] = value;
+                    break;
+                }
+                name++;
+            }
+            if (*name) continue;
+            else {
+                PyObject*** argname = argnames;
+                while (argname != first_kw_arg) {
+                    if ((**argname == key) || (
+                            (CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**argname) == PyString_GET_SIZE(key))
+                             && _PyString_Eq(**argname, key))) {
+                        goto arg_passed_twice;
+                    }
+                    argname++;
+                }
+            }
+        } else
+        #endif
+        if (likely(PyUnicode_Check(key))) {
+            while (*name) {
+                int cmp = (**name == key) ? 0 :
+                #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3
+                    (PyUnicode_GET_SIZE(**name) != PyUnicode_GET_SIZE(key)) ? 1 :
+                #endif
+                    PyUnicode_Compare(**name, key);
+                if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad;
+                if (cmp == 0) {
+                    values[name-argnames] = value;
+                    break;
+                }
+                name++;
+            }
+            if (*name) continue;
+            else {
+                PyObject*** argname = argnames;
+                while (argname != first_kw_arg) {
+                    int cmp = (**argname == key) ? 0 :
+                    #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3
+                        (PyUnicode_GET_SIZE(**argname) != PyUnicode_GET_SIZE(key)) ? 1 :
+                    #endif
+                        PyUnicode_Compare(**argname, key);
+                    if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad;
+                    if (cmp == 0) goto arg_passed_twice;
+                    argname++;
+                }
+            }
+        } else
+            goto invalid_keyword_type;
+        if (kwds2) {
+            if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
+        } else {
+            goto invalid_keyword;
+        }
+    }
+    return 0;
+arg_passed_twice:
+    __Pyx_RaiseDoubleKeywordsError(function_name, key);
+    goto bad;
+invalid_keyword_type:
+    PyErr_Format(PyExc_TypeError,
+        "%s() keywords must be strings", function_name);
+    goto bad;
+invalid_keyword:
+    PyErr_Format(PyExc_TypeError,
+    #if PY_MAJOR_VERSION < 3
+        "%s() got an unexpected keyword argument '%s'",
+        function_name, PyString_AsString(key));
+    #else
+        "%s() got an unexpected keyword argument '%U'",
+        function_name, key);
+    #endif
+bad:
+    return -1;
+}
+
+static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    PyObject *tmp_type, *tmp_value, *tmp_tb;
+    PyThreadState *tstate = PyThreadState_GET();
+    tmp_type = tstate->curexc_type;
+    tmp_value = tstate->curexc_value;
+    tmp_tb = tstate->curexc_traceback;
+    tstate->curexc_type = type;
+    tstate->curexc_value = value;
+    tstate->curexc_traceback = tb;
+    Py_XDECREF(tmp_type);
+    Py_XDECREF(tmp_value);
+    Py_XDECREF(tmp_tb);
+#else
+    PyErr_Restore(type, value, tb);
+#endif
+}
+static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    PyThreadState *tstate = PyThreadState_GET();
+    *type = tstate->curexc_type;
+    *value = tstate->curexc_value;
+    *tb = tstate->curexc_traceback;
+    tstate->curexc_type = 0;
+    tstate->curexc_value = 0;
+    tstate->curexc_traceback = 0;
+#else
+    PyErr_Fetch(type, value, tb);
+#endif
+}
+
+#if PY_MAJOR_VERSION < 3
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb,
+                        CYTHON_UNUSED PyObject *cause) {
+    Py_XINCREF(type);
+    if (!value || value == Py_None)
+        value = NULL;
+    else
+        Py_INCREF(value);
+    if (!tb || tb == Py_None)
+        tb = NULL;
+    else {
+        Py_INCREF(tb);
+        if (!PyTraceBack_Check(tb)) {
+            PyErr_SetString(PyExc_TypeError,
+                "raise: arg 3 must be a traceback or None");
+            goto raise_error;
+        }
+    }
+    #if PY_VERSION_HEX < 0x02050000
+    if (PyClass_Check(type)) {
+    #else
+    if (PyType_Check(type)) {
+    #endif
+#if CYTHON_COMPILING_IN_PYPY
+        if (!value) {
+            Py_INCREF(Py_None);
+            value = Py_None;
+        }
+#endif
+        PyErr_NormalizeException(&type, &value, &tb);
+    } else {
+        if (value) {
+            PyErr_SetString(PyExc_TypeError,
+                "instance exception may not have a separate value");
+            goto raise_error;
+        }
+        value = type;
+        #if PY_VERSION_HEX < 0x02050000
+            if (PyInstance_Check(type)) {
+                type = (PyObject*) ((PyInstanceObject*)type)->in_class;
+                Py_INCREF(type);
+            }
+            else {
+                type = 0;
+                PyErr_SetString(PyExc_TypeError,
+                    "raise: exception must be an old-style class or instance");
+                goto raise_error;
+            }
+        #else
+            type = (PyObject*) Py_TYPE(type);
+            Py_INCREF(type);
+            if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
+                PyErr_SetString(PyExc_TypeError,
+                    "raise: exception class must be a subclass of BaseException");
+                goto raise_error;
+            }
+        #endif
+    }
+    __Pyx_ErrRestore(type, value, tb);
+    return;
+raise_error:
+    Py_XDECREF(value);
+    Py_XDECREF(type);
+    Py_XDECREF(tb);
+    return;
+}
+#else /* Python 3+ */
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause) {
+    PyObject* owned_instance = NULL;
+    if (tb == Py_None) {
+        tb = 0;
+    } else if (tb && !PyTraceBack_Check(tb)) {
+        PyErr_SetString(PyExc_TypeError,
+            "raise: arg 3 must be a traceback or None");
+        goto bad;
+    }
+    if (value == Py_None)
+        value = 0;
+    if (PyExceptionInstance_Check(type)) {
+        if (value) {
+            PyErr_SetString(PyExc_TypeError,
+                "instance exception may not have a separate value");
+            goto bad;
+        }
+        value = type;
+        type = (PyObject*) Py_TYPE(value);
+    } else if (PyExceptionClass_Check(type)) {
+        PyObject *args;
+        if (!value)
+            args = PyTuple_New(0);
+        else if (PyTuple_Check(value)) {
+            Py_INCREF(value);
+            args = value;
+        }
+        else
+            args = PyTuple_Pack(1, value);
+        if (!args)
+            goto bad;
+        owned_instance = PyEval_CallObject(type, args);
+        Py_DECREF(args);
+        if (!owned_instance)
+            goto bad;
+        value = owned_instance;
+        if (!PyExceptionInstance_Check(value)) {
+            PyErr_Format(PyExc_TypeError,
+                         "calling %R should have returned an instance of "
+                         "BaseException, not %R",
+                         type, Py_TYPE(value));
+            goto bad;
+        }
+    } else {
+        PyErr_SetString(PyExc_TypeError,
+            "raise: exception class must be a subclass of BaseException");
+        goto bad;
+    }
+    if (cause && cause != Py_None) {
+        PyObject *fixed_cause;
+        if (PyExceptionClass_Check(cause)) {
+            fixed_cause = PyObject_CallObject(cause, NULL);
+            if (fixed_cause == NULL)
+                goto bad;
+        }
+        else if (PyExceptionInstance_Check(cause)) {
+            fixed_cause = cause;
+            Py_INCREF(fixed_cause);
+        }
+        else {
+            PyErr_SetString(PyExc_TypeError,
+                            "exception causes must derive from "
+                            "BaseException");
+            goto bad;
+        }
+        PyException_SetCause(value, fixed_cause);
+    }
+    PyErr_SetObject(type, value);
+    if (tb) {
+        PyThreadState *tstate = PyThreadState_GET();
+        PyObject* tmp_tb = tstate->curexc_traceback;
+        if (tb != tmp_tb) {
+            Py_INCREF(tb);
+            tstate->curexc_traceback = tb;
+            Py_XDECREF(tmp_tb);
+        }
+    }
+bad:
+    Py_XDECREF(owned_instance);
+    return;
+}
+#endif
+
+static CYTHON_INLINE unsigned char __Pyx_PyInt_AsUnsignedChar(PyObject* x) {
+    const unsigned char neg_one = (unsigned char)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(unsigned char) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(unsigned char)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to unsigned char" :
+                    "value too large to convert to unsigned char");
+            }
+            return (unsigned char)-1;
+        }
+        return (unsigned char)val;
+    }
+    return (unsigned char)__Pyx_PyInt_AsUnsignedLong(x);
+}
+
+static CYTHON_INLINE unsigned short __Pyx_PyInt_AsUnsignedShort(PyObject* x) {
+    const unsigned short neg_one = (unsigned short)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(unsigned short) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(unsigned short)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to unsigned short" :
+                    "value too large to convert to unsigned short");
+            }
+            return (unsigned short)-1;
+        }
+        return (unsigned short)val;
+    }
+    return (unsigned short)__Pyx_PyInt_AsUnsignedLong(x);
+}
+
+static CYTHON_INLINE unsigned int __Pyx_PyInt_AsUnsignedInt(PyObject* x) {
+    const unsigned int neg_one = (unsigned int)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(unsigned int) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(unsigned int)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to unsigned int" :
+                    "value too large to convert to unsigned int");
+            }
+            return (unsigned int)-1;
+        }
+        return (unsigned int)val;
+    }
+    return (unsigned int)__Pyx_PyInt_AsUnsignedLong(x);
+}
+
+static CYTHON_INLINE char __Pyx_PyInt_AsChar(PyObject* x) {
+    const char neg_one = (char)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(char) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(char)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to char" :
+                    "value too large to convert to char");
+            }
+            return (char)-1;
+        }
+        return (char)val;
+    }
+    return (char)__Pyx_PyInt_AsLong(x);
+}
+
+static CYTHON_INLINE short __Pyx_PyInt_AsShort(PyObject* x) {
+    const short neg_one = (short)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(short) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(short)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to short" :
+                    "value too large to convert to short");
+            }
+            return (short)-1;
+        }
+        return (short)val;
+    }
+    return (short)__Pyx_PyInt_AsLong(x);
+}
+
+static CYTHON_INLINE int __Pyx_PyInt_AsInt(PyObject* x) {
+    const int neg_one = (int)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(int) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(int)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to int" :
+                    "value too large to convert to int");
+            }
+            return (int)-1;
+        }
+        return (int)val;
+    }
+    return (int)__Pyx_PyInt_AsLong(x);
+}
+
+static CYTHON_INLINE signed char __Pyx_PyInt_AsSignedChar(PyObject* x) {
+    const signed char neg_one = (signed char)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(signed char) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(signed char)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to signed char" :
+                    "value too large to convert to signed char");
+            }
+            return (signed char)-1;
+        }
+        return (signed char)val;
+    }
+    return (signed char)__Pyx_PyInt_AsSignedLong(x);
+}
+
+static CYTHON_INLINE signed short __Pyx_PyInt_AsSignedShort(PyObject* x) {
+    const signed short neg_one = (signed short)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(signed short) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(signed short)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to signed short" :
+                    "value too large to convert to signed short");
+            }
+            return (signed short)-1;
+        }
+        return (signed short)val;
+    }
+    return (signed short)__Pyx_PyInt_AsSignedLong(x);
+}
+
+static CYTHON_INLINE signed int __Pyx_PyInt_AsSignedInt(PyObject* x) {
+    const signed int neg_one = (signed int)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(signed int) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(signed int)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to signed int" :
+                    "value too large to convert to signed int");
+            }
+            return (signed int)-1;
+        }
+        return (signed int)val;
+    }
+    return (signed int)__Pyx_PyInt_AsSignedLong(x);
+}
+
+static CYTHON_INLINE int __Pyx_PyInt_AsLongDouble(PyObject* x) {
+    const int neg_one = (int)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(int) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(int)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to int" :
+                    "value too large to convert to int");
+            }
+            return (int)-1;
+        }
+        return (int)val;
+    }
+    return (int)__Pyx_PyInt_AsLong(x);
+}
+
+static CYTHON_INLINE unsigned long __Pyx_PyInt_AsUnsignedLong(PyObject* x) {
+    const unsigned long neg_one = (unsigned long)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to unsigned long");
+            return (unsigned long)-1;
+        }
+        return (unsigned long)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to unsigned long");
+                return (unsigned long)-1;
+            }
+            return (unsigned long)PyLong_AsUnsignedLong(x);
+        } else {
+            return (unsigned long)PyLong_AsLong(x);
+        }
+    } else {
+        unsigned long val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (unsigned long)-1;
+        val = __Pyx_PyInt_AsUnsignedLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE unsigned PY_LONG_LONG __Pyx_PyInt_AsUnsignedLongLong(PyObject* x) {
+    const unsigned PY_LONG_LONG neg_one = (unsigned PY_LONG_LONG)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to unsigned PY_LONG_LONG");
+            return (unsigned PY_LONG_LONG)-1;
+        }
+        return (unsigned PY_LONG_LONG)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to unsigned PY_LONG_LONG");
+                return (unsigned PY_LONG_LONG)-1;
+            }
+            return (unsigned PY_LONG_LONG)PyLong_AsUnsignedLongLong(x);
+        } else {
+            return (unsigned PY_LONG_LONG)PyLong_AsLongLong(x);
+        }
+    } else {
+        unsigned PY_LONG_LONG val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (unsigned PY_LONG_LONG)-1;
+        val = __Pyx_PyInt_AsUnsignedLongLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE long __Pyx_PyInt_AsLong(PyObject* x) {
+    const long neg_one = (long)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to long");
+            return (long)-1;
+        }
+        return (long)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to long");
+                return (long)-1;
+            }
+            return (long)PyLong_AsUnsignedLong(x);
+        } else {
+            return (long)PyLong_AsLong(x);
+        }
+    } else {
+        long val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (long)-1;
+        val = __Pyx_PyInt_AsLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE PY_LONG_LONG __Pyx_PyInt_AsLongLong(PyObject* x) {
+    const PY_LONG_LONG neg_one = (PY_LONG_LONG)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to PY_LONG_LONG");
+            return (PY_LONG_LONG)-1;
+        }
+        return (PY_LONG_LONG)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to PY_LONG_LONG");
+                return (PY_LONG_LONG)-1;
+            }
+            return (PY_LONG_LONG)PyLong_AsUnsignedLongLong(x);
+        } else {
+            return (PY_LONG_LONG)PyLong_AsLongLong(x);
+        }
+    } else {
+        PY_LONG_LONG val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (PY_LONG_LONG)-1;
+        val = __Pyx_PyInt_AsLongLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE signed long __Pyx_PyInt_AsSignedLong(PyObject* x) {
+    const signed long neg_one = (signed long)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to signed long");
+            return (signed long)-1;
+        }
+        return (signed long)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to signed long");
+                return (signed long)-1;
+            }
+            return (signed long)PyLong_AsUnsignedLong(x);
+        } else {
+            return (signed long)PyLong_AsLong(x);
+        }
+    } else {
+        signed long val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (signed long)-1;
+        val = __Pyx_PyInt_AsSignedLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE signed PY_LONG_LONG __Pyx_PyInt_AsSignedLongLong(PyObject* x) {
+    const signed PY_LONG_LONG neg_one = (signed PY_LONG_LONG)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to signed PY_LONG_LONG");
+            return (signed PY_LONG_LONG)-1;
+        }
+        return (signed PY_LONG_LONG)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to signed PY_LONG_LONG");
+                return (signed PY_LONG_LONG)-1;
+            }
+            return (signed PY_LONG_LONG)PyLong_AsUnsignedLongLong(x);
+        } else {
+            return (signed PY_LONG_LONG)PyLong_AsLongLong(x);
+        }
+    } else {
+        signed PY_LONG_LONG val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (signed PY_LONG_LONG)-1;
+        val = __Pyx_PyInt_AsSignedLongLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static int __Pyx_check_binary_version(void) {
+    char ctversion[4], rtversion[4];
+    PyOS_snprintf(ctversion, 4, "%d.%d", PY_MAJOR_VERSION, PY_MINOR_VERSION);
+    PyOS_snprintf(rtversion, 4, "%s", Py_GetVersion());
+    if (ctversion[0] != rtversion[0] || ctversion[2] != rtversion[2]) {
+        char message[200];
+        PyOS_snprintf(message, sizeof(message),
+                      "compiletime version %s of module '%.100s' "
+                      "does not match runtime version %s",
+                      ctversion, __Pyx_MODULE_NAME, rtversion);
+        #if PY_VERSION_HEX < 0x02050000
+        return PyErr_Warn(NULL, message);
+        #else
+        return PyErr_WarnEx(NULL, message, 1);
+        #endif
+    }
+    return 0;
+}
+
+static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) {
+    int start = 0, mid = 0, end = count - 1;
+    if (end >= 0 && code_line > entries[end].code_line) {
+        return count;
+    }
+    while (start < end) {
+        mid = (start + end) / 2;
+        if (code_line < entries[mid].code_line) {
+            end = mid;
+        } else if (code_line > entries[mid].code_line) {
+             start = mid + 1;
+        } else {
+            return mid;
+        }
+    }
+    if (code_line <= entries[mid].code_line) {
+        return mid;
+    } else {
+        return mid + 1;
+    }
+}
+static PyCodeObject *__pyx_find_code_object(int code_line) {
+    PyCodeObject* code_object;
+    int pos;
+    if (unlikely(!code_line) || unlikely(!__pyx_code_cache.entries)) {
+        return NULL;
+    }
+    pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line);
+    if (unlikely(pos >= __pyx_code_cache.count) || unlikely(__pyx_code_cache.entries[pos].code_line != code_line)) {
+        return NULL;
+    }
+    code_object = __pyx_code_cache.entries[pos].code_object;
+    Py_INCREF(code_object);
+    return code_object;
+}
+static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) {
+    int pos, i;
+    __Pyx_CodeObjectCacheEntry* entries = __pyx_code_cache.entries;
+    if (unlikely(!code_line)) {
+        return;
+    }
+    if (unlikely(!entries)) {
+        entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Malloc(64*sizeof(__Pyx_CodeObjectCacheEntry));
+        if (likely(entries)) {
+            __pyx_code_cache.entries = entries;
+            __pyx_code_cache.max_count = 64;
+            __pyx_code_cache.count = 1;
+            entries[0].code_line = code_line;
+            entries[0].code_object = code_object;
+            Py_INCREF(code_object);
+        }
+        return;
+    }
+    pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line);
+    if ((pos < __pyx_code_cache.count) && unlikely(__pyx_code_cache.entries[pos].code_line == code_line)) {
+        PyCodeObject* tmp = entries[pos].code_object;
+        entries[pos].code_object = code_object;
+        Py_DECREF(tmp);
+        return;
+    }
+    if (__pyx_code_cache.count == __pyx_code_cache.max_count) {
+        int new_max = __pyx_code_cache.max_count + 64;
+        entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Realloc(
+            __pyx_code_cache.entries, new_max*sizeof(__Pyx_CodeObjectCacheEntry));
+        if (unlikely(!entries)) {
+            return;
+        }
+        __pyx_code_cache.entries = entries;
+        __pyx_code_cache.max_count = new_max;
+    }
+    for (i=__pyx_code_cache.count; i>pos; i--) {
+        entries[i] = entries[i-1];
+    }
+    entries[pos].code_line = code_line;
+    entries[pos].code_object = code_object;
+    __pyx_code_cache.count++;
+    Py_INCREF(code_object);
+}
+
+#include "compile.h"
+#include "frameobject.h"
+#include "traceback.h"
+static PyCodeObject* __Pyx_CreateCodeObjectForTraceback(
+            const char *funcname, int c_line,
+            int py_line, const char *filename) {
+    PyCodeObject *py_code = 0;
+    PyObject *py_srcfile = 0;
+    PyObject *py_funcname = 0;
+    #if PY_MAJOR_VERSION < 3
+    py_srcfile = PyString_FromString(filename);
+    #else
+    py_srcfile = PyUnicode_FromString(filename);
+    #endif
+    if (!py_srcfile) goto bad;
+    if (c_line) {
+        #if PY_MAJOR_VERSION < 3
+        py_funcname = PyString_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line);
+        #else
+        py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line);
+        #endif
+    }
+    else {
+        #if PY_MAJOR_VERSION < 3
+        py_funcname = PyString_FromString(funcname);
+        #else
+        py_funcname = PyUnicode_FromString(funcname);
+        #endif
+    }
+    if (!py_funcname) goto bad;
+    py_code = __Pyx_PyCode_New(
+        0,            /*int argcount,*/
+        0,            /*int kwonlyargcount,*/
+        0,            /*int nlocals,*/
+        0,            /*int stacksize,*/
+        0,            /*int flags,*/
+        __pyx_empty_bytes, /*PyObject *code,*/
+        __pyx_empty_tuple, /*PyObject *consts,*/
+        __pyx_empty_tuple, /*PyObject *names,*/
+        __pyx_empty_tuple, /*PyObject *varnames,*/
+        __pyx_empty_tuple, /*PyObject *freevars,*/
+        __pyx_empty_tuple, /*PyObject *cellvars,*/
+        py_srcfile,   /*PyObject *filename,*/
+        py_funcname,  /*PyObject *name,*/
+        py_line,      /*int firstlineno,*/
+        __pyx_empty_bytes  /*PyObject *lnotab*/
+    );
+    Py_DECREF(py_srcfile);
+    Py_DECREF(py_funcname);
+    return py_code;
+bad:
+    Py_XDECREF(py_srcfile);
+    Py_XDECREF(py_funcname);
+    return NULL;
+}
+static void __Pyx_AddTraceback(const char *funcname, int c_line,
+                               int py_line, const char *filename) {
+    PyCodeObject *py_code = 0;
+    PyObject *py_globals = 0;
+    PyFrameObject *py_frame = 0;
+    py_code = __pyx_find_code_object(c_line ? c_line : py_line);
+    if (!py_code) {
+        py_code = __Pyx_CreateCodeObjectForTraceback(
+            funcname, c_line, py_line, filename);
+        if (!py_code) goto bad;
+        __pyx_insert_code_object(c_line ? c_line : py_line, py_code);
+    }
+    py_globals = PyModule_GetDict(__pyx_m);
+    if (!py_globals) goto bad;
+    py_frame = PyFrame_New(
+        PyThreadState_GET(), /*PyThreadState *tstate,*/
+        py_code,             /*PyCodeObject *code,*/
+        py_globals,          /*PyObject *globals,*/
+        0                    /*PyObject *locals*/
+    );
+    if (!py_frame) goto bad;
+    py_frame->f_lineno = py_line;
+    PyTraceBack_Here(py_frame);
+bad:
+    Py_XDECREF(py_code);
+    Py_XDECREF(py_frame);
+}
+
+static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
+    while (t->p) {
+        #if PY_MAJOR_VERSION < 3
+        if (t->is_unicode) {
+            *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
+        } else if (t->intern) {
+            *t->p = PyString_InternFromString(t->s);
+        } else {
+            *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
+        }
+        #else  /* Python 3+ has unicode identifiers */
+        if (t->is_unicode | t->is_str) {
+            if (t->intern) {
+                *t->p = PyUnicode_InternFromString(t->s);
+            } else if (t->encoding) {
+                *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL);
+            } else {
+                *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
+            }
+        } else {
+            *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
+        }
+        #endif
+        if (!*t->p)
+            return -1;
+        ++t;
+    }
+    return 0;
+}
+
+static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) {
+   int is_true = x == Py_True;
+   if (is_true | (x == Py_False) | (x == Py_None)) return is_true;
+   else return PyObject_IsTrue(x);
+}
+static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x) {
+  PyNumberMethods *m;
+  const char *name = NULL;
+  PyObject *res = NULL;
+#if PY_VERSION_HEX < 0x03000000
+  if (PyInt_Check(x) || PyLong_Check(x))
+#else
+  if (PyLong_Check(x))
+#endif
+    return Py_INCREF(x), x;
+  m = Py_TYPE(x)->tp_as_number;
+#if PY_VERSION_HEX < 0x03000000
+  if (m && m->nb_int) {
+    name = "int";
+    res = PyNumber_Int(x);
+  }
+  else if (m && m->nb_long) {
+    name = "long";
+    res = PyNumber_Long(x);
+  }
+#else
+  if (m && m->nb_int) {
+    name = "int";
+    res = PyNumber_Long(x);
+  }
+#endif
+  if (res) {
+#if PY_VERSION_HEX < 0x03000000
+    if (!PyInt_Check(res) && !PyLong_Check(res)) {
+#else
+    if (!PyLong_Check(res)) {
+#endif
+      PyErr_Format(PyExc_TypeError,
+                   "__%s__ returned non-%s (type %.200s)",
+                   name, name, Py_TYPE(res)->tp_name);
+      Py_DECREF(res);
+      return NULL;
+    }
+  }
+  else if (!PyErr_Occurred()) {
+    PyErr_SetString(PyExc_TypeError,
+                    "an integer is required");
+  }
+  return res;
+}
+static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) {
+  Py_ssize_t ival;
+  PyObject* x = PyNumber_Index(b);
+  if (!x) return -1;
+  ival = PyInt_AsSsize_t(x);
+  Py_DECREF(x);
+  return ival;
+}
+static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) {
+#if PY_VERSION_HEX < 0x02050000
+   if (ival <= LONG_MAX)
+       return PyInt_FromLong((long)ival);
+   else {
+       unsigned char *bytes = (unsigned char *) &ival;
+       int one = 1; int little = (int)*(unsigned char*)&one;
+       return _PyLong_FromByteArray(bytes, sizeof(size_t), little, 0);
+   }
+#else
+   return PyInt_FromSize_t(ival);
+#endif
+}
+static CYTHON_INLINE size_t __Pyx_PyInt_AsSize_t(PyObject* x) {
+   unsigned PY_LONG_LONG val = __Pyx_PyInt_AsUnsignedLongLong(x);
+   if (unlikely(val == (unsigned PY_LONG_LONG)-1 && PyErr_Occurred())) {
+       return (size_t)-1;
+   } else if (unlikely(val != (unsigned PY_LONG_LONG)(size_t)val)) {
+       PyErr_SetString(PyExc_OverflowError,
+                       "value too large to convert to size_t");
+       return (size_t)-1;
+   }
+   return (size_t)val;
+}
+
+
+#endif /* Py_PYTHON_H */
diff --git a/lib/bx/intervals/cluster.pyx b/lib/bx/intervals/cluster.pyx
new file mode 100644
index 0000000..fe58283
--- /dev/null
+++ b/lib/bx/intervals/cluster.pyx
@@ -0,0 +1,122 @@
+"""
+Kanwei Li, 2009
+Inspired by previous ClusterTree
+
+Provides a ClusterTree data structure that supports efficient finding of 
+clusters of intervals that are within a certain distance apart.
+
+This clustering algorithm uses a binary tree structure. Nodes correspond to 
+non-overlapping intervals, where overlapping means that the distance between
+two intervals is less or equal to the max separation.
+
+The tree self-balances using rotations based on the binomial sequence. Merges
+among nodes are performed whenever a node is changed/added that will cause other
+nodes to form a new cluster.
+
+C source code is in src/cluster.c
+"""
+
+cdef extern from "cluster.h":
+    
+    cdef struct struct_interval:
+        int start
+        int end
+        int id
+        struct_interval * next
+
+    ctypedef struct_interval interval
+    
+    cdef struct struct_clusternode:
+        int start
+        int end
+        struct_interval *interval_head
+        struct_interval *interval_tail
+    
+    ctypedef struct_clusternode clusternode
+    
+    cdef struct struct_clustertree:
+        int max_dist
+        int min_intervals
+
+        struct_clusternode *root
+    
+    ctypedef struct_clustertree clustertree
+    
+    cdef struct struct_treeitr:
+        struct_treeitr *next
+        struct_clusternode *node
+    
+    ctypedef struct_treeitr treeitr
+    
+    clusternode* clusternode_insert(clustertree *tree, clusternode *node, int start, int end, int id)
+    clustertree* create_clustertree(int max_dist, int min_intervals)
+    treeitr* clusteritr(clustertree *tree)
+    void freeclusteritr(treeitr *itr)
+    void free_tree(clustertree *tree)
+
+cdef class ClusterTree:
+    cdef clustertree *tree
+    cdef int mincols
+    cdef int minregions
+    
+    def __cinit__(self, mincols, minregions):
+        self.tree = create_clustertree(mincols, minregions)
+        self.mincols = mincols
+        self.minregions = minregions
+        
+    def __dealloc__(self):
+        free_tree(self.tree)
+    
+    def insert(self, s, e, id):
+        ''' Insert an interval with start, end, id as parameters'''
+        if s > e: raise ValueError("Interval start must be before end")
+        self.tree.root = clusternode_insert(self.tree, self.tree.root, s, e, id)
+                
+    def getregions(self):
+        ''' Returns a list clusters in ascending order of starting position.
+            Each cluster is a tuple of (start, end, [sorted ids of intervals in cluster])
+        
+        tree = ClusterTree(0, 0)
+        Insert (6, 7, 1), (1, 2, 3), (9, 10, 2), (3, 4, 0), (3, 8, 4)
+        tree.getregions() returns [(1, 2, [3]), (3, 8, [0, 1, 4]), (9, 10, [2])]
+        '''
+        cdef treeitr *itr
+        cdef interval *ival
+        
+        regions = []
+        itr = clusteritr(self.tree)
+        
+        while (itr):
+            ids = []
+            ival = itr.node.interval_head
+            while (ival):
+                ids.append(ival.id)
+                ival = ival.next
+
+            regions.append( (itr.node.start, itr.node.end, sorted(ids)) )
+            itr = itr.next
+        freeclusteritr(itr)
+        return regions
+        
+    def getlines(self):
+        ''' Similar to getregions except it just returns a list of ids of intervals
+            The above example would return [3, 0, 1, 4, 2]
+         '''
+        cdef treeitr *itr
+        cdef interval *ival
+        
+        lines = []
+        itr = clusteritr(self.tree)
+        
+        while (itr):
+            ids = []
+            ival = itr.node.interval_head
+            while (ival):
+                ids.append(ival.id)
+                ival = ival.next
+            
+            lines.extend(sorted(ids))
+            itr = itr.next
+        freeclusteritr(itr)
+        return lines
+        
diff --git a/lib/bx/intervals/cluster_tests.py b/lib/bx/intervals/cluster_tests.py
new file mode 100644
index 0000000..8438b92
--- /dev/null
+++ b/lib/bx/intervals/cluster_tests.py
@@ -0,0 +1,103 @@
+import sys, os
+import unittest
+try:
+    sys.path.insert(0, os.path.dirname(os.path.dirname(__file__)))
+except:
+    sys.path.insert(0, os.path.dirname(os.path.abspath(".")))
+
+# from bx.intervals.cluster import ClusterTree
+from cluster import ClusterTree
+
+class TestCluster(unittest.TestCase):
+    def setUp(self):
+        self.tree = ClusterTree(0, 0)
+    
+    def insertpairs(self, pairs):
+        for i, (s, e) in enumerate(pairs):
+            self.tree.insert(s, e, i)
+    
+    def test_merge_case(self):
+        pairs = [(3, 4), (6, 7), (9, 10), (1, 2), (3, 8)]
+        self.insertpairs(pairs)
+        
+        self.assertEqual( [(1, 2, [3]), (3, 8, [0, 1, 4]), (9, 10, [2])], self.tree.getregions() )
+    
+    def test_trivial(self):
+        pairs = [ (1, 4), (4, 5) ]
+        self.insertpairs(pairs)
+        
+        self.assertEqual( [(1, 5, [0, 1])], self.tree.getregions() )
+        
+    def test_easymerge(self):
+        pairs = [ (1, 2), (4, 5), (2, 4) ]
+        self.insertpairs(pairs)
+
+        self.assertEqual( [(1, 5, [0, 1, 2])], self.tree.getregions() )
+        
+    def test_hardmerge(self):
+        pairs = [ (1, 2), (8, 9), (3, 4), (5, 6), (7, 8), (1, 10) ]
+        self.insertpairs(pairs)
+
+        self.assertEqual( [(1, 10, [0, 1, 2, 3, 4, 5])], self.tree.getregions() )
+    
+    def test_duplicates(self):
+        pairs = [ (1, 1), (1, 2), (3, 4), (3, 4), (1, 4) ]
+        self.insertpairs(pairs)
+
+        self.assertEqual( [(1, 4, [0, 1, 2, 3, 4])], self.tree.getregions() )
+        
+    def test_startbeforeend(self):
+        self.assertRaises(ValueError, self.tree.insert, 4, 2, 0)
+        
+    def test_large_sorted(self):
+        upto = 100000
+        pairs = [ (2*i + 1, 2*i + 2) for i in range(upto) ]
+        self.insertpairs(pairs)
+        self.tree.insert( 0, upto*3, upto )
+        self.assertEqual( [ (0, upto*3, [x for x in range(upto+1)]) ], self.tree.getregions() )
+        
+    def test_minregions(self):
+        self.tree = ClusterTree(0, 2)
+        pairs = [(3, 4), (6, 7), (9, 10), (1, 2), (3, 8)]
+        self.insertpairs(pairs)
+        
+        self.assertEqual( [(3, 8, [0, 1, 4])], self.tree.getregions() )
+        
+    def test_distance(self):
+        self.tree = ClusterTree(1, 0)
+        pairs = [(3, 4), (6, 7), (9, 10), (1, 2), (3, 8)]
+        self.insertpairs(pairs)
+        
+        self.assertEqual( [(1, 10, [0, 1, 2, 3, 4])], self.tree.getregions() )
+        
+    def test_merge_left_right(self):
+        pairs = [(6, 7, 1), (1, 2, 3), (9, 10, 2), (3, 4, 0), (3, 8, 4)]
+        for s, e, i in pairs:
+            self.tree.insert(s, e, i)
+
+        self.assertEqual( [(1, 2, [3]), (3, 8, [0, 1, 4]), (9, 10, [2])], self.tree.getregions() )
+    
+    def test_larger(self):
+        pairs = [(1, 2), (3, 4), (5, 6), (7, 8), (9, 10), (11, 12), (13, 14), (15, 16), (17, 18), (19, 20),
+                (1, 3), (4, 10), (10, 15), (15, 20), (21, 22)]
+        self.insertpairs(pairs)
+        
+        self.assertEqual( [(1, 20, [x for x in range(14)]), (21, 22, [14])], self.tree.getregions() )
+    
+    def test_another(self):
+        pairs = [(3, 4, 1), (13, 14, 6), (21, 22, 14), (5, 6, 2), (4, 10, 11), (1, 2, 0), (11, 12, 5), (1, 3, 10), (7, 8, 3), (15, 16, 7), (15, 20, 13), (19, 20, 9), (10, 15, 12), (17, 18, 8), (9, 10, 4)]
+        # pairs = [(3, 4, 1), (13, 14, 6), (21, 22, 14), (5, 6, 2), (4, 10, 11), (1, 2, 0), (11, 12, 5), (1, 3, 10), (7, 8, 3), (15, 16, 7), (15, 20, 13), (19, 20, 9), (10, 15, 12), (9, 10, 4)]
+        for s, e, i in pairs:
+            self.tree.insert(s, e, i)
+        
+        self.assertEqual( [(1, 20, [x for x in range(14)]), (21, 22, [14])], self.tree.getregions() )
+        
+    def test_none(self):
+        pairs = []
+        self.insertpairs(pairs)
+
+        self.assertEqual( [], self.tree.getregions() )
+        
+
+if __name__ == '__main__':
+    unittest.main()
\ No newline at end of file
diff --git a/lib/bx/intervals/intersection.c b/lib/bx/intervals/intersection.c
new file mode 100644
index 0000000..009960e
--- /dev/null
+++ b/lib/bx/intervals/intersection.c
@@ -0,0 +1,8477 @@
+/* Generated by Cython 0.18 on Mon Jul 15 13:25:44 2013 */
+
+#define PY_SSIZE_T_CLEAN
+#include "Python.h"
+#ifndef Py_PYTHON_H
+    #error Python headers needed to compile C extensions, please install development version of Python.
+#elif PY_VERSION_HEX < 0x02040000
+    #error Cython requires Python 2.4+.
+#else
+#include <stddef.h> /* For offsetof */
+#ifndef offsetof
+#define offsetof(type, member) ( (size_t) & ((type*)0) -> member )
+#endif
+#if !defined(WIN32) && !defined(MS_WINDOWS)
+  #ifndef __stdcall
+    #define __stdcall
+  #endif
+  #ifndef __cdecl
+    #define __cdecl
+  #endif
+  #ifndef __fastcall
+    #define __fastcall
+  #endif
+#endif
+#ifndef DL_IMPORT
+  #define DL_IMPORT(t) t
+#endif
+#ifndef DL_EXPORT
+  #define DL_EXPORT(t) t
+#endif
+#ifndef PY_LONG_LONG
+  #define PY_LONG_LONG LONG_LONG
+#endif
+#ifndef Py_HUGE_VAL
+  #define Py_HUGE_VAL HUGE_VAL
+#endif
+#ifdef PYPY_VERSION
+#define CYTHON_COMPILING_IN_PYPY 1
+#define CYTHON_COMPILING_IN_CPYTHON 0
+#else
+#define CYTHON_COMPILING_IN_PYPY 0
+#define CYTHON_COMPILING_IN_CPYTHON 1
+#endif
+#if PY_VERSION_HEX < 0x02050000
+  typedef int Py_ssize_t;
+  #define PY_SSIZE_T_MAX INT_MAX
+  #define PY_SSIZE_T_MIN INT_MIN
+  #define PY_FORMAT_SIZE_T ""
+  #define CYTHON_FORMAT_SSIZE_T ""
+  #define PyInt_FromSsize_t(z) PyInt_FromLong(z)
+  #define PyInt_AsSsize_t(o)   __Pyx_PyInt_AsInt(o)
+  #define PyNumber_Index(o)    ((PyNumber_Check(o) && !PyFloat_Check(o)) ? PyNumber_Int(o) : \
+                                (PyErr_Format(PyExc_TypeError, \
+                                              "expected index value, got %.200s", Py_TYPE(o)->tp_name), \
+                                 (PyObject*)0))
+  #define __Pyx_PyIndex_Check(o) (PyNumber_Check(o) && !PyFloat_Check(o) && \
+                                  !PyComplex_Check(o))
+  #define PyIndex_Check __Pyx_PyIndex_Check
+  #define PyErr_WarnEx(category, message, stacklevel) PyErr_Warn(category, message)
+  #define __PYX_BUILD_PY_SSIZE_T "i"
+#else
+  #define __PYX_BUILD_PY_SSIZE_T "n"
+  #define CYTHON_FORMAT_SSIZE_T "z"
+  #define __Pyx_PyIndex_Check PyIndex_Check
+#endif
+#if PY_VERSION_HEX < 0x02060000
+  #define Py_REFCNT(ob) (((PyObject*)(ob))->ob_refcnt)
+  #define Py_TYPE(ob)   (((PyObject*)(ob))->ob_type)
+  #define Py_SIZE(ob)   (((PyVarObject*)(ob))->ob_size)
+  #define PyVarObject_HEAD_INIT(type, size) \
+          PyObject_HEAD_INIT(type) size,
+  #define PyType_Modified(t)
+  typedef struct {
+     void *buf;
+     PyObject *obj;
+     Py_ssize_t len;
+     Py_ssize_t itemsize;
+     int readonly;
+     int ndim;
+     char *format;
+     Py_ssize_t *shape;
+     Py_ssize_t *strides;
+     Py_ssize_t *suboffsets;
+     void *internal;
+  } Py_buffer;
+  #define PyBUF_SIMPLE 0
+  #define PyBUF_WRITABLE 0x0001
+  #define PyBUF_FORMAT 0x0004
+  #define PyBUF_ND 0x0008
+  #define PyBUF_STRIDES (0x0010 | PyBUF_ND)
+  #define PyBUF_C_CONTIGUOUS (0x0020 | PyBUF_STRIDES)
+  #define PyBUF_F_CONTIGUOUS (0x0040 | PyBUF_STRIDES)
+  #define PyBUF_ANY_CONTIGUOUS (0x0080 | PyBUF_STRIDES)
+  #define PyBUF_INDIRECT (0x0100 | PyBUF_STRIDES)
+  #define PyBUF_RECORDS (PyBUF_STRIDES | PyBUF_FORMAT | PyBUF_WRITABLE)
+  #define PyBUF_FULL (PyBUF_INDIRECT | PyBUF_FORMAT | PyBUF_WRITABLE)
+  typedef int (*getbufferproc)(PyObject *, Py_buffer *, int);
+  typedef void (*releasebufferproc)(PyObject *, Py_buffer *);
+#endif
+#if PY_MAJOR_VERSION < 3
+  #define __Pyx_BUILTIN_MODULE_NAME "__builtin__"
+  #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \
+          PyCode_New(a, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
+#else
+  #define __Pyx_BUILTIN_MODULE_NAME "builtins"
+  #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \
+          PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
+#endif
+#if PY_MAJOR_VERSION < 3 && PY_MINOR_VERSION < 6
+  #define PyUnicode_FromString(s) PyUnicode_Decode(s, strlen(s), "UTF-8", "strict")
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define Py_TPFLAGS_CHECKTYPES 0
+  #define Py_TPFLAGS_HAVE_INDEX 0
+#endif
+#if (PY_VERSION_HEX < 0x02060000) || (PY_MAJOR_VERSION >= 3)
+  #define Py_TPFLAGS_HAVE_NEWBUFFER 0
+#endif
+#if PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND)
+  #define CYTHON_PEP393_ENABLED 1
+  #define __Pyx_PyUnicode_READY(op)       (likely(PyUnicode_IS_READY(op)) ? \
+                                              0 : _PyUnicode_Ready((PyObject *)(op)))
+  #define __Pyx_PyUnicode_GET_LENGTH(u)   PyUnicode_GET_LENGTH(u)
+  #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_READ_CHAR(u, i)
+  #define __Pyx_PyUnicode_READ(k, d, i)   PyUnicode_READ(k, d, i)
+#else
+  #define CYTHON_PEP393_ENABLED 0
+  #define __Pyx_PyUnicode_READY(op)       (0)
+  #define __Pyx_PyUnicode_GET_LENGTH(u)   PyUnicode_GET_SIZE(u)
+  #define __Pyx_PyUnicode_READ_CHAR(u, i) ((Py_UCS4)(PyUnicode_AS_UNICODE(u)[i]))
+  #define __Pyx_PyUnicode_READ(k, d, i)   ((k=k), (Py_UCS4)(((Py_UNICODE*)d)[i]))
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define PyBaseString_Type            PyUnicode_Type
+  #define PyStringObject               PyUnicodeObject
+  #define PyString_Type                PyUnicode_Type
+  #define PyString_Check               PyUnicode_Check
+  #define PyString_CheckExact          PyUnicode_CheckExact
+#endif
+#if PY_VERSION_HEX < 0x02060000
+  #define PyBytesObject                PyStringObject
+  #define PyBytes_Type                 PyString_Type
+  #define PyBytes_Check                PyString_Check
+  #define PyBytes_CheckExact           PyString_CheckExact
+  #define PyBytes_FromString           PyString_FromString
+  #define PyBytes_FromStringAndSize    PyString_FromStringAndSize
+  #define PyBytes_FromFormat           PyString_FromFormat
+  #define PyBytes_DecodeEscape         PyString_DecodeEscape
+  #define PyBytes_AsString             PyString_AsString
+  #define PyBytes_AsStringAndSize      PyString_AsStringAndSize
+  #define PyBytes_Size                 PyString_Size
+  #define PyBytes_AS_STRING            PyString_AS_STRING
+  #define PyBytes_GET_SIZE             PyString_GET_SIZE
+  #define PyBytes_Repr                 PyString_Repr
+  #define PyBytes_Concat               PyString_Concat
+  #define PyBytes_ConcatAndDel         PyString_ConcatAndDel
+#endif
+#if PY_VERSION_HEX < 0x02060000
+  #define PySet_Check(obj)             PyObject_TypeCheck(obj, &PySet_Type)
+  #define PyFrozenSet_Check(obj)       PyObject_TypeCheck(obj, &PyFrozenSet_Type)
+#endif
+#ifndef PySet_CheckExact
+  #define PySet_CheckExact(obj)        (Py_TYPE(obj) == &PySet_Type)
+#endif
+#define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type)
+#if PY_MAJOR_VERSION >= 3
+  #define PyIntObject                  PyLongObject
+  #define PyInt_Type                   PyLong_Type
+  #define PyInt_Check(op)              PyLong_Check(op)
+  #define PyInt_CheckExact(op)         PyLong_CheckExact(op)
+  #define PyInt_FromString             PyLong_FromString
+  #define PyInt_FromUnicode            PyLong_FromUnicode
+  #define PyInt_FromLong               PyLong_FromLong
+  #define PyInt_FromSize_t             PyLong_FromSize_t
+  #define PyInt_FromSsize_t            PyLong_FromSsize_t
+  #define PyInt_AsLong                 PyLong_AsLong
+  #define PyInt_AS_LONG                PyLong_AS_LONG
+  #define PyInt_AsSsize_t              PyLong_AsSsize_t
+  #define PyInt_AsUnsignedLongMask     PyLong_AsUnsignedLongMask
+  #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define PyBoolObject                 PyLongObject
+#endif
+#if PY_VERSION_HEX < 0x03020000
+  typedef long Py_hash_t;
+  #define __Pyx_PyInt_FromHash_t PyInt_FromLong
+  #define __Pyx_PyInt_AsHash_t   PyInt_AsLong
+#else
+  #define __Pyx_PyInt_FromHash_t PyInt_FromSsize_t
+  #define __Pyx_PyInt_AsHash_t   PyInt_AsSsize_t
+#endif
+#if (PY_MAJOR_VERSION < 3) || (PY_VERSION_HEX >= 0x03010300)
+  #define __Pyx_PySequence_GetSlice(obj, a, b) PySequence_GetSlice(obj, a, b)
+  #define __Pyx_PySequence_SetSlice(obj, a, b, value) PySequence_SetSlice(obj, a, b, value)
+  #define __Pyx_PySequence_DelSlice(obj, a, b) PySequence_DelSlice(obj, a, b)
+#else
+  #define __Pyx_PySequence_GetSlice(obj, a, b) (unlikely(!(obj)) ? \
+        (PyErr_SetString(PyExc_SystemError, "null argument to internal routine"), (PyObject*)0) : \
+        (likely((obj)->ob_type->tp_as_mapping) ? (PySequence_GetSlice(obj, a, b)) : \
+            (PyErr_Format(PyExc_TypeError, "'%.200s' object is unsliceable", (obj)->ob_type->tp_name), (PyObject*)0)))
+  #define __Pyx_PySequence_SetSlice(obj, a, b, value) (unlikely(!(obj)) ? \
+        (PyErr_SetString(PyExc_SystemError, "null argument to internal routine"), -1) : \
+        (likely((obj)->ob_type->tp_as_mapping) ? (PySequence_SetSlice(obj, a, b, value)) : \
+            (PyErr_Format(PyExc_TypeError, "'%.200s' object doesn't support slice assignment", (obj)->ob_type->tp_name), -1)))
+  #define __Pyx_PySequence_DelSlice(obj, a, b) (unlikely(!(obj)) ? \
+        (PyErr_SetString(PyExc_SystemError, "null argument to internal routine"), -1) : \
+        (likely((obj)->ob_type->tp_as_mapping) ? (PySequence_DelSlice(obj, a, b)) : \
+            (PyErr_Format(PyExc_TypeError, "'%.200s' object doesn't support slice deletion", (obj)->ob_type->tp_name), -1)))
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define PyMethod_New(func, self, klass) ((self) ? PyMethod_New(func, self) : PyInstanceMethod_New(func))
+#endif
+#if PY_VERSION_HEX < 0x02050000
+  #define __Pyx_GetAttrString(o,n)   PyObject_GetAttrString((o),((char *)(n)))
+  #define __Pyx_SetAttrString(o,n,a) PyObject_SetAttrString((o),((char *)(n)),(a))
+  #define __Pyx_DelAttrString(o,n)   PyObject_DelAttrString((o),((char *)(n)))
+#else
+  #define __Pyx_GetAttrString(o,n)   PyObject_GetAttrString((o),(n))
+  #define __Pyx_SetAttrString(o,n,a) PyObject_SetAttrString((o),(n),(a))
+  #define __Pyx_DelAttrString(o,n)   PyObject_DelAttrString((o),(n))
+#endif
+#if PY_VERSION_HEX < 0x02050000
+  #define __Pyx_NAMESTR(n) ((char *)(n))
+  #define __Pyx_DOCSTR(n)  ((char *)(n))
+#else
+  #define __Pyx_NAMESTR(n) (n)
+  #define __Pyx_DOCSTR(n)  (n)
+#endif
+
+
+#if PY_MAJOR_VERSION >= 3
+  #define __Pyx_PyNumber_Divide(x,y)         PyNumber_TrueDivide(x,y)
+  #define __Pyx_PyNumber_InPlaceDivide(x,y)  PyNumber_InPlaceTrueDivide(x,y)
+#else
+  #define __Pyx_PyNumber_Divide(x,y)         PyNumber_Divide(x,y)
+  #define __Pyx_PyNumber_InPlaceDivide(x,y)  PyNumber_InPlaceDivide(x,y)
+#endif
+
+#ifndef __PYX_EXTERN_C
+  #ifdef __cplusplus
+    #define __PYX_EXTERN_C extern "C"
+  #else
+    #define __PYX_EXTERN_C extern
+  #endif
+#endif
+
+#if defined(WIN32) || defined(MS_WINDOWS)
+#define _USE_MATH_DEFINES
+#endif
+#include <math.h>
+#define __PYX_HAVE__bx__intervals__intersection
+#define __PYX_HAVE_API__bx__intervals__intersection
+#include "stdlib.h"
+#ifdef _OPENMP
+#include <omp.h>
+#endif /* _OPENMP */
+
+#ifdef PYREX_WITHOUT_ASSERTIONS
+#define CYTHON_WITHOUT_ASSERTIONS
+#endif
+
+#ifndef CYTHON_INLINE
+  #if defined(__GNUC__)
+    #define CYTHON_INLINE __inline__
+  #elif defined(_MSC_VER)
+    #define CYTHON_INLINE __inline
+  #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+    #define CYTHON_INLINE inline
+  #else
+    #define CYTHON_INLINE
+  #endif
+#endif
+#ifndef CYTHON_UNUSED
+# if defined(__GNUC__)
+#   if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
+#     define CYTHON_UNUSED __attribute__ ((__unused__))
+#   else
+#     define CYTHON_UNUSED
+#   endif
+# elif defined(__ICC) || (defined(__INTEL_COMPILER) && !defined(_MSC_VER))
+#   define CYTHON_UNUSED __attribute__ ((__unused__))
+# else
+#   define CYTHON_UNUSED
+# endif
+#endif
+typedef struct {PyObject **p; char *s; const long n; const char* encoding; const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry; /*proto*/
+
+#define __Pyx_PyBytes_FromUString(s) PyBytes_FromString((char*)s)
+#define __Pyx_PyBytes_AsUString(s)   ((unsigned char*) PyBytes_AsString(s))
+#define __Pyx_Owned_Py_None(b) (Py_INCREF(Py_None), Py_None)
+#define __Pyx_PyBool_FromLong(b) ((b) ? (Py_INCREF(Py_True), Py_True) : (Py_INCREF(Py_False), Py_False))
+static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*);
+static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x);
+static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*);
+static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t);
+static CYTHON_INLINE size_t __Pyx_PyInt_AsSize_t(PyObject*);
+#if CYTHON_COMPILING_IN_CPYTHON
+#define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x))
+#else
+#define __pyx_PyFloat_AsDouble(x) PyFloat_AsDouble(x)
+#endif
+#define __pyx_PyFloat_AsFloat(x) ((float) __pyx_PyFloat_AsDouble(x))
+
+
+#ifdef __GNUC__
+  /* Test for GCC > 2.95 */
+  #if __GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))
+    #define likely(x)   __builtin_expect(!!(x), 1)
+    #define unlikely(x) __builtin_expect(!!(x), 0)
+  #else /* __GNUC__ > 2 ... */
+    #define likely(x)   (x)
+    #define unlikely(x) (x)
+  #endif /* __GNUC__ > 2 ... */
+#else /* __GNUC__ */
+  #define likely(x)   (x)
+  #define unlikely(x) (x)
+#endif /* __GNUC__ */
+    
+static PyObject *__pyx_m;
+static PyObject *__pyx_b;
+static PyObject *__pyx_empty_tuple;
+static PyObject *__pyx_empty_bytes;
+static int __pyx_lineno;
+static int __pyx_clineno = 0;
+static const char * __pyx_cfilenm= __FILE__;
+static const char *__pyx_filename;
+
+
+static const char *__pyx_f[] = {
+  "intersection.pyx",
+};
+
+/*--- Type declarations ---*/
+struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode;
+struct __pyx_obj_2bx_9intervals_12intersection_IntervalTree;
+struct __pyx_obj_2bx_9intervals_12intersection_Interval;
+struct __pyx_opt_args_2bx_9intervals_12intersection_12IntervalNode_left;
+struct __pyx_opt_args_2bx_9intervals_12intersection_12IntervalNode_right;
+
+/* "bx/intervals/intersection.pyx":231
+ * 
+ * 
+ *     cpdef left(self, position, int n=1, int max_dist=2500):             # <<<<<<<<<<<<<<
+ *         """
+ *         find n features with a start > than `position`
+ */
+struct __pyx_opt_args_2bx_9intervals_12intersection_12IntervalNode_left {
+  int __pyx_n;
+  int n;
+  int max_dist;
+};
+
+/* "bx/intervals/intersection.pyx":246
+ *         return r[:n]
+ * 
+ *     cpdef right(self, position, int n=1, int max_dist=2500):             # <<<<<<<<<<<<<<
+ *         """
+ *         find n features with a end < than position
+ */
+struct __pyx_opt_args_2bx_9intervals_12intersection_12IntervalNode_right {
+  int __pyx_n;
+  int n;
+  int max_dist;
+};
+
+/* "bx/intervals/intersection.pyx":60
+ * cdef float nlog = -1.0 / log(0.5)
+ * 
+ * cdef class IntervalNode:             # <<<<<<<<<<<<<<
+ *     """
+ *     A single node of an `IntervalTree`.
+ */
+struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode {
+  PyObject_HEAD
+  struct __pyx_vtabstruct_2bx_9intervals_12intersection_IntervalNode *__pyx_vtab;
+  float priority;
+  PyObject *interval;
+  int start;
+  int end;
+  int minend;
+  int maxend;
+  int minstart;
+  struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *cleft;
+  struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *cright;
+  struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *croot;
+};
+
+
+/* "bx/intervals/intersection.pyx":325
+ *             return self == other or self > other
+ * 
+ * cdef class IntervalTree:             # <<<<<<<<<<<<<<
+ *     """
+ *     Data structure for performing window intersect queries on a set of
+ */
+struct __pyx_obj_2bx_9intervals_12intersection_IntervalTree {
+  PyObject_HEAD
+  struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *root;
+};
+
+
+/* "bx/intervals/intersection.pyx":273
+ * ## ---- Wrappers that retain the old interface -------------------------------
+ * 
+ * cdef class Interval:             # <<<<<<<<<<<<<<
+ *     """
+ *     Basic feature, with required integer start and end properties.
+ */
+struct __pyx_obj_2bx_9intervals_12intersection_Interval {
+  PyObject_HEAD
+  int start;
+  int end;
+  PyObject *value;
+  PyObject *chrom;
+  PyObject *strand;
+};
+
+
+
+/* "bx/intervals/intersection.pyx":60
+ * cdef float nlog = -1.0 / log(0.5)
+ * 
+ * cdef class IntervalNode:             # <<<<<<<<<<<<<<
+ *     """
+ *     A single node of an `IntervalTree`.
+ */
+
+struct __pyx_vtabstruct_2bx_9intervals_12intersection_IntervalNode {
+  struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *(*insert)(struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *, int, int, PyObject *, int __pyx_skip_dispatch);
+  struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *(*rotate_right)(struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *);
+  struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *(*rotate_left)(struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *);
+  void (*set_ends)(struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *);
+  void (*_intersect)(struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *, int, int, PyObject *);
+  void (*_seek_left)(struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *, int, PyObject *, int, int);
+  void (*_seek_right)(struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *, int, PyObject *, int, int);
+  PyObject *(*left)(struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *, PyObject *, int __pyx_skip_dispatch, struct __pyx_opt_args_2bx_9intervals_12intersection_12IntervalNode_left *__pyx_optional_args);
+  PyObject *(*right)(struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *, PyObject *, int __pyx_skip_dispatch, struct __pyx_opt_args_2bx_9intervals_12intersection_12IntervalNode_right *__pyx_optional_args);
+  void (*_traverse)(struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *, PyObject *);
+};
+static struct __pyx_vtabstruct_2bx_9intervals_12intersection_IntervalNode *__pyx_vtabptr_2bx_9intervals_12intersection_IntervalNode;
+static CYTHON_INLINE void __pyx_f_2bx_9intervals_12intersection_12IntervalNode_set_ends(struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *);
+#ifndef CYTHON_REFNANNY
+  #define CYTHON_REFNANNY 0
+#endif
+#if CYTHON_REFNANNY
+  typedef struct {
+    void (*INCREF)(void*, PyObject*, int);
+    void (*DECREF)(void*, PyObject*, int);
+    void (*GOTREF)(void*, PyObject*, int);
+    void (*GIVEREF)(void*, PyObject*, int);
+    void* (*SetupContext)(const char*, int, const char*);
+    void (*FinishContext)(void**);
+  } __Pyx_RefNannyAPIStruct;
+  static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL;
+  static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname); /*proto*/
+  #define __Pyx_RefNannyDeclarations void *__pyx_refnanny = NULL;
+#ifdef WITH_THREAD
+  #define __Pyx_RefNannySetupContext(name, acquire_gil) \
+          if (acquire_gil) { \
+              PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure(); \
+              __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__); \
+              PyGILState_Release(__pyx_gilstate_save); \
+          } else { \
+              __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__); \
+          }
+#else
+  #define __Pyx_RefNannySetupContext(name, acquire_gil) \
+          __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__)
+#endif
+  #define __Pyx_RefNannyFinishContext() \
+          __Pyx_RefNanny->FinishContext(&__pyx_refnanny)
+  #define __Pyx_INCREF(r)  __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_DECREF(r)  __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_GOTREF(r)  __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_XINCREF(r)  do { if((r) != NULL) {__Pyx_INCREF(r); }} while(0)
+  #define __Pyx_XDECREF(r)  do { if((r) != NULL) {__Pyx_DECREF(r); }} while(0)
+  #define __Pyx_XGOTREF(r)  do { if((r) != NULL) {__Pyx_GOTREF(r); }} while(0)
+  #define __Pyx_XGIVEREF(r) do { if((r) != NULL) {__Pyx_GIVEREF(r);}} while(0)
+#else
+  #define __Pyx_RefNannyDeclarations
+  #define __Pyx_RefNannySetupContext(name, acquire_gil)
+  #define __Pyx_RefNannyFinishContext()
+  #define __Pyx_INCREF(r) Py_INCREF(r)
+  #define __Pyx_DECREF(r) Py_DECREF(r)
+  #define __Pyx_GOTREF(r)
+  #define __Pyx_GIVEREF(r)
+  #define __Pyx_XINCREF(r) Py_XINCREF(r)
+  #define __Pyx_XDECREF(r) Py_XDECREF(r)
+  #define __Pyx_XGOTREF(r)
+  #define __Pyx_XGIVEREF(r)
+#endif /* CYTHON_REFNANNY */
+#define __Pyx_CLEAR(r)    do { PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);} while(0)
+#define __Pyx_XCLEAR(r)   do { if((r) != NULL) {PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);}} while(0)
+
+static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
+    Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/
+
+static void __Pyx_RaiseDoubleKeywordsError(const char* func_name, PyObject* kw_name); /*proto*/
+
+static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
+    PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
+    const char* function_name); /*proto*/
+
+static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type); /*proto*/
+
+static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/
+
+static CYTHON_INLINE int __Pyx_CheckKeywordStrings(PyObject *kwdict, const char* function_name, int kw_allowed); /*proto*/
+
+static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level); /*proto*/
+
+static CYTHON_INLINE unsigned char __Pyx_PyInt_AsUnsignedChar(PyObject *);
+
+static CYTHON_INLINE unsigned short __Pyx_PyInt_AsUnsignedShort(PyObject *);
+
+static CYTHON_INLINE unsigned int __Pyx_PyInt_AsUnsignedInt(PyObject *);
+
+static CYTHON_INLINE char __Pyx_PyInt_AsChar(PyObject *);
+
+static CYTHON_INLINE short __Pyx_PyInt_AsShort(PyObject *);
+
+static CYTHON_INLINE int __Pyx_PyInt_AsInt(PyObject *);
+
+static CYTHON_INLINE signed char __Pyx_PyInt_AsSignedChar(PyObject *);
+
+static CYTHON_INLINE signed short __Pyx_PyInt_AsSignedShort(PyObject *);
+
+static CYTHON_INLINE signed int __Pyx_PyInt_AsSignedInt(PyObject *);
+
+static CYTHON_INLINE int __Pyx_PyInt_AsLongDouble(PyObject *);
+
+static CYTHON_INLINE unsigned long __Pyx_PyInt_AsUnsignedLong(PyObject *);
+
+static CYTHON_INLINE unsigned PY_LONG_LONG __Pyx_PyInt_AsUnsignedLongLong(PyObject *);
+
+static CYTHON_INLINE long __Pyx_PyInt_AsLong(PyObject *);
+
+static CYTHON_INLINE PY_LONG_LONG __Pyx_PyInt_AsLongLong(PyObject *);
+
+static CYTHON_INLINE signed long __Pyx_PyInt_AsSignedLong(PyObject *);
+
+static CYTHON_INLINE signed PY_LONG_LONG __Pyx_PyInt_AsSignedLongLong(PyObject *);
+
+static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
+static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
+
+static void __Pyx_WriteUnraisable(const char *name, int clineno,
+                                  int lineno, const char *filename); /*proto*/
+
+static int __Pyx_check_binary_version(void);
+
+static int __Pyx_SetVtable(PyObject *dict, void *vtable); /*proto*/
+
+typedef struct {
+    int code_line;
+    PyCodeObject* code_object;
+} __Pyx_CodeObjectCacheEntry;
+struct __Pyx_CodeObjectCache {
+    int count;
+    int max_count;
+    __Pyx_CodeObjectCacheEntry* entries;
+};
+static struct __Pyx_CodeObjectCache __pyx_code_cache = {0,0,NULL};
+static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line);
+static PyCodeObject *__pyx_find_code_object(int code_line);
+static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object);
+
+static void __Pyx_AddTraceback(const char *funcname, int c_line,
+                               int py_line, const char *filename); /*proto*/
+
+static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
+
+
+/* Module declarations from 'bx.intervals.intersection' */
+static PyTypeObject *__pyx_ptype_2bx_9intervals_12intersection_IntervalNode = 0;
+static PyTypeObject *__pyx_ptype_2bx_9intervals_12intersection_Interval = 0;
+static PyTypeObject *__pyx_ptype_2bx_9intervals_12intersection_IntervalTree = 0;
+static float __pyx_v_2bx_9intervals_12intersection_nlog;
+static struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *__pyx_v_2bx_9intervals_12intersection_EmptyNode = 0;
+static CYTHON_INLINE int __pyx_f_2bx_9intervals_12intersection_imax2(int, int); /*proto*/
+static CYTHON_INLINE int __pyx_f_2bx_9intervals_12intersection_imax3(int, int, int); /*proto*/
+static CYTHON_INLINE int __pyx_f_2bx_9intervals_12intersection_imin3(int, int, int); /*proto*/
+static CYTHON_INLINE int __pyx_f_2bx_9intervals_12intersection_imin2(int, int); /*proto*/
+#define __Pyx_MODULE_NAME "bx.intervals.intersection"
+int __pyx_module_is_main_bx__intervals__intersection = 0;
+
+/* Implementation of 'bx.intervals.intersection' */
+static PyObject *__pyx_pf_2bx_9intervals_12intersection_12IntervalNode_9left_node___get__(struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_2bx_9intervals_12intersection_12IntervalNode_10right_node___get__(struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_2bx_9intervals_12intersection_12IntervalNode_9root_node___get__(struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_2bx_9intervals_12intersection_12IntervalNode___repr__(struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *__pyx_v_self); /* proto */
+static int __pyx_pf_2bx_9intervals_12intersection_12IntervalNode_2__cinit__(struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *__pyx_v_self, int __pyx_v_start, int __pyx_v_end, PyObject *__pyx_v_interval); /* proto */
+static PyObject *__pyx_pf_2bx_9intervals_12intersection_12IntervalNode_4insert(struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *__pyx_v_self, int __pyx_v_start, int __pyx_v_end, PyObject *__pyx_v_interval); /* proto */
+static PyObject *__pyx_pf_2bx_9intervals_12intersection_12IntervalNode_6intersect(struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *__pyx_v_self, int __pyx_v_start, int __pyx_v_end, CYTHON_UNUSED PyObject *__pyx_v_sort); /* proto */
+static PyObject *__pyx_pf_2bx_9intervals_12intersection_12IntervalNode_8left(struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *__pyx_v_self, PyObject *__pyx_v_position, int __pyx_v_n, int __pyx_v_max_dist); /* proto */
+static PyObject *__pyx_pf_2bx_9intervals_12intersection_12IntervalNode_10right(struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *__pyx_v_self, PyObject *__pyx_v_position, int __pyx_v_n, int __pyx_v_max_dist); /* proto */
+static PyObject *__pyx_pf_2bx_9intervals_12intersection_12IntervalNode_12traverse(struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *__pyx_v_self, PyObject *__pyx_v_func); /* proto */
+static PyObject *__pyx_pf_2bx_9intervals_12intersection_12IntervalNode_8interval___get__(struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *__pyx_v_self); /* proto */
+static int __pyx_pf_2bx_9intervals_12intersection_12IntervalNode_8interval_2__set__(struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *__pyx_v_self, PyObject *__pyx_v_value); /* proto */
+static int __pyx_pf_2bx_9intervals_12intersection_12IntervalNode_8interval_4__del__(struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_2bx_9intervals_12intersection_12IntervalNode_5start___get__(struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *__pyx_v_self); /* proto */
+static int __pyx_pf_2bx_9intervals_12intersection_12IntervalNode_5start_2__set__(struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *__pyx_v_self, PyObject *__pyx_v_value); /* proto */
+static PyObject *__pyx_pf_2bx_9intervals_12intersection_12IntervalNode_3end___get__(struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *__pyx_v_self); /* proto */
+static int __pyx_pf_2bx_9intervals_12intersection_12IntervalNode_3end_2__set__(struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *__pyx_v_self, PyObject *__pyx_v_value); /* proto */
+static int __pyx_pf_2bx_9intervals_12intersection_8Interval___init__(struct __pyx_obj_2bx_9intervals_12intersection_Interval *__pyx_v_self, int __pyx_v_start, int __pyx_v_end, PyObject *__pyx_v_value, PyObject *__pyx_v_chrom, PyObject *__pyx_v_strand); /* proto */
+static PyObject *__pyx_pf_2bx_9intervals_12intersection_8Interval_2__repr__(struct __pyx_obj_2bx_9intervals_12intersection_Interval *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_2bx_9intervals_12intersection_8Interval_4__richcmp__(PyObject *__pyx_v_self, PyObject *__pyx_v_other, PyObject *__pyx_v_op); /* proto */
+static PyObject *__pyx_pf_2bx_9intervals_12intersection_8Interval_5start___get__(struct __pyx_obj_2bx_9intervals_12intersection_Interval *__pyx_v_self); /* proto */
+static int __pyx_pf_2bx_9intervals_12intersection_8Interval_5start_2__set__(struct __pyx_obj_2bx_9intervals_12intersection_Interval *__pyx_v_self, PyObject *__pyx_v_value); /* proto */
+static PyObject *__pyx_pf_2bx_9intervals_12intersection_8Interval_3end___get__(struct __pyx_obj_2bx_9intervals_12intersection_Interval *__pyx_v_self); /* proto */
+static int __pyx_pf_2bx_9intervals_12intersection_8Interval_3end_2__set__(struct __pyx_obj_2bx_9intervals_12intersection_Interval *__pyx_v_self, PyObject *__pyx_v_value); /* proto */
+static PyObject *__pyx_pf_2bx_9intervals_12intersection_8Interval_5value___get__(struct __pyx_obj_2bx_9intervals_12intersection_Interval *__pyx_v_self); /* proto */
+static int __pyx_pf_2bx_9intervals_12intersection_8Interval_5value_2__set__(struct __pyx_obj_2bx_9intervals_12intersection_Interval *__pyx_v_self, PyObject *__pyx_v_value); /* proto */
+static int __pyx_pf_2bx_9intervals_12intersection_8Interval_5value_4__del__(struct __pyx_obj_2bx_9intervals_12intersection_Interval *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_2bx_9intervals_12intersection_8Interval_5chrom___get__(struct __pyx_obj_2bx_9intervals_12intersection_Interval *__pyx_v_self); /* proto */
+static int __pyx_pf_2bx_9intervals_12intersection_8Interval_5chrom_2__set__(struct __pyx_obj_2bx_9intervals_12intersection_Interval *__pyx_v_self, PyObject *__pyx_v_value); /* proto */
+static int __pyx_pf_2bx_9intervals_12intersection_8Interval_5chrom_4__del__(struct __pyx_obj_2bx_9intervals_12intersection_Interval *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_2bx_9intervals_12intersection_8Interval_6strand___get__(struct __pyx_obj_2bx_9intervals_12intersection_Interval *__pyx_v_self); /* proto */
+static int __pyx_pf_2bx_9intervals_12intersection_8Interval_6strand_2__set__(struct __pyx_obj_2bx_9intervals_12intersection_Interval *__pyx_v_self, PyObject *__pyx_v_value); /* proto */
+static int __pyx_pf_2bx_9intervals_12intersection_8Interval_6strand_4__del__(struct __pyx_obj_2bx_9intervals_12intersection_Interval *__pyx_v_self); /* proto */
+static int __pyx_pf_2bx_9intervals_12intersection_12IntervalTree___cinit__(CYTHON_UNUSED struct __pyx_obj_2bx_9intervals_12intersection_IntervalTree *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_2bx_9intervals_12intersection_12IntervalTree_2insert(struct __pyx_obj_2bx_9intervals_12intersection_IntervalTree *__pyx_v_self, int __pyx_v_start, int __pyx_v_end, PyObject *__pyx_v_value); /* proto */
+static PyObject *__pyx_pf_2bx_9intervals_12intersection_12IntervalTree_4find(struct __pyx_obj_2bx_9intervals_12intersection_IntervalTree *__pyx_v_self, PyObject *__pyx_v_start, PyObject *__pyx_v_end); /* proto */
+static PyObject *__pyx_pf_2bx_9intervals_12intersection_12IntervalTree_6before(struct __pyx_obj_2bx_9intervals_12intersection_IntervalTree *__pyx_v_self, PyObject *__pyx_v_position, PyObject *__pyx_v_num_intervals, PyObject *__pyx_v_max_dist); /* proto */
+static PyObject *__pyx_pf_2bx_9intervals_12intersection_12IntervalTree_8after(struct __pyx_obj_2bx_9intervals_12intersection_IntervalTree *__pyx_v_self, PyObject *__pyx_v_position, PyObject *__pyx_v_num_intervals, PyObject *__pyx_v_max_dist); /* proto */
+static PyObject *__pyx_pf_2bx_9intervals_12intersection_12IntervalTree_10insert_interval(struct __pyx_obj_2bx_9intervals_12intersection_IntervalTree *__pyx_v_self, PyObject *__pyx_v_interval); /* proto */
+static PyObject *__pyx_pf_2bx_9intervals_12intersection_12IntervalTree_12before_interval(struct __pyx_obj_2bx_9intervals_12intersection_IntervalTree *__pyx_v_self, PyObject *__pyx_v_interval, PyObject *__pyx_v_num_intervals, PyObject *__pyx_v_max_dist); /* proto */
+static PyObject *__pyx_pf_2bx_9intervals_12intersection_12IntervalTree_14after_interval(struct __pyx_obj_2bx_9intervals_12intersection_IntervalTree *__pyx_v_self, PyObject *__pyx_v_interval, PyObject *__pyx_v_num_intervals, PyObject *__pyx_v_max_dist); /* proto */
+static PyObject *__pyx_pf_2bx_9intervals_12intersection_12IntervalTree_16upstream_of_interval(struct __pyx_obj_2bx_9intervals_12intersection_IntervalTree *__pyx_v_self, PyObject *__pyx_v_interval, PyObject *__pyx_v_num_intervals, PyObject *__pyx_v_max_dist); /* proto */
+static PyObject *__pyx_pf_2bx_9intervals_12intersection_12IntervalTree_18downstream_of_interval(struct __pyx_obj_2bx_9intervals_12intersection_IntervalTree *__pyx_v_self, PyObject *__pyx_v_interval, PyObject *__pyx_v_num_intervals, PyObject *__pyx_v_max_dist); /* proto */
+static PyObject *__pyx_pf_2bx_9intervals_12intersection_12IntervalTree_20traverse(struct __pyx_obj_2bx_9intervals_12intersection_IntervalTree *__pyx_v_self, PyObject *__pyx_v_fn); /* proto */
+static char __pyx_k_1[] = "IntervalNode(%i, %i)";
+static char __pyx_k_5[] = "start must be less than end";
+static char __pyx_k_6[] = "Interval(%d, %d";
+static char __pyx_k_7[] = ", value=";
+static char __pyx_k_8[] = ")";
+static char __pyx_k_9[] = "-";
+static char __pyx_k_10[] = "\nData structure for performing intersect queries on a set of intervals which\npreserves all information about the intervals (unlike bitset projection methods).\n\n:Authors: James Taylor (james at jamestaylor.org),\n          Ian Schenk (ian.schenck at gmail.com),\n          Brent Pedersen (bpederse at gmail.com)\n";
+static char __pyx_k__n[] = "n";
+static char __pyx_k__add[] = "add";
+static char __pyx_k__end[] = "end";
+static char __pyx_k__key[] = "key";
+static char __pyx_k__find[] = "find";
+static char __pyx_k__left[] = "left";
+static char __pyx_k__sort[] = "sort";
+static char __pyx_k__chrom[] = "chrom";
+static char __pyx_k__right[] = "right";
+static char __pyx_k__start[] = "start";
+static char __pyx_k__value[] = "value";
+static char __pyx_k__insert[] = "insert";
+static char __pyx_k__strand[] = "strand";
+static char __pyx_k__reverse[] = "reverse";
+static char __pyx_k____main__[] = "__main__";
+static char __pyx_k____test__[] = "__test__";
+static char __pyx_k__interval[] = "interval";
+static char __pyx_k__max_dist[] = "max_dist";
+static char __pyx_k__operator[] = "operator";
+static char __pyx_k__position[] = "position";
+static char __pyx_k__traverse[] = "traverse";
+static char __pyx_k__intersect[] = "intersect";
+static char __pyx_k__attrgetter[] = "attrgetter";
+static char __pyx_k__Intersecter[] = "Intersecter";
+static char __pyx_k__add_interval[] = "add_interval";
+static char __pyx_k__num_intervals[] = "num_intervals";
+static char __pyx_k__insert_interval[] = "insert_interval";
+static PyObject *__pyx_kp_s_1;
+static PyObject *__pyx_kp_s_5;
+static PyObject *__pyx_kp_s_6;
+static PyObject *__pyx_kp_s_7;
+static PyObject *__pyx_kp_s_8;
+static PyObject *__pyx_kp_s_9;
+static PyObject *__pyx_n_s__Intersecter;
+static PyObject *__pyx_n_s____main__;
+static PyObject *__pyx_n_s____test__;
+static PyObject *__pyx_n_s__add;
+static PyObject *__pyx_n_s__add_interval;
+static PyObject *__pyx_n_s__attrgetter;
+static PyObject *__pyx_n_s__chrom;
+static PyObject *__pyx_n_s__end;
+static PyObject *__pyx_n_s__find;
+static PyObject *__pyx_n_s__insert;
+static PyObject *__pyx_n_s__insert_interval;
+static PyObject *__pyx_n_s__intersect;
+static PyObject *__pyx_n_s__interval;
+static PyObject *__pyx_n_s__key;
+static PyObject *__pyx_n_s__left;
+static PyObject *__pyx_n_s__max_dist;
+static PyObject *__pyx_n_s__n;
+static PyObject *__pyx_n_s__num_intervals;
+static PyObject *__pyx_n_s__operator;
+static PyObject *__pyx_n_s__position;
+static PyObject *__pyx_n_s__reverse;
+static PyObject *__pyx_n_s__right;
+static PyObject *__pyx_n_s__sort;
+static PyObject *__pyx_n_s__start;
+static PyObject *__pyx_n_s__strand;
+static PyObject *__pyx_n_s__traverse;
+static PyObject *__pyx_n_s__value;
+static PyObject *__pyx_int_0;
+static PyObject *__pyx_int_1;
+static PyObject *__pyx_int_2;
+static PyObject *__pyx_int_3;
+static PyObject *__pyx_int_4;
+static PyObject *__pyx_int_5;
+static PyObject *__pyx_int_neg_1;
+static PyObject *__pyx_int_2500;
+static PyObject *__pyx_k_2;
+static PyObject *__pyx_k_tuple_3;
+static PyObject *__pyx_k_tuple_4;
+static PyObject *__pyx_k_tuple_11;
+
+/* "bx/intervals/intersection.pyx":32
+ *     int iabs(int)
+ * 
+ * cdef inline int imax2(int a, int b):             # <<<<<<<<<<<<<<
+ *     if b > a: return b
+ *     return a
+ */
+
+static CYTHON_INLINE int __pyx_f_2bx_9intervals_12intersection_imax2(int __pyx_v_a, int __pyx_v_b) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("imax2", 0);
+
+  /* "bx/intervals/intersection.pyx":33
+ * 
+ * cdef inline int imax2(int a, int b):
+ *     if b > a: return b             # <<<<<<<<<<<<<<
+ *     return a
+ * 
+ */
+  __pyx_t_1 = (__pyx_v_b > __pyx_v_a);
+  if (__pyx_t_1) {
+    __pyx_r = __pyx_v_b;
+    goto __pyx_L0;
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  /* "bx/intervals/intersection.pyx":34
+ * cdef inline int imax2(int a, int b):
+ *     if b > a: return b
+ *     return a             # <<<<<<<<<<<<<<
+ * 
+ * cdef inline int imax3(int a, int b, int c):
+ */
+  __pyx_r = __pyx_v_a;
+  goto __pyx_L0;
+
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/intervals/intersection.pyx":36
+ *     return a
+ * 
+ * cdef inline int imax3(int a, int b, int c):             # <<<<<<<<<<<<<<
+ *     if b > a:
+ *         if c > b:
+ */
+
+static CYTHON_INLINE int __pyx_f_2bx_9intervals_12intersection_imax3(int __pyx_v_a, int __pyx_v_b, int __pyx_v_c) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("imax3", 0);
+
+  /* "bx/intervals/intersection.pyx":37
+ * 
+ * cdef inline int imax3(int a, int b, int c):
+ *     if b > a:             # <<<<<<<<<<<<<<
+ *         if c > b:
+ *             return c
+ */
+  __pyx_t_1 = (__pyx_v_b > __pyx_v_a);
+  if (__pyx_t_1) {
+
+    /* "bx/intervals/intersection.pyx":38
+ * cdef inline int imax3(int a, int b, int c):
+ *     if b > a:
+ *         if c > b:             # <<<<<<<<<<<<<<
+ *             return c
+ *         return b
+ */
+    __pyx_t_1 = (__pyx_v_c > __pyx_v_b);
+    if (__pyx_t_1) {
+
+      /* "bx/intervals/intersection.pyx":39
+ *     if b > a:
+ *         if c > b:
+ *             return c             # <<<<<<<<<<<<<<
+ *         return b
+ *     if a > c:
+ */
+      __pyx_r = __pyx_v_c;
+      goto __pyx_L0;
+      goto __pyx_L4;
+    }
+    __pyx_L4:;
+
+    /* "bx/intervals/intersection.pyx":40
+ *         if c > b:
+ *             return c
+ *         return b             # <<<<<<<<<<<<<<
+ *     if a > c:
+ *         return a
+ */
+    __pyx_r = __pyx_v_b;
+    goto __pyx_L0;
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  /* "bx/intervals/intersection.pyx":41
+ *             return c
+ *         return b
+ *     if a > c:             # <<<<<<<<<<<<<<
+ *         return a
+ *     return c
+ */
+  __pyx_t_1 = (__pyx_v_a > __pyx_v_c);
+  if (__pyx_t_1) {
+
+    /* "bx/intervals/intersection.pyx":42
+ *         return b
+ *     if a > c:
+ *         return a             # <<<<<<<<<<<<<<
+ *     return c
+ * 
+ */
+    __pyx_r = __pyx_v_a;
+    goto __pyx_L0;
+    goto __pyx_L5;
+  }
+  __pyx_L5:;
+
+  /* "bx/intervals/intersection.pyx":43
+ *     if a > c:
+ *         return a
+ *     return c             # <<<<<<<<<<<<<<
+ * 
+ * cdef inline int imin3(int a, int b, int c):
+ */
+  __pyx_r = __pyx_v_c;
+  goto __pyx_L0;
+
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/intervals/intersection.pyx":45
+ *     return c
+ * 
+ * cdef inline int imin3(int a, int b, int c):             # <<<<<<<<<<<<<<
+ *     if b < a:
+ *         if c < b:
+ */
+
+static CYTHON_INLINE int __pyx_f_2bx_9intervals_12intersection_imin3(int __pyx_v_a, int __pyx_v_b, int __pyx_v_c) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("imin3", 0);
+
+  /* "bx/intervals/intersection.pyx":46
+ * 
+ * cdef inline int imin3(int a, int b, int c):
+ *     if b < a:             # <<<<<<<<<<<<<<
+ *         if c < b:
+ *             return c
+ */
+  __pyx_t_1 = (__pyx_v_b < __pyx_v_a);
+  if (__pyx_t_1) {
+
+    /* "bx/intervals/intersection.pyx":47
+ * cdef inline int imin3(int a, int b, int c):
+ *     if b < a:
+ *         if c < b:             # <<<<<<<<<<<<<<
+ *             return c
+ *         return b
+ */
+    __pyx_t_1 = (__pyx_v_c < __pyx_v_b);
+    if (__pyx_t_1) {
+
+      /* "bx/intervals/intersection.pyx":48
+ *     if b < a:
+ *         if c < b:
+ *             return c             # <<<<<<<<<<<<<<
+ *         return b
+ *     if a < c:
+ */
+      __pyx_r = __pyx_v_c;
+      goto __pyx_L0;
+      goto __pyx_L4;
+    }
+    __pyx_L4:;
+
+    /* "bx/intervals/intersection.pyx":49
+ *         if c < b:
+ *             return c
+ *         return b             # <<<<<<<<<<<<<<
+ *     if a < c:
+ *         return a
+ */
+    __pyx_r = __pyx_v_b;
+    goto __pyx_L0;
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  /* "bx/intervals/intersection.pyx":50
+ *             return c
+ *         return b
+ *     if a < c:             # <<<<<<<<<<<<<<
+ *         return a
+ *     return c
+ */
+  __pyx_t_1 = (__pyx_v_a < __pyx_v_c);
+  if (__pyx_t_1) {
+
+    /* "bx/intervals/intersection.pyx":51
+ *         return b
+ *     if a < c:
+ *         return a             # <<<<<<<<<<<<<<
+ *     return c
+ * 
+ */
+    __pyx_r = __pyx_v_a;
+    goto __pyx_L0;
+    goto __pyx_L5;
+  }
+  __pyx_L5:;
+
+  /* "bx/intervals/intersection.pyx":52
+ *     if a < c:
+ *         return a
+ *     return c             # <<<<<<<<<<<<<<
+ * 
+ * cdef inline int imin2(int a, int b):
+ */
+  __pyx_r = __pyx_v_c;
+  goto __pyx_L0;
+
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/intervals/intersection.pyx":54
+ *     return c
+ * 
+ * cdef inline int imin2(int a, int b):             # <<<<<<<<<<<<<<
+ *     if b < a: return b
+ *     return a
+ */
+
+static CYTHON_INLINE int __pyx_f_2bx_9intervals_12intersection_imin2(int __pyx_v_a, int __pyx_v_b) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("imin2", 0);
+
+  /* "bx/intervals/intersection.pyx":55
+ * 
+ * cdef inline int imin2(int a, int b):
+ *     if b < a: return b             # <<<<<<<<<<<<<<
+ *     return a
+ * 
+ */
+  __pyx_t_1 = (__pyx_v_b < __pyx_v_a);
+  if (__pyx_t_1) {
+    __pyx_r = __pyx_v_b;
+    goto __pyx_L0;
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  /* "bx/intervals/intersection.pyx":56
+ * cdef inline int imin2(int a, int b):
+ *     if b < a: return b
+ *     return a             # <<<<<<<<<<<<<<
+ * 
+ * cdef float nlog = -1.0 / log(0.5)
+ */
+  __pyx_r = __pyx_v_a;
+  goto __pyx_L0;
+
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_9intervals_12intersection_12IntervalNode_9left_node_1__get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_2bx_9intervals_12intersection_12IntervalNode_9left_node_1__get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_9intervals_12intersection_12IntervalNode_9left_node___get__(((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/intervals/intersection.pyx":74
+ * 
+ *     property left_node:
+ *         def __get__(self):             # <<<<<<<<<<<<<<
+ *             return self.cleft if self.cleft is not EmptyNode else None
+ *     property right_node:
+ */
+
+static PyObject *__pyx_pf_2bx_9intervals_12intersection_12IntervalNode_9left_node___get__(struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_t_2;
+  __Pyx_RefNannySetupContext("__get__", 0);
+
+  /* "bx/intervals/intersection.pyx":75
+ *     property left_node:
+ *         def __get__(self):
+ *             return self.cleft if self.cleft is not EmptyNode else None             # <<<<<<<<<<<<<<
+ *     property right_node:
+ *         def __get__(self):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_2 = (__pyx_v_self->cleft != __pyx_v_2bx_9intervals_12intersection_EmptyNode);
+  if (__pyx_t_2) {
+    __Pyx_INCREF(((PyObject *)__pyx_v_self->cleft));
+    __pyx_t_1 = ((PyObject *)__pyx_v_self->cleft);
+  } else {
+    __Pyx_INCREF(Py_None);
+    __pyx_t_1 = Py_None;
+  }
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_9intervals_12intersection_12IntervalNode_10right_node_1__get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_2bx_9intervals_12intersection_12IntervalNode_10right_node_1__get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_9intervals_12intersection_12IntervalNode_10right_node___get__(((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/intervals/intersection.pyx":77
+ *             return self.cleft if self.cleft is not EmptyNode else None
+ *     property right_node:
+ *         def __get__(self):             # <<<<<<<<<<<<<<
+ *             return self.cright if self.cright is not EmptyNode else None
+ *     property root_node:
+ */
+
+static PyObject *__pyx_pf_2bx_9intervals_12intersection_12IntervalNode_10right_node___get__(struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_t_2;
+  __Pyx_RefNannySetupContext("__get__", 0);
+
+  /* "bx/intervals/intersection.pyx":78
+ *     property right_node:
+ *         def __get__(self):
+ *             return self.cright if self.cright is not EmptyNode else None             # <<<<<<<<<<<<<<
+ *     property root_node:
+ *         def __get__(self):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_2 = (__pyx_v_self->cright != __pyx_v_2bx_9intervals_12intersection_EmptyNode);
+  if (__pyx_t_2) {
+    __Pyx_INCREF(((PyObject *)__pyx_v_self->cright));
+    __pyx_t_1 = ((PyObject *)__pyx_v_self->cright);
+  } else {
+    __Pyx_INCREF(Py_None);
+    __pyx_t_1 = Py_None;
+  }
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_9intervals_12intersection_12IntervalNode_9root_node_1__get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_2bx_9intervals_12intersection_12IntervalNode_9root_node_1__get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_9intervals_12intersection_12IntervalNode_9root_node___get__(((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/intervals/intersection.pyx":80
+ *             return self.cright if self.cright is not EmptyNode else None
+ *     property root_node:
+ *         def __get__(self):             # <<<<<<<<<<<<<<
+ *             return self.croot if self.croot is not EmptyNode else None
+ * 
+ */
+
+static PyObject *__pyx_pf_2bx_9intervals_12intersection_12IntervalNode_9root_node___get__(struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_t_2;
+  __Pyx_RefNannySetupContext("__get__", 0);
+
+  /* "bx/intervals/intersection.pyx":81
+ *     property root_node:
+ *         def __get__(self):
+ *             return self.croot if self.croot is not EmptyNode else None             # <<<<<<<<<<<<<<
+ * 
+ *     def __repr__(self):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_2 = (__pyx_v_self->croot != __pyx_v_2bx_9intervals_12intersection_EmptyNode);
+  if (__pyx_t_2) {
+    __Pyx_INCREF(((PyObject *)__pyx_v_self->croot));
+    __pyx_t_1 = ((PyObject *)__pyx_v_self->croot);
+  } else {
+    __Pyx_INCREF(Py_None);
+    __pyx_t_1 = Py_None;
+  }
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_9intervals_12intersection_12IntervalNode_1__repr__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_2bx_9intervals_12intersection_12IntervalNode_1__repr__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__repr__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_9intervals_12intersection_12IntervalNode___repr__(((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/intervals/intersection.pyx":83
+ *             return self.croot if self.croot is not EmptyNode else None
+ * 
+ *     def __repr__(self):             # <<<<<<<<<<<<<<
+ *         return "IntervalNode(%i, %i)" % (self.start, self.end)
+ * 
+ */
+
+static PyObject *__pyx_pf_2bx_9intervals_12intersection_12IntervalNode___repr__(struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__repr__", 0);
+
+  /* "bx/intervals/intersection.pyx":84
+ * 
+ *     def __repr__(self):
+ *         return "IntervalNode(%i, %i)" % (self.start, self.end)             # <<<<<<<<<<<<<<
+ * 
+ *     def __cinit__(IntervalNode self, int start, int end, object interval):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = PyInt_FromLong(__pyx_v_self->start); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 84; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = PyInt_FromLong(__pyx_v_self->end); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 84; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 84; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1);
+  __Pyx_GIVEREF(__pyx_t_1);
+  PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_2);
+  __Pyx_GIVEREF(__pyx_t_2);
+  __pyx_t_1 = 0;
+  __pyx_t_2 = 0;
+  __pyx_t_2 = PyNumber_Remainder(((PyObject *)__pyx_kp_s_1), ((PyObject *)__pyx_t_3)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 84; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(((PyObject *)__pyx_t_2));
+  __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
+  __pyx_r = ((PyObject *)__pyx_t_2);
+  __pyx_t_2 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_AddTraceback("bx.intervals.intersection.IntervalNode.__repr__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_2bx_9intervals_12intersection_12IntervalNode_3__cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static int __pyx_pw_2bx_9intervals_12intersection_12IntervalNode_3__cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  int __pyx_v_start;
+  int __pyx_v_end;
+  PyObject *__pyx_v_interval = 0;
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__cinit__ (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__start,&__pyx_n_s__end,&__pyx_n_s__interval,0};
+    PyObject* values[3] = {0,0,0};
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__start)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__end)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("__cinit__", 1, 3, 3, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 86; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+        case  2:
+        if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__interval)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("__cinit__", 1, 3, 3, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 86; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__cinit__") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 86; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else if (PyTuple_GET_SIZE(__pyx_args) != 3) {
+      goto __pyx_L5_argtuple_error;
+    } else {
+      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+      values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+    }
+    __pyx_v_start = __Pyx_PyInt_AsInt(values[0]); if (unlikely((__pyx_v_start == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 86; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_end = __Pyx_PyInt_AsInt(values[1]); if (unlikely((__pyx_v_end == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 86; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_interval = values[2];
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("__cinit__", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 86; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.intervals.intersection.IntervalNode.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return -1;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_9intervals_12intersection_12IntervalNode_2__cinit__(((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self), __pyx_v_start, __pyx_v_end, __pyx_v_interval);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/intervals/intersection.pyx":86
+ *         return "IntervalNode(%i, %i)" % (self.start, self.end)
+ * 
+ *     def __cinit__(IntervalNode self, int start, int end, object interval):             # <<<<<<<<<<<<<<
+ *         # Python lacks the binomial distribution, so we convert a
+ *         # uniform into a binomial because it naturally scales with
+ */
+
+static int __pyx_pf_2bx_9intervals_12intersection_12IntervalNode_2__cinit__(struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *__pyx_v_self, int __pyx_v_start, int __pyx_v_end, PyObject *__pyx_v_interval) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  double __pyx_t_1;
+  double __pyx_t_2;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__cinit__", 0);
+
+  /* "bx/intervals/intersection.pyx":91
+ *         # tree size.  Also, python's uniform is perfect since the
+ *         # upper limit is not inclusive, which gives us undefined here.
+ *         self.priority = ceil(nlog * log(-1.0/(1.0 * rand()/RAND_MAX - 1)))             # <<<<<<<<<<<<<<
+ *         self.start    = start
+ *         self.end      = end
+ */
+  __pyx_t_1 = (1.0 * rand());
+  if (unlikely(RAND_MAX == 0)) {
+    PyErr_Format(PyExc_ZeroDivisionError, "float division");
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 91; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  __pyx_t_2 = ((__pyx_t_1 / RAND_MAX) - 1.0);
+  if (unlikely(__pyx_t_2 == 0)) {
+    PyErr_Format(PyExc_ZeroDivisionError, "float division");
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 91; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  __pyx_v_self->priority = ceil((__pyx_v_2bx_9intervals_12intersection_nlog * log((-1.0 / __pyx_t_2))));
+
+  /* "bx/intervals/intersection.pyx":92
+ *         # upper limit is not inclusive, which gives us undefined here.
+ *         self.priority = ceil(nlog * log(-1.0/(1.0 * rand()/RAND_MAX - 1)))
+ *         self.start    = start             # <<<<<<<<<<<<<<
+ *         self.end      = end
+ *         self.interval = interval
+ */
+  __pyx_v_self->start = __pyx_v_start;
+
+  /* "bx/intervals/intersection.pyx":93
+ *         self.priority = ceil(nlog * log(-1.0/(1.0 * rand()/RAND_MAX - 1)))
+ *         self.start    = start
+ *         self.end      = end             # <<<<<<<<<<<<<<
+ *         self.interval = interval
+ *         self.maxend   = end
+ */
+  __pyx_v_self->end = __pyx_v_end;
+
+  /* "bx/intervals/intersection.pyx":94
+ *         self.start    = start
+ *         self.end      = end
+ *         self.interval = interval             # <<<<<<<<<<<<<<
+ *         self.maxend   = end
+ *         self.minstart = start
+ */
+  __Pyx_INCREF(__pyx_v_interval);
+  __Pyx_GIVEREF(__pyx_v_interval);
+  __Pyx_GOTREF(__pyx_v_self->interval);
+  __Pyx_DECREF(__pyx_v_self->interval);
+  __pyx_v_self->interval = __pyx_v_interval;
+
+  /* "bx/intervals/intersection.pyx":95
+ *         self.end      = end
+ *         self.interval = interval
+ *         self.maxend   = end             # <<<<<<<<<<<<<<
+ *         self.minstart = start
+ *         self.minend   = end
+ */
+  __pyx_v_self->maxend = __pyx_v_end;
+
+  /* "bx/intervals/intersection.pyx":96
+ *         self.interval = interval
+ *         self.maxend   = end
+ *         self.minstart = start             # <<<<<<<<<<<<<<
+ *         self.minend   = end
+ *         self.cleft    = EmptyNode
+ */
+  __pyx_v_self->minstart = __pyx_v_start;
+
+  /* "bx/intervals/intersection.pyx":97
+ *         self.maxend   = end
+ *         self.minstart = start
+ *         self.minend   = end             # <<<<<<<<<<<<<<
+ *         self.cleft    = EmptyNode
+ *         self.cright   = EmptyNode
+ */
+  __pyx_v_self->minend = __pyx_v_end;
+
+  /* "bx/intervals/intersection.pyx":98
+ *         self.minstart = start
+ *         self.minend   = end
+ *         self.cleft    = EmptyNode             # <<<<<<<<<<<<<<
+ *         self.cright   = EmptyNode
+ *         self.croot    = EmptyNode
+ */
+  __Pyx_INCREF(((PyObject *)__pyx_v_2bx_9intervals_12intersection_EmptyNode));
+  __Pyx_GIVEREF(((PyObject *)__pyx_v_2bx_9intervals_12intersection_EmptyNode));
+  __Pyx_GOTREF(__pyx_v_self->cleft);
+  __Pyx_DECREF(((PyObject *)__pyx_v_self->cleft));
+  __pyx_v_self->cleft = __pyx_v_2bx_9intervals_12intersection_EmptyNode;
+
+  /* "bx/intervals/intersection.pyx":99
+ *         self.minend   = end
+ *         self.cleft    = EmptyNode
+ *         self.cright   = EmptyNode             # <<<<<<<<<<<<<<
+ *         self.croot    = EmptyNode
+ * 
+ */
+  __Pyx_INCREF(((PyObject *)__pyx_v_2bx_9intervals_12intersection_EmptyNode));
+  __Pyx_GIVEREF(((PyObject *)__pyx_v_2bx_9intervals_12intersection_EmptyNode));
+  __Pyx_GOTREF(__pyx_v_self->cright);
+  __Pyx_DECREF(((PyObject *)__pyx_v_self->cright));
+  __pyx_v_self->cright = __pyx_v_2bx_9intervals_12intersection_EmptyNode;
+
+  /* "bx/intervals/intersection.pyx":100
+ *         self.cleft    = EmptyNode
+ *         self.cright   = EmptyNode
+ *         self.croot    = EmptyNode             # <<<<<<<<<<<<<<
+ * 
+ *     cpdef IntervalNode insert(IntervalNode self, int start, int end, object interval):
+ */
+  __Pyx_INCREF(((PyObject *)__pyx_v_2bx_9intervals_12intersection_EmptyNode));
+  __Pyx_GIVEREF(((PyObject *)__pyx_v_2bx_9intervals_12intersection_EmptyNode));
+  __Pyx_GOTREF(__pyx_v_self->croot);
+  __Pyx_DECREF(((PyObject *)__pyx_v_self->croot));
+  __pyx_v_self->croot = __pyx_v_2bx_9intervals_12intersection_EmptyNode;
+
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_AddTraceback("bx.intervals.intersection.IntervalNode.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = -1;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/intervals/intersection.pyx":102
+ *         self.croot    = EmptyNode
+ * 
+ *     cpdef IntervalNode insert(IntervalNode self, int start, int end, object interval):             # <<<<<<<<<<<<<<
+ *         """
+ *         Insert a new IntervalNode into the tree of which this node is
+ */
+
+static PyObject *__pyx_pw_2bx_9intervals_12intersection_12IntervalNode_5insert(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *__pyx_f_2bx_9intervals_12intersection_12IntervalNode_insert(struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *__pyx_v_self, int __pyx_v_start, int __pyx_v_end, PyObject *__pyx_v_interval, int __pyx_skip_dispatch) {
+  struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *__pyx_v_croot = 0;
+  int __pyx_v_decision_endpoint;
+  struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  int __pyx_t_5;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("insert", 0);
+  /* Check if called by wrapper */
+  if (unlikely(__pyx_skip_dispatch)) ;
+  /* Check if overridden in Python */
+  else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
+    __pyx_t_1 = PyObject_GetAttr(((PyObject *)__pyx_v_self), __pyx_n_s__insert); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 102; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_2bx_9intervals_12intersection_12IntervalNode_5insert)) {
+      __Pyx_XDECREF(((PyObject *)__pyx_r));
+      __pyx_t_2 = PyInt_FromLong(__pyx_v_start); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 102; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_2);
+      __pyx_t_3 = PyInt_FromLong(__pyx_v_end); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 102; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_4 = PyTuple_New(3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 102; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_2);
+      __Pyx_GIVEREF(__pyx_t_2);
+      PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_3);
+      __Pyx_GIVEREF(__pyx_t_3);
+      __Pyx_INCREF(__pyx_v_interval);
+      PyTuple_SET_ITEM(__pyx_t_4, 2, __pyx_v_interval);
+      __Pyx_GIVEREF(__pyx_v_interval);
+      __pyx_t_2 = 0;
+      __pyx_t_3 = 0;
+      __pyx_t_3 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_4), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 102; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
+      if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_ptype_2bx_9intervals_12intersection_IntervalNode))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 102; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_r = ((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)__pyx_t_3);
+      __pyx_t_3 = 0;
+      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+      goto __pyx_L0;
+    }
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  }
+
+  /* "bx/intervals/intersection.pyx":108
+ *         may or may not be this node!)
+ *         """
+ *         cdef IntervalNode croot = self             # <<<<<<<<<<<<<<
+ *         # If starts are the same, decide which to add interval to based on
+ *         # end, thus maintaining sortedness relative to start/end
+ */
+  __Pyx_INCREF(((PyObject *)__pyx_v_self));
+  __pyx_v_croot = __pyx_v_self;
+
+  /* "bx/intervals/intersection.pyx":111
+ *         # If starts are the same, decide which to add interval to based on
+ *         # end, thus maintaining sortedness relative to start/end
+ *         cdef int decision_endpoint = start             # <<<<<<<<<<<<<<
+ *         if start == self.start:
+ *             decision_endpoint = end
+ */
+  __pyx_v_decision_endpoint = __pyx_v_start;
+
+  /* "bx/intervals/intersection.pyx":112
+ *         # end, thus maintaining sortedness relative to start/end
+ *         cdef int decision_endpoint = start
+ *         if start == self.start:             # <<<<<<<<<<<<<<
+ *             decision_endpoint = end
+ * 
+ */
+  __pyx_t_5 = (__pyx_v_start == __pyx_v_self->start);
+  if (__pyx_t_5) {
+
+    /* "bx/intervals/intersection.pyx":113
+ *         cdef int decision_endpoint = start
+ *         if start == self.start:
+ *             decision_endpoint = end             # <<<<<<<<<<<<<<
+ * 
+ *         if decision_endpoint > self.start:
+ */
+    __pyx_v_decision_endpoint = __pyx_v_end;
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  /* "bx/intervals/intersection.pyx":115
+ *             decision_endpoint = end
+ * 
+ *         if decision_endpoint > self.start:             # <<<<<<<<<<<<<<
+ *             # insert to cright tree
+ *             if self.cright is not EmptyNode:
+ */
+  __pyx_t_5 = (__pyx_v_decision_endpoint > __pyx_v_self->start);
+  if (__pyx_t_5) {
+
+    /* "bx/intervals/intersection.pyx":117
+ *         if decision_endpoint > self.start:
+ *             # insert to cright tree
+ *             if self.cright is not EmptyNode:             # <<<<<<<<<<<<<<
+ *                 self.cright = self.cright.insert( start, end, interval )
+ *             else:
+ */
+    __pyx_t_5 = (__pyx_v_self->cright != __pyx_v_2bx_9intervals_12intersection_EmptyNode);
+    if (__pyx_t_5) {
+
+      /* "bx/intervals/intersection.pyx":118
+ *             # insert to cright tree
+ *             if self.cright is not EmptyNode:
+ *                 self.cright = self.cright.insert( start, end, interval )             # <<<<<<<<<<<<<<
+ *             else:
+ *                 self.cright = IntervalNode( start, end, interval )
+ */
+      __pyx_t_1 = ((PyObject *)((struct __pyx_vtabstruct_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self->cright->__pyx_vtab)->insert(__pyx_v_self->cright, __pyx_v_start, __pyx_v_end, __pyx_v_interval, 0)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 118; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_1);
+      __Pyx_GIVEREF(__pyx_t_1);
+      __Pyx_GOTREF(__pyx_v_self->cright);
+      __Pyx_DECREF(((PyObject *)__pyx_v_self->cright));
+      __pyx_v_self->cright = ((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)__pyx_t_1);
+      __pyx_t_1 = 0;
+      goto __pyx_L5;
+    }
+    /*else*/ {
+
+      /* "bx/intervals/intersection.pyx":120
+ *                 self.cright = self.cright.insert( start, end, interval )
+ *             else:
+ *                 self.cright = IntervalNode( start, end, interval )             # <<<<<<<<<<<<<<
+ *             # rebalance tree
+ *             if self.priority < self.cright.priority:
+ */
+      __pyx_t_1 = PyInt_FromLong(__pyx_v_start); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_1);
+      __pyx_t_3 = PyInt_FromLong(__pyx_v_end); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_4 = PyTuple_New(3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_1);
+      __Pyx_GIVEREF(__pyx_t_1);
+      PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_3);
+      __Pyx_GIVEREF(__pyx_t_3);
+      __Pyx_INCREF(__pyx_v_interval);
+      PyTuple_SET_ITEM(__pyx_t_4, 2, __pyx_v_interval);
+      __Pyx_GIVEREF(__pyx_v_interval);
+      __pyx_t_1 = 0;
+      __pyx_t_3 = 0;
+      __pyx_t_3 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_2bx_9intervals_12intersection_IntervalNode)), ((PyObject *)__pyx_t_4), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
+      __Pyx_GIVEREF(__pyx_t_3);
+      __Pyx_GOTREF(__pyx_v_self->cright);
+      __Pyx_DECREF(((PyObject *)__pyx_v_self->cright));
+      __pyx_v_self->cright = ((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)__pyx_t_3);
+      __pyx_t_3 = 0;
+    }
+    __pyx_L5:;
+
+    /* "bx/intervals/intersection.pyx":122
+ *                 self.cright = IntervalNode( start, end, interval )
+ *             # rebalance tree
+ *             if self.priority < self.cright.priority:             # <<<<<<<<<<<<<<
+ *                 croot = self.rotate_left()
+ *         else:
+ */
+    __pyx_t_5 = (__pyx_v_self->priority < __pyx_v_self->cright->priority);
+    if (__pyx_t_5) {
+
+      /* "bx/intervals/intersection.pyx":123
+ *             # rebalance tree
+ *             if self.priority < self.cright.priority:
+ *                 croot = self.rotate_left()             # <<<<<<<<<<<<<<
+ *         else:
+ *             # insert to cleft tree
+ */
+      __pyx_t_3 = ((PyObject *)((struct __pyx_vtabstruct_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self->__pyx_vtab)->rotate_left(__pyx_v_self)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __Pyx_DECREF(((PyObject *)__pyx_v_croot));
+      __pyx_v_croot = ((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)__pyx_t_3);
+      __pyx_t_3 = 0;
+      goto __pyx_L6;
+    }
+    __pyx_L6:;
+    goto __pyx_L4;
+  }
+  /*else*/ {
+
+    /* "bx/intervals/intersection.pyx":126
+ *         else:
+ *             # insert to cleft tree
+ *             if self.cleft is not EmptyNode:             # <<<<<<<<<<<<<<
+ *                 self.cleft = self.cleft.insert( start, end, interval)
+ *             else:
+ */
+    __pyx_t_5 = (__pyx_v_self->cleft != __pyx_v_2bx_9intervals_12intersection_EmptyNode);
+    if (__pyx_t_5) {
+
+      /* "bx/intervals/intersection.pyx":127
+ *             # insert to cleft tree
+ *             if self.cleft is not EmptyNode:
+ *                 self.cleft = self.cleft.insert( start, end, interval)             # <<<<<<<<<<<<<<
+ *             else:
+ *                 self.cleft = IntervalNode( start, end, interval)
+ */
+      __pyx_t_3 = ((PyObject *)((struct __pyx_vtabstruct_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self->cleft->__pyx_vtab)->insert(__pyx_v_self->cleft, __pyx_v_start, __pyx_v_end, __pyx_v_interval, 0)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __Pyx_GIVEREF(__pyx_t_3);
+      __Pyx_GOTREF(__pyx_v_self->cleft);
+      __Pyx_DECREF(((PyObject *)__pyx_v_self->cleft));
+      __pyx_v_self->cleft = ((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)__pyx_t_3);
+      __pyx_t_3 = 0;
+      goto __pyx_L7;
+    }
+    /*else*/ {
+
+      /* "bx/intervals/intersection.pyx":129
+ *                 self.cleft = self.cleft.insert( start, end, interval)
+ *             else:
+ *                 self.cleft = IntervalNode( start, end, interval)             # <<<<<<<<<<<<<<
+ *             # rebalance tree
+ *             if self.priority < self.cleft.priority:
+ */
+      __pyx_t_3 = PyInt_FromLong(__pyx_v_start); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 129; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_4 = PyInt_FromLong(__pyx_v_end); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 129; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __pyx_t_1 = PyTuple_New(3); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 129; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_1);
+      PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_3);
+      __Pyx_GIVEREF(__pyx_t_3);
+      PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_t_4);
+      __Pyx_GIVEREF(__pyx_t_4);
+      __Pyx_INCREF(__pyx_v_interval);
+      PyTuple_SET_ITEM(__pyx_t_1, 2, __pyx_v_interval);
+      __Pyx_GIVEREF(__pyx_v_interval);
+      __pyx_t_3 = 0;
+      __pyx_t_4 = 0;
+      __pyx_t_4 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_2bx_9intervals_12intersection_IntervalNode)), ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 129; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+      __Pyx_GIVEREF(__pyx_t_4);
+      __Pyx_GOTREF(__pyx_v_self->cleft);
+      __Pyx_DECREF(((PyObject *)__pyx_v_self->cleft));
+      __pyx_v_self->cleft = ((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)__pyx_t_4);
+      __pyx_t_4 = 0;
+    }
+    __pyx_L7:;
+
+    /* "bx/intervals/intersection.pyx":131
+ *                 self.cleft = IntervalNode( start, end, interval)
+ *             # rebalance tree
+ *             if self.priority < self.cleft.priority:             # <<<<<<<<<<<<<<
+ *                 croot = self.rotate_right()
+ * 
+ */
+    __pyx_t_5 = (__pyx_v_self->priority < __pyx_v_self->cleft->priority);
+    if (__pyx_t_5) {
+
+      /* "bx/intervals/intersection.pyx":132
+ *             # rebalance tree
+ *             if self.priority < self.cleft.priority:
+ *                 croot = self.rotate_right()             # <<<<<<<<<<<<<<
+ * 
+ *         croot.set_ends()
+ */
+      __pyx_t_4 = ((PyObject *)((struct __pyx_vtabstruct_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self->__pyx_vtab)->rotate_right(__pyx_v_self)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __Pyx_DECREF(((PyObject *)__pyx_v_croot));
+      __pyx_v_croot = ((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)__pyx_t_4);
+      __pyx_t_4 = 0;
+      goto __pyx_L8;
+    }
+    __pyx_L8:;
+  }
+  __pyx_L4:;
+
+  /* "bx/intervals/intersection.pyx":134
+ *                 croot = self.rotate_right()
+ * 
+ *         croot.set_ends()             # <<<<<<<<<<<<<<
+ *         self.cleft.croot  = croot
+ *         self.cright.croot = croot
+ */
+  __pyx_f_2bx_9intervals_12intersection_12IntervalNode_set_ends(__pyx_v_croot);
+
+  /* "bx/intervals/intersection.pyx":135
+ * 
+ *         croot.set_ends()
+ *         self.cleft.croot  = croot             # <<<<<<<<<<<<<<
+ *         self.cright.croot = croot
+ *         return croot
+ */
+  __Pyx_INCREF(((PyObject *)__pyx_v_croot));
+  __Pyx_GIVEREF(((PyObject *)__pyx_v_croot));
+  __Pyx_GOTREF(__pyx_v_self->cleft->croot);
+  __Pyx_DECREF(((PyObject *)__pyx_v_self->cleft->croot));
+  __pyx_v_self->cleft->croot = __pyx_v_croot;
+
+  /* "bx/intervals/intersection.pyx":136
+ *         croot.set_ends()
+ *         self.cleft.croot  = croot
+ *         self.cright.croot = croot             # <<<<<<<<<<<<<<
+ *         return croot
+ * 
+ */
+  __Pyx_INCREF(((PyObject *)__pyx_v_croot));
+  __Pyx_GIVEREF(((PyObject *)__pyx_v_croot));
+  __Pyx_GOTREF(__pyx_v_self->cright->croot);
+  __Pyx_DECREF(((PyObject *)__pyx_v_self->cright->croot));
+  __pyx_v_self->cright->croot = __pyx_v_croot;
+
+  /* "bx/intervals/intersection.pyx":137
+ *         self.cleft.croot  = croot
+ *         self.cright.croot = croot
+ *         return croot             # <<<<<<<<<<<<<<
+ * 
+ *     cdef IntervalNode rotate_right(IntervalNode self):
+ */
+  __Pyx_XDECREF(((PyObject *)__pyx_r));
+  __Pyx_INCREF(((PyObject *)__pyx_v_croot));
+  __pyx_r = __pyx_v_croot;
+  goto __pyx_L0;
+
+  __pyx_r = ((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)Py_None); __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_AddTraceback("bx.intervals.intersection.IntervalNode.insert", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XDECREF((PyObject *)__pyx_v_croot);
+  __Pyx_XGIVEREF((PyObject *)__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_9intervals_12intersection_12IntervalNode_5insert(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_2bx_9intervals_12intersection_12IntervalNode_4insert[] = "\n        Insert a new IntervalNode into the tree of which this node is\n        currently the root. The return value is the new root of the tree (which\n        may or may not be this node!)\n        ";
+static PyObject *__pyx_pw_2bx_9intervals_12intersection_12IntervalNode_5insert(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  int __pyx_v_start;
+  int __pyx_v_end;
+  PyObject *__pyx_v_interval = 0;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("insert (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__start,&__pyx_n_s__end,&__pyx_n_s__interval,0};
+    PyObject* values[3] = {0,0,0};
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__start)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__end)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("insert", 1, 3, 3, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 102; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+        case  2:
+        if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__interval)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("insert", 1, 3, 3, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 102; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "insert") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 102; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else if (PyTuple_GET_SIZE(__pyx_args) != 3) {
+      goto __pyx_L5_argtuple_error;
+    } else {
+      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+      values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+    }
+    __pyx_v_start = __Pyx_PyInt_AsInt(values[0]); if (unlikely((__pyx_v_start == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 102; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_end = __Pyx_PyInt_AsInt(values[1]); if (unlikely((__pyx_v_end == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 102; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_interval = values[2];
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("insert", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 102; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.intervals.intersection.IntervalNode.insert", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_9intervals_12intersection_12IntervalNode_4insert(((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self), __pyx_v_start, __pyx_v_end, __pyx_v_interval);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/intervals/intersection.pyx":102
+ *         self.croot    = EmptyNode
+ * 
+ *     cpdef IntervalNode insert(IntervalNode self, int start, int end, object interval):             # <<<<<<<<<<<<<<
+ *         """
+ *         Insert a new IntervalNode into the tree of which this node is
+ */
+
+static PyObject *__pyx_pf_2bx_9intervals_12intersection_12IntervalNode_4insert(struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *__pyx_v_self, int __pyx_v_start, int __pyx_v_end, PyObject *__pyx_v_interval) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("insert", 0);
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = ((PyObject *)((struct __pyx_vtabstruct_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self->__pyx_vtab)->insert(__pyx_v_self, __pyx_v_start, __pyx_v_end, __pyx_v_interval, 1)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 102; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("bx.intervals.intersection.IntervalNode.insert", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/intervals/intersection.pyx":139
+ *         return croot
+ * 
+ *     cdef IntervalNode rotate_right(IntervalNode self):             # <<<<<<<<<<<<<<
+ *         cdef IntervalNode croot = self.cleft
+ *         self.cleft  = self.cleft.cright
+ */
+
+static struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *__pyx_f_2bx_9intervals_12intersection_12IntervalNode_rotate_right(struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *__pyx_v_self) {
+  struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *__pyx_v_croot = 0;
+  struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  __Pyx_RefNannySetupContext("rotate_right", 0);
+
+  /* "bx/intervals/intersection.pyx":140
+ * 
+ *     cdef IntervalNode rotate_right(IntervalNode self):
+ *         cdef IntervalNode croot = self.cleft             # <<<<<<<<<<<<<<
+ *         self.cleft  = self.cleft.cright
+ *         croot.cright = self
+ */
+  __pyx_t_1 = ((PyObject *)__pyx_v_self->cleft);
+  __Pyx_INCREF(__pyx_t_1);
+  __pyx_v_croot = ((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)__pyx_t_1);
+  __pyx_t_1 = 0;
+
+  /* "bx/intervals/intersection.pyx":141
+ *     cdef IntervalNode rotate_right(IntervalNode self):
+ *         cdef IntervalNode croot = self.cleft
+ *         self.cleft  = self.cleft.cright             # <<<<<<<<<<<<<<
+ *         croot.cright = self
+ *         self.set_ends()
+ */
+  __pyx_t_1 = ((PyObject *)__pyx_v_self->cleft->cright);
+  __Pyx_INCREF(__pyx_t_1);
+  __Pyx_GIVEREF(__pyx_t_1);
+  __Pyx_GOTREF(__pyx_v_self->cleft);
+  __Pyx_DECREF(((PyObject *)__pyx_v_self->cleft));
+  __pyx_v_self->cleft = ((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)__pyx_t_1);
+  __pyx_t_1 = 0;
+
+  /* "bx/intervals/intersection.pyx":142
+ *         cdef IntervalNode croot = self.cleft
+ *         self.cleft  = self.cleft.cright
+ *         croot.cright = self             # <<<<<<<<<<<<<<
+ *         self.set_ends()
+ *         return croot
+ */
+  __Pyx_INCREF(((PyObject *)__pyx_v_self));
+  __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
+  __Pyx_GOTREF(__pyx_v_croot->cright);
+  __Pyx_DECREF(((PyObject *)__pyx_v_croot->cright));
+  __pyx_v_croot->cright = __pyx_v_self;
+
+  /* "bx/intervals/intersection.pyx":143
+ *         self.cleft  = self.cleft.cright
+ *         croot.cright = self
+ *         self.set_ends()             # <<<<<<<<<<<<<<
+ *         return croot
+ * 
+ */
+  __pyx_f_2bx_9intervals_12intersection_12IntervalNode_set_ends(__pyx_v_self);
+
+  /* "bx/intervals/intersection.pyx":144
+ *         croot.cright = self
+ *         self.set_ends()
+ *         return croot             # <<<<<<<<<<<<<<
+ * 
+ *     cdef IntervalNode rotate_left(IntervalNode self):
+ */
+  __Pyx_XDECREF(((PyObject *)__pyx_r));
+  __Pyx_INCREF(((PyObject *)__pyx_v_croot));
+  __pyx_r = __pyx_v_croot;
+  goto __pyx_L0;
+
+  __pyx_r = ((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)Py_None); __Pyx_INCREF(Py_None);
+  __pyx_L0:;
+  __Pyx_XDECREF((PyObject *)__pyx_v_croot);
+  __Pyx_XGIVEREF((PyObject *)__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/intervals/intersection.pyx":146
+ *         return croot
+ * 
+ *     cdef IntervalNode rotate_left(IntervalNode self):             # <<<<<<<<<<<<<<
+ *         cdef IntervalNode croot = self.cright
+ *         self.cright = self.cright.cleft
+ */
+
+static struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *__pyx_f_2bx_9intervals_12intersection_12IntervalNode_rotate_left(struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *__pyx_v_self) {
+  struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *__pyx_v_croot = 0;
+  struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  __Pyx_RefNannySetupContext("rotate_left", 0);
+
+  /* "bx/intervals/intersection.pyx":147
+ * 
+ *     cdef IntervalNode rotate_left(IntervalNode self):
+ *         cdef IntervalNode croot = self.cright             # <<<<<<<<<<<<<<
+ *         self.cright = self.cright.cleft
+ *         croot.cleft  = self
+ */
+  __pyx_t_1 = ((PyObject *)__pyx_v_self->cright);
+  __Pyx_INCREF(__pyx_t_1);
+  __pyx_v_croot = ((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)__pyx_t_1);
+  __pyx_t_1 = 0;
+
+  /* "bx/intervals/intersection.pyx":148
+ *     cdef IntervalNode rotate_left(IntervalNode self):
+ *         cdef IntervalNode croot = self.cright
+ *         self.cright = self.cright.cleft             # <<<<<<<<<<<<<<
+ *         croot.cleft  = self
+ *         self.set_ends()
+ */
+  __pyx_t_1 = ((PyObject *)__pyx_v_self->cright->cleft);
+  __Pyx_INCREF(__pyx_t_1);
+  __Pyx_GIVEREF(__pyx_t_1);
+  __Pyx_GOTREF(__pyx_v_self->cright);
+  __Pyx_DECREF(((PyObject *)__pyx_v_self->cright));
+  __pyx_v_self->cright = ((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)__pyx_t_1);
+  __pyx_t_1 = 0;
+
+  /* "bx/intervals/intersection.pyx":149
+ *         cdef IntervalNode croot = self.cright
+ *         self.cright = self.cright.cleft
+ *         croot.cleft  = self             # <<<<<<<<<<<<<<
+ *         self.set_ends()
+ *         return croot
+ */
+  __Pyx_INCREF(((PyObject *)__pyx_v_self));
+  __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
+  __Pyx_GOTREF(__pyx_v_croot->cleft);
+  __Pyx_DECREF(((PyObject *)__pyx_v_croot->cleft));
+  __pyx_v_croot->cleft = __pyx_v_self;
+
+  /* "bx/intervals/intersection.pyx":150
+ *         self.cright = self.cright.cleft
+ *         croot.cleft  = self
+ *         self.set_ends()             # <<<<<<<<<<<<<<
+ *         return croot
+ * 
+ */
+  __pyx_f_2bx_9intervals_12intersection_12IntervalNode_set_ends(__pyx_v_self);
+
+  /* "bx/intervals/intersection.pyx":151
+ *         croot.cleft  = self
+ *         self.set_ends()
+ *         return croot             # <<<<<<<<<<<<<<
+ * 
+ *     cdef inline void set_ends(IntervalNode self):
+ */
+  __Pyx_XDECREF(((PyObject *)__pyx_r));
+  __Pyx_INCREF(((PyObject *)__pyx_v_croot));
+  __pyx_r = __pyx_v_croot;
+  goto __pyx_L0;
+
+  __pyx_r = ((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)Py_None); __Pyx_INCREF(Py_None);
+  __pyx_L0:;
+  __Pyx_XDECREF((PyObject *)__pyx_v_croot);
+  __Pyx_XGIVEREF((PyObject *)__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/intervals/intersection.pyx":153
+ *         return croot
+ * 
+ *     cdef inline void set_ends(IntervalNode self):             # <<<<<<<<<<<<<<
+ *         if self.cright is not EmptyNode and self.cleft is not EmptyNode:
+ *             self.maxend = imax3(self.end, self.cright.maxend, self.cleft.maxend)
+ */
+
+static CYTHON_INLINE void __pyx_f_2bx_9intervals_12intersection_12IntervalNode_set_ends(struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *__pyx_v_self) {
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  int __pyx_t_2;
+  int __pyx_t_3;
+  __Pyx_RefNannySetupContext("set_ends", 0);
+
+  /* "bx/intervals/intersection.pyx":154
+ * 
+ *     cdef inline void set_ends(IntervalNode self):
+ *         if self.cright is not EmptyNode and self.cleft is not EmptyNode:             # <<<<<<<<<<<<<<
+ *             self.maxend = imax3(self.end, self.cright.maxend, self.cleft.maxend)
+ *             self.minend = imin3(self.end, self.cright.minend, self.cleft.minend)
+ */
+  __pyx_t_1 = (__pyx_v_self->cright != __pyx_v_2bx_9intervals_12intersection_EmptyNode);
+  if (__pyx_t_1) {
+    __pyx_t_2 = (__pyx_v_self->cleft != __pyx_v_2bx_9intervals_12intersection_EmptyNode);
+    __pyx_t_3 = __pyx_t_2;
+  } else {
+    __pyx_t_3 = __pyx_t_1;
+  }
+  if (__pyx_t_3) {
+
+    /* "bx/intervals/intersection.pyx":155
+ *     cdef inline void set_ends(IntervalNode self):
+ *         if self.cright is not EmptyNode and self.cleft is not EmptyNode:
+ *             self.maxend = imax3(self.end, self.cright.maxend, self.cleft.maxend)             # <<<<<<<<<<<<<<
+ *             self.minend = imin3(self.end, self.cright.minend, self.cleft.minend)
+ *             self.minstart = imin3(self.start, self.cright.minstart, self.cleft.minstart)
+ */
+    __pyx_v_self->maxend = __pyx_f_2bx_9intervals_12intersection_imax3(__pyx_v_self->end, __pyx_v_self->cright->maxend, __pyx_v_self->cleft->maxend);
+
+    /* "bx/intervals/intersection.pyx":156
+ *         if self.cright is not EmptyNode and self.cleft is not EmptyNode:
+ *             self.maxend = imax3(self.end, self.cright.maxend, self.cleft.maxend)
+ *             self.minend = imin3(self.end, self.cright.minend, self.cleft.minend)             # <<<<<<<<<<<<<<
+ *             self.minstart = imin3(self.start, self.cright.minstart, self.cleft.minstart)
+ *         elif self.cright is not EmptyNode:
+ */
+    __pyx_v_self->minend = __pyx_f_2bx_9intervals_12intersection_imin3(__pyx_v_self->end, __pyx_v_self->cright->minend, __pyx_v_self->cleft->minend);
+
+    /* "bx/intervals/intersection.pyx":157
+ *             self.maxend = imax3(self.end, self.cright.maxend, self.cleft.maxend)
+ *             self.minend = imin3(self.end, self.cright.minend, self.cleft.minend)
+ *             self.minstart = imin3(self.start, self.cright.minstart, self.cleft.minstart)             # <<<<<<<<<<<<<<
+ *         elif self.cright is not EmptyNode:
+ *             self.maxend = imax2(self.end, self.cright.maxend)
+ */
+    __pyx_v_self->minstart = __pyx_f_2bx_9intervals_12intersection_imin3(__pyx_v_self->start, __pyx_v_self->cright->minstart, __pyx_v_self->cleft->minstart);
+    goto __pyx_L3;
+  }
+
+  /* "bx/intervals/intersection.pyx":158
+ *             self.minend = imin3(self.end, self.cright.minend, self.cleft.minend)
+ *             self.minstart = imin3(self.start, self.cright.minstart, self.cleft.minstart)
+ *         elif self.cright is not EmptyNode:             # <<<<<<<<<<<<<<
+ *             self.maxend = imax2(self.end, self.cright.maxend)
+ *             self.minend = imin2(self.end, self.cright.minend)
+ */
+  __pyx_t_3 = (__pyx_v_self->cright != __pyx_v_2bx_9intervals_12intersection_EmptyNode);
+  if (__pyx_t_3) {
+
+    /* "bx/intervals/intersection.pyx":159
+ *             self.minstart = imin3(self.start, self.cright.minstart, self.cleft.minstart)
+ *         elif self.cright is not EmptyNode:
+ *             self.maxend = imax2(self.end, self.cright.maxend)             # <<<<<<<<<<<<<<
+ *             self.minend = imin2(self.end, self.cright.minend)
+ *             self.minstart = imin2(self.start, self.cright.minstart)
+ */
+    __pyx_v_self->maxend = __pyx_f_2bx_9intervals_12intersection_imax2(__pyx_v_self->end, __pyx_v_self->cright->maxend);
+
+    /* "bx/intervals/intersection.pyx":160
+ *         elif self.cright is not EmptyNode:
+ *             self.maxend = imax2(self.end, self.cright.maxend)
+ *             self.minend = imin2(self.end, self.cright.minend)             # <<<<<<<<<<<<<<
+ *             self.minstart = imin2(self.start, self.cright.minstart)
+ *         elif self.cleft is not EmptyNode:
+ */
+    __pyx_v_self->minend = __pyx_f_2bx_9intervals_12intersection_imin2(__pyx_v_self->end, __pyx_v_self->cright->minend);
+
+    /* "bx/intervals/intersection.pyx":161
+ *             self.maxend = imax2(self.end, self.cright.maxend)
+ *             self.minend = imin2(self.end, self.cright.minend)
+ *             self.minstart = imin2(self.start, self.cright.minstart)             # <<<<<<<<<<<<<<
+ *         elif self.cleft is not EmptyNode:
+ *             self.maxend = imax2(self.end, self.cleft.maxend)
+ */
+    __pyx_v_self->minstart = __pyx_f_2bx_9intervals_12intersection_imin2(__pyx_v_self->start, __pyx_v_self->cright->minstart);
+    goto __pyx_L3;
+  }
+
+  /* "bx/intervals/intersection.pyx":162
+ *             self.minend = imin2(self.end, self.cright.minend)
+ *             self.minstart = imin2(self.start, self.cright.minstart)
+ *         elif self.cleft is not EmptyNode:             # <<<<<<<<<<<<<<
+ *             self.maxend = imax2(self.end, self.cleft.maxend)
+ *             self.minend = imin2(self.end, self.cleft.minend)
+ */
+  __pyx_t_3 = (__pyx_v_self->cleft != __pyx_v_2bx_9intervals_12intersection_EmptyNode);
+  if (__pyx_t_3) {
+
+    /* "bx/intervals/intersection.pyx":163
+ *             self.minstart = imin2(self.start, self.cright.minstart)
+ *         elif self.cleft is not EmptyNode:
+ *             self.maxend = imax2(self.end, self.cleft.maxend)             # <<<<<<<<<<<<<<
+ *             self.minend = imin2(self.end, self.cleft.minend)
+ *             self.minstart = imin2(self.start, self.cleft.minstart)
+ */
+    __pyx_v_self->maxend = __pyx_f_2bx_9intervals_12intersection_imax2(__pyx_v_self->end, __pyx_v_self->cleft->maxend);
+
+    /* "bx/intervals/intersection.pyx":164
+ *         elif self.cleft is not EmptyNode:
+ *             self.maxend = imax2(self.end, self.cleft.maxend)
+ *             self.minend = imin2(self.end, self.cleft.minend)             # <<<<<<<<<<<<<<
+ *             self.minstart = imin2(self.start, self.cleft.minstart)
+ * 
+ */
+    __pyx_v_self->minend = __pyx_f_2bx_9intervals_12intersection_imin2(__pyx_v_self->end, __pyx_v_self->cleft->minend);
+
+    /* "bx/intervals/intersection.pyx":165
+ *             self.maxend = imax2(self.end, self.cleft.maxend)
+ *             self.minend = imin2(self.end, self.cleft.minend)
+ *             self.minstart = imin2(self.start, self.cleft.minstart)             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_self->minstart = __pyx_f_2bx_9intervals_12intersection_imin2(__pyx_v_self->start, __pyx_v_self->cleft->minstart);
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  __Pyx_RefNannyFinishContext();
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_9intervals_12intersection_12IntervalNode_7intersect(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_2bx_9intervals_12intersection_12IntervalNode_6intersect[] = "\n        given a start and a end, return a list of features\n        falling within that range\n        ";
+static PyObject *__pyx_pw_2bx_9intervals_12intersection_12IntervalNode_7intersect(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  int __pyx_v_start;
+  int __pyx_v_end;
+  CYTHON_UNUSED PyObject *__pyx_v_sort = 0;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("intersect (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__start,&__pyx_n_s__end,&__pyx_n_s__sort,0};
+    PyObject* values[3] = {0,0,0};
+    values[2] = __pyx_k_2;
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__start)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__end)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("intersect", 0, 2, 3, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 168; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+        case  2:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s__sort);
+          if (value) { values[2] = value; kw_args--; }
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "intersect") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 168; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else {
+      switch (PyTuple_GET_SIZE(__pyx_args)) {
+        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+    }
+    __pyx_v_start = __Pyx_PyInt_AsInt(values[0]); if (unlikely((__pyx_v_start == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 168; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_end = __Pyx_PyInt_AsInt(values[1]); if (unlikely((__pyx_v_end == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 168; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_sort = values[2];
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("intersect", 0, 2, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 168; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.intervals.intersection.IntervalNode.intersect", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_9intervals_12intersection_12IntervalNode_6intersect(((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self), __pyx_v_start, __pyx_v_end, __pyx_v_sort);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/intervals/intersection.pyx":168
+ * 
+ * 
+ *     def intersect( self, int start, int end, sort=True ):             # <<<<<<<<<<<<<<
+ *         """
+ *         given a start and a end, return a list of features
+ */
+
+static PyObject *__pyx_pf_2bx_9intervals_12intersection_12IntervalNode_6intersect(struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *__pyx_v_self, int __pyx_v_start, int __pyx_v_end, CYTHON_UNUSED PyObject *__pyx_v_sort) {
+  PyObject *__pyx_v_results = 0;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("intersect", 0);
+
+  /* "bx/intervals/intersection.pyx":173
+ *         falling within that range
+ *         """
+ *         cdef list results = []             # <<<<<<<<<<<<<<
+ *         self._intersect( start, end, results )
+ *         return results
+ */
+  __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 173; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_v_results = ((PyObject*)__pyx_t_1);
+  __pyx_t_1 = 0;
+
+  /* "bx/intervals/intersection.pyx":174
+ *         """
+ *         cdef list results = []
+ *         self._intersect( start, end, results )             # <<<<<<<<<<<<<<
+ *         return results
+ * 
+ */
+  ((struct __pyx_vtabstruct_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self->__pyx_vtab)->_intersect(__pyx_v_self, __pyx_v_start, __pyx_v_end, __pyx_v_results);
+
+  /* "bx/intervals/intersection.pyx":175
+ *         cdef list results = []
+ *         self._intersect( start, end, results )
+ *         return results             # <<<<<<<<<<<<<<
+ * 
+ *     find = intersect
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __Pyx_INCREF(((PyObject *)__pyx_v_results));
+  __pyx_r = ((PyObject *)__pyx_v_results);
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("bx.intervals.intersection.IntervalNode.intersect", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_results);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/intervals/intersection.pyx":179
+ *     find = intersect
+ * 
+ *     cdef void _intersect( IntervalNode self, int start, int end, list results):             # <<<<<<<<<<<<<<
+ *         # Left subtree
+ *         if self.cleft is not EmptyNode and self.cleft.maxend > start:
+ */
+
+static void __pyx_f_2bx_9intervals_12intersection_12IntervalNode__intersect(struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *__pyx_v_self, int __pyx_v_start, int __pyx_v_end, PyObject *__pyx_v_results) {
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  int __pyx_t_2;
+  int __pyx_t_3;
+  PyObject *__pyx_t_4 = NULL;
+  int __pyx_t_5;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("_intersect", 0);
+
+  /* "bx/intervals/intersection.pyx":181
+ *     cdef void _intersect( IntervalNode self, int start, int end, list results):
+ *         # Left subtree
+ *         if self.cleft is not EmptyNode and self.cleft.maxend > start:             # <<<<<<<<<<<<<<
+ *             self.cleft._intersect( start, end, results )
+ *         # This interval
+ */
+  __pyx_t_1 = (__pyx_v_self->cleft != __pyx_v_2bx_9intervals_12intersection_EmptyNode);
+  if (__pyx_t_1) {
+    __pyx_t_2 = (__pyx_v_self->cleft->maxend > __pyx_v_start);
+    __pyx_t_3 = __pyx_t_2;
+  } else {
+    __pyx_t_3 = __pyx_t_1;
+  }
+  if (__pyx_t_3) {
+
+    /* "bx/intervals/intersection.pyx":182
+ *         # Left subtree
+ *         if self.cleft is not EmptyNode and self.cleft.maxend > start:
+ *             self.cleft._intersect( start, end, results )             # <<<<<<<<<<<<<<
+ *         # This interval
+ *         if ( self.end > start ) and ( self.start < end ):
+ */
+    ((struct __pyx_vtabstruct_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self->cleft->__pyx_vtab)->_intersect(__pyx_v_self->cleft, __pyx_v_start, __pyx_v_end, __pyx_v_results);
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  /* "bx/intervals/intersection.pyx":184
+ *             self.cleft._intersect( start, end, results )
+ *         # This interval
+ *         if ( self.end > start ) and ( self.start < end ):             # <<<<<<<<<<<<<<
+ *             results.append( self.interval )
+ *         # Right subtree
+ */
+  __pyx_t_3 = (__pyx_v_self->end > __pyx_v_start);
+  if (__pyx_t_3) {
+    __pyx_t_1 = (__pyx_v_self->start < __pyx_v_end);
+    __pyx_t_2 = __pyx_t_1;
+  } else {
+    __pyx_t_2 = __pyx_t_3;
+  }
+  if (__pyx_t_2) {
+
+    /* "bx/intervals/intersection.pyx":185
+ *         # This interval
+ *         if ( self.end > start ) and ( self.start < end ):
+ *             results.append( self.interval )             # <<<<<<<<<<<<<<
+ *         # Right subtree
+ *         if self.cright is not EmptyNode and self.start < end:
+ */
+    if (unlikely(((PyObject *)__pyx_v_results) == Py_None)) {
+      PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "append");
+      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 185; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+    __pyx_t_4 = __pyx_v_self->interval;
+    __Pyx_INCREF(__pyx_t_4);
+    __pyx_t_5 = PyList_Append(__pyx_v_results, __pyx_t_4); if (unlikely(__pyx_t_5 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 185; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    goto __pyx_L4;
+  }
+  __pyx_L4:;
+
+  /* "bx/intervals/intersection.pyx":187
+ *             results.append( self.interval )
+ *         # Right subtree
+ *         if self.cright is not EmptyNode and self.start < end:             # <<<<<<<<<<<<<<
+ *             self.cright._intersect( start, end, results )
+ * 
+ */
+  __pyx_t_2 = (__pyx_v_self->cright != __pyx_v_2bx_9intervals_12intersection_EmptyNode);
+  if (__pyx_t_2) {
+    __pyx_t_3 = (__pyx_v_self->start < __pyx_v_end);
+    __pyx_t_1 = __pyx_t_3;
+  } else {
+    __pyx_t_1 = __pyx_t_2;
+  }
+  if (__pyx_t_1) {
+
+    /* "bx/intervals/intersection.pyx":188
+ *         # Right subtree
+ *         if self.cright is not EmptyNode and self.start < end:
+ *             self.cright._intersect( start, end, results )             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    ((struct __pyx_vtabstruct_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self->cright->__pyx_vtab)->_intersect(__pyx_v_self->cright, __pyx_v_start, __pyx_v_end, __pyx_v_results);
+    goto __pyx_L5;
+  }
+  __pyx_L5:;
+
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_WriteUnraisable("bx.intervals.intersection.IntervalNode._intersect", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+}
+
+/* "bx/intervals/intersection.pyx":191
+ * 
+ * 
+ *     cdef void _seek_left(IntervalNode self, int position, list results, int n, int max_dist):             # <<<<<<<<<<<<<<
+ *         # we know we can bail in these 2 cases.
+ *         if self.maxend + max_dist < position:
+ */
+
+static void __pyx_f_2bx_9intervals_12intersection_12IntervalNode__seek_left(struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *__pyx_v_self, int __pyx_v_position, PyObject *__pyx_v_results, int __pyx_v_n, int __pyx_v_max_dist) {
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  int __pyx_t_2;
+  PyObject *__pyx_t_3 = NULL;
+  int __pyx_t_4;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("_seek_left", 0);
+
+  /* "bx/intervals/intersection.pyx":193
+ *     cdef void _seek_left(IntervalNode self, int position, list results, int n, int max_dist):
+ *         # we know we can bail in these 2 cases.
+ *         if self.maxend + max_dist < position:             # <<<<<<<<<<<<<<
+ *             return
+ *         if self.minstart > position:
+ */
+  __pyx_t_1 = ((__pyx_v_self->maxend + __pyx_v_max_dist) < __pyx_v_position);
+  if (__pyx_t_1) {
+
+    /* "bx/intervals/intersection.pyx":194
+ *         # we know we can bail in these 2 cases.
+ *         if self.maxend + max_dist < position:
+ *             return             # <<<<<<<<<<<<<<
+ *         if self.minstart > position:
+ *             return
+ */
+    goto __pyx_L0;
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  /* "bx/intervals/intersection.pyx":195
+ *         if self.maxend + max_dist < position:
+ *             return
+ *         if self.minstart > position:             # <<<<<<<<<<<<<<
+ *             return
+ * 
+ */
+  __pyx_t_1 = (__pyx_v_self->minstart > __pyx_v_position);
+  if (__pyx_t_1) {
+
+    /* "bx/intervals/intersection.pyx":196
+ *             return
+ *         if self.minstart > position:
+ *             return             # <<<<<<<<<<<<<<
+ * 
+ *         # the ordering of these 3 blocks makes it so the results are
+ */
+    goto __pyx_L0;
+    goto __pyx_L4;
+  }
+  __pyx_L4:;
+
+  /* "bx/intervals/intersection.pyx":200
+ *         # the ordering of these 3 blocks makes it so the results are
+ *         # ordered nearest to farest from the query position
+ *         if self.cright is not EmptyNode:             # <<<<<<<<<<<<<<
+ *             self.cright._seek_left(position, results, n, max_dist)
+ * 
+ */
+  __pyx_t_1 = (__pyx_v_self->cright != __pyx_v_2bx_9intervals_12intersection_EmptyNode);
+  if (__pyx_t_1) {
+
+    /* "bx/intervals/intersection.pyx":201
+ *         # ordered nearest to farest from the query position
+ *         if self.cright is not EmptyNode:
+ *             self.cright._seek_left(position, results, n, max_dist)             # <<<<<<<<<<<<<<
+ * 
+ *         if -1 < position - self.end < max_dist:
+ */
+    ((struct __pyx_vtabstruct_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self->cright->__pyx_vtab)->_seek_left(__pyx_v_self->cright, __pyx_v_position, __pyx_v_results, __pyx_v_n, __pyx_v_max_dist);
+    goto __pyx_L5;
+  }
+  __pyx_L5:;
+
+  /* "bx/intervals/intersection.pyx":203
+ *             self.cright._seek_left(position, results, n, max_dist)
+ * 
+ *         if -1 < position - self.end < max_dist:             # <<<<<<<<<<<<<<
+ *             results.append(self.interval)
+ * 
+ */
+  __pyx_t_2 = (__pyx_v_position - __pyx_v_self->end);
+  __pyx_t_1 = (-1 < __pyx_t_2);
+  if (__pyx_t_1) {
+    __pyx_t_1 = (__pyx_t_2 < __pyx_v_max_dist);
+  }
+  if (__pyx_t_1) {
+
+    /* "bx/intervals/intersection.pyx":204
+ * 
+ *         if -1 < position - self.end < max_dist:
+ *             results.append(self.interval)             # <<<<<<<<<<<<<<
+ * 
+ *         # TODO: can these conditionals be more stringent?
+ */
+    if (unlikely(((PyObject *)__pyx_v_results) == Py_None)) {
+      PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "append");
+      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 204; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+    __pyx_t_3 = __pyx_v_self->interval;
+    __Pyx_INCREF(__pyx_t_3);
+    __pyx_t_4 = PyList_Append(__pyx_v_results, __pyx_t_3); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 204; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    goto __pyx_L6;
+  }
+  __pyx_L6:;
+
+  /* "bx/intervals/intersection.pyx":207
+ * 
+ *         # TODO: can these conditionals be more stringent?
+ *         if self.cleft is not EmptyNode:             # <<<<<<<<<<<<<<
+ *                 self.cleft._seek_left(position, results, n, max_dist)
+ * 
+ */
+  __pyx_t_1 = (__pyx_v_self->cleft != __pyx_v_2bx_9intervals_12intersection_EmptyNode);
+  if (__pyx_t_1) {
+
+    /* "bx/intervals/intersection.pyx":208
+ *         # TODO: can these conditionals be more stringent?
+ *         if self.cleft is not EmptyNode:
+ *                 self.cleft._seek_left(position, results, n, max_dist)             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    ((struct __pyx_vtabstruct_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self->cleft->__pyx_vtab)->_seek_left(__pyx_v_self->cleft, __pyx_v_position, __pyx_v_results, __pyx_v_n, __pyx_v_max_dist);
+    goto __pyx_L7;
+  }
+  __pyx_L7:;
+
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_WriteUnraisable("bx.intervals.intersection.IntervalNode._seek_left", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+}
+
+/* "bx/intervals/intersection.pyx":212
+ * 
+ * 
+ *     cdef void _seek_right(IntervalNode self, int position, list results, int n, int max_dist):             # <<<<<<<<<<<<<<
+ *         # we know we can bail in these 2 cases.
+ *         if self.maxend < position: return
+ */
+
+static void __pyx_f_2bx_9intervals_12intersection_12IntervalNode__seek_right(struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *__pyx_v_self, int __pyx_v_position, PyObject *__pyx_v_results, int __pyx_v_n, int __pyx_v_max_dist) {
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  int __pyx_t_2;
+  PyObject *__pyx_t_3 = NULL;
+  int __pyx_t_4;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("_seek_right", 0);
+
+  /* "bx/intervals/intersection.pyx":214
+ *     cdef void _seek_right(IntervalNode self, int position, list results, int n, int max_dist):
+ *         # we know we can bail in these 2 cases.
+ *         if self.maxend < position: return             # <<<<<<<<<<<<<<
+ *         if self.minstart - max_dist > position: return
+ * 
+ */
+  __pyx_t_1 = (__pyx_v_self->maxend < __pyx_v_position);
+  if (__pyx_t_1) {
+    goto __pyx_L0;
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  /* "bx/intervals/intersection.pyx":215
+ *         # we know we can bail in these 2 cases.
+ *         if self.maxend < position: return
+ *         if self.minstart - max_dist > position: return             # <<<<<<<<<<<<<<
+ * 
+ *         #print "SEEK_RIGHT:",self, self.cleft, self.maxend, self.minstart, position
+ */
+  __pyx_t_1 = ((__pyx_v_self->minstart - __pyx_v_max_dist) > __pyx_v_position);
+  if (__pyx_t_1) {
+    goto __pyx_L0;
+    goto __pyx_L4;
+  }
+  __pyx_L4:;
+
+  /* "bx/intervals/intersection.pyx":221
+ *         # the ordering of these 3 blocks makes it so the results are
+ *         # ordered nearest to farest from the query position
+ *         if self.cleft is not EmptyNode:             # <<<<<<<<<<<<<<
+ *                 self.cleft._seek_right(position, results, n, max_dist)
+ * 
+ */
+  __pyx_t_1 = (__pyx_v_self->cleft != __pyx_v_2bx_9intervals_12intersection_EmptyNode);
+  if (__pyx_t_1) {
+
+    /* "bx/intervals/intersection.pyx":222
+ *         # ordered nearest to farest from the query position
+ *         if self.cleft is not EmptyNode:
+ *                 self.cleft._seek_right(position, results, n, max_dist)             # <<<<<<<<<<<<<<
+ * 
+ *         if -1 < self.start - position < max_dist:
+ */
+    ((struct __pyx_vtabstruct_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self->cleft->__pyx_vtab)->_seek_right(__pyx_v_self->cleft, __pyx_v_position, __pyx_v_results, __pyx_v_n, __pyx_v_max_dist);
+    goto __pyx_L5;
+  }
+  __pyx_L5:;
+
+  /* "bx/intervals/intersection.pyx":224
+ *                 self.cleft._seek_right(position, results, n, max_dist)
+ * 
+ *         if -1 < self.start - position < max_dist:             # <<<<<<<<<<<<<<
+ *             results.append(self.interval)
+ * 
+ */
+  __pyx_t_2 = (__pyx_v_self->start - __pyx_v_position);
+  __pyx_t_1 = (-1 < __pyx_t_2);
+  if (__pyx_t_1) {
+    __pyx_t_1 = (__pyx_t_2 < __pyx_v_max_dist);
+  }
+  if (__pyx_t_1) {
+
+    /* "bx/intervals/intersection.pyx":225
+ * 
+ *         if -1 < self.start - position < max_dist:
+ *             results.append(self.interval)             # <<<<<<<<<<<<<<
+ * 
+ *         if self.cright is not EmptyNode:
+ */
+    if (unlikely(((PyObject *)__pyx_v_results) == Py_None)) {
+      PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "append");
+      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 225; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+    __pyx_t_3 = __pyx_v_self->interval;
+    __Pyx_INCREF(__pyx_t_3);
+    __pyx_t_4 = PyList_Append(__pyx_v_results, __pyx_t_3); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 225; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    goto __pyx_L6;
+  }
+  __pyx_L6:;
+
+  /* "bx/intervals/intersection.pyx":227
+ *             results.append(self.interval)
+ * 
+ *         if self.cright is not EmptyNode:             # <<<<<<<<<<<<<<
+ *                 self.cright._seek_right(position, results, n, max_dist)
+ * 
+ */
+  __pyx_t_1 = (__pyx_v_self->cright != __pyx_v_2bx_9intervals_12intersection_EmptyNode);
+  if (__pyx_t_1) {
+
+    /* "bx/intervals/intersection.pyx":228
+ * 
+ *         if self.cright is not EmptyNode:
+ *                 self.cright._seek_right(position, results, n, max_dist)             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    ((struct __pyx_vtabstruct_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self->cright->__pyx_vtab)->_seek_right(__pyx_v_self->cright, __pyx_v_position, __pyx_v_results, __pyx_v_n, __pyx_v_max_dist);
+    goto __pyx_L7;
+  }
+  __pyx_L7:;
+
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_WriteUnraisable("bx.intervals.intersection.IntervalNode._seek_right", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+}
+
+/* "bx/intervals/intersection.pyx":231
+ * 
+ * 
+ *     cpdef left(self, position, int n=1, int max_dist=2500):             # <<<<<<<<<<<<<<
+ *         """
+ *         find n features with a start > than `position`
+ */
+
+static PyObject *__pyx_pw_2bx_9intervals_12intersection_12IntervalNode_9left(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyObject *__pyx_f_2bx_9intervals_12intersection_12IntervalNode_left(struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *__pyx_v_self, PyObject *__pyx_v_position, int __pyx_skip_dispatch, struct __pyx_opt_args_2bx_9intervals_12intersection_12IntervalNode_left *__pyx_optional_args) {
+  int __pyx_v_n = ((int)1);
+  int __pyx_v_max_dist = ((int)2500);
+  PyObject *__pyx_v_results = 0;
+  PyObject *__pyx_v_r = NULL;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  int __pyx_t_5;
+  Py_ssize_t __pyx_t_6;
+  int __pyx_t_7;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("left", 0);
+  if (__pyx_optional_args) {
+    if (__pyx_optional_args->__pyx_n > 0) {
+      __pyx_v_n = __pyx_optional_args->n;
+      if (__pyx_optional_args->__pyx_n > 1) {
+        __pyx_v_max_dist = __pyx_optional_args->max_dist;
+      }
+    }
+  }
+  /* Check if called by wrapper */
+  if (unlikely(__pyx_skip_dispatch)) ;
+  /* Check if overridden in Python */
+  else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
+    __pyx_t_1 = PyObject_GetAttr(((PyObject *)__pyx_v_self), __pyx_n_s__left); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 231; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_2bx_9intervals_12intersection_12IntervalNode_9left)) {
+      __Pyx_XDECREF(__pyx_r);
+      __pyx_t_2 = PyInt_FromLong(__pyx_v_n); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 231; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_2);
+      __pyx_t_3 = PyInt_FromLong(__pyx_v_max_dist); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 231; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_4 = PyTuple_New(3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 231; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __Pyx_INCREF(__pyx_v_position);
+      PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_v_position);
+      __Pyx_GIVEREF(__pyx_v_position);
+      PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_2);
+      __Pyx_GIVEREF(__pyx_t_2);
+      PyTuple_SET_ITEM(__pyx_t_4, 2, __pyx_t_3);
+      __Pyx_GIVEREF(__pyx_t_3);
+      __pyx_t_2 = 0;
+      __pyx_t_3 = 0;
+      __pyx_t_3 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_4), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 231; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
+      __pyx_r = __pyx_t_3;
+      __pyx_t_3 = 0;
+      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+      goto __pyx_L0;
+    }
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  }
+
+  /* "bx/intervals/intersection.pyx":238
+ *         max_dist: the maximum distance to look before giving up.
+ *         """
+ *         cdef list results = []             # <<<<<<<<<<<<<<
+ *         # use start - 1 becuase .left() assumes strictly left-of
+ *         self._seek_left( position - 1, results, n, max_dist )
+ */
+  __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 238; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_v_results = ((PyObject*)__pyx_t_1);
+  __pyx_t_1 = 0;
+
+  /* "bx/intervals/intersection.pyx":240
+ *         cdef list results = []
+ *         # use start - 1 becuase .left() assumes strictly left-of
+ *         self._seek_left( position - 1, results, n, max_dist )             # <<<<<<<<<<<<<<
+ *         if len(results) == n: return results
+ *         r = results
+ */
+  __pyx_t_1 = PyNumber_Subtract(__pyx_v_position, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 240; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_5 = __Pyx_PyInt_AsInt(__pyx_t_1); if (unlikely((__pyx_t_5 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 240; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  ((struct __pyx_vtabstruct_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self->__pyx_vtab)->_seek_left(__pyx_v_self, __pyx_t_5, __pyx_v_results, __pyx_v_n, __pyx_v_max_dist);
+
+  /* "bx/intervals/intersection.pyx":241
+ *         # use start - 1 becuase .left() assumes strictly left-of
+ *         self._seek_left( position - 1, results, n, max_dist )
+ *         if len(results) == n: return results             # <<<<<<<<<<<<<<
+ *         r = results
+ *         r.sort(key=operator.attrgetter('end'), reverse=True)
+ */
+  __pyx_t_6 = PyList_GET_SIZE(((PyObject *)__pyx_v_results)); if (unlikely(__pyx_t_6 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 241; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_7 = (__pyx_t_6 == __pyx_v_n);
+  if (__pyx_t_7) {
+    __Pyx_XDECREF(__pyx_r);
+    __Pyx_INCREF(((PyObject *)__pyx_v_results));
+    __pyx_r = ((PyObject *)__pyx_v_results);
+    goto __pyx_L0;
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  /* "bx/intervals/intersection.pyx":242
+ *         self._seek_left( position - 1, results, n, max_dist )
+ *         if len(results) == n: return results
+ *         r = results             # <<<<<<<<<<<<<<
+ *         r.sort(key=operator.attrgetter('end'), reverse=True)
+ *         return r[:n]
+ */
+  __Pyx_INCREF(((PyObject *)__pyx_v_results));
+  __pyx_v_r = __pyx_v_results;
+
+  /* "bx/intervals/intersection.pyx":243
+ *         if len(results) == n: return results
+ *         r = results
+ *         r.sort(key=operator.attrgetter('end'), reverse=True)             # <<<<<<<<<<<<<<
+ *         return r[:n]
+ * 
+ */
+  __pyx_t_1 = PyObject_GetAttr(((PyObject *)__pyx_v_r), __pyx_n_s__sort); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 243; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_3 = PyDict_New(); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 243; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(((PyObject *)__pyx_t_3));
+  __pyx_t_4 = __Pyx_GetName(__pyx_m, __pyx_n_s__operator); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 243; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __pyx_t_2 = PyObject_GetAttr(__pyx_t_4, __pyx_n_s__attrgetter); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 243; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  __pyx_t_4 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_k_tuple_3), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 243; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  if (PyDict_SetItem(__pyx_t_3, ((PyObject *)__pyx_n_s__key), __pyx_t_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 243; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  __pyx_t_4 = __Pyx_PyBool_FromLong(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 243; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  if (PyDict_SetItem(__pyx_t_3, ((PyObject *)__pyx_n_s__reverse), __pyx_t_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 243; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  __pyx_t_4 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_empty_tuple), ((PyObject *)__pyx_t_3)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 243; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+
+  /* "bx/intervals/intersection.pyx":244
+ *         r = results
+ *         r.sort(key=operator.attrgetter('end'), reverse=True)
+ *         return r[:n]             # <<<<<<<<<<<<<<
+ * 
+ *     cpdef right(self, position, int n=1, int max_dist=2500):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_4 = __Pyx_PySequence_GetSlice(((PyObject *)__pyx_v_r), 0, __pyx_v_n); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 244; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(((PyObject *)__pyx_t_4));
+  __pyx_r = ((PyObject *)__pyx_t_4);
+  __pyx_t_4 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_AddTraceback("bx.intervals.intersection.IntervalNode.left", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_results);
+  __Pyx_XDECREF(__pyx_v_r);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_9intervals_12intersection_12IntervalNode_9left(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_2bx_9intervals_12intersection_12IntervalNode_8left[] = "\n        find n features with a start > than `position`\n        f: a Interval object (or anything with an `end` attribute)\n        n: the number of features to return\n        max_dist: the maximum distance to look before giving up.\n        ";
+static PyObject *__pyx_pw_2bx_9intervals_12intersection_12IntervalNode_9left(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_position = 0;
+  int __pyx_v_n;
+  int __pyx_v_max_dist;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("left (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__position,&__pyx_n_s__n,&__pyx_n_s__max_dist,0};
+    PyObject* values[3] = {0,0,0};
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__position)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s__n);
+          if (value) { values[1] = value; kw_args--; }
+        }
+        case  2:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s__max_dist);
+          if (value) { values[2] = value; kw_args--; }
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "left") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 231; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else {
+      switch (PyTuple_GET_SIZE(__pyx_args)) {
+        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+    }
+    __pyx_v_position = values[0];
+    if (values[1]) {
+      __pyx_v_n = __Pyx_PyInt_AsInt(values[1]); if (unlikely((__pyx_v_n == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 231; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    } else {
+      __pyx_v_n = ((int)1);
+    }
+    if (values[2]) {
+      __pyx_v_max_dist = __Pyx_PyInt_AsInt(values[2]); if (unlikely((__pyx_v_max_dist == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 231; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    } else {
+      __pyx_v_max_dist = ((int)2500);
+    }
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("left", 0, 1, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 231; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.intervals.intersection.IntervalNode.left", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_9intervals_12intersection_12IntervalNode_8left(((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self), __pyx_v_position, __pyx_v_n, __pyx_v_max_dist);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/intervals/intersection.pyx":231
+ * 
+ * 
+ *     cpdef left(self, position, int n=1, int max_dist=2500):             # <<<<<<<<<<<<<<
+ *         """
+ *         find n features with a start > than `position`
+ */
+
+static PyObject *__pyx_pf_2bx_9intervals_12intersection_12IntervalNode_8left(struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *__pyx_v_self, PyObject *__pyx_v_position, int __pyx_v_n, int __pyx_v_max_dist) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  struct __pyx_opt_args_2bx_9intervals_12intersection_12IntervalNode_left __pyx_t_2;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("left", 0);
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_2.__pyx_n = 2;
+  __pyx_t_2.n = __pyx_v_n;
+  __pyx_t_2.max_dist = __pyx_v_max_dist;
+  __pyx_t_1 = ((struct __pyx_vtabstruct_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self->__pyx_vtab)->left(__pyx_v_self, __pyx_v_position, 1, &__pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 231; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("bx.intervals.intersection.IntervalNode.left", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/intervals/intersection.pyx":246
+ *         return r[:n]
+ * 
+ *     cpdef right(self, position, int n=1, int max_dist=2500):             # <<<<<<<<<<<<<<
+ *         """
+ *         find n features with a end < than position
+ */
+
+static PyObject *__pyx_pw_2bx_9intervals_12intersection_12IntervalNode_11right(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyObject *__pyx_f_2bx_9intervals_12intersection_12IntervalNode_right(struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *__pyx_v_self, PyObject *__pyx_v_position, int __pyx_skip_dispatch, struct __pyx_opt_args_2bx_9intervals_12intersection_12IntervalNode_right *__pyx_optional_args) {
+  int __pyx_v_n = ((int)1);
+  int __pyx_v_max_dist = ((int)2500);
+  PyObject *__pyx_v_results = 0;
+  PyObject *__pyx_v_r = NULL;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  int __pyx_t_5;
+  Py_ssize_t __pyx_t_6;
+  int __pyx_t_7;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("right", 0);
+  if (__pyx_optional_args) {
+    if (__pyx_optional_args->__pyx_n > 0) {
+      __pyx_v_n = __pyx_optional_args->n;
+      if (__pyx_optional_args->__pyx_n > 1) {
+        __pyx_v_max_dist = __pyx_optional_args->max_dist;
+      }
+    }
+  }
+  /* Check if called by wrapper */
+  if (unlikely(__pyx_skip_dispatch)) ;
+  /* Check if overridden in Python */
+  else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
+    __pyx_t_1 = PyObject_GetAttr(((PyObject *)__pyx_v_self), __pyx_n_s__right); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 246; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_2bx_9intervals_12intersection_12IntervalNode_11right)) {
+      __Pyx_XDECREF(__pyx_r);
+      __pyx_t_2 = PyInt_FromLong(__pyx_v_n); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 246; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_2);
+      __pyx_t_3 = PyInt_FromLong(__pyx_v_max_dist); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 246; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_4 = PyTuple_New(3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 246; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __Pyx_INCREF(__pyx_v_position);
+      PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_v_position);
+      __Pyx_GIVEREF(__pyx_v_position);
+      PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_2);
+      __Pyx_GIVEREF(__pyx_t_2);
+      PyTuple_SET_ITEM(__pyx_t_4, 2, __pyx_t_3);
+      __Pyx_GIVEREF(__pyx_t_3);
+      __pyx_t_2 = 0;
+      __pyx_t_3 = 0;
+      __pyx_t_3 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_4), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 246; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
+      __pyx_r = __pyx_t_3;
+      __pyx_t_3 = 0;
+      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+      goto __pyx_L0;
+    }
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  }
+
+  /* "bx/intervals/intersection.pyx":253
+ *         max_dist: the maximum distance to look before giving up.
+ *         """
+ *         cdef list results = []             # <<<<<<<<<<<<<<
+ *         # use end + 1 becuase .right() assumes strictly right-of
+ *         self._seek_right(position + 1, results, n, max_dist)
+ */
+  __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 253; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_v_results = ((PyObject*)__pyx_t_1);
+  __pyx_t_1 = 0;
+
+  /* "bx/intervals/intersection.pyx":255
+ *         cdef list results = []
+ *         # use end + 1 becuase .right() assumes strictly right-of
+ *         self._seek_right(position + 1, results, n, max_dist)             # <<<<<<<<<<<<<<
+ *         if len(results) == n: return results
+ *         r = results
+ */
+  __pyx_t_1 = PyNumber_Add(__pyx_v_position, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 255; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_5 = __Pyx_PyInt_AsInt(__pyx_t_1); if (unlikely((__pyx_t_5 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 255; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  ((struct __pyx_vtabstruct_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self->__pyx_vtab)->_seek_right(__pyx_v_self, __pyx_t_5, __pyx_v_results, __pyx_v_n, __pyx_v_max_dist);
+
+  /* "bx/intervals/intersection.pyx":256
+ *         # use end + 1 becuase .right() assumes strictly right-of
+ *         self._seek_right(position + 1, results, n, max_dist)
+ *         if len(results) == n: return results             # <<<<<<<<<<<<<<
+ *         r = results
+ *         r.sort(key=operator.attrgetter('start'))
+ */
+  __pyx_t_6 = PyList_GET_SIZE(((PyObject *)__pyx_v_results)); if (unlikely(__pyx_t_6 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 256; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_7 = (__pyx_t_6 == __pyx_v_n);
+  if (__pyx_t_7) {
+    __Pyx_XDECREF(__pyx_r);
+    __Pyx_INCREF(((PyObject *)__pyx_v_results));
+    __pyx_r = ((PyObject *)__pyx_v_results);
+    goto __pyx_L0;
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  /* "bx/intervals/intersection.pyx":257
+ *         self._seek_right(position + 1, results, n, max_dist)
+ *         if len(results) == n: return results
+ *         r = results             # <<<<<<<<<<<<<<
+ *         r.sort(key=operator.attrgetter('start'))
+ *         return r[:n]
+ */
+  __Pyx_INCREF(((PyObject *)__pyx_v_results));
+  __pyx_v_r = __pyx_v_results;
+
+  /* "bx/intervals/intersection.pyx":258
+ *         if len(results) == n: return results
+ *         r = results
+ *         r.sort(key=operator.attrgetter('start'))             # <<<<<<<<<<<<<<
+ *         return r[:n]
+ * 
+ */
+  __pyx_t_1 = PyObject_GetAttr(((PyObject *)__pyx_v_r), __pyx_n_s__sort); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 258; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_3 = PyDict_New(); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 258; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(((PyObject *)__pyx_t_3));
+  __pyx_t_4 = __Pyx_GetName(__pyx_m, __pyx_n_s__operator); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 258; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __pyx_t_2 = PyObject_GetAttr(__pyx_t_4, __pyx_n_s__attrgetter); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 258; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  __pyx_t_4 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_k_tuple_4), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 258; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  if (PyDict_SetItem(__pyx_t_3, ((PyObject *)__pyx_n_s__key), __pyx_t_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 258; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  __pyx_t_4 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_empty_tuple), ((PyObject *)__pyx_t_3)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 258; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+
+  /* "bx/intervals/intersection.pyx":259
+ *         r = results
+ *         r.sort(key=operator.attrgetter('start'))
+ *         return r[:n]             # <<<<<<<<<<<<<<
+ * 
+ *     def traverse(self, func):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_4 = __Pyx_PySequence_GetSlice(((PyObject *)__pyx_v_r), 0, __pyx_v_n); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 259; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(((PyObject *)__pyx_t_4));
+  __pyx_r = ((PyObject *)__pyx_t_4);
+  __pyx_t_4 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_AddTraceback("bx.intervals.intersection.IntervalNode.right", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_results);
+  __Pyx_XDECREF(__pyx_v_r);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_9intervals_12intersection_12IntervalNode_11right(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_2bx_9intervals_12intersection_12IntervalNode_10right[] = "\n        find n features with a end < than position\n        f: a Interval object (or anything with a `start` attribute)\n        n: the number of features to return\n        max_dist: the maximum distance to look before giving up.\n        ";
+static PyObject *__pyx_pw_2bx_9intervals_12intersection_12IntervalNode_11right(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_position = 0;
+  int __pyx_v_n;
+  int __pyx_v_max_dist;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("right (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__position,&__pyx_n_s__n,&__pyx_n_s__max_dist,0};
+    PyObject* values[3] = {0,0,0};
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__position)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s__n);
+          if (value) { values[1] = value; kw_args--; }
+        }
+        case  2:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s__max_dist);
+          if (value) { values[2] = value; kw_args--; }
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "right") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 246; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else {
+      switch (PyTuple_GET_SIZE(__pyx_args)) {
+        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+    }
+    __pyx_v_position = values[0];
+    if (values[1]) {
+      __pyx_v_n = __Pyx_PyInt_AsInt(values[1]); if (unlikely((__pyx_v_n == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 246; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    } else {
+      __pyx_v_n = ((int)1);
+    }
+    if (values[2]) {
+      __pyx_v_max_dist = __Pyx_PyInt_AsInt(values[2]); if (unlikely((__pyx_v_max_dist == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 246; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    } else {
+      __pyx_v_max_dist = ((int)2500);
+    }
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("right", 0, 1, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 246; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.intervals.intersection.IntervalNode.right", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_9intervals_12intersection_12IntervalNode_10right(((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self), __pyx_v_position, __pyx_v_n, __pyx_v_max_dist);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/intervals/intersection.pyx":246
+ *         return r[:n]
+ * 
+ *     cpdef right(self, position, int n=1, int max_dist=2500):             # <<<<<<<<<<<<<<
+ *         """
+ *         find n features with a end < than position
+ */
+
+static PyObject *__pyx_pf_2bx_9intervals_12intersection_12IntervalNode_10right(struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *__pyx_v_self, PyObject *__pyx_v_position, int __pyx_v_n, int __pyx_v_max_dist) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  struct __pyx_opt_args_2bx_9intervals_12intersection_12IntervalNode_right __pyx_t_2;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("right", 0);
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_2.__pyx_n = 2;
+  __pyx_t_2.n = __pyx_v_n;
+  __pyx_t_2.max_dist = __pyx_v_max_dist;
+  __pyx_t_1 = ((struct __pyx_vtabstruct_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self->__pyx_vtab)->right(__pyx_v_self, __pyx_v_position, 1, &__pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 246; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("bx.intervals.intersection.IntervalNode.right", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_9intervals_12intersection_12IntervalNode_13traverse(PyObject *__pyx_v_self, PyObject *__pyx_v_func); /*proto*/
+static PyObject *__pyx_pw_2bx_9intervals_12intersection_12IntervalNode_13traverse(PyObject *__pyx_v_self, PyObject *__pyx_v_func) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("traverse (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_9intervals_12intersection_12IntervalNode_12traverse(((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self), ((PyObject *)__pyx_v_func));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/intervals/intersection.pyx":261
+ *         return r[:n]
+ * 
+ *     def traverse(self, func):             # <<<<<<<<<<<<<<
+ *         self._traverse(func)
+ * 
+ */
+
+static PyObject *__pyx_pf_2bx_9intervals_12intersection_12IntervalNode_12traverse(struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *__pyx_v_self, PyObject *__pyx_v_func) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("traverse", 0);
+
+  /* "bx/intervals/intersection.pyx":262
+ * 
+ *     def traverse(self, func):
+ *         self._traverse(func)             # <<<<<<<<<<<<<<
+ * 
+ *     cdef void _traverse(IntervalNode self, object func):
+ */
+  ((struct __pyx_vtabstruct_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self->__pyx_vtab)->_traverse(__pyx_v_self, __pyx_v_func);
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/intervals/intersection.pyx":264
+ *         self._traverse(func)
+ * 
+ *     cdef void _traverse(IntervalNode self, object func):             # <<<<<<<<<<<<<<
+ *         if self.cleft is not EmptyNode: self.cleft._traverse(func)
+ *         func(self)
+ */
+
+static void __pyx_f_2bx_9intervals_12intersection_12IntervalNode__traverse(struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *__pyx_v_self, PyObject *__pyx_v_func) {
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("_traverse", 0);
+
+  /* "bx/intervals/intersection.pyx":265
+ * 
+ *     cdef void _traverse(IntervalNode self, object func):
+ *         if self.cleft is not EmptyNode: self.cleft._traverse(func)             # <<<<<<<<<<<<<<
+ *         func(self)
+ *         if self.cright is not EmptyNode: self.cright._traverse(func)
+ */
+  __pyx_t_1 = (__pyx_v_self->cleft != __pyx_v_2bx_9intervals_12intersection_EmptyNode);
+  if (__pyx_t_1) {
+    ((struct __pyx_vtabstruct_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self->cleft->__pyx_vtab)->_traverse(__pyx_v_self->cleft, __pyx_v_func);
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  /* "bx/intervals/intersection.pyx":266
+ *     cdef void _traverse(IntervalNode self, object func):
+ *         if self.cleft is not EmptyNode: self.cleft._traverse(func)
+ *         func(self)             # <<<<<<<<<<<<<<
+ *         if self.cright is not EmptyNode: self.cright._traverse(func)
+ * 
+ */
+  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 266; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_INCREF(((PyObject *)__pyx_v_self));
+  PyTuple_SET_ITEM(__pyx_t_2, 0, ((PyObject *)__pyx_v_self));
+  __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
+  __pyx_t_3 = PyObject_Call(__pyx_v_func, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 266; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+  /* "bx/intervals/intersection.pyx":267
+ *         if self.cleft is not EmptyNode: self.cleft._traverse(func)
+ *         func(self)
+ *         if self.cright is not EmptyNode: self.cright._traverse(func)             # <<<<<<<<<<<<<<
+ * 
+ * cdef IntervalNode EmptyNode = IntervalNode( 0, 0, Interval(0, 0))
+ */
+  __pyx_t_1 = (__pyx_v_self->cright != __pyx_v_2bx_9intervals_12intersection_EmptyNode);
+  if (__pyx_t_1) {
+    ((struct __pyx_vtabstruct_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self->cright->__pyx_vtab)->_traverse(__pyx_v_self->cright, __pyx_v_func);
+    goto __pyx_L4;
+  }
+  __pyx_L4:;
+
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_WriteUnraisable("bx.intervals.intersection.IntervalNode._traverse", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_9intervals_12intersection_12IntervalNode_8interval_1__get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_2bx_9intervals_12intersection_12IntervalNode_8interval_1__get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_9intervals_12intersection_12IntervalNode_8interval___get__(((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/intervals/intersection.pyx":68
+ *     """
+ *     cdef float priority
+ *     cdef public object interval             # <<<<<<<<<<<<<<
+ *     cdef public int start, end
+ *     cdef int minend, maxend, minstart
+ */
+
+static PyObject *__pyx_pf_2bx_9intervals_12intersection_12IntervalNode_8interval___get__(struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__get__", 0);
+  __Pyx_XDECREF(__pyx_r);
+  __Pyx_INCREF(__pyx_v_self->interval);
+  __pyx_r = __pyx_v_self->interval;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_2bx_9intervals_12intersection_12IntervalNode_8interval_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value); /*proto*/
+static int __pyx_pw_2bx_9intervals_12intersection_12IntervalNode_8interval_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__set__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_9intervals_12intersection_12IntervalNode_8interval_2__set__(((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self), ((PyObject *)__pyx_v_value));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_2bx_9intervals_12intersection_12IntervalNode_8interval_2__set__(struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__set__", 0);
+  __Pyx_INCREF(__pyx_v_value);
+  __Pyx_GIVEREF(__pyx_v_value);
+  __Pyx_GOTREF(__pyx_v_self->interval);
+  __Pyx_DECREF(__pyx_v_self->interval);
+  __pyx_v_self->interval = __pyx_v_value;
+
+  __pyx_r = 0;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_2bx_9intervals_12intersection_12IntervalNode_8interval_5__del__(PyObject *__pyx_v_self); /*proto*/
+static int __pyx_pw_2bx_9intervals_12intersection_12IntervalNode_8interval_5__del__(PyObject *__pyx_v_self) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__del__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_9intervals_12intersection_12IntervalNode_8interval_4__del__(((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_2bx_9intervals_12intersection_12IntervalNode_8interval_4__del__(struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *__pyx_v_self) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__del__", 0);
+  __Pyx_INCREF(Py_None);
+  __Pyx_GIVEREF(Py_None);
+  __Pyx_GOTREF(__pyx_v_self->interval);
+  __Pyx_DECREF(__pyx_v_self->interval);
+  __pyx_v_self->interval = Py_None;
+
+  __pyx_r = 0;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_9intervals_12intersection_12IntervalNode_5start_1__get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_2bx_9intervals_12intersection_12IntervalNode_5start_1__get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_9intervals_12intersection_12IntervalNode_5start___get__(((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/intervals/intersection.pyx":69
+ *     cdef float priority
+ *     cdef public object interval
+ *     cdef public int start, end             # <<<<<<<<<<<<<<
+ *     cdef int minend, maxend, minstart
+ *     cdef IntervalNode cleft, cright, croot
+ */
+
+static PyObject *__pyx_pf_2bx_9intervals_12intersection_12IntervalNode_5start___get__(struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__get__", 0);
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = PyInt_FromLong(__pyx_v_self->start); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 69; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("bx.intervals.intersection.IntervalNode.start.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_2bx_9intervals_12intersection_12IntervalNode_5start_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value); /*proto*/
+static int __pyx_pw_2bx_9intervals_12intersection_12IntervalNode_5start_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__set__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_9intervals_12intersection_12IntervalNode_5start_2__set__(((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self), ((PyObject *)__pyx_v_value));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_2bx_9intervals_12intersection_12IntervalNode_5start_2__set__(struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__set__", 0);
+  __pyx_t_1 = __Pyx_PyInt_AsInt(__pyx_v_value); if (unlikely((__pyx_t_1 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 69; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_v_self->start = __pyx_t_1;
+
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_AddTraceback("bx.intervals.intersection.IntervalNode.start.__set__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = -1;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_9intervals_12intersection_12IntervalNode_3end_1__get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_2bx_9intervals_12intersection_12IntervalNode_3end_1__get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_9intervals_12intersection_12IntervalNode_3end___get__(((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_2bx_9intervals_12intersection_12IntervalNode_3end___get__(struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__get__", 0);
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = PyInt_FromLong(__pyx_v_self->end); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 69; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("bx.intervals.intersection.IntervalNode.end.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_2bx_9intervals_12intersection_12IntervalNode_3end_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value); /*proto*/
+static int __pyx_pw_2bx_9intervals_12intersection_12IntervalNode_3end_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__set__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_9intervals_12intersection_12IntervalNode_3end_2__set__(((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self), ((PyObject *)__pyx_v_value));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_2bx_9intervals_12intersection_12IntervalNode_3end_2__set__(struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__set__", 0);
+  __pyx_t_1 = __Pyx_PyInt_AsInt(__pyx_v_value); if (unlikely((__pyx_t_1 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 69; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_v_self->end = __pyx_t_1;
+
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_AddTraceback("bx.intervals.intersection.IntervalNode.end.__set__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = -1;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_2bx_9intervals_12intersection_8Interval_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static int __pyx_pw_2bx_9intervals_12intersection_8Interval_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  int __pyx_v_start;
+  int __pyx_v_end;
+  PyObject *__pyx_v_value = 0;
+  PyObject *__pyx_v_chrom = 0;
+  PyObject *__pyx_v_strand = 0;
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__init__ (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__start,&__pyx_n_s__end,&__pyx_n_s__value,&__pyx_n_s__chrom,&__pyx_n_s__strand,0};
+    PyObject* values[5] = {0,0,0,0,0};
+
+    /* "bx/intervals/intersection.pyx":290
+ *     cdef public object value, chrom, strand
+ * 
+ *     def __init__(self, int start, int end, object value=None, object chrom=None, object strand=None ):             # <<<<<<<<<<<<<<
+ *         assert start <= end, "start must be less than end"
+ *         self.start  = start
+ */
+    values[2] = ((PyObject *)Py_None);
+    values[3] = ((PyObject *)Py_None);
+    values[4] = ((PyObject *)Py_None);
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+        case  4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__start)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__end)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("__init__", 0, 2, 5, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 290; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+        case  2:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s__value);
+          if (value) { values[2] = value; kw_args--; }
+        }
+        case  3:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s__chrom);
+          if (value) { values[3] = value; kw_args--; }
+        }
+        case  4:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s__strand);
+          if (value) { values[4] = value; kw_args--; }
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 290; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else {
+      switch (PyTuple_GET_SIZE(__pyx_args)) {
+        case  5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+        case  4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+    }
+    __pyx_v_start = __Pyx_PyInt_AsInt(values[0]); if (unlikely((__pyx_v_start == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 290; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_end = __Pyx_PyInt_AsInt(values[1]); if (unlikely((__pyx_v_end == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 290; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_value = values[2];
+    __pyx_v_chrom = values[3];
+    __pyx_v_strand = values[4];
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("__init__", 0, 2, 5, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 290; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.intervals.intersection.Interval.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return -1;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_9intervals_12intersection_8Interval___init__(((struct __pyx_obj_2bx_9intervals_12intersection_Interval *)__pyx_v_self), __pyx_v_start, __pyx_v_end, __pyx_v_value, __pyx_v_chrom, __pyx_v_strand);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_2bx_9intervals_12intersection_8Interval___init__(struct __pyx_obj_2bx_9intervals_12intersection_Interval *__pyx_v_self, int __pyx_v_start, int __pyx_v_end, PyObject *__pyx_v_value, PyObject *__pyx_v_chrom, PyObject *__pyx_v_strand) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__init__", 0);
+
+  /* "bx/intervals/intersection.pyx":291
+ * 
+ *     def __init__(self, int start, int end, object value=None, object chrom=None, object strand=None ):
+ *         assert start <= end, "start must be less than end"             # <<<<<<<<<<<<<<
+ *         self.start  = start
+ *         self.end   = end
+ */
+  #ifndef CYTHON_WITHOUT_ASSERTIONS
+  if (unlikely(!(__pyx_v_start <= __pyx_v_end))) {
+    PyErr_SetObject(PyExc_AssertionError, ((PyObject *)__pyx_kp_s_5));
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 291; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  #endif
+
+  /* "bx/intervals/intersection.pyx":292
+ *     def __init__(self, int start, int end, object value=None, object chrom=None, object strand=None ):
+ *         assert start <= end, "start must be less than end"
+ *         self.start  = start             # <<<<<<<<<<<<<<
+ *         self.end   = end
+ *         self.value = value
+ */
+  __pyx_v_self->start = __pyx_v_start;
+
+  /* "bx/intervals/intersection.pyx":293
+ *         assert start <= end, "start must be less than end"
+ *         self.start  = start
+ *         self.end   = end             # <<<<<<<<<<<<<<
+ *         self.value = value
+ *         self.chrom = chrom
+ */
+  __pyx_v_self->end = __pyx_v_end;
+
+  /* "bx/intervals/intersection.pyx":294
+ *         self.start  = start
+ *         self.end   = end
+ *         self.value = value             # <<<<<<<<<<<<<<
+ *         self.chrom = chrom
+ *         self.strand = strand
+ */
+  __Pyx_INCREF(__pyx_v_value);
+  __Pyx_GIVEREF(__pyx_v_value);
+  __Pyx_GOTREF(__pyx_v_self->value);
+  __Pyx_DECREF(__pyx_v_self->value);
+  __pyx_v_self->value = __pyx_v_value;
+
+  /* "bx/intervals/intersection.pyx":295
+ *         self.end   = end
+ *         self.value = value
+ *         self.chrom = chrom             # <<<<<<<<<<<<<<
+ *         self.strand = strand
+ * 
+ */
+  __Pyx_INCREF(__pyx_v_chrom);
+  __Pyx_GIVEREF(__pyx_v_chrom);
+  __Pyx_GOTREF(__pyx_v_self->chrom);
+  __Pyx_DECREF(__pyx_v_self->chrom);
+  __pyx_v_self->chrom = __pyx_v_chrom;
+
+  /* "bx/intervals/intersection.pyx":296
+ *         self.value = value
+ *         self.chrom = chrom
+ *         self.strand = strand             # <<<<<<<<<<<<<<
+ * 
+ *     def __repr__(self):
+ */
+  __Pyx_INCREF(__pyx_v_strand);
+  __Pyx_GIVEREF(__pyx_v_strand);
+  __Pyx_GOTREF(__pyx_v_self->strand);
+  __Pyx_DECREF(__pyx_v_self->strand);
+  __pyx_v_self->strand = __pyx_v_strand;
+
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_AddTraceback("bx.intervals.intersection.Interval.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = -1;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_9intervals_12intersection_8Interval_3__repr__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_2bx_9intervals_12intersection_8Interval_3__repr__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__repr__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_9intervals_12intersection_8Interval_2__repr__(((struct __pyx_obj_2bx_9intervals_12intersection_Interval *)__pyx_v_self));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/intervals/intersection.pyx":298
+ *         self.strand = strand
+ * 
+ *     def __repr__(self):             # <<<<<<<<<<<<<<
+ *         fstr = "Interval(%d, %d" % (self.start, self.end)
+ *         if not self.value is None:
+ */
+
+static PyObject *__pyx_pf_2bx_9intervals_12intersection_8Interval_2__repr__(struct __pyx_obj_2bx_9intervals_12intersection_Interval *__pyx_v_self) {
+  PyObject *__pyx_v_fstr = NULL;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  int __pyx_t_4;
+  int __pyx_t_5;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__repr__", 0);
+
+  /* "bx/intervals/intersection.pyx":299
+ * 
+ *     def __repr__(self):
+ *         fstr = "Interval(%d, %d" % (self.start, self.end)             # <<<<<<<<<<<<<<
+ *         if not self.value is None:
+ *             fstr += ", value=" + str(self.value)
+ */
+  __pyx_t_1 = PyInt_FromLong(__pyx_v_self->start); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 299; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = PyInt_FromLong(__pyx_v_self->end); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 299; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 299; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1);
+  __Pyx_GIVEREF(__pyx_t_1);
+  PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_2);
+  __Pyx_GIVEREF(__pyx_t_2);
+  __pyx_t_1 = 0;
+  __pyx_t_2 = 0;
+  __pyx_t_2 = PyNumber_Remainder(((PyObject *)__pyx_kp_s_6), ((PyObject *)__pyx_t_3)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 299; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(((PyObject *)__pyx_t_2));
+  __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
+  __pyx_v_fstr = ((PyObject *)__pyx_t_2);
+  __pyx_t_2 = 0;
+
+  /* "bx/intervals/intersection.pyx":300
+ *     def __repr__(self):
+ *         fstr = "Interval(%d, %d" % (self.start, self.end)
+ *         if not self.value is None:             # <<<<<<<<<<<<<<
+ *             fstr += ", value=" + str(self.value)
+ *         fstr += ")"
+ */
+  __pyx_t_4 = (__pyx_v_self->value == Py_None);
+  __pyx_t_5 = (!__pyx_t_4);
+  if (__pyx_t_5) {
+
+    /* "bx/intervals/intersection.pyx":301
+ *         fstr = "Interval(%d, %d" % (self.start, self.end)
+ *         if not self.value is None:
+ *             fstr += ", value=" + str(self.value)             # <<<<<<<<<<<<<<
+ *         fstr += ")"
+ *         return fstr
+ */
+    __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 301; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __Pyx_INCREF(__pyx_v_self->value);
+    PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_self->value);
+    __Pyx_GIVEREF(__pyx_v_self->value);
+    __pyx_t_3 = PyObject_Call(((PyObject *)((PyObject*)(&PyString_Type))), ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 301; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
+    __pyx_t_2 = PyNumber_Add(((PyObject *)__pyx_kp_s_7), __pyx_t_3); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 301; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __pyx_t_3 = PyNumber_InPlaceAdd(__pyx_v_fstr, __pyx_t_2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 301; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    __Pyx_DECREF(__pyx_v_fstr);
+    __pyx_v_fstr = __pyx_t_3;
+    __pyx_t_3 = 0;
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  /* "bx/intervals/intersection.pyx":302
+ *         if not self.value is None:
+ *             fstr += ", value=" + str(self.value)
+ *         fstr += ")"             # <<<<<<<<<<<<<<
+ *         return fstr
+ * 
+ */
+  __pyx_t_3 = PyNumber_InPlaceAdd(__pyx_v_fstr, ((PyObject *)__pyx_kp_s_8)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 302; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_v_fstr);
+  __pyx_v_fstr = __pyx_t_3;
+  __pyx_t_3 = 0;
+
+  /* "bx/intervals/intersection.pyx":303
+ *             fstr += ", value=" + str(self.value)
+ *         fstr += ")"
+ *         return fstr             # <<<<<<<<<<<<<<
+ * 
+ *     def __richcmp__(self, other, op):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __Pyx_INCREF(__pyx_v_fstr);
+  __pyx_r = __pyx_v_fstr;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_AddTraceback("bx.intervals.intersection.Interval.__repr__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_fstr);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_9intervals_12intersection_8Interval_5__richcmp__(PyObject *__pyx_v_self, PyObject *__pyx_v_other, int __pyx_arg_op); /*proto*/
+static PyObject *__pyx_pw_2bx_9intervals_12intersection_8Interval_5__richcmp__(PyObject *__pyx_v_self, PyObject *__pyx_v_other, int __pyx_arg_op) {
+  PyObject *__pyx_v_op = 0;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__richcmp__ (wrapper)", 0);
+  __pyx_v_op = PyInt_FromLong(__pyx_arg_op); if (unlikely(!__pyx_v_op)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 305; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __Pyx_GOTREF(__pyx_v_op);
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.intervals.intersection.Interval.__richcmp__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_9intervals_12intersection_8Interval_4__richcmp__(((PyObject *)__pyx_v_self), ((PyObject *)__pyx_v_other), ((PyObject *)__pyx_v_op));
+  __Pyx_XDECREF(__pyx_v_op);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/intervals/intersection.pyx":305
+ *         return fstr
+ * 
+ *     def __richcmp__(self, other, op):             # <<<<<<<<<<<<<<
+ *         if op == 0:
+ *             # <
+ */
+
+static PyObject *__pyx_pf_2bx_9intervals_12intersection_8Interval_4__richcmp__(PyObject *__pyx_v_self, PyObject *__pyx_v_other, PyObject *__pyx_v_op) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_t_2;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  PyObject *__pyx_t_5 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__richcmp__", 0);
+
+  /* "bx/intervals/intersection.pyx":306
+ * 
+ *     def __richcmp__(self, other, op):
+ *         if op == 0:             # <<<<<<<<<<<<<<
+ *             # <
+ *             return self.start < other.start or self.end < other.end
+ */
+  __pyx_t_1 = PyObject_RichCompare(__pyx_v_op, __pyx_int_0, Py_EQ); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 306; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 306; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  if (__pyx_t_2) {
+
+    /* "bx/intervals/intersection.pyx":308
+ *         if op == 0:
+ *             # <
+ *             return self.start < other.start or self.end < other.end             # <<<<<<<<<<<<<<
+ *         elif op == 1:
+ *             # <=
+ */
+    __Pyx_XDECREF(__pyx_r);
+    __pyx_t_1 = PyObject_GetAttr(__pyx_v_self, __pyx_n_s__start); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 308; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __pyx_t_3 = PyObject_GetAttr(__pyx_v_other, __pyx_n_s__start); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 308; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __pyx_t_4 = PyObject_RichCompare(__pyx_t_1, __pyx_t_3, Py_LT); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 308; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 308; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (!__pyx_t_2) {
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      __pyx_t_3 = PyObject_GetAttr(__pyx_v_self, __pyx_n_s__end); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 308; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_1 = PyObject_GetAttr(__pyx_v_other, __pyx_n_s__end); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 308; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_1);
+      __pyx_t_5 = PyObject_RichCompare(__pyx_t_3, __pyx_t_1, Py_LT); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 308; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+      __pyx_t_1 = __pyx_t_5;
+      __pyx_t_5 = 0;
+    } else {
+      __pyx_t_1 = __pyx_t_4;
+      __pyx_t_4 = 0;
+    }
+    __pyx_r = __pyx_t_1;
+    __pyx_t_1 = 0;
+    goto __pyx_L0;
+    goto __pyx_L3;
+  }
+
+  /* "bx/intervals/intersection.pyx":309
+ *             # <
+ *             return self.start < other.start or self.end < other.end
+ *         elif op == 1:             # <<<<<<<<<<<<<<
+ *             # <=
+ *             return self == other or self < other
+ */
+  __pyx_t_1 = PyObject_RichCompare(__pyx_v_op, __pyx_int_1, Py_EQ); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 309; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 309; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  if (__pyx_t_2) {
+
+    /* "bx/intervals/intersection.pyx":311
+ *         elif op == 1:
+ *             # <=
+ *             return self == other or self < other             # <<<<<<<<<<<<<<
+ *         elif op == 2:
+ *             # ==
+ */
+    __Pyx_XDECREF(__pyx_r);
+    __pyx_t_1 = PyObject_RichCompare(__pyx_v_self, __pyx_v_other, Py_EQ); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 311; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 311; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (!__pyx_t_2) {
+      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+      __pyx_t_4 = PyObject_RichCompare(__pyx_v_self, __pyx_v_other, Py_LT); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 311; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_5 = __pyx_t_4;
+      __pyx_t_4 = 0;
+    } else {
+      __pyx_t_5 = __pyx_t_1;
+      __pyx_t_1 = 0;
+    }
+    __pyx_r = __pyx_t_5;
+    __pyx_t_5 = 0;
+    goto __pyx_L0;
+    goto __pyx_L3;
+  }
+
+  /* "bx/intervals/intersection.pyx":312
+ *             # <=
+ *             return self == other or self < other
+ *         elif op == 2:             # <<<<<<<<<<<<<<
+ *             # ==
+ *             return self.start == other.start and self.end == other.end
+ */
+  __pyx_t_5 = PyObject_RichCompare(__pyx_v_op, __pyx_int_2, Py_EQ); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 312; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 312; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+  if (__pyx_t_2) {
+
+    /* "bx/intervals/intersection.pyx":314
+ *         elif op == 2:
+ *             # ==
+ *             return self.start == other.start and self.end == other.end             # <<<<<<<<<<<<<<
+ *         elif op == 3:
+ *             # !=
+ */
+    __Pyx_XDECREF(__pyx_r);
+    __pyx_t_5 = PyObject_GetAttr(__pyx_v_self, __pyx_n_s__start); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 314; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_5);
+    __pyx_t_1 = PyObject_GetAttr(__pyx_v_other, __pyx_n_s__start); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 314; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __pyx_t_4 = PyObject_RichCompare(__pyx_t_5, __pyx_t_1, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 314; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 314; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (__pyx_t_2) {
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      __pyx_t_1 = PyObject_GetAttr(__pyx_v_self, __pyx_n_s__end); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 314; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_1);
+      __pyx_t_5 = PyObject_GetAttr(__pyx_v_other, __pyx_n_s__end); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 314; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_5);
+      __pyx_t_3 = PyObject_RichCompare(__pyx_t_1, __pyx_t_5, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 314; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      __pyx_t_5 = __pyx_t_3;
+      __pyx_t_3 = 0;
+    } else {
+      __pyx_t_5 = __pyx_t_4;
+      __pyx_t_4 = 0;
+    }
+    __pyx_r = __pyx_t_5;
+    __pyx_t_5 = 0;
+    goto __pyx_L0;
+    goto __pyx_L3;
+  }
+
+  /* "bx/intervals/intersection.pyx":315
+ *             # ==
+ *             return self.start == other.start and self.end == other.end
+ *         elif op == 3:             # <<<<<<<<<<<<<<
+ *             # !=
+ *             return self.start != other.start or self.end != other.end
+ */
+  __pyx_t_5 = PyObject_RichCompare(__pyx_v_op, __pyx_int_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 315; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 315; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+  if (__pyx_t_2) {
+
+    /* "bx/intervals/intersection.pyx":317
+ *         elif op == 3:
+ *             # !=
+ *             return self.start != other.start or self.end != other.end             # <<<<<<<<<<<<<<
+ *         elif op == 4:
+ *             # >
+ */
+    __Pyx_XDECREF(__pyx_r);
+    __pyx_t_5 = PyObject_GetAttr(__pyx_v_self, __pyx_n_s__start); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 317; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_5);
+    __pyx_t_4 = PyObject_GetAttr(__pyx_v_other, __pyx_n_s__start); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 317; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    __pyx_t_3 = PyObject_RichCompare(__pyx_t_5, __pyx_t_4, Py_NE); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 317; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 317; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (!__pyx_t_2) {
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_t_4 = PyObject_GetAttr(__pyx_v_self, __pyx_n_s__end); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 317; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __pyx_t_5 = PyObject_GetAttr(__pyx_v_other, __pyx_n_s__end); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 317; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_5);
+      __pyx_t_1 = PyObject_RichCompare(__pyx_t_4, __pyx_t_5, Py_NE); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 317; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      __pyx_t_5 = __pyx_t_1;
+      __pyx_t_1 = 0;
+    } else {
+      __pyx_t_5 = __pyx_t_3;
+      __pyx_t_3 = 0;
+    }
+    __pyx_r = __pyx_t_5;
+    __pyx_t_5 = 0;
+    goto __pyx_L0;
+    goto __pyx_L3;
+  }
+
+  /* "bx/intervals/intersection.pyx":318
+ *             # !=
+ *             return self.start != other.start or self.end != other.end
+ *         elif op == 4:             # <<<<<<<<<<<<<<
+ *             # >
+ *             return self.start > other.start or self.end > other.end
+ */
+  __pyx_t_5 = PyObject_RichCompare(__pyx_v_op, __pyx_int_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 318; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 318; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+  if (__pyx_t_2) {
+
+    /* "bx/intervals/intersection.pyx":320
+ *         elif op == 4:
+ *             # >
+ *             return self.start > other.start or self.end > other.end             # <<<<<<<<<<<<<<
+ *         elif op == 5:
+ *             # >=
+ */
+    __Pyx_XDECREF(__pyx_r);
+    __pyx_t_5 = PyObject_GetAttr(__pyx_v_self, __pyx_n_s__start); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 320; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_5);
+    __pyx_t_3 = PyObject_GetAttr(__pyx_v_other, __pyx_n_s__start); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 320; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __pyx_t_1 = PyObject_RichCompare(__pyx_t_5, __pyx_t_3, Py_GT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 320; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 320; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (!__pyx_t_2) {
+      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+      __pyx_t_3 = PyObject_GetAttr(__pyx_v_self, __pyx_n_s__end); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 320; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_5 = PyObject_GetAttr(__pyx_v_other, __pyx_n_s__end); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 320; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_5);
+      __pyx_t_4 = PyObject_RichCompare(__pyx_t_3, __pyx_t_5, Py_GT); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 320; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      __pyx_t_5 = __pyx_t_4;
+      __pyx_t_4 = 0;
+    } else {
+      __pyx_t_5 = __pyx_t_1;
+      __pyx_t_1 = 0;
+    }
+    __pyx_r = __pyx_t_5;
+    __pyx_t_5 = 0;
+    goto __pyx_L0;
+    goto __pyx_L3;
+  }
+
+  /* "bx/intervals/intersection.pyx":321
+ *             # >
+ *             return self.start > other.start or self.end > other.end
+ *         elif op == 5:             # <<<<<<<<<<<<<<
+ *             # >=
+ *             return self == other or self > other
+ */
+  __pyx_t_5 = PyObject_RichCompare(__pyx_v_op, __pyx_int_5, Py_EQ); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 321; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 321; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+  if (__pyx_t_2) {
+
+    /* "bx/intervals/intersection.pyx":323
+ *         elif op == 5:
+ *             # >=
+ *             return self == other or self > other             # <<<<<<<<<<<<<<
+ * 
+ * cdef class IntervalTree:
+ */
+    __Pyx_XDECREF(__pyx_r);
+    __pyx_t_5 = PyObject_RichCompare(__pyx_v_self, __pyx_v_other, Py_EQ); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (!__pyx_t_2) {
+      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      __pyx_t_1 = PyObject_RichCompare(__pyx_v_self, __pyx_v_other, Py_GT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = __pyx_t_1;
+      __pyx_t_1 = 0;
+    } else {
+      __pyx_t_4 = __pyx_t_5;
+      __pyx_t_5 = 0;
+    }
+    __pyx_r = __pyx_t_4;
+    __pyx_t_4 = 0;
+    goto __pyx_L0;
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_XDECREF(__pyx_t_5);
+  __Pyx_AddTraceback("bx.intervals.intersection.Interval.__richcmp__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_9intervals_12intersection_8Interval_5start_1__get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_2bx_9intervals_12intersection_8Interval_5start_1__get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_9intervals_12intersection_8Interval_5start___get__(((struct __pyx_obj_2bx_9intervals_12intersection_Interval *)__pyx_v_self));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/intervals/intersection.pyx":287
+ * 
+ *     """
+ *     cdef public int start, end             # <<<<<<<<<<<<<<
+ *     cdef public object value, chrom, strand
+ * 
+ */
+
+static PyObject *__pyx_pf_2bx_9intervals_12intersection_8Interval_5start___get__(struct __pyx_obj_2bx_9intervals_12intersection_Interval *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__get__", 0);
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = PyInt_FromLong(__pyx_v_self->start); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 287; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("bx.intervals.intersection.Interval.start.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_2bx_9intervals_12intersection_8Interval_5start_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value); /*proto*/
+static int __pyx_pw_2bx_9intervals_12intersection_8Interval_5start_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__set__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_9intervals_12intersection_8Interval_5start_2__set__(((struct __pyx_obj_2bx_9intervals_12intersection_Interval *)__pyx_v_self), ((PyObject *)__pyx_v_value));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_2bx_9intervals_12intersection_8Interval_5start_2__set__(struct __pyx_obj_2bx_9intervals_12intersection_Interval *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__set__", 0);
+  __pyx_t_1 = __Pyx_PyInt_AsInt(__pyx_v_value); if (unlikely((__pyx_t_1 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 287; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_v_self->start = __pyx_t_1;
+
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_AddTraceback("bx.intervals.intersection.Interval.start.__set__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = -1;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_9intervals_12intersection_8Interval_3end_1__get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_2bx_9intervals_12intersection_8Interval_3end_1__get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_9intervals_12intersection_8Interval_3end___get__(((struct __pyx_obj_2bx_9intervals_12intersection_Interval *)__pyx_v_self));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_2bx_9intervals_12intersection_8Interval_3end___get__(struct __pyx_obj_2bx_9intervals_12intersection_Interval *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__get__", 0);
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = PyInt_FromLong(__pyx_v_self->end); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 287; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("bx.intervals.intersection.Interval.end.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_2bx_9intervals_12intersection_8Interval_3end_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value); /*proto*/
+static int __pyx_pw_2bx_9intervals_12intersection_8Interval_3end_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__set__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_9intervals_12intersection_8Interval_3end_2__set__(((struct __pyx_obj_2bx_9intervals_12intersection_Interval *)__pyx_v_self), ((PyObject *)__pyx_v_value));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_2bx_9intervals_12intersection_8Interval_3end_2__set__(struct __pyx_obj_2bx_9intervals_12intersection_Interval *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__set__", 0);
+  __pyx_t_1 = __Pyx_PyInt_AsInt(__pyx_v_value); if (unlikely((__pyx_t_1 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 287; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_v_self->end = __pyx_t_1;
+
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_AddTraceback("bx.intervals.intersection.Interval.end.__set__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = -1;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_9intervals_12intersection_8Interval_5value_1__get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_2bx_9intervals_12intersection_8Interval_5value_1__get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_9intervals_12intersection_8Interval_5value___get__(((struct __pyx_obj_2bx_9intervals_12intersection_Interval *)__pyx_v_self));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/intervals/intersection.pyx":288
+ *     """
+ *     cdef public int start, end
+ *     cdef public object value, chrom, strand             # <<<<<<<<<<<<<<
+ * 
+ *     def __init__(self, int start, int end, object value=None, object chrom=None, object strand=None ):
+ */
+
+static PyObject *__pyx_pf_2bx_9intervals_12intersection_8Interval_5value___get__(struct __pyx_obj_2bx_9intervals_12intersection_Interval *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__get__", 0);
+  __Pyx_XDECREF(__pyx_r);
+  __Pyx_INCREF(__pyx_v_self->value);
+  __pyx_r = __pyx_v_self->value;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_2bx_9intervals_12intersection_8Interval_5value_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value); /*proto*/
+static int __pyx_pw_2bx_9intervals_12intersection_8Interval_5value_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__set__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_9intervals_12intersection_8Interval_5value_2__set__(((struct __pyx_obj_2bx_9intervals_12intersection_Interval *)__pyx_v_self), ((PyObject *)__pyx_v_value));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_2bx_9intervals_12intersection_8Interval_5value_2__set__(struct __pyx_obj_2bx_9intervals_12intersection_Interval *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__set__", 0);
+  __Pyx_INCREF(__pyx_v_value);
+  __Pyx_GIVEREF(__pyx_v_value);
+  __Pyx_GOTREF(__pyx_v_self->value);
+  __Pyx_DECREF(__pyx_v_self->value);
+  __pyx_v_self->value = __pyx_v_value;
+
+  __pyx_r = 0;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_2bx_9intervals_12intersection_8Interval_5value_5__del__(PyObject *__pyx_v_self); /*proto*/
+static int __pyx_pw_2bx_9intervals_12intersection_8Interval_5value_5__del__(PyObject *__pyx_v_self) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__del__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_9intervals_12intersection_8Interval_5value_4__del__(((struct __pyx_obj_2bx_9intervals_12intersection_Interval *)__pyx_v_self));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_2bx_9intervals_12intersection_8Interval_5value_4__del__(struct __pyx_obj_2bx_9intervals_12intersection_Interval *__pyx_v_self) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__del__", 0);
+  __Pyx_INCREF(Py_None);
+  __Pyx_GIVEREF(Py_None);
+  __Pyx_GOTREF(__pyx_v_self->value);
+  __Pyx_DECREF(__pyx_v_self->value);
+  __pyx_v_self->value = Py_None;
+
+  __pyx_r = 0;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_9intervals_12intersection_8Interval_5chrom_1__get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_2bx_9intervals_12intersection_8Interval_5chrom_1__get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_9intervals_12intersection_8Interval_5chrom___get__(((struct __pyx_obj_2bx_9intervals_12intersection_Interval *)__pyx_v_self));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_2bx_9intervals_12intersection_8Interval_5chrom___get__(struct __pyx_obj_2bx_9intervals_12intersection_Interval *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__get__", 0);
+  __Pyx_XDECREF(__pyx_r);
+  __Pyx_INCREF(__pyx_v_self->chrom);
+  __pyx_r = __pyx_v_self->chrom;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_2bx_9intervals_12intersection_8Interval_5chrom_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value); /*proto*/
+static int __pyx_pw_2bx_9intervals_12intersection_8Interval_5chrom_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__set__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_9intervals_12intersection_8Interval_5chrom_2__set__(((struct __pyx_obj_2bx_9intervals_12intersection_Interval *)__pyx_v_self), ((PyObject *)__pyx_v_value));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_2bx_9intervals_12intersection_8Interval_5chrom_2__set__(struct __pyx_obj_2bx_9intervals_12intersection_Interval *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__set__", 0);
+  __Pyx_INCREF(__pyx_v_value);
+  __Pyx_GIVEREF(__pyx_v_value);
+  __Pyx_GOTREF(__pyx_v_self->chrom);
+  __Pyx_DECREF(__pyx_v_self->chrom);
+  __pyx_v_self->chrom = __pyx_v_value;
+
+  __pyx_r = 0;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_2bx_9intervals_12intersection_8Interval_5chrom_5__del__(PyObject *__pyx_v_self); /*proto*/
+static int __pyx_pw_2bx_9intervals_12intersection_8Interval_5chrom_5__del__(PyObject *__pyx_v_self) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__del__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_9intervals_12intersection_8Interval_5chrom_4__del__(((struct __pyx_obj_2bx_9intervals_12intersection_Interval *)__pyx_v_self));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_2bx_9intervals_12intersection_8Interval_5chrom_4__del__(struct __pyx_obj_2bx_9intervals_12intersection_Interval *__pyx_v_self) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__del__", 0);
+  __Pyx_INCREF(Py_None);
+  __Pyx_GIVEREF(Py_None);
+  __Pyx_GOTREF(__pyx_v_self->chrom);
+  __Pyx_DECREF(__pyx_v_self->chrom);
+  __pyx_v_self->chrom = Py_None;
+
+  __pyx_r = 0;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_9intervals_12intersection_8Interval_6strand_1__get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_2bx_9intervals_12intersection_8Interval_6strand_1__get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_9intervals_12intersection_8Interval_6strand___get__(((struct __pyx_obj_2bx_9intervals_12intersection_Interval *)__pyx_v_self));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_2bx_9intervals_12intersection_8Interval_6strand___get__(struct __pyx_obj_2bx_9intervals_12intersection_Interval *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__get__", 0);
+  __Pyx_XDECREF(__pyx_r);
+  __Pyx_INCREF(__pyx_v_self->strand);
+  __pyx_r = __pyx_v_self->strand;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_2bx_9intervals_12intersection_8Interval_6strand_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value); /*proto*/
+static int __pyx_pw_2bx_9intervals_12intersection_8Interval_6strand_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__set__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_9intervals_12intersection_8Interval_6strand_2__set__(((struct __pyx_obj_2bx_9intervals_12intersection_Interval *)__pyx_v_self), ((PyObject *)__pyx_v_value));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_2bx_9intervals_12intersection_8Interval_6strand_2__set__(struct __pyx_obj_2bx_9intervals_12intersection_Interval *__pyx_v_self, PyObject *__pyx_v_value) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__set__", 0);
+  __Pyx_INCREF(__pyx_v_value);
+  __Pyx_GIVEREF(__pyx_v_value);
+  __Pyx_GOTREF(__pyx_v_self->strand);
+  __Pyx_DECREF(__pyx_v_self->strand);
+  __pyx_v_self->strand = __pyx_v_value;
+
+  __pyx_r = 0;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_2bx_9intervals_12intersection_8Interval_6strand_5__del__(PyObject *__pyx_v_self); /*proto*/
+static int __pyx_pw_2bx_9intervals_12intersection_8Interval_6strand_5__del__(PyObject *__pyx_v_self) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__del__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_9intervals_12intersection_8Interval_6strand_4__del__(((struct __pyx_obj_2bx_9intervals_12intersection_Interval *)__pyx_v_self));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_2bx_9intervals_12intersection_8Interval_6strand_4__del__(struct __pyx_obj_2bx_9intervals_12intersection_Interval *__pyx_v_self) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__del__", 0);
+  __Pyx_INCREF(Py_None);
+  __Pyx_GIVEREF(Py_None);
+  __Pyx_GOTREF(__pyx_v_self->strand);
+  __Pyx_DECREF(__pyx_v_self->strand);
+  __pyx_v_self->strand = Py_None;
+
+  __pyx_r = 0;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static int __pyx_pw_2bx_9intervals_12intersection_12IntervalTree_1__cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static int __pyx_pw_2bx_9intervals_12intersection_12IntervalTree_1__cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__cinit__ (wrapper)", 0);
+  if (unlikely(PyTuple_GET_SIZE(__pyx_args) > 0)) {
+    __Pyx_RaiseArgtupleInvalid("__cinit__", 1, 0, 0, PyTuple_GET_SIZE(__pyx_args)); return -1;}
+  if (unlikely(__pyx_kwds) && unlikely(PyDict_Size(__pyx_kwds) > 0) && unlikely(!__Pyx_CheckKeywordStrings(__pyx_kwds, "__cinit__", 0))) return -1;
+  __pyx_r = __pyx_pf_2bx_9intervals_12intersection_12IntervalTree___cinit__(((struct __pyx_obj_2bx_9intervals_12intersection_IntervalTree *)__pyx_v_self));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/intervals/intersection.pyx":383
+ *     cdef IntervalNode root
+ * 
+ *     def __cinit__( self ):             # <<<<<<<<<<<<<<
+ *         root = None
+ * 
+ */
+
+static int __pyx_pf_2bx_9intervals_12intersection_12IntervalTree___cinit__(CYTHON_UNUSED struct __pyx_obj_2bx_9intervals_12intersection_IntervalTree *__pyx_v_self) {
+  CYTHON_UNUSED PyObject *__pyx_v_root = NULL;
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__cinit__", 0);
+
+  /* "bx/intervals/intersection.pyx":384
+ * 
+ *     def __cinit__( self ):
+ *         root = None             # <<<<<<<<<<<<<<
+ * 
+ *     # ---- Position based interfaces -----------------------------------------
+ */
+  __Pyx_INCREF(Py_None);
+  __pyx_v_root = Py_None;
+
+  __pyx_r = 0;
+  __Pyx_XDECREF(__pyx_v_root);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_9intervals_12intersection_12IntervalTree_3insert(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_2bx_9intervals_12intersection_12IntervalTree_2insert[] = "\n        Insert the interval [start,end) associated with value `value`.\n        ";
+static PyObject *__pyx_pw_2bx_9intervals_12intersection_12IntervalTree_3insert(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  int __pyx_v_start;
+  int __pyx_v_end;
+  PyObject *__pyx_v_value = 0;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("insert (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__start,&__pyx_n_s__end,&__pyx_n_s__value,0};
+    PyObject* values[3] = {0,0,0};
+
+    /* "bx/intervals/intersection.pyx":388
+ *     # ---- Position based interfaces -----------------------------------------
+ * 
+ *     def insert( self, int start, int end, object value=None ):             # <<<<<<<<<<<<<<
+ *         """
+ *         Insert the interval [start,end) associated with value `value`.
+ */
+    values[2] = ((PyObject *)Py_None);
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__start)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__end)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("insert", 0, 2, 3, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 388; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+        case  2:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s__value);
+          if (value) { values[2] = value; kw_args--; }
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "insert") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 388; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else {
+      switch (PyTuple_GET_SIZE(__pyx_args)) {
+        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+    }
+    __pyx_v_start = __Pyx_PyInt_AsInt(values[0]); if (unlikely((__pyx_v_start == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 388; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_end = __Pyx_PyInt_AsInt(values[1]); if (unlikely((__pyx_v_end == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 388; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_value = values[2];
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("insert", 0, 2, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 388; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.intervals.intersection.IntervalTree.insert", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_9intervals_12intersection_12IntervalTree_2insert(((struct __pyx_obj_2bx_9intervals_12intersection_IntervalTree *)__pyx_v_self), __pyx_v_start, __pyx_v_end, __pyx_v_value);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_2bx_9intervals_12intersection_12IntervalTree_2insert(struct __pyx_obj_2bx_9intervals_12intersection_IntervalTree *__pyx_v_self, int __pyx_v_start, int __pyx_v_end, PyObject *__pyx_v_value) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("insert", 0);
+
+  /* "bx/intervals/intersection.pyx":392
+ *         Insert the interval [start,end) associated with value `value`.
+ *         """
+ *         if self.root is None:             # <<<<<<<<<<<<<<
+ *             self.root = IntervalNode( start, end, value )
+ *         else:
+ */
+  __pyx_t_1 = (((PyObject *)__pyx_v_self->root) == Py_None);
+  if (__pyx_t_1) {
+
+    /* "bx/intervals/intersection.pyx":393
+ *         """
+ *         if self.root is None:
+ *             self.root = IntervalNode( start, end, value )             # <<<<<<<<<<<<<<
+ *         else:
+ *             self.root = self.root.insert( start, end, value )
+ */
+    __pyx_t_2 = PyInt_FromLong(__pyx_v_start); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 393; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_t_3 = PyInt_FromLong(__pyx_v_end); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 393; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __pyx_t_4 = PyTuple_New(3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 393; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_2);
+    __Pyx_GIVEREF(__pyx_t_2);
+    PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_3);
+    __Pyx_GIVEREF(__pyx_t_3);
+    __Pyx_INCREF(__pyx_v_value);
+    PyTuple_SET_ITEM(__pyx_t_4, 2, __pyx_v_value);
+    __Pyx_GIVEREF(__pyx_v_value);
+    __pyx_t_2 = 0;
+    __pyx_t_3 = 0;
+    __pyx_t_3 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_2bx_9intervals_12intersection_IntervalNode)), ((PyObject *)__pyx_t_4), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 393; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
+    __Pyx_GIVEREF(__pyx_t_3);
+    __Pyx_GOTREF(__pyx_v_self->root);
+    __Pyx_DECREF(((PyObject *)__pyx_v_self->root));
+    __pyx_v_self->root = ((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)__pyx_t_3);
+    __pyx_t_3 = 0;
+    goto __pyx_L3;
+  }
+  /*else*/ {
+
+    /* "bx/intervals/intersection.pyx":395
+ *             self.root = IntervalNode( start, end, value )
+ *         else:
+ *             self.root = self.root.insert( start, end, value )             # <<<<<<<<<<<<<<
+ * 
+ *     add = insert
+ */
+    __pyx_t_3 = ((PyObject *)((struct __pyx_vtabstruct_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self->root->__pyx_vtab)->insert(__pyx_v_self->root, __pyx_v_start, __pyx_v_end, __pyx_v_value, 0)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 395; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_GIVEREF(__pyx_t_3);
+    __Pyx_GOTREF(__pyx_v_self->root);
+    __Pyx_DECREF(((PyObject *)__pyx_v_self->root));
+    __pyx_v_self->root = ((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)__pyx_t_3);
+    __pyx_t_3 = 0;
+  }
+  __pyx_L3:;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_AddTraceback("bx.intervals.intersection.IntervalTree.insert", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_9intervals_12intersection_12IntervalTree_5find(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_2bx_9intervals_12intersection_12IntervalTree_4find[] = "\n        Return a sorted list of all intervals overlapping [start,end).\n        ";
+static PyObject *__pyx_pw_2bx_9intervals_12intersection_12IntervalTree_5find(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_start = 0;
+  PyObject *__pyx_v_end = 0;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("find (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__start,&__pyx_n_s__end,0};
+    PyObject* values[2] = {0,0};
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__start)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__end)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("find", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 400; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "find") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 400; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
+      goto __pyx_L5_argtuple_error;
+    } else {
+      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+    }
+    __pyx_v_start = values[0];
+    __pyx_v_end = values[1];
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("find", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 400; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.intervals.intersection.IntervalTree.find", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_9intervals_12intersection_12IntervalTree_4find(((struct __pyx_obj_2bx_9intervals_12intersection_IntervalTree *)__pyx_v_self), __pyx_v_start, __pyx_v_end);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/intervals/intersection.pyx":400
+ * 
+ * 
+ *     def find( self, start, end ):             # <<<<<<<<<<<<<<
+ *         """
+ *         Return a sorted list of all intervals overlapping [start,end).
+ */
+
+static PyObject *__pyx_pf_2bx_9intervals_12intersection_12IntervalTree_4find(struct __pyx_obj_2bx_9intervals_12intersection_IntervalTree *__pyx_v_self, PyObject *__pyx_v_start, PyObject *__pyx_v_end) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("find", 0);
+
+  /* "bx/intervals/intersection.pyx":404
+ *         Return a sorted list of all intervals overlapping [start,end).
+ *         """
+ *         if self.root is None:             # <<<<<<<<<<<<<<
+ *             return []
+ *         return self.root.find( start, end )
+ */
+  __pyx_t_1 = (((PyObject *)__pyx_v_self->root) == Py_None);
+  if (__pyx_t_1) {
+
+    /* "bx/intervals/intersection.pyx":405
+ *         """
+ *         if self.root is None:
+ *             return []             # <<<<<<<<<<<<<<
+ *         return self.root.find( start, end )
+ * 
+ */
+    __Pyx_XDECREF(__pyx_r);
+    __pyx_t_2 = PyList_New(0); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 405; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_r = ((PyObject *)__pyx_t_2);
+    __pyx_t_2 = 0;
+    goto __pyx_L0;
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  /* "bx/intervals/intersection.pyx":406
+ *         if self.root is None:
+ *             return []
+ *         return self.root.find( start, end )             # <<<<<<<<<<<<<<
+ * 
+ *     def before( self, position, num_intervals=1, max_dist=2500 ):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_2 = PyObject_GetAttr(((PyObject *)__pyx_v_self->root), __pyx_n_s__find); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 406; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 406; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_INCREF(__pyx_v_start);
+  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_start);
+  __Pyx_GIVEREF(__pyx_v_start);
+  __Pyx_INCREF(__pyx_v_end);
+  PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_v_end);
+  __Pyx_GIVEREF(__pyx_v_end);
+  __pyx_t_4 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 406; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
+  __pyx_r = __pyx_t_4;
+  __pyx_t_4 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_AddTraceback("bx.intervals.intersection.IntervalTree.find", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_9intervals_12intersection_12IntervalTree_7before(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_2bx_9intervals_12intersection_12IntervalTree_6before[] = "\n        Find `num_intervals` intervals that lie before `position` and are no\n        further than `max_dist` positions away\n        ";
+static PyObject *__pyx_pw_2bx_9intervals_12intersection_12IntervalTree_7before(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_position = 0;
+  PyObject *__pyx_v_num_intervals = 0;
+  PyObject *__pyx_v_max_dist = 0;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("before (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__position,&__pyx_n_s__num_intervals,&__pyx_n_s__max_dist,0};
+    PyObject* values[3] = {0,0,0};
+    values[1] = ((PyObject *)__pyx_int_1);
+    values[2] = ((PyObject *)__pyx_int_2500);
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__position)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s__num_intervals);
+          if (value) { values[1] = value; kw_args--; }
+        }
+        case  2:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s__max_dist);
+          if (value) { values[2] = value; kw_args--; }
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "before") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 408; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else {
+      switch (PyTuple_GET_SIZE(__pyx_args)) {
+        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+    }
+    __pyx_v_position = values[0];
+    __pyx_v_num_intervals = values[1];
+    __pyx_v_max_dist = values[2];
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("before", 0, 1, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 408; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.intervals.intersection.IntervalTree.before", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_9intervals_12intersection_12IntervalTree_6before(((struct __pyx_obj_2bx_9intervals_12intersection_IntervalTree *)__pyx_v_self), __pyx_v_position, __pyx_v_num_intervals, __pyx_v_max_dist);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/intervals/intersection.pyx":408
+ *         return self.root.find( start, end )
+ * 
+ *     def before( self, position, num_intervals=1, max_dist=2500 ):             # <<<<<<<<<<<<<<
+ *         """
+ *         Find `num_intervals` intervals that lie before `position` and are no
+ */
+
+static PyObject *__pyx_pf_2bx_9intervals_12intersection_12IntervalTree_6before(struct __pyx_obj_2bx_9intervals_12intersection_IntervalTree *__pyx_v_self, PyObject *__pyx_v_position, PyObject *__pyx_v_num_intervals, PyObject *__pyx_v_max_dist) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
+  int __pyx_t_3;
+  int __pyx_t_4;
+  struct __pyx_opt_args_2bx_9intervals_12intersection_12IntervalNode_left __pyx_t_5;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("before", 0);
+
+  /* "bx/intervals/intersection.pyx":413
+ *         further than `max_dist` positions away
+ *         """
+ *         if self.root is None:             # <<<<<<<<<<<<<<
+ *             return []
+ *         return self.root.left( position, num_intervals, max_dist )
+ */
+  __pyx_t_1 = (((PyObject *)__pyx_v_self->root) == Py_None);
+  if (__pyx_t_1) {
+
+    /* "bx/intervals/intersection.pyx":414
+ *         """
+ *         if self.root is None:
+ *             return []             # <<<<<<<<<<<<<<
+ *         return self.root.left( position, num_intervals, max_dist )
+ * 
+ */
+    __Pyx_XDECREF(__pyx_r);
+    __pyx_t_2 = PyList_New(0); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 414; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_r = ((PyObject *)__pyx_t_2);
+    __pyx_t_2 = 0;
+    goto __pyx_L0;
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  /* "bx/intervals/intersection.pyx":415
+ *         if self.root is None:
+ *             return []
+ *         return self.root.left( position, num_intervals, max_dist )             # <<<<<<<<<<<<<<
+ * 
+ *     def after( self, position, num_intervals=1, max_dist=2500 ):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_3 = __Pyx_PyInt_AsInt(__pyx_v_num_intervals); if (unlikely((__pyx_t_3 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 415; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_4 = __Pyx_PyInt_AsInt(__pyx_v_max_dist); if (unlikely((__pyx_t_4 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 415; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_5.__pyx_n = 2;
+  __pyx_t_5.n = __pyx_t_3;
+  __pyx_t_5.max_dist = __pyx_t_4;
+  __pyx_t_2 = ((struct __pyx_vtabstruct_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self->root->__pyx_vtab)->left(__pyx_v_self->root, __pyx_v_position, 0, &__pyx_t_5); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 415; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_r = __pyx_t_2;
+  __pyx_t_2 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_AddTraceback("bx.intervals.intersection.IntervalTree.before", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_9intervals_12intersection_12IntervalTree_9after(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_2bx_9intervals_12intersection_12IntervalTree_8after[] = "\n        Find `num_intervals` intervals that lie after `position` and are no\n        further than `max_dist` positions away\n        ";
+static PyObject *__pyx_pw_2bx_9intervals_12intersection_12IntervalTree_9after(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_position = 0;
+  PyObject *__pyx_v_num_intervals = 0;
+  PyObject *__pyx_v_max_dist = 0;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("after (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__position,&__pyx_n_s__num_intervals,&__pyx_n_s__max_dist,0};
+    PyObject* values[3] = {0,0,0};
+    values[1] = ((PyObject *)__pyx_int_1);
+    values[2] = ((PyObject *)__pyx_int_2500);
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__position)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s__num_intervals);
+          if (value) { values[1] = value; kw_args--; }
+        }
+        case  2:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s__max_dist);
+          if (value) { values[2] = value; kw_args--; }
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "after") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 417; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else {
+      switch (PyTuple_GET_SIZE(__pyx_args)) {
+        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+    }
+    __pyx_v_position = values[0];
+    __pyx_v_num_intervals = values[1];
+    __pyx_v_max_dist = values[2];
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("after", 0, 1, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 417; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.intervals.intersection.IntervalTree.after", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_9intervals_12intersection_12IntervalTree_8after(((struct __pyx_obj_2bx_9intervals_12intersection_IntervalTree *)__pyx_v_self), __pyx_v_position, __pyx_v_num_intervals, __pyx_v_max_dist);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/intervals/intersection.pyx":417
+ *         return self.root.left( position, num_intervals, max_dist )
+ * 
+ *     def after( self, position, num_intervals=1, max_dist=2500 ):             # <<<<<<<<<<<<<<
+ *         """
+ *         Find `num_intervals` intervals that lie after `position` and are no
+ */
+
+static PyObject *__pyx_pf_2bx_9intervals_12intersection_12IntervalTree_8after(struct __pyx_obj_2bx_9intervals_12intersection_IntervalTree *__pyx_v_self, PyObject *__pyx_v_position, PyObject *__pyx_v_num_intervals, PyObject *__pyx_v_max_dist) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
+  int __pyx_t_3;
+  int __pyx_t_4;
+  struct __pyx_opt_args_2bx_9intervals_12intersection_12IntervalNode_right __pyx_t_5;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("after", 0);
+
+  /* "bx/intervals/intersection.pyx":422
+ *         further than `max_dist` positions away
+ *         """
+ *         if self.root is None:             # <<<<<<<<<<<<<<
+ *             return []
+ *         return self.root.right( position, num_intervals, max_dist )
+ */
+  __pyx_t_1 = (((PyObject *)__pyx_v_self->root) == Py_None);
+  if (__pyx_t_1) {
+
+    /* "bx/intervals/intersection.pyx":423
+ *         """
+ *         if self.root is None:
+ *             return []             # <<<<<<<<<<<<<<
+ *         return self.root.right( position, num_intervals, max_dist )
+ * 
+ */
+    __Pyx_XDECREF(__pyx_r);
+    __pyx_t_2 = PyList_New(0); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 423; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_r = ((PyObject *)__pyx_t_2);
+    __pyx_t_2 = 0;
+    goto __pyx_L0;
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  /* "bx/intervals/intersection.pyx":424
+ *         if self.root is None:
+ *             return []
+ *         return self.root.right( position, num_intervals, max_dist )             # <<<<<<<<<<<<<<
+ * 
+ *     # ---- Interval-like object based interfaces -----------------------------
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_3 = __Pyx_PyInt_AsInt(__pyx_v_num_intervals); if (unlikely((__pyx_t_3 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 424; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_4 = __Pyx_PyInt_AsInt(__pyx_v_max_dist); if (unlikely((__pyx_t_4 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 424; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_5.__pyx_n = 2;
+  __pyx_t_5.n = __pyx_t_3;
+  __pyx_t_5.max_dist = __pyx_t_4;
+  __pyx_t_2 = ((struct __pyx_vtabstruct_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self->root->__pyx_vtab)->right(__pyx_v_self->root, __pyx_v_position, 0, &__pyx_t_5); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 424; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_r = __pyx_t_2;
+  __pyx_t_2 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_AddTraceback("bx.intervals.intersection.IntervalTree.after", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_9intervals_12intersection_12IntervalTree_11insert_interval(PyObject *__pyx_v_self, PyObject *__pyx_v_interval); /*proto*/
+static char __pyx_doc_2bx_9intervals_12intersection_12IntervalTree_10insert_interval[] = "\n        Insert an \"interval\" like object (one with at least start and end\n        attributes)\n        ";
+static PyObject *__pyx_pw_2bx_9intervals_12intersection_12IntervalTree_11insert_interval(PyObject *__pyx_v_self, PyObject *__pyx_v_interval) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("insert_interval (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_9intervals_12intersection_12IntervalTree_10insert_interval(((struct __pyx_obj_2bx_9intervals_12intersection_IntervalTree *)__pyx_v_self), ((PyObject *)__pyx_v_interval));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/intervals/intersection.pyx":428
+ *     # ---- Interval-like object based interfaces -----------------------------
+ * 
+ *     def insert_interval( self, interval ):             # <<<<<<<<<<<<<<
+ *         """
+ *         Insert an "interval" like object (one with at least start and end
+ */
+
+static PyObject *__pyx_pf_2bx_9intervals_12intersection_12IntervalTree_10insert_interval(struct __pyx_obj_2bx_9intervals_12intersection_IntervalTree *__pyx_v_self, PyObject *__pyx_v_interval) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("insert_interval", 0);
+
+  /* "bx/intervals/intersection.pyx":433
+ *         attributes)
+ *         """
+ *         self.insert( interval.start, interval.end, interval )             # <<<<<<<<<<<<<<
+ * 
+ *     add_interval = insert_interval
+ */
+  __pyx_t_1 = PyObject_GetAttr(((PyObject *)__pyx_v_self), __pyx_n_s__insert); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 433; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = PyObject_GetAttr(__pyx_v_interval, __pyx_n_s__start); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 433; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = PyObject_GetAttr(__pyx_v_interval, __pyx_n_s__end); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 433; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_4 = PyTuple_New(3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 433; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_2);
+  __Pyx_GIVEREF(__pyx_t_2);
+  PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_3);
+  __Pyx_GIVEREF(__pyx_t_3);
+  __Pyx_INCREF(__pyx_v_interval);
+  PyTuple_SET_ITEM(__pyx_t_4, 2, __pyx_v_interval);
+  __Pyx_GIVEREF(__pyx_v_interval);
+  __pyx_t_2 = 0;
+  __pyx_t_3 = 0;
+  __pyx_t_3 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_4), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 433; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_AddTraceback("bx.intervals.intersection.IntervalTree.insert_interval", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_9intervals_12intersection_12IntervalTree_13before_interval(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_2bx_9intervals_12intersection_12IntervalTree_12before_interval[] = "\n        Find `num_intervals` intervals that lie completely before `interval`\n        and are no further than `max_dist` positions away\n        ";
+static PyObject *__pyx_pw_2bx_9intervals_12intersection_12IntervalTree_13before_interval(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_interval = 0;
+  PyObject *__pyx_v_num_intervals = 0;
+  PyObject *__pyx_v_max_dist = 0;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("before_interval (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__interval,&__pyx_n_s__num_intervals,&__pyx_n_s__max_dist,0};
+    PyObject* values[3] = {0,0,0};
+    values[1] = ((PyObject *)__pyx_int_1);
+    values[2] = ((PyObject *)__pyx_int_2500);
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__interval)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s__num_intervals);
+          if (value) { values[1] = value; kw_args--; }
+        }
+        case  2:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s__max_dist);
+          if (value) { values[2] = value; kw_args--; }
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "before_interval") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 437; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else {
+      switch (PyTuple_GET_SIZE(__pyx_args)) {
+        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+    }
+    __pyx_v_interval = values[0];
+    __pyx_v_num_intervals = values[1];
+    __pyx_v_max_dist = values[2];
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("before_interval", 0, 1, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 437; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.intervals.intersection.IntervalTree.before_interval", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_9intervals_12intersection_12IntervalTree_12before_interval(((struct __pyx_obj_2bx_9intervals_12intersection_IntervalTree *)__pyx_v_self), __pyx_v_interval, __pyx_v_num_intervals, __pyx_v_max_dist);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/intervals/intersection.pyx":437
+ *     add_interval = insert_interval
+ * 
+ *     def before_interval( self, interval, num_intervals=1, max_dist=2500 ):             # <<<<<<<<<<<<<<
+ *         """
+ *         Find `num_intervals` intervals that lie completely before `interval`
+ */
+
+static PyObject *__pyx_pf_2bx_9intervals_12intersection_12IntervalTree_12before_interval(struct __pyx_obj_2bx_9intervals_12intersection_IntervalTree *__pyx_v_self, PyObject *__pyx_v_interval, PyObject *__pyx_v_num_intervals, PyObject *__pyx_v_max_dist) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
+  int __pyx_t_3;
+  int __pyx_t_4;
+  PyObject *__pyx_t_5 = NULL;
+  struct __pyx_opt_args_2bx_9intervals_12intersection_12IntervalNode_left __pyx_t_6;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("before_interval", 0);
+
+  /* "bx/intervals/intersection.pyx":442
+ *         and are no further than `max_dist` positions away
+ *         """
+ *         if self.root is None:             # <<<<<<<<<<<<<<
+ *             return []
+ *         return self.root.left( interval.start, num_intervals, max_dist )
+ */
+  __pyx_t_1 = (((PyObject *)__pyx_v_self->root) == Py_None);
+  if (__pyx_t_1) {
+
+    /* "bx/intervals/intersection.pyx":443
+ *         """
+ *         if self.root is None:
+ *             return []             # <<<<<<<<<<<<<<
+ *         return self.root.left( interval.start, num_intervals, max_dist )
+ * 
+ */
+    __Pyx_XDECREF(__pyx_r);
+    __pyx_t_2 = PyList_New(0); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 443; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_r = ((PyObject *)__pyx_t_2);
+    __pyx_t_2 = 0;
+    goto __pyx_L0;
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  /* "bx/intervals/intersection.pyx":444
+ *         if self.root is None:
+ *             return []
+ *         return self.root.left( interval.start, num_intervals, max_dist )             # <<<<<<<<<<<<<<
+ * 
+ *     def after_interval( self, interval, num_intervals=1, max_dist=2500 ):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_2 = PyObject_GetAttr(__pyx_v_interval, __pyx_n_s__start); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 444; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = __Pyx_PyInt_AsInt(__pyx_v_num_intervals); if (unlikely((__pyx_t_3 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 444; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_4 = __Pyx_PyInt_AsInt(__pyx_v_max_dist); if (unlikely((__pyx_t_4 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 444; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_6.__pyx_n = 2;
+  __pyx_t_6.n = __pyx_t_3;
+  __pyx_t_6.max_dist = __pyx_t_4;
+  __pyx_t_5 = ((struct __pyx_vtabstruct_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self->root->__pyx_vtab)->left(__pyx_v_self->root, __pyx_t_2, 0, &__pyx_t_6); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 444; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_r = __pyx_t_5;
+  __pyx_t_5 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_5);
+  __Pyx_AddTraceback("bx.intervals.intersection.IntervalTree.before_interval", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_9intervals_12intersection_12IntervalTree_15after_interval(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_2bx_9intervals_12intersection_12IntervalTree_14after_interval[] = "\n        Find `num_intervals` intervals that lie completely after `interval` and\n        are no further than `max_dist` positions away\n        ";
+static PyObject *__pyx_pw_2bx_9intervals_12intersection_12IntervalTree_15after_interval(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_interval = 0;
+  PyObject *__pyx_v_num_intervals = 0;
+  PyObject *__pyx_v_max_dist = 0;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("after_interval (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__interval,&__pyx_n_s__num_intervals,&__pyx_n_s__max_dist,0};
+    PyObject* values[3] = {0,0,0};
+    values[1] = ((PyObject *)__pyx_int_1);
+    values[2] = ((PyObject *)__pyx_int_2500);
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__interval)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s__num_intervals);
+          if (value) { values[1] = value; kw_args--; }
+        }
+        case  2:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s__max_dist);
+          if (value) { values[2] = value; kw_args--; }
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "after_interval") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 446; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else {
+      switch (PyTuple_GET_SIZE(__pyx_args)) {
+        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+    }
+    __pyx_v_interval = values[0];
+    __pyx_v_num_intervals = values[1];
+    __pyx_v_max_dist = values[2];
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("after_interval", 0, 1, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 446; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.intervals.intersection.IntervalTree.after_interval", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_9intervals_12intersection_12IntervalTree_14after_interval(((struct __pyx_obj_2bx_9intervals_12intersection_IntervalTree *)__pyx_v_self), __pyx_v_interval, __pyx_v_num_intervals, __pyx_v_max_dist);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/intervals/intersection.pyx":446
+ *         return self.root.left( interval.start, num_intervals, max_dist )
+ * 
+ *     def after_interval( self, interval, num_intervals=1, max_dist=2500 ):             # <<<<<<<<<<<<<<
+ *         """
+ *         Find `num_intervals` intervals that lie completely after `interval` and
+ */
+
+static PyObject *__pyx_pf_2bx_9intervals_12intersection_12IntervalTree_14after_interval(struct __pyx_obj_2bx_9intervals_12intersection_IntervalTree *__pyx_v_self, PyObject *__pyx_v_interval, PyObject *__pyx_v_num_intervals, PyObject *__pyx_v_max_dist) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
+  int __pyx_t_3;
+  int __pyx_t_4;
+  PyObject *__pyx_t_5 = NULL;
+  struct __pyx_opt_args_2bx_9intervals_12intersection_12IntervalNode_right __pyx_t_6;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("after_interval", 0);
+
+  /* "bx/intervals/intersection.pyx":451
+ *         are no further than `max_dist` positions away
+ *         """
+ *         if self.root is None:             # <<<<<<<<<<<<<<
+ *             return []
+ *         return self.root.right( interval.end, num_intervals, max_dist )
+ */
+  __pyx_t_1 = (((PyObject *)__pyx_v_self->root) == Py_None);
+  if (__pyx_t_1) {
+
+    /* "bx/intervals/intersection.pyx":452
+ *         """
+ *         if self.root is None:
+ *             return []             # <<<<<<<<<<<<<<
+ *         return self.root.right( interval.end, num_intervals, max_dist )
+ * 
+ */
+    __Pyx_XDECREF(__pyx_r);
+    __pyx_t_2 = PyList_New(0); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 452; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_r = ((PyObject *)__pyx_t_2);
+    __pyx_t_2 = 0;
+    goto __pyx_L0;
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  /* "bx/intervals/intersection.pyx":453
+ *         if self.root is None:
+ *             return []
+ *         return self.root.right( interval.end, num_intervals, max_dist )             # <<<<<<<<<<<<<<
+ * 
+ *     def upstream_of_interval( self, interval, num_intervals=1, max_dist=2500 ):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_2 = PyObject_GetAttr(__pyx_v_interval, __pyx_n_s__end); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 453; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = __Pyx_PyInt_AsInt(__pyx_v_num_intervals); if (unlikely((__pyx_t_3 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 453; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_4 = __Pyx_PyInt_AsInt(__pyx_v_max_dist); if (unlikely((__pyx_t_4 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 453; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_6.__pyx_n = 2;
+  __pyx_t_6.n = __pyx_t_3;
+  __pyx_t_6.max_dist = __pyx_t_4;
+  __pyx_t_5 = ((struct __pyx_vtabstruct_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self->root->__pyx_vtab)->right(__pyx_v_self->root, __pyx_t_2, 0, &__pyx_t_6); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 453; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_r = __pyx_t_5;
+  __pyx_t_5 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_5);
+  __Pyx_AddTraceback("bx.intervals.intersection.IntervalTree.after_interval", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_9intervals_12intersection_12IntervalTree_17upstream_of_interval(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_2bx_9intervals_12intersection_12IntervalTree_16upstream_of_interval[] = "\n        Find `num_intervals` intervals that lie completely upstream of\n        `interval` and are no further than `max_dist` positions away\n        ";
+static PyObject *__pyx_pw_2bx_9intervals_12intersection_12IntervalTree_17upstream_of_interval(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_interval = 0;
+  PyObject *__pyx_v_num_intervals = 0;
+  PyObject *__pyx_v_max_dist = 0;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("upstream_of_interval (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__interval,&__pyx_n_s__num_intervals,&__pyx_n_s__max_dist,0};
+    PyObject* values[3] = {0,0,0};
+    values[1] = ((PyObject *)__pyx_int_1);
+    values[2] = ((PyObject *)__pyx_int_2500);
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__interval)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s__num_intervals);
+          if (value) { values[1] = value; kw_args--; }
+        }
+        case  2:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s__max_dist);
+          if (value) { values[2] = value; kw_args--; }
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "upstream_of_interval") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 455; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else {
+      switch (PyTuple_GET_SIZE(__pyx_args)) {
+        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+    }
+    __pyx_v_interval = values[0];
+    __pyx_v_num_intervals = values[1];
+    __pyx_v_max_dist = values[2];
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("upstream_of_interval", 0, 1, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 455; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.intervals.intersection.IntervalTree.upstream_of_interval", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_9intervals_12intersection_12IntervalTree_16upstream_of_interval(((struct __pyx_obj_2bx_9intervals_12intersection_IntervalTree *)__pyx_v_self), __pyx_v_interval, __pyx_v_num_intervals, __pyx_v_max_dist);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/intervals/intersection.pyx":455
+ *         return self.root.right( interval.end, num_intervals, max_dist )
+ * 
+ *     def upstream_of_interval( self, interval, num_intervals=1, max_dist=2500 ):             # <<<<<<<<<<<<<<
+ *         """
+ *         Find `num_intervals` intervals that lie completely upstream of
+ */
+
+static PyObject *__pyx_pf_2bx_9intervals_12intersection_12IntervalTree_16upstream_of_interval(struct __pyx_obj_2bx_9intervals_12intersection_IntervalTree *__pyx_v_self, PyObject *__pyx_v_interval, PyObject *__pyx_v_num_intervals, PyObject *__pyx_v_max_dist) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  int __pyx_t_4;
+  int __pyx_t_5;
+  int __pyx_t_6;
+  int __pyx_t_7;
+  struct __pyx_opt_args_2bx_9intervals_12intersection_12IntervalNode_right __pyx_t_8;
+  struct __pyx_opt_args_2bx_9intervals_12intersection_12IntervalNode_left __pyx_t_9;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("upstream_of_interval", 0);
+
+  /* "bx/intervals/intersection.pyx":460
+ *         `interval` and are no further than `max_dist` positions away
+ *         """
+ *         if self.root is None:             # <<<<<<<<<<<<<<
+ *             return []
+ *         if interval.strand == -1 or interval.strand == "-":
+ */
+  __pyx_t_1 = (((PyObject *)__pyx_v_self->root) == Py_None);
+  if (__pyx_t_1) {
+
+    /* "bx/intervals/intersection.pyx":461
+ *         """
+ *         if self.root is None:
+ *             return []             # <<<<<<<<<<<<<<
+ *         if interval.strand == -1 or interval.strand == "-":
+ *             return self.root.right( interval.end, num_intervals, max_dist )
+ */
+    __Pyx_XDECREF(__pyx_r);
+    __pyx_t_2 = PyList_New(0); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 461; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_r = ((PyObject *)__pyx_t_2);
+    __pyx_t_2 = 0;
+    goto __pyx_L0;
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  /* "bx/intervals/intersection.pyx":462
+ *         if self.root is None:
+ *             return []
+ *         if interval.strand == -1 or interval.strand == "-":             # <<<<<<<<<<<<<<
+ *             return self.root.right( interval.end, num_intervals, max_dist )
+ *         else:
+ */
+  __pyx_t_2 = PyObject_GetAttr(__pyx_v_interval, __pyx_n_s__strand); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = PyObject_RichCompare(__pyx_t_2, __pyx_int_neg_1, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  if (!__pyx_t_1) {
+    __pyx_t_3 = PyObject_GetAttr(__pyx_v_interval, __pyx_n_s__strand); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __pyx_t_2 = PyObject_RichCompare(__pyx_t_3, ((PyObject *)__pyx_kp_s_9), Py_EQ); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    __pyx_t_5 = __pyx_t_4;
+  } else {
+    __pyx_t_5 = __pyx_t_1;
+  }
+  if (__pyx_t_5) {
+
+    /* "bx/intervals/intersection.pyx":463
+ *             return []
+ *         if interval.strand == -1 or interval.strand == "-":
+ *             return self.root.right( interval.end, num_intervals, max_dist )             # <<<<<<<<<<<<<<
+ *         else:
+ *             return self.root.left( interval.start, num_intervals, max_dist )
+ */
+    __Pyx_XDECREF(__pyx_r);
+    __pyx_t_2 = PyObject_GetAttr(__pyx_v_interval, __pyx_n_s__end); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 463; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_t_6 = __Pyx_PyInt_AsInt(__pyx_v_num_intervals); if (unlikely((__pyx_t_6 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 463; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_7 = __Pyx_PyInt_AsInt(__pyx_v_max_dist); if (unlikely((__pyx_t_7 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 463; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_8.__pyx_n = 2;
+    __pyx_t_8.n = __pyx_t_6;
+    __pyx_t_8.max_dist = __pyx_t_7;
+    __pyx_t_3 = ((struct __pyx_vtabstruct_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self->root->__pyx_vtab)->right(__pyx_v_self->root, __pyx_t_2, 0, &__pyx_t_8); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 463; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    __pyx_r = __pyx_t_3;
+    __pyx_t_3 = 0;
+    goto __pyx_L0;
+    goto __pyx_L4;
+  }
+  /*else*/ {
+
+    /* "bx/intervals/intersection.pyx":465
+ *             return self.root.right( interval.end, num_intervals, max_dist )
+ *         else:
+ *             return self.root.left( interval.start, num_intervals, max_dist )             # <<<<<<<<<<<<<<
+ * 
+ *     def downstream_of_interval( self, interval, num_intervals=1, max_dist=2500 ):
+ */
+    __Pyx_XDECREF(__pyx_r);
+    __pyx_t_3 = PyObject_GetAttr(__pyx_v_interval, __pyx_n_s__start); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 465; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __pyx_t_7 = __Pyx_PyInt_AsInt(__pyx_v_num_intervals); if (unlikely((__pyx_t_7 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 465; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_6 = __Pyx_PyInt_AsInt(__pyx_v_max_dist); if (unlikely((__pyx_t_6 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 465; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_9.__pyx_n = 2;
+    __pyx_t_9.n = __pyx_t_7;
+    __pyx_t_9.max_dist = __pyx_t_6;
+    __pyx_t_2 = ((struct __pyx_vtabstruct_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self->root->__pyx_vtab)->left(__pyx_v_self->root, __pyx_t_3, 0, &__pyx_t_9); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 465; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __pyx_r = __pyx_t_2;
+    __pyx_t_2 = 0;
+    goto __pyx_L0;
+  }
+  __pyx_L4:;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_AddTraceback("bx.intervals.intersection.IntervalTree.upstream_of_interval", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_9intervals_12intersection_12IntervalTree_19downstream_of_interval(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_2bx_9intervals_12intersection_12IntervalTree_18downstream_of_interval[] = "\n        Find `num_intervals` intervals that lie completely downstream of\n        `interval` and are no further than `max_dist` positions away\n        ";
+static PyObject *__pyx_pw_2bx_9intervals_12intersection_12IntervalTree_19downstream_of_interval(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_interval = 0;
+  PyObject *__pyx_v_num_intervals = 0;
+  PyObject *__pyx_v_max_dist = 0;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("downstream_of_interval (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__interval,&__pyx_n_s__num_intervals,&__pyx_n_s__max_dist,0};
+    PyObject* values[3] = {0,0,0};
+    values[1] = ((PyObject *)__pyx_int_1);
+    values[2] = ((PyObject *)__pyx_int_2500);
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__interval)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s__num_intervals);
+          if (value) { values[1] = value; kw_args--; }
+        }
+        case  2:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s__max_dist);
+          if (value) { values[2] = value; kw_args--; }
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "downstream_of_interval") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 467; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else {
+      switch (PyTuple_GET_SIZE(__pyx_args)) {
+        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+    }
+    __pyx_v_interval = values[0];
+    __pyx_v_num_intervals = values[1];
+    __pyx_v_max_dist = values[2];
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("downstream_of_interval", 0, 1, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 467; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.intervals.intersection.IntervalTree.downstream_of_interval", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_9intervals_12intersection_12IntervalTree_18downstream_of_interval(((struct __pyx_obj_2bx_9intervals_12intersection_IntervalTree *)__pyx_v_self), __pyx_v_interval, __pyx_v_num_intervals, __pyx_v_max_dist);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/intervals/intersection.pyx":467
+ *             return self.root.left( interval.start, num_intervals, max_dist )
+ * 
+ *     def downstream_of_interval( self, interval, num_intervals=1, max_dist=2500 ):             # <<<<<<<<<<<<<<
+ *         """
+ *         Find `num_intervals` intervals that lie completely downstream of
+ */
+
+static PyObject *__pyx_pf_2bx_9intervals_12intersection_12IntervalTree_18downstream_of_interval(struct __pyx_obj_2bx_9intervals_12intersection_IntervalTree *__pyx_v_self, PyObject *__pyx_v_interval, PyObject *__pyx_v_num_intervals, PyObject *__pyx_v_max_dist) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  int __pyx_t_4;
+  int __pyx_t_5;
+  int __pyx_t_6;
+  int __pyx_t_7;
+  struct __pyx_opt_args_2bx_9intervals_12intersection_12IntervalNode_left __pyx_t_8;
+  struct __pyx_opt_args_2bx_9intervals_12intersection_12IntervalNode_right __pyx_t_9;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("downstream_of_interval", 0);
+
+  /* "bx/intervals/intersection.pyx":472
+ *         `interval` and are no further than `max_dist` positions away
+ *         """
+ *         if self.root is None:             # <<<<<<<<<<<<<<
+ *             return []
+ *         if interval.strand == -1 or interval.strand == "-":
+ */
+  __pyx_t_1 = (((PyObject *)__pyx_v_self->root) == Py_None);
+  if (__pyx_t_1) {
+
+    /* "bx/intervals/intersection.pyx":473
+ *         """
+ *         if self.root is None:
+ *             return []             # <<<<<<<<<<<<<<
+ *         if interval.strand == -1 or interval.strand == "-":
+ *             return self.root.left( interval.start, num_intervals, max_dist )
+ */
+    __Pyx_XDECREF(__pyx_r);
+    __pyx_t_2 = PyList_New(0); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 473; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_r = ((PyObject *)__pyx_t_2);
+    __pyx_t_2 = 0;
+    goto __pyx_L0;
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  /* "bx/intervals/intersection.pyx":474
+ *         if self.root is None:
+ *             return []
+ *         if interval.strand == -1 or interval.strand == "-":             # <<<<<<<<<<<<<<
+ *             return self.root.left( interval.start, num_intervals, max_dist )
+ *         else:
+ */
+  __pyx_t_2 = PyObject_GetAttr(__pyx_v_interval, __pyx_n_s__strand); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 474; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = PyObject_RichCompare(__pyx_t_2, __pyx_int_neg_1, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 474; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 474; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  if (!__pyx_t_1) {
+    __pyx_t_3 = PyObject_GetAttr(__pyx_v_interval, __pyx_n_s__strand); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 474; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __pyx_t_2 = PyObject_RichCompare(__pyx_t_3, ((PyObject *)__pyx_kp_s_9), Py_EQ); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 474; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 474; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    __pyx_t_5 = __pyx_t_4;
+  } else {
+    __pyx_t_5 = __pyx_t_1;
+  }
+  if (__pyx_t_5) {
+
+    /* "bx/intervals/intersection.pyx":475
+ *             return []
+ *         if interval.strand == -1 or interval.strand == "-":
+ *             return self.root.left( interval.start, num_intervals, max_dist )             # <<<<<<<<<<<<<<
+ *         else:
+ *             return self.root.right( interval.end, num_intervals, max_dist )
+ */
+    __Pyx_XDECREF(__pyx_r);
+    __pyx_t_2 = PyObject_GetAttr(__pyx_v_interval, __pyx_n_s__start); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 475; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_t_6 = __Pyx_PyInt_AsInt(__pyx_v_num_intervals); if (unlikely((__pyx_t_6 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 475; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_7 = __Pyx_PyInt_AsInt(__pyx_v_max_dist); if (unlikely((__pyx_t_7 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 475; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_8.__pyx_n = 2;
+    __pyx_t_8.n = __pyx_t_6;
+    __pyx_t_8.max_dist = __pyx_t_7;
+    __pyx_t_3 = ((struct __pyx_vtabstruct_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self->root->__pyx_vtab)->left(__pyx_v_self->root, __pyx_t_2, 0, &__pyx_t_8); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 475; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    __pyx_r = __pyx_t_3;
+    __pyx_t_3 = 0;
+    goto __pyx_L0;
+    goto __pyx_L4;
+  }
+  /*else*/ {
+
+    /* "bx/intervals/intersection.pyx":477
+ *             return self.root.left( interval.start, num_intervals, max_dist )
+ *         else:
+ *             return self.root.right( interval.end, num_intervals, max_dist )             # <<<<<<<<<<<<<<
+ * 
+ *     def traverse(self, fn):
+ */
+    __Pyx_XDECREF(__pyx_r);
+    __pyx_t_3 = PyObject_GetAttr(__pyx_v_interval, __pyx_n_s__end); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 477; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __pyx_t_7 = __Pyx_PyInt_AsInt(__pyx_v_num_intervals); if (unlikely((__pyx_t_7 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 477; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_6 = __Pyx_PyInt_AsInt(__pyx_v_max_dist); if (unlikely((__pyx_t_6 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 477; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_9.__pyx_n = 2;
+    __pyx_t_9.n = __pyx_t_7;
+    __pyx_t_9.max_dist = __pyx_t_6;
+    __pyx_t_2 = ((struct __pyx_vtabstruct_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self->root->__pyx_vtab)->right(__pyx_v_self->root, __pyx_t_3, 0, &__pyx_t_9); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 477; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __pyx_r = __pyx_t_2;
+    __pyx_t_2 = 0;
+    goto __pyx_L0;
+  }
+  __pyx_L4:;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_AddTraceback("bx.intervals.intersection.IntervalTree.downstream_of_interval", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_9intervals_12intersection_12IntervalTree_21traverse(PyObject *__pyx_v_self, PyObject *__pyx_v_fn); /*proto*/
+static char __pyx_doc_2bx_9intervals_12intersection_12IntervalTree_20traverse[] = "\n        call fn for each element in the tree\n        ";
+static PyObject *__pyx_pw_2bx_9intervals_12intersection_12IntervalTree_21traverse(PyObject *__pyx_v_self, PyObject *__pyx_v_fn) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("traverse (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_9intervals_12intersection_12IntervalTree_20traverse(((struct __pyx_obj_2bx_9intervals_12intersection_IntervalTree *)__pyx_v_self), ((PyObject *)__pyx_v_fn));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/intervals/intersection.pyx":479
+ *             return self.root.right( interval.end, num_intervals, max_dist )
+ * 
+ *     def traverse(self, fn):             # <<<<<<<<<<<<<<
+ *         """
+ *         call fn for each element in the tree
+ */
+
+static PyObject *__pyx_pf_2bx_9intervals_12intersection_12IntervalTree_20traverse(struct __pyx_obj_2bx_9intervals_12intersection_IntervalTree *__pyx_v_self, PyObject *__pyx_v_fn) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("traverse", 0);
+
+  /* "bx/intervals/intersection.pyx":483
+ *         call fn for each element in the tree
+ *         """
+ *         if self.root is None:             # <<<<<<<<<<<<<<
+ *             return None
+ *         return self.root.traverse(fn)
+ */
+  __pyx_t_1 = (((PyObject *)__pyx_v_self->root) == Py_None);
+  if (__pyx_t_1) {
+
+    /* "bx/intervals/intersection.pyx":484
+ *         """
+ *         if self.root is None:
+ *             return None             # <<<<<<<<<<<<<<
+ *         return self.root.traverse(fn)
+ * 
+ */
+    __Pyx_XDECREF(__pyx_r);
+    __Pyx_INCREF(Py_None);
+    __pyx_r = Py_None;
+    goto __pyx_L0;
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  /* "bx/intervals/intersection.pyx":485
+ *         if self.root is None:
+ *             return None
+ *         return self.root.traverse(fn)             # <<<<<<<<<<<<<<
+ * 
+ * # For backward compatibility
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_2 = PyObject_GetAttr(((PyObject *)__pyx_v_self->root), __pyx_n_s__traverse); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 485; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 485; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_INCREF(__pyx_v_fn);
+  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_fn);
+  __Pyx_GIVEREF(__pyx_v_fn);
+  __pyx_t_4 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 485; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
+  __pyx_r = __pyx_t_4;
+  __pyx_t_4 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_AddTraceback("bx.intervals.intersection.IntervalTree.traverse", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+static struct __pyx_vtabstruct_2bx_9intervals_12intersection_IntervalNode __pyx_vtable_2bx_9intervals_12intersection_IntervalNode;
+
+static PyObject *__pyx_tp_new_2bx_9intervals_12intersection_IntervalNode(PyTypeObject *t, PyObject *a, PyObject *k) {
+  struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *p;
+  PyObject *o = (*t->tp_alloc)(t, 0);
+  if (!o) return 0;
+  p = ((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)o);
+  p->__pyx_vtab = __pyx_vtabptr_2bx_9intervals_12intersection_IntervalNode;
+  p->interval = Py_None; Py_INCREF(Py_None);
+  p->cleft = ((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)Py_None); Py_INCREF(Py_None);
+  p->cright = ((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)Py_None); Py_INCREF(Py_None);
+  p->croot = ((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)Py_None); Py_INCREF(Py_None);
+  if (__pyx_pw_2bx_9intervals_12intersection_12IntervalNode_3__cinit__(o, a, k) < 0) {
+    Py_DECREF(o); o = 0;
+  }
+  return o;
+}
+
+static void __pyx_tp_dealloc_2bx_9intervals_12intersection_IntervalNode(PyObject *o) {
+  struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *p = (struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)o;
+  PyObject_GC_UnTrack(o);
+  Py_CLEAR(p->interval);
+  Py_CLEAR(p->cleft);
+  Py_CLEAR(p->cright);
+  Py_CLEAR(p->croot);
+  PyObject_GC_Track(o);
+  (*Py_TYPE(o)->tp_free)(o);
+}
+
+static int __pyx_tp_traverse_2bx_9intervals_12intersection_IntervalNode(PyObject *o, visitproc v, void *a) {
+  int e;
+  struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *p = (struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)o;
+  if (p->interval) {
+    e = (*v)(p->interval, a); if (e) return e;
+  }
+  if (p->cleft) {
+    e = (*v)(((PyObject*)p->cleft), a); if (e) return e;
+  }
+  if (p->cright) {
+    e = (*v)(((PyObject*)p->cright), a); if (e) return e;
+  }
+  if (p->croot) {
+    e = (*v)(((PyObject*)p->croot), a); if (e) return e;
+  }
+  return 0;
+}
+
+static int __pyx_tp_clear_2bx_9intervals_12intersection_IntervalNode(PyObject *o) {
+  struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *p = (struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)o;
+  PyObject* tmp;
+  tmp = ((PyObject*)p->interval);
+  p->interval = Py_None; Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  tmp = ((PyObject*)p->cleft);
+  p->cleft = ((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)Py_None); Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  tmp = ((PyObject*)p->cright);
+  p->cright = ((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)Py_None); Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  tmp = ((PyObject*)p->croot);
+  p->croot = ((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)Py_None); Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  return 0;
+}
+
+static PyObject *__pyx_getprop_2bx_9intervals_12intersection_12IntervalNode_left_node(PyObject *o, CYTHON_UNUSED void *x) {
+  return __pyx_pw_2bx_9intervals_12intersection_12IntervalNode_9left_node_1__get__(o);
+}
+
+static PyObject *__pyx_getprop_2bx_9intervals_12intersection_12IntervalNode_right_node(PyObject *o, CYTHON_UNUSED void *x) {
+  return __pyx_pw_2bx_9intervals_12intersection_12IntervalNode_10right_node_1__get__(o);
+}
+
+static PyObject *__pyx_getprop_2bx_9intervals_12intersection_12IntervalNode_root_node(PyObject *o, CYTHON_UNUSED void *x) {
+  return __pyx_pw_2bx_9intervals_12intersection_12IntervalNode_9root_node_1__get__(o);
+}
+
+static PyObject *__pyx_getprop_2bx_9intervals_12intersection_12IntervalNode_interval(PyObject *o, CYTHON_UNUSED void *x) {
+  return __pyx_pw_2bx_9intervals_12intersection_12IntervalNode_8interval_1__get__(o);
+}
+
+static int __pyx_setprop_2bx_9intervals_12intersection_12IntervalNode_interval(PyObject *o, PyObject *v, CYTHON_UNUSED void *x) {
+  if (v) {
+    return __pyx_pw_2bx_9intervals_12intersection_12IntervalNode_8interval_3__set__(o, v);
+  }
+  else {
+    return __pyx_pw_2bx_9intervals_12intersection_12IntervalNode_8interval_5__del__(o);
+  }
+}
+
+static PyObject *__pyx_getprop_2bx_9intervals_12intersection_12IntervalNode_start(PyObject *o, CYTHON_UNUSED void *x) {
+  return __pyx_pw_2bx_9intervals_12intersection_12IntervalNode_5start_1__get__(o);
+}
+
+static int __pyx_setprop_2bx_9intervals_12intersection_12IntervalNode_start(PyObject *o, PyObject *v, CYTHON_UNUSED void *x) {
+  if (v) {
+    return __pyx_pw_2bx_9intervals_12intersection_12IntervalNode_5start_3__set__(o, v);
+  }
+  else {
+    PyErr_SetString(PyExc_NotImplementedError, "__del__");
+    return -1;
+  }
+}
+
+static PyObject *__pyx_getprop_2bx_9intervals_12intersection_12IntervalNode_end(PyObject *o, CYTHON_UNUSED void *x) {
+  return __pyx_pw_2bx_9intervals_12intersection_12IntervalNode_3end_1__get__(o);
+}
+
+static int __pyx_setprop_2bx_9intervals_12intersection_12IntervalNode_end(PyObject *o, PyObject *v, CYTHON_UNUSED void *x) {
+  if (v) {
+    return __pyx_pw_2bx_9intervals_12intersection_12IntervalNode_3end_3__set__(o, v);
+  }
+  else {
+    PyErr_SetString(PyExc_NotImplementedError, "__del__");
+    return -1;
+  }
+}
+
+static PyMethodDef __pyx_methods_2bx_9intervals_12intersection_IntervalNode[] = {
+  {__Pyx_NAMESTR("insert"), (PyCFunction)__pyx_pw_2bx_9intervals_12intersection_12IntervalNode_5insert, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(__pyx_doc_2bx_9intervals_12intersection_12IntervalNode_4insert)},
+  {__Pyx_NAMESTR("intersect"), (PyCFunction)__pyx_pw_2bx_9intervals_12intersection_12IntervalNode_7intersect, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(__pyx_doc_2bx_9intervals_12intersection_12IntervalNode_6intersect)},
+  {__Pyx_NAMESTR("left"), (PyCFunction)__pyx_pw_2bx_9intervals_12intersection_12IntervalNode_9left, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(__pyx_doc_2bx_9intervals_12intersection_12IntervalNode_8left)},
+  {__Pyx_NAMESTR("right"), (PyCFunction)__pyx_pw_2bx_9intervals_12intersection_12IntervalNode_11right, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(__pyx_doc_2bx_9intervals_12intersection_12IntervalNode_10right)},
+  {__Pyx_NAMESTR("traverse"), (PyCFunction)__pyx_pw_2bx_9intervals_12intersection_12IntervalNode_13traverse, METH_O, __Pyx_DOCSTR(0)},
+  {0, 0, 0, 0}
+};
+
+static struct PyGetSetDef __pyx_getsets_2bx_9intervals_12intersection_IntervalNode[] = {
+  {(char *)"left_node", __pyx_getprop_2bx_9intervals_12intersection_12IntervalNode_left_node, 0, 0, 0},
+  {(char *)"right_node", __pyx_getprop_2bx_9intervals_12intersection_12IntervalNode_right_node, 0, 0, 0},
+  {(char *)"root_node", __pyx_getprop_2bx_9intervals_12intersection_12IntervalNode_root_node, 0, 0, 0},
+  {(char *)"interval", __pyx_getprop_2bx_9intervals_12intersection_12IntervalNode_interval, __pyx_setprop_2bx_9intervals_12intersection_12IntervalNode_interval, 0, 0},
+  {(char *)"start", __pyx_getprop_2bx_9intervals_12intersection_12IntervalNode_start, __pyx_setprop_2bx_9intervals_12intersection_12IntervalNode_start, 0, 0},
+  {(char *)"end", __pyx_getprop_2bx_9intervals_12intersection_12IntervalNode_end, __pyx_setprop_2bx_9intervals_12intersection_12IntervalNode_end, 0, 0},
+  {0, 0, 0, 0, 0}
+};
+
+static PyNumberMethods __pyx_tp_as_number_IntervalNode = {
+  0, /*nb_add*/
+  0, /*nb_subtract*/
+  0, /*nb_multiply*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_divide*/
+  #endif
+  0, /*nb_remainder*/
+  0, /*nb_divmod*/
+  0, /*nb_power*/
+  0, /*nb_negative*/
+  0, /*nb_positive*/
+  0, /*nb_absolute*/
+  0, /*nb_nonzero*/
+  0, /*nb_invert*/
+  0, /*nb_lshift*/
+  0, /*nb_rshift*/
+  0, /*nb_and*/
+  0, /*nb_xor*/
+  0, /*nb_or*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_coerce*/
+  #endif
+  0, /*nb_int*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_long*/
+  #else
+  0, /*reserved*/
+  #endif
+  0, /*nb_float*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_oct*/
+  #endif
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_hex*/
+  #endif
+  0, /*nb_inplace_add*/
+  0, /*nb_inplace_subtract*/
+  0, /*nb_inplace_multiply*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_inplace_divide*/
+  #endif
+  0, /*nb_inplace_remainder*/
+  0, /*nb_inplace_power*/
+  0, /*nb_inplace_lshift*/
+  0, /*nb_inplace_rshift*/
+  0, /*nb_inplace_and*/
+  0, /*nb_inplace_xor*/
+  0, /*nb_inplace_or*/
+  0, /*nb_floor_divide*/
+  0, /*nb_true_divide*/
+  0, /*nb_inplace_floor_divide*/
+  0, /*nb_inplace_true_divide*/
+  #if PY_VERSION_HEX >= 0x02050000
+  0, /*nb_index*/
+  #endif
+};
+
+static PySequenceMethods __pyx_tp_as_sequence_IntervalNode = {
+  0, /*sq_length*/
+  0, /*sq_concat*/
+  0, /*sq_repeat*/
+  0, /*sq_item*/
+  0, /*sq_slice*/
+  0, /*sq_ass_item*/
+  0, /*sq_ass_slice*/
+  0, /*sq_contains*/
+  0, /*sq_inplace_concat*/
+  0, /*sq_inplace_repeat*/
+};
+
+static PyMappingMethods __pyx_tp_as_mapping_IntervalNode = {
+  0, /*mp_length*/
+  0, /*mp_subscript*/
+  0, /*mp_ass_subscript*/
+};
+
+static PyBufferProcs __pyx_tp_as_buffer_IntervalNode = {
+  #if PY_MAJOR_VERSION < 3
+  0, /*bf_getreadbuffer*/
+  #endif
+  #if PY_MAJOR_VERSION < 3
+  0, /*bf_getwritebuffer*/
+  #endif
+  #if PY_MAJOR_VERSION < 3
+  0, /*bf_getsegcount*/
+  #endif
+  #if PY_MAJOR_VERSION < 3
+  0, /*bf_getcharbuffer*/
+  #endif
+  #if PY_VERSION_HEX >= 0x02060000
+  0, /*bf_getbuffer*/
+  #endif
+  #if PY_VERSION_HEX >= 0x02060000
+  0, /*bf_releasebuffer*/
+  #endif
+};
+
+static PyTypeObject __pyx_type_2bx_9intervals_12intersection_IntervalNode = {
+  PyVarObject_HEAD_INIT(0, 0)
+  __Pyx_NAMESTR("bx.intervals.intersection.IntervalNode"), /*tp_name*/
+  sizeof(struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode), /*tp_basicsize*/
+  0, /*tp_itemsize*/
+  __pyx_tp_dealloc_2bx_9intervals_12intersection_IntervalNode, /*tp_dealloc*/
+  0, /*tp_print*/
+  0, /*tp_getattr*/
+  0, /*tp_setattr*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*tp_compare*/
+  #else
+  0, /*reserved*/
+  #endif
+  __pyx_pw_2bx_9intervals_12intersection_12IntervalNode_1__repr__, /*tp_repr*/
+  &__pyx_tp_as_number_IntervalNode, /*tp_as_number*/
+  &__pyx_tp_as_sequence_IntervalNode, /*tp_as_sequence*/
+  &__pyx_tp_as_mapping_IntervalNode, /*tp_as_mapping*/
+  0, /*tp_hash*/
+  0, /*tp_call*/
+  0, /*tp_str*/
+  0, /*tp_getattro*/
+  0, /*tp_setattro*/
+  &__pyx_tp_as_buffer_IntervalNode, /*tp_as_buffer*/
+  Py_TPFLAGS_DEFAULT|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+  __Pyx_DOCSTR("\n    A single node of an `IntervalTree`.\n    \n    NOTE: Unless you really know what you are doing, you probably should us\n          `IntervalTree` rather than using this directly. \n    "), /*tp_doc*/
+  __pyx_tp_traverse_2bx_9intervals_12intersection_IntervalNode, /*tp_traverse*/
+  __pyx_tp_clear_2bx_9intervals_12intersection_IntervalNode, /*tp_clear*/
+  0, /*tp_richcompare*/
+  0, /*tp_weaklistoffset*/
+  0, /*tp_iter*/
+  0, /*tp_iternext*/
+  __pyx_methods_2bx_9intervals_12intersection_IntervalNode, /*tp_methods*/
+  0, /*tp_members*/
+  __pyx_getsets_2bx_9intervals_12intersection_IntervalNode, /*tp_getset*/
+  0, /*tp_base*/
+  0, /*tp_dict*/
+  0, /*tp_descr_get*/
+  0, /*tp_descr_set*/
+  0, /*tp_dictoffset*/
+  0, /*tp_init*/
+  0, /*tp_alloc*/
+  __pyx_tp_new_2bx_9intervals_12intersection_IntervalNode, /*tp_new*/
+  0, /*tp_free*/
+  0, /*tp_is_gc*/
+  0, /*tp_bases*/
+  0, /*tp_mro*/
+  0, /*tp_cache*/
+  0, /*tp_subclasses*/
+  0, /*tp_weaklist*/
+  0, /*tp_del*/
+  #if PY_VERSION_HEX >= 0x02060000
+  0, /*tp_version_tag*/
+  #endif
+};
+
+static PyObject *__pyx_tp_new_2bx_9intervals_12intersection_Interval(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) {
+  struct __pyx_obj_2bx_9intervals_12intersection_Interval *p;
+  PyObject *o = (*t->tp_alloc)(t, 0);
+  if (!o) return 0;
+  p = ((struct __pyx_obj_2bx_9intervals_12intersection_Interval *)o);
+  p->value = Py_None; Py_INCREF(Py_None);
+  p->chrom = Py_None; Py_INCREF(Py_None);
+  p->strand = Py_None; Py_INCREF(Py_None);
+  return o;
+}
+
+static void __pyx_tp_dealloc_2bx_9intervals_12intersection_Interval(PyObject *o) {
+  struct __pyx_obj_2bx_9intervals_12intersection_Interval *p = (struct __pyx_obj_2bx_9intervals_12intersection_Interval *)o;
+  PyObject_GC_UnTrack(o);
+  Py_CLEAR(p->value);
+  Py_CLEAR(p->chrom);
+  Py_CLEAR(p->strand);
+  PyObject_GC_Track(o);
+  (*Py_TYPE(o)->tp_free)(o);
+}
+
+static int __pyx_tp_traverse_2bx_9intervals_12intersection_Interval(PyObject *o, visitproc v, void *a) {
+  int e;
+  struct __pyx_obj_2bx_9intervals_12intersection_Interval *p = (struct __pyx_obj_2bx_9intervals_12intersection_Interval *)o;
+  if (p->value) {
+    e = (*v)(p->value, a); if (e) return e;
+  }
+  if (p->chrom) {
+    e = (*v)(p->chrom, a); if (e) return e;
+  }
+  if (p->strand) {
+    e = (*v)(p->strand, a); if (e) return e;
+  }
+  return 0;
+}
+
+static int __pyx_tp_clear_2bx_9intervals_12intersection_Interval(PyObject *o) {
+  struct __pyx_obj_2bx_9intervals_12intersection_Interval *p = (struct __pyx_obj_2bx_9intervals_12intersection_Interval *)o;
+  PyObject* tmp;
+  tmp = ((PyObject*)p->value);
+  p->value = Py_None; Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  tmp = ((PyObject*)p->chrom);
+  p->chrom = Py_None; Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  tmp = ((PyObject*)p->strand);
+  p->strand = Py_None; Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  return 0;
+}
+
+static PyObject *__pyx_getprop_2bx_9intervals_12intersection_8Interval_start(PyObject *o, CYTHON_UNUSED void *x) {
+  return __pyx_pw_2bx_9intervals_12intersection_8Interval_5start_1__get__(o);
+}
+
+static int __pyx_setprop_2bx_9intervals_12intersection_8Interval_start(PyObject *o, PyObject *v, CYTHON_UNUSED void *x) {
+  if (v) {
+    return __pyx_pw_2bx_9intervals_12intersection_8Interval_5start_3__set__(o, v);
+  }
+  else {
+    PyErr_SetString(PyExc_NotImplementedError, "__del__");
+    return -1;
+  }
+}
+
+static PyObject *__pyx_getprop_2bx_9intervals_12intersection_8Interval_end(PyObject *o, CYTHON_UNUSED void *x) {
+  return __pyx_pw_2bx_9intervals_12intersection_8Interval_3end_1__get__(o);
+}
+
+static int __pyx_setprop_2bx_9intervals_12intersection_8Interval_end(PyObject *o, PyObject *v, CYTHON_UNUSED void *x) {
+  if (v) {
+    return __pyx_pw_2bx_9intervals_12intersection_8Interval_3end_3__set__(o, v);
+  }
+  else {
+    PyErr_SetString(PyExc_NotImplementedError, "__del__");
+    return -1;
+  }
+}
+
+static PyObject *__pyx_getprop_2bx_9intervals_12intersection_8Interval_value(PyObject *o, CYTHON_UNUSED void *x) {
+  return __pyx_pw_2bx_9intervals_12intersection_8Interval_5value_1__get__(o);
+}
+
+static int __pyx_setprop_2bx_9intervals_12intersection_8Interval_value(PyObject *o, PyObject *v, CYTHON_UNUSED void *x) {
+  if (v) {
+    return __pyx_pw_2bx_9intervals_12intersection_8Interval_5value_3__set__(o, v);
+  }
+  else {
+    return __pyx_pw_2bx_9intervals_12intersection_8Interval_5value_5__del__(o);
+  }
+}
+
+static PyObject *__pyx_getprop_2bx_9intervals_12intersection_8Interval_chrom(PyObject *o, CYTHON_UNUSED void *x) {
+  return __pyx_pw_2bx_9intervals_12intersection_8Interval_5chrom_1__get__(o);
+}
+
+static int __pyx_setprop_2bx_9intervals_12intersection_8Interval_chrom(PyObject *o, PyObject *v, CYTHON_UNUSED void *x) {
+  if (v) {
+    return __pyx_pw_2bx_9intervals_12intersection_8Interval_5chrom_3__set__(o, v);
+  }
+  else {
+    return __pyx_pw_2bx_9intervals_12intersection_8Interval_5chrom_5__del__(o);
+  }
+}
+
+static PyObject *__pyx_getprop_2bx_9intervals_12intersection_8Interval_strand(PyObject *o, CYTHON_UNUSED void *x) {
+  return __pyx_pw_2bx_9intervals_12intersection_8Interval_6strand_1__get__(o);
+}
+
+static int __pyx_setprop_2bx_9intervals_12intersection_8Interval_strand(PyObject *o, PyObject *v, CYTHON_UNUSED void *x) {
+  if (v) {
+    return __pyx_pw_2bx_9intervals_12intersection_8Interval_6strand_3__set__(o, v);
+  }
+  else {
+    return __pyx_pw_2bx_9intervals_12intersection_8Interval_6strand_5__del__(o);
+  }
+}
+
+static PyMethodDef __pyx_methods_2bx_9intervals_12intersection_Interval[] = {
+  {0, 0, 0, 0}
+};
+
+static struct PyGetSetDef __pyx_getsets_2bx_9intervals_12intersection_Interval[] = {
+  {(char *)"start", __pyx_getprop_2bx_9intervals_12intersection_8Interval_start, __pyx_setprop_2bx_9intervals_12intersection_8Interval_start, 0, 0},
+  {(char *)"end", __pyx_getprop_2bx_9intervals_12intersection_8Interval_end, __pyx_setprop_2bx_9intervals_12intersection_8Interval_end, 0, 0},
+  {(char *)"value", __pyx_getprop_2bx_9intervals_12intersection_8Interval_value, __pyx_setprop_2bx_9intervals_12intersection_8Interval_value, 0, 0},
+  {(char *)"chrom", __pyx_getprop_2bx_9intervals_12intersection_8Interval_chrom, __pyx_setprop_2bx_9intervals_12intersection_8Interval_chrom, 0, 0},
+  {(char *)"strand", __pyx_getprop_2bx_9intervals_12intersection_8Interval_strand, __pyx_setprop_2bx_9intervals_12intersection_8Interval_strand, 0, 0},
+  {0, 0, 0, 0, 0}
+};
+
+static PyNumberMethods __pyx_tp_as_number_Interval = {
+  0, /*nb_add*/
+  0, /*nb_subtract*/
+  0, /*nb_multiply*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_divide*/
+  #endif
+  0, /*nb_remainder*/
+  0, /*nb_divmod*/
+  0, /*nb_power*/
+  0, /*nb_negative*/
+  0, /*nb_positive*/
+  0, /*nb_absolute*/
+  0, /*nb_nonzero*/
+  0, /*nb_invert*/
+  0, /*nb_lshift*/
+  0, /*nb_rshift*/
+  0, /*nb_and*/
+  0, /*nb_xor*/
+  0, /*nb_or*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_coerce*/
+  #endif
+  0, /*nb_int*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_long*/
+  #else
+  0, /*reserved*/
+  #endif
+  0, /*nb_float*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_oct*/
+  #endif
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_hex*/
+  #endif
+  0, /*nb_inplace_add*/
+  0, /*nb_inplace_subtract*/
+  0, /*nb_inplace_multiply*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_inplace_divide*/
+  #endif
+  0, /*nb_inplace_remainder*/
+  0, /*nb_inplace_power*/
+  0, /*nb_inplace_lshift*/
+  0, /*nb_inplace_rshift*/
+  0, /*nb_inplace_and*/
+  0, /*nb_inplace_xor*/
+  0, /*nb_inplace_or*/
+  0, /*nb_floor_divide*/
+  0, /*nb_true_divide*/
+  0, /*nb_inplace_floor_divide*/
+  0, /*nb_inplace_true_divide*/
+  #if PY_VERSION_HEX >= 0x02050000
+  0, /*nb_index*/
+  #endif
+};
+
+static PySequenceMethods __pyx_tp_as_sequence_Interval = {
+  0, /*sq_length*/
+  0, /*sq_concat*/
+  0, /*sq_repeat*/
+  0, /*sq_item*/
+  0, /*sq_slice*/
+  0, /*sq_ass_item*/
+  0, /*sq_ass_slice*/
+  0, /*sq_contains*/
+  0, /*sq_inplace_concat*/
+  0, /*sq_inplace_repeat*/
+};
+
+static PyMappingMethods __pyx_tp_as_mapping_Interval = {
+  0, /*mp_length*/
+  0, /*mp_subscript*/
+  0, /*mp_ass_subscript*/
+};
+
+static PyBufferProcs __pyx_tp_as_buffer_Interval = {
+  #if PY_MAJOR_VERSION < 3
+  0, /*bf_getreadbuffer*/
+  #endif
+  #if PY_MAJOR_VERSION < 3
+  0, /*bf_getwritebuffer*/
+  #endif
+  #if PY_MAJOR_VERSION < 3
+  0, /*bf_getsegcount*/
+  #endif
+  #if PY_MAJOR_VERSION < 3
+  0, /*bf_getcharbuffer*/
+  #endif
+  #if PY_VERSION_HEX >= 0x02060000
+  0, /*bf_getbuffer*/
+  #endif
+  #if PY_VERSION_HEX >= 0x02060000
+  0, /*bf_releasebuffer*/
+  #endif
+};
+
+static PyTypeObject __pyx_type_2bx_9intervals_12intersection_Interval = {
+  PyVarObject_HEAD_INIT(0, 0)
+  __Pyx_NAMESTR("bx.intervals.intersection.Interval"), /*tp_name*/
+  sizeof(struct __pyx_obj_2bx_9intervals_12intersection_Interval), /*tp_basicsize*/
+  0, /*tp_itemsize*/
+  __pyx_tp_dealloc_2bx_9intervals_12intersection_Interval, /*tp_dealloc*/
+  0, /*tp_print*/
+  0, /*tp_getattr*/
+  0, /*tp_setattr*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*tp_compare*/
+  #else
+  0, /*reserved*/
+  #endif
+  __pyx_pw_2bx_9intervals_12intersection_8Interval_3__repr__, /*tp_repr*/
+  &__pyx_tp_as_number_Interval, /*tp_as_number*/
+  &__pyx_tp_as_sequence_Interval, /*tp_as_sequence*/
+  &__pyx_tp_as_mapping_Interval, /*tp_as_mapping*/
+  0, /*tp_hash*/
+  0, /*tp_call*/
+  0, /*tp_str*/
+  0, /*tp_getattro*/
+  0, /*tp_setattro*/
+  &__pyx_tp_as_buffer_Interval, /*tp_as_buffer*/
+  Py_TPFLAGS_DEFAULT|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+  __Pyx_DOCSTR("\n    Basic feature, with required integer start and end properties.\n    Also accepts optional strand as +1 or -1 (used for up/downstream queries),\n    a name, and any arbitrary data is sent in on the info keyword argument\n\n    >>> from bx.intervals.intersection import Interval\n\n    >>> f1 = Interval(23, 36)\n    >>> f2 = Interval(34, 48, value={'chr':12, 'anno':'transposon'})\n    >>> f2\n    Interval(34, 48, value={'anno': 'transposon', 'chr': 12})\n\n    "), /*tp_doc*/
+  __pyx_tp_traverse_2bx_9intervals_12intersection_Interval, /*tp_traverse*/
+  __pyx_tp_clear_2bx_9intervals_12intersection_Interval, /*tp_clear*/
+  __pyx_pw_2bx_9intervals_12intersection_8Interval_5__richcmp__, /*tp_richcompare*/
+  0, /*tp_weaklistoffset*/
+  0, /*tp_iter*/
+  0, /*tp_iternext*/
+  __pyx_methods_2bx_9intervals_12intersection_Interval, /*tp_methods*/
+  0, /*tp_members*/
+  __pyx_getsets_2bx_9intervals_12intersection_Interval, /*tp_getset*/
+  0, /*tp_base*/
+  0, /*tp_dict*/
+  0, /*tp_descr_get*/
+  0, /*tp_descr_set*/
+  0, /*tp_dictoffset*/
+  __pyx_pw_2bx_9intervals_12intersection_8Interval_1__init__, /*tp_init*/
+  0, /*tp_alloc*/
+  __pyx_tp_new_2bx_9intervals_12intersection_Interval, /*tp_new*/
+  0, /*tp_free*/
+  0, /*tp_is_gc*/
+  0, /*tp_bases*/
+  0, /*tp_mro*/
+  0, /*tp_cache*/
+  0, /*tp_subclasses*/
+  0, /*tp_weaklist*/
+  0, /*tp_del*/
+  #if PY_VERSION_HEX >= 0x02060000
+  0, /*tp_version_tag*/
+  #endif
+};
+
+static PyObject *__pyx_tp_new_2bx_9intervals_12intersection_IntervalTree(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) {
+  struct __pyx_obj_2bx_9intervals_12intersection_IntervalTree *p;
+  PyObject *o = (*t->tp_alloc)(t, 0);
+  if (!o) return 0;
+  p = ((struct __pyx_obj_2bx_9intervals_12intersection_IntervalTree *)o);
+  p->root = ((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)Py_None); Py_INCREF(Py_None);
+  if (__pyx_pw_2bx_9intervals_12intersection_12IntervalTree_1__cinit__(o, __pyx_empty_tuple, NULL) < 0) {
+    Py_DECREF(o); o = 0;
+  }
+  return o;
+}
+
+static void __pyx_tp_dealloc_2bx_9intervals_12intersection_IntervalTree(PyObject *o) {
+  struct __pyx_obj_2bx_9intervals_12intersection_IntervalTree *p = (struct __pyx_obj_2bx_9intervals_12intersection_IntervalTree *)o;
+  PyObject_GC_UnTrack(o);
+  Py_CLEAR(p->root);
+  PyObject_GC_Track(o);
+  (*Py_TYPE(o)->tp_free)(o);
+}
+
+static int __pyx_tp_traverse_2bx_9intervals_12intersection_IntervalTree(PyObject *o, visitproc v, void *a) {
+  int e;
+  struct __pyx_obj_2bx_9intervals_12intersection_IntervalTree *p = (struct __pyx_obj_2bx_9intervals_12intersection_IntervalTree *)o;
+  if (p->root) {
+    e = (*v)(((PyObject*)p->root), a); if (e) return e;
+  }
+  return 0;
+}
+
+static int __pyx_tp_clear_2bx_9intervals_12intersection_IntervalTree(PyObject *o) {
+  struct __pyx_obj_2bx_9intervals_12intersection_IntervalTree *p = (struct __pyx_obj_2bx_9intervals_12intersection_IntervalTree *)o;
+  PyObject* tmp;
+  tmp = ((PyObject*)p->root);
+  p->root = ((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)Py_None); Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  return 0;
+}
+
+static PyMethodDef __pyx_methods_2bx_9intervals_12intersection_IntervalTree[] = {
+  {__Pyx_NAMESTR("insert"), (PyCFunction)__pyx_pw_2bx_9intervals_12intersection_12IntervalTree_3insert, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(__pyx_doc_2bx_9intervals_12intersection_12IntervalTree_2insert)},
+  {__Pyx_NAMESTR("find"), (PyCFunction)__pyx_pw_2bx_9intervals_12intersection_12IntervalTree_5find, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(__pyx_doc_2bx_9intervals_12intersection_12IntervalTree_4find)},
+  {__Pyx_NAMESTR("before"), (PyCFunction)__pyx_pw_2bx_9intervals_12intersection_12IntervalTree_7before, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(__pyx_doc_2bx_9intervals_12intersection_12IntervalTree_6before)},
+  {__Pyx_NAMESTR("after"), (PyCFunction)__pyx_pw_2bx_9intervals_12intersection_12IntervalTree_9after, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(__pyx_doc_2bx_9intervals_12intersection_12IntervalTree_8after)},
+  {__Pyx_NAMESTR("insert_interval"), (PyCFunction)__pyx_pw_2bx_9intervals_12intersection_12IntervalTree_11insert_interval, METH_O, __Pyx_DOCSTR(__pyx_doc_2bx_9intervals_12intersection_12IntervalTree_10insert_interval)},
+  {__Pyx_NAMESTR("before_interval"), (PyCFunction)__pyx_pw_2bx_9intervals_12intersection_12IntervalTree_13before_interval, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(__pyx_doc_2bx_9intervals_12intersection_12IntervalTree_12before_interval)},
+  {__Pyx_NAMESTR("after_interval"), (PyCFunction)__pyx_pw_2bx_9intervals_12intersection_12IntervalTree_15after_interval, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(__pyx_doc_2bx_9intervals_12intersection_12IntervalTree_14after_interval)},
+  {__Pyx_NAMESTR("upstream_of_interval"), (PyCFunction)__pyx_pw_2bx_9intervals_12intersection_12IntervalTree_17upstream_of_interval, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(__pyx_doc_2bx_9intervals_12intersection_12IntervalTree_16upstream_of_interval)},
+  {__Pyx_NAMESTR("downstream_of_interval"), (PyCFunction)__pyx_pw_2bx_9intervals_12intersection_12IntervalTree_19downstream_of_interval, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(__pyx_doc_2bx_9intervals_12intersection_12IntervalTree_18downstream_of_interval)},
+  {__Pyx_NAMESTR("traverse"), (PyCFunction)__pyx_pw_2bx_9intervals_12intersection_12IntervalTree_21traverse, METH_O, __Pyx_DOCSTR(__pyx_doc_2bx_9intervals_12intersection_12IntervalTree_20traverse)},
+  {0, 0, 0, 0}
+};
+
+static PyNumberMethods __pyx_tp_as_number_IntervalTree = {
+  0, /*nb_add*/
+  0, /*nb_subtract*/
+  0, /*nb_multiply*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_divide*/
+  #endif
+  0, /*nb_remainder*/
+  0, /*nb_divmod*/
+  0, /*nb_power*/
+  0, /*nb_negative*/
+  0, /*nb_positive*/
+  0, /*nb_absolute*/
+  0, /*nb_nonzero*/
+  0, /*nb_invert*/
+  0, /*nb_lshift*/
+  0, /*nb_rshift*/
+  0, /*nb_and*/
+  0, /*nb_xor*/
+  0, /*nb_or*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_coerce*/
+  #endif
+  0, /*nb_int*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_long*/
+  #else
+  0, /*reserved*/
+  #endif
+  0, /*nb_float*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_oct*/
+  #endif
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_hex*/
+  #endif
+  0, /*nb_inplace_add*/
+  0, /*nb_inplace_subtract*/
+  0, /*nb_inplace_multiply*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_inplace_divide*/
+  #endif
+  0, /*nb_inplace_remainder*/
+  0, /*nb_inplace_power*/
+  0, /*nb_inplace_lshift*/
+  0, /*nb_inplace_rshift*/
+  0, /*nb_inplace_and*/
+  0, /*nb_inplace_xor*/
+  0, /*nb_inplace_or*/
+  0, /*nb_floor_divide*/
+  0, /*nb_true_divide*/
+  0, /*nb_inplace_floor_divide*/
+  0, /*nb_inplace_true_divide*/
+  #if PY_VERSION_HEX >= 0x02050000
+  0, /*nb_index*/
+  #endif
+};
+
+static PySequenceMethods __pyx_tp_as_sequence_IntervalTree = {
+  0, /*sq_length*/
+  0, /*sq_concat*/
+  0, /*sq_repeat*/
+  0, /*sq_item*/
+  0, /*sq_slice*/
+  0, /*sq_ass_item*/
+  0, /*sq_ass_slice*/
+  0, /*sq_contains*/
+  0, /*sq_inplace_concat*/
+  0, /*sq_inplace_repeat*/
+};
+
+static PyMappingMethods __pyx_tp_as_mapping_IntervalTree = {
+  0, /*mp_length*/
+  0, /*mp_subscript*/
+  0, /*mp_ass_subscript*/
+};
+
+static PyBufferProcs __pyx_tp_as_buffer_IntervalTree = {
+  #if PY_MAJOR_VERSION < 3
+  0, /*bf_getreadbuffer*/
+  #endif
+  #if PY_MAJOR_VERSION < 3
+  0, /*bf_getwritebuffer*/
+  #endif
+  #if PY_MAJOR_VERSION < 3
+  0, /*bf_getsegcount*/
+  #endif
+  #if PY_MAJOR_VERSION < 3
+  0, /*bf_getcharbuffer*/
+  #endif
+  #if PY_VERSION_HEX >= 0x02060000
+  0, /*bf_getbuffer*/
+  #endif
+  #if PY_VERSION_HEX >= 0x02060000
+  0, /*bf_releasebuffer*/
+  #endif
+};
+
+static PyTypeObject __pyx_type_2bx_9intervals_12intersection_IntervalTree = {
+  PyVarObject_HEAD_INIT(0, 0)
+  __Pyx_NAMESTR("bx.intervals.intersection.IntervalTree"), /*tp_name*/
+  sizeof(struct __pyx_obj_2bx_9intervals_12intersection_IntervalTree), /*tp_basicsize*/
+  0, /*tp_itemsize*/
+  __pyx_tp_dealloc_2bx_9intervals_12intersection_IntervalTree, /*tp_dealloc*/
+  0, /*tp_print*/
+  0, /*tp_getattr*/
+  0, /*tp_setattr*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*tp_compare*/
+  #else
+  0, /*reserved*/
+  #endif
+  0, /*tp_repr*/
+  &__pyx_tp_as_number_IntervalTree, /*tp_as_number*/
+  &__pyx_tp_as_sequence_IntervalTree, /*tp_as_sequence*/
+  &__pyx_tp_as_mapping_IntervalTree, /*tp_as_mapping*/
+  0, /*tp_hash*/
+  0, /*tp_call*/
+  0, /*tp_str*/
+  0, /*tp_getattro*/
+  0, /*tp_setattro*/
+  &__pyx_tp_as_buffer_IntervalTree, /*tp_as_buffer*/
+  Py_TPFLAGS_DEFAULT|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+  __Pyx_DOCSTR("\n    Data structure for performing window intersect queries on a set of \n    of possibly overlapping 1d intervals.\n    \n    Usage\n    =====\n    \n    Create an empty IntervalTree\n    \n    >>> from bx.intervals.intersection import Interval, IntervalTree\n    >>> intersecter = IntervalTree()\n    \n    An interval is a start and end position and a value (possibly None).\n    You can add any object as an interval:\n    \n    >>> intersecter.insert( 0, 10, \"food\" )\ [...]
+  __pyx_tp_traverse_2bx_9intervals_12intersection_IntervalTree, /*tp_traverse*/
+  __pyx_tp_clear_2bx_9intervals_12intersection_IntervalTree, /*tp_clear*/
+  0, /*tp_richcompare*/
+  0, /*tp_weaklistoffset*/
+  0, /*tp_iter*/
+  0, /*tp_iternext*/
+  __pyx_methods_2bx_9intervals_12intersection_IntervalTree, /*tp_methods*/
+  0, /*tp_members*/
+  0, /*tp_getset*/
+  0, /*tp_base*/
+  0, /*tp_dict*/
+  0, /*tp_descr_get*/
+  0, /*tp_descr_set*/
+  0, /*tp_dictoffset*/
+  0, /*tp_init*/
+  0, /*tp_alloc*/
+  __pyx_tp_new_2bx_9intervals_12intersection_IntervalTree, /*tp_new*/
+  0, /*tp_free*/
+  0, /*tp_is_gc*/
+  0, /*tp_bases*/
+  0, /*tp_mro*/
+  0, /*tp_cache*/
+  0, /*tp_subclasses*/
+  0, /*tp_weaklist*/
+  0, /*tp_del*/
+  #if PY_VERSION_HEX >= 0x02060000
+  0, /*tp_version_tag*/
+  #endif
+};
+
+static PyMethodDef __pyx_methods[] = {
+  {0, 0, 0, 0}
+};
+
+#if PY_MAJOR_VERSION >= 3
+static struct PyModuleDef __pyx_moduledef = {
+  #if PY_VERSION_HEX < 0x03020000
+    { PyObject_HEAD_INIT(NULL) NULL, 0, NULL },
+  #else
+    PyModuleDef_HEAD_INIT,
+  #endif
+    __Pyx_NAMESTR("intersection"),
+    __Pyx_DOCSTR(__pyx_k_10), /* m_doc */
+    -1, /* m_size */
+    __pyx_methods /* m_methods */,
+    NULL, /* m_reload */
+    NULL, /* m_traverse */
+    NULL, /* m_clear */
+    NULL /* m_free */
+};
+#endif
+
+static __Pyx_StringTabEntry __pyx_string_tab[] = {
+  {&__pyx_kp_s_1, __pyx_k_1, sizeof(__pyx_k_1), 0, 0, 1, 0},
+  {&__pyx_kp_s_5, __pyx_k_5, sizeof(__pyx_k_5), 0, 0, 1, 0},
+  {&__pyx_kp_s_6, __pyx_k_6, sizeof(__pyx_k_6), 0, 0, 1, 0},
+  {&__pyx_kp_s_7, __pyx_k_7, sizeof(__pyx_k_7), 0, 0, 1, 0},
+  {&__pyx_kp_s_8, __pyx_k_8, sizeof(__pyx_k_8), 0, 0, 1, 0},
+  {&__pyx_kp_s_9, __pyx_k_9, sizeof(__pyx_k_9), 0, 0, 1, 0},
+  {&__pyx_n_s__Intersecter, __pyx_k__Intersecter, sizeof(__pyx_k__Intersecter), 0, 0, 1, 1},
+  {&__pyx_n_s____main__, __pyx_k____main__, sizeof(__pyx_k____main__), 0, 0, 1, 1},
+  {&__pyx_n_s____test__, __pyx_k____test__, sizeof(__pyx_k____test__), 0, 0, 1, 1},
+  {&__pyx_n_s__add, __pyx_k__add, sizeof(__pyx_k__add), 0, 0, 1, 1},
+  {&__pyx_n_s__add_interval, __pyx_k__add_interval, sizeof(__pyx_k__add_interval), 0, 0, 1, 1},
+  {&__pyx_n_s__attrgetter, __pyx_k__attrgetter, sizeof(__pyx_k__attrgetter), 0, 0, 1, 1},
+  {&__pyx_n_s__chrom, __pyx_k__chrom, sizeof(__pyx_k__chrom), 0, 0, 1, 1},
+  {&__pyx_n_s__end, __pyx_k__end, sizeof(__pyx_k__end), 0, 0, 1, 1},
+  {&__pyx_n_s__find, __pyx_k__find, sizeof(__pyx_k__find), 0, 0, 1, 1},
+  {&__pyx_n_s__insert, __pyx_k__insert, sizeof(__pyx_k__insert), 0, 0, 1, 1},
+  {&__pyx_n_s__insert_interval, __pyx_k__insert_interval, sizeof(__pyx_k__insert_interval), 0, 0, 1, 1},
+  {&__pyx_n_s__intersect, __pyx_k__intersect, sizeof(__pyx_k__intersect), 0, 0, 1, 1},
+  {&__pyx_n_s__interval, __pyx_k__interval, sizeof(__pyx_k__interval), 0, 0, 1, 1},
+  {&__pyx_n_s__key, __pyx_k__key, sizeof(__pyx_k__key), 0, 0, 1, 1},
+  {&__pyx_n_s__left, __pyx_k__left, sizeof(__pyx_k__left), 0, 0, 1, 1},
+  {&__pyx_n_s__max_dist, __pyx_k__max_dist, sizeof(__pyx_k__max_dist), 0, 0, 1, 1},
+  {&__pyx_n_s__n, __pyx_k__n, sizeof(__pyx_k__n), 0, 0, 1, 1},
+  {&__pyx_n_s__num_intervals, __pyx_k__num_intervals, sizeof(__pyx_k__num_intervals), 0, 0, 1, 1},
+  {&__pyx_n_s__operator, __pyx_k__operator, sizeof(__pyx_k__operator), 0, 0, 1, 1},
+  {&__pyx_n_s__position, __pyx_k__position, sizeof(__pyx_k__position), 0, 0, 1, 1},
+  {&__pyx_n_s__reverse, __pyx_k__reverse, sizeof(__pyx_k__reverse), 0, 0, 1, 1},
+  {&__pyx_n_s__right, __pyx_k__right, sizeof(__pyx_k__right), 0, 0, 1, 1},
+  {&__pyx_n_s__sort, __pyx_k__sort, sizeof(__pyx_k__sort), 0, 0, 1, 1},
+  {&__pyx_n_s__start, __pyx_k__start, sizeof(__pyx_k__start), 0, 0, 1, 1},
+  {&__pyx_n_s__strand, __pyx_k__strand, sizeof(__pyx_k__strand), 0, 0, 1, 1},
+  {&__pyx_n_s__traverse, __pyx_k__traverse, sizeof(__pyx_k__traverse), 0, 0, 1, 1},
+  {&__pyx_n_s__value, __pyx_k__value, sizeof(__pyx_k__value), 0, 0, 1, 1},
+  {0, 0, 0, 0, 0, 0, 0}
+};
+static int __Pyx_InitCachedBuiltins(void) {
+  return 0;
+}
+
+static int __Pyx_InitCachedConstants(void) {
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0);
+
+  /* "bx/intervals/intersection.pyx":243
+ *         if len(results) == n: return results
+ *         r = results
+ *         r.sort(key=operator.attrgetter('end'), reverse=True)             # <<<<<<<<<<<<<<
+ *         return r[:n]
+ * 
+ */
+  __pyx_k_tuple_3 = PyTuple_Pack(1, ((PyObject *)__pyx_n_s__end)); if (unlikely(!__pyx_k_tuple_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 243; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_k_tuple_3);
+  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_3));
+
+  /* "bx/intervals/intersection.pyx":258
+ *         if len(results) == n: return results
+ *         r = results
+ *         r.sort(key=operator.attrgetter('start'))             # <<<<<<<<<<<<<<
+ *         return r[:n]
+ * 
+ */
+  __pyx_k_tuple_4 = PyTuple_Pack(1, ((PyObject *)__pyx_n_s__start)); if (unlikely(!__pyx_k_tuple_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 258; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_k_tuple_4);
+  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_4));
+
+  /* "bx/intervals/intersection.pyx":269
+ *         if self.cright is not EmptyNode: self.cright._traverse(func)
+ * 
+ * cdef IntervalNode EmptyNode = IntervalNode( 0, 0, Interval(0, 0))             # <<<<<<<<<<<<<<
+ * 
+ * ## ---- Wrappers that retain the old interface -------------------------------
+ */
+  __pyx_k_tuple_11 = PyTuple_Pack(2, __pyx_int_0, __pyx_int_0); if (unlikely(!__pyx_k_tuple_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 269; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_k_tuple_11);
+  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_11));
+  __Pyx_RefNannyFinishContext();
+  return 0;
+  __pyx_L1_error:;
+  __Pyx_RefNannyFinishContext();
+  return -1;
+}
+
+static int __Pyx_InitGlobals(void) {
+  if (__Pyx_InitStrings(__pyx_string_tab) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  __pyx_int_0 = PyInt_FromLong(0); if (unlikely(!__pyx_int_0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  __pyx_int_1 = PyInt_FromLong(1); if (unlikely(!__pyx_int_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  __pyx_int_2 = PyInt_FromLong(2); if (unlikely(!__pyx_int_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  __pyx_int_3 = PyInt_FromLong(3); if (unlikely(!__pyx_int_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  __pyx_int_4 = PyInt_FromLong(4); if (unlikely(!__pyx_int_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  __pyx_int_5 = PyInt_FromLong(5); if (unlikely(!__pyx_int_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  __pyx_int_neg_1 = PyInt_FromLong(-1); if (unlikely(!__pyx_int_neg_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  __pyx_int_2500 = PyInt_FromLong(2500); if (unlikely(!__pyx_int_2500)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  return 0;
+  __pyx_L1_error:;
+  return -1;
+}
+
+#if PY_MAJOR_VERSION < 3
+PyMODINIT_FUNC initintersection(void); /*proto*/
+PyMODINIT_FUNC initintersection(void)
+#else
+PyMODINIT_FUNC PyInit_intersection(void); /*proto*/
+PyMODINIT_FUNC PyInit_intersection(void)
+#endif
+{
+  PyObject *__pyx_t_1 = NULL;
+  float __pyx_t_2;
+  PyObject *__pyx_t_3 = NULL;
+  __Pyx_RefNannyDeclarations
+  #if CYTHON_REFNANNY
+  __Pyx_RefNanny = __Pyx_RefNannyImportAPI("refnanny");
+  if (!__Pyx_RefNanny) {
+      PyErr_Clear();
+      __Pyx_RefNanny = __Pyx_RefNannyImportAPI("Cython.Runtime.refnanny");
+      if (!__Pyx_RefNanny)
+          Py_FatalError("failed to import 'refnanny' module");
+  }
+  #endif
+  __Pyx_RefNannySetupContext("PyMODINIT_FUNC PyInit_intersection(void)", 0);
+  if ( __Pyx_check_binary_version() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_bytes)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #ifdef __Pyx_CyFunction_USED
+  if (__Pyx_CyFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #endif
+  #ifdef __Pyx_FusedFunction_USED
+  if (__pyx_FusedFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #endif
+  #ifdef __Pyx_Generator_USED
+  if (__pyx_Generator_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #endif
+  /*--- Library function declarations ---*/
+  /*--- Threads initialization code ---*/
+  #if defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS
+  #ifdef WITH_THREAD /* Python build with threading support? */
+  PyEval_InitThreads();
+  #endif
+  #endif
+  /*--- Module creation code ---*/
+  #if PY_MAJOR_VERSION < 3
+  __pyx_m = Py_InitModule4(__Pyx_NAMESTR("intersection"), __pyx_methods, __Pyx_DOCSTR(__pyx_k_10), 0, PYTHON_API_VERSION); Py_XINCREF(__pyx_m);
+  #else
+  __pyx_m = PyModule_Create(&__pyx_moduledef);
+  #endif
+  if (unlikely(!__pyx_m)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #if PY_MAJOR_VERSION >= 3
+  {
+    PyObject *modules = PyImport_GetModuleDict(); if (unlikely(!modules)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (!PyDict_GetItemString(modules, "bx.intervals.intersection")) {
+      if (unlikely(PyDict_SetItemString(modules, "bx.intervals.intersection", __pyx_m) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+  }
+  #endif
+  __pyx_b = PyImport_AddModule(__Pyx_NAMESTR(__Pyx_BUILTIN_MODULE_NAME)); if (unlikely(!__pyx_b)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #if CYTHON_COMPILING_IN_PYPY
+  Py_INCREF(__pyx_b);
+  #endif
+  if (__Pyx_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  /*--- Initialize various global constants etc. ---*/
+  if (unlikely(__Pyx_InitGlobals() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (__pyx_module_is_main_bx__intervals__intersection) {
+    if (__Pyx_SetAttrString(__pyx_m, "__name__", __pyx_n_s____main__) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  }
+  /*--- Builtin init code ---*/
+  if (unlikely(__Pyx_InitCachedBuiltins() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  /*--- Constants init code ---*/
+  if (unlikely(__Pyx_InitCachedConstants() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  /*--- Global init code ---*/
+  __pyx_v_2bx_9intervals_12intersection_EmptyNode = ((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)Py_None); Py_INCREF(Py_None);
+  /*--- Variable export code ---*/
+  /*--- Function export code ---*/
+  /*--- Type init code ---*/
+  __pyx_vtabptr_2bx_9intervals_12intersection_IntervalNode = &__pyx_vtable_2bx_9intervals_12intersection_IntervalNode;
+  __pyx_vtable_2bx_9intervals_12intersection_IntervalNode.insert = (struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *(*)(struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *, int, int, PyObject *, int __pyx_skip_dispatch))__pyx_f_2bx_9intervals_12intersection_12IntervalNode_insert;
+  __pyx_vtable_2bx_9intervals_12intersection_IntervalNode.rotate_right = (struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *(*)(struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *))__pyx_f_2bx_9intervals_12intersection_12IntervalNode_rotate_right;
+  __pyx_vtable_2bx_9intervals_12intersection_IntervalNode.rotate_left = (struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *(*)(struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *))__pyx_f_2bx_9intervals_12intersection_12IntervalNode_rotate_left;
+  __pyx_vtable_2bx_9intervals_12intersection_IntervalNode.set_ends = (void (*)(struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *))__pyx_f_2bx_9intervals_12intersection_12IntervalNode_set_ends;
+  __pyx_vtable_2bx_9intervals_12intersection_IntervalNode._intersect = (void (*)(struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *, int, int, PyObject *))__pyx_f_2bx_9intervals_12intersection_12IntervalNode__intersect;
+  __pyx_vtable_2bx_9intervals_12intersection_IntervalNode._seek_left = (void (*)(struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *, int, PyObject *, int, int))__pyx_f_2bx_9intervals_12intersection_12IntervalNode__seek_left;
+  __pyx_vtable_2bx_9intervals_12intersection_IntervalNode._seek_right = (void (*)(struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *, int, PyObject *, int, int))__pyx_f_2bx_9intervals_12intersection_12IntervalNode__seek_right;
+  __pyx_vtable_2bx_9intervals_12intersection_IntervalNode.left = (PyObject *(*)(struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *, PyObject *, int __pyx_skip_dispatch, struct __pyx_opt_args_2bx_9intervals_12intersection_12IntervalNode_left *__pyx_optional_args))__pyx_f_2bx_9intervals_12intersection_12IntervalNode_left;
+  __pyx_vtable_2bx_9intervals_12intersection_IntervalNode.right = (PyObject *(*)(struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *, PyObject *, int __pyx_skip_dispatch, struct __pyx_opt_args_2bx_9intervals_12intersection_12IntervalNode_right *__pyx_optional_args))__pyx_f_2bx_9intervals_12intersection_12IntervalNode_right;
+  __pyx_vtable_2bx_9intervals_12intersection_IntervalNode._traverse = (void (*)(struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *, PyObject *))__pyx_f_2bx_9intervals_12intersection_12IntervalNode__traverse;
+  if (PyType_Ready(&__pyx_type_2bx_9intervals_12intersection_IntervalNode) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 60; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (__Pyx_SetVtable(__pyx_type_2bx_9intervals_12intersection_IntervalNode.tp_dict, __pyx_vtabptr_2bx_9intervals_12intersection_IntervalNode) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 60; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (__Pyx_SetAttrString(__pyx_m, "IntervalNode", (PyObject *)&__pyx_type_2bx_9intervals_12intersection_IntervalNode) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 60; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_2bx_9intervals_12intersection_IntervalNode = &__pyx_type_2bx_9intervals_12intersection_IntervalNode;
+  if (PyType_Ready(&__pyx_type_2bx_9intervals_12intersection_Interval) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 273; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (__Pyx_SetAttrString(__pyx_m, "Interval", (PyObject *)&__pyx_type_2bx_9intervals_12intersection_Interval) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 273; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_2bx_9intervals_12intersection_Interval = &__pyx_type_2bx_9intervals_12intersection_Interval;
+  if (PyType_Ready(&__pyx_type_2bx_9intervals_12intersection_IntervalTree) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (__Pyx_SetAttrString(__pyx_m, "IntervalTree", (PyObject *)&__pyx_type_2bx_9intervals_12intersection_IntervalTree) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_2bx_9intervals_12intersection_IntervalTree = &__pyx_type_2bx_9intervals_12intersection_IntervalTree;
+  /*--- Type import code ---*/
+  /*--- Variable import code ---*/
+  /*--- Function import code ---*/
+  /*--- Execution code ---*/
+
+  /* "bx/intervals/intersection.pyx":22
+ * #cython: cdivision=True
+ * 
+ * import operator             # <<<<<<<<<<<<<<
+ * 
+ * cdef extern from "stdlib.h":
+ */
+  __pyx_t_1 = __Pyx_Import(((PyObject *)__pyx_n_s__operator), 0, -1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 22; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s__operator, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 22; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "bx/intervals/intersection.pyx":58
+ *     return a
+ * 
+ * cdef float nlog = -1.0 / log(0.5)             # <<<<<<<<<<<<<<
+ * 
+ * cdef class IntervalNode:
+ */
+  __pyx_t_2 = log(0.5);
+  if (unlikely(__pyx_t_2 == 0)) {
+    PyErr_Format(PyExc_ZeroDivisionError, "float division");
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 58; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  __pyx_v_2bx_9intervals_12intersection_nlog = (-1.0 / __pyx_t_2);
+
+  /* "bx/intervals/intersection.pyx":168
+ * 
+ * 
+ *     def intersect( self, int start, int end, sort=True ):             # <<<<<<<<<<<<<<
+ *         """
+ *         given a start and a end, return a list of features
+ */
+  __pyx_t_1 = __Pyx_PyBool_FromLong(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 168; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_k_2 = __pyx_t_1;
+  __Pyx_GIVEREF(__pyx_t_1);
+  __pyx_t_1 = 0;
+
+  /* "bx/intervals/intersection.pyx":177
+ *         return results
+ * 
+ *     find = intersect             # <<<<<<<<<<<<<<
+ * 
+ *     cdef void _intersect( IntervalNode self, int start, int end, list results):
+ */
+  __pyx_t_1 = __Pyx_GetName((PyObject *)__pyx_ptype_2bx_9intervals_12intersection_IntervalNode, __pyx_n_s__intersect); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 177; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem((PyObject *)__pyx_ptype_2bx_9intervals_12intersection_IntervalNode->tp_dict, __pyx_n_s__find, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 177; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  PyType_Modified(__pyx_ptype_2bx_9intervals_12intersection_IntervalNode);
+
+  /* "bx/intervals/intersection.pyx":269
+ *         if self.cright is not EmptyNode: self.cright._traverse(func)
+ * 
+ * cdef IntervalNode EmptyNode = IntervalNode( 0, 0, Interval(0, 0))             # <<<<<<<<<<<<<<
+ * 
+ * ## ---- Wrappers that retain the old interface -------------------------------
+ */
+  __pyx_t_1 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_2bx_9intervals_12intersection_Interval)), ((PyObject *)__pyx_k_tuple_11), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 269; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_3 = PyTuple_New(3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 269; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_INCREF(__pyx_int_0);
+  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_int_0);
+  __Pyx_GIVEREF(__pyx_int_0);
+  __Pyx_INCREF(__pyx_int_0);
+  PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_int_0);
+  __Pyx_GIVEREF(__pyx_int_0);
+  PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_t_1);
+  __Pyx_GIVEREF(__pyx_t_1);
+  __pyx_t_1 = 0;
+  __pyx_t_1 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_2bx_9intervals_12intersection_IntervalNode)), ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 269; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
+  __Pyx_XGOTREF(((PyObject *)__pyx_v_2bx_9intervals_12intersection_EmptyNode));
+  __Pyx_DECREF(((PyObject *)__pyx_v_2bx_9intervals_12intersection_EmptyNode));
+  __Pyx_GIVEREF(__pyx_t_1);
+  __pyx_v_2bx_9intervals_12intersection_EmptyNode = ((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)__pyx_t_1);
+  __pyx_t_1 = 0;
+
+  /* "bx/intervals/intersection.pyx":397
+ *             self.root = self.root.insert( start, end, value )
+ * 
+ *     add = insert             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+  __pyx_t_1 = __Pyx_GetName((PyObject *)__pyx_ptype_2bx_9intervals_12intersection_IntervalTree, __pyx_n_s__insert); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem((PyObject *)__pyx_ptype_2bx_9intervals_12intersection_IntervalTree->tp_dict, __pyx_n_s__add, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  PyType_Modified(__pyx_ptype_2bx_9intervals_12intersection_IntervalTree);
+
+  /* "bx/intervals/intersection.pyx":435
+ *         self.insert( interval.start, interval.end, interval )
+ * 
+ *     add_interval = insert_interval             # <<<<<<<<<<<<<<
+ * 
+ *     def before_interval( self, interval, num_intervals=1, max_dist=2500 ):
+ */
+  __pyx_t_1 = __Pyx_GetName((PyObject *)__pyx_ptype_2bx_9intervals_12intersection_IntervalTree, __pyx_n_s__insert_interval); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 435; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem((PyObject *)__pyx_ptype_2bx_9intervals_12intersection_IntervalTree->tp_dict, __pyx_n_s__add_interval, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 435; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  PyType_Modified(__pyx_ptype_2bx_9intervals_12intersection_IntervalTree);
+
+  /* "bx/intervals/intersection.pyx":488
+ * 
+ * # For backward compatibility
+ * Intersecter = IntervalTree             # <<<<<<<<<<<<<<
+ */
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s__Intersecter, ((PyObject *)((PyObject*)__pyx_ptype_2bx_9intervals_12intersection_IntervalTree))) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 488; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "bx/intervals/intersection.pyx":1
+ * """             # <<<<<<<<<<<<<<
+ * Data structure for performing intersect queries on a set of intervals which
+ * preserves all information about the intervals (unlike bitset projection methods).
+ */
+  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(((PyObject *)__pyx_t_1));
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s____test__, ((PyObject *)__pyx_t_1)) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_3);
+  if (__pyx_m) {
+    __Pyx_AddTraceback("init bx.intervals.intersection", __pyx_clineno, __pyx_lineno, __pyx_filename);
+    Py_DECREF(__pyx_m); __pyx_m = 0;
+  } else if (!PyErr_Occurred()) {
+    PyErr_SetString(PyExc_ImportError, "init bx.intervals.intersection");
+  }
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  #if PY_MAJOR_VERSION < 3
+  return;
+  #else
+  return __pyx_m;
+  #endif
+}
+
+/* Runtime support code */
+#if CYTHON_REFNANNY
+static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) {
+    PyObject *m = NULL, *p = NULL;
+    void *r = NULL;
+    m = PyImport_ImportModule((char *)modname);
+    if (!m) goto end;
+    p = PyObject_GetAttrString(m, (char *)"RefNannyAPI");
+    if (!p) goto end;
+    r = PyLong_AsVoidPtr(p);
+end:
+    Py_XDECREF(p);
+    Py_XDECREF(m);
+    return (__Pyx_RefNannyAPIStruct *)r;
+}
+#endif /* CYTHON_REFNANNY */
+
+static void __Pyx_RaiseArgtupleInvalid(
+    const char* func_name,
+    int exact,
+    Py_ssize_t num_min,
+    Py_ssize_t num_max,
+    Py_ssize_t num_found)
+{
+    Py_ssize_t num_expected;
+    const char *more_or_less;
+    if (num_found < num_min) {
+        num_expected = num_min;
+        more_or_less = "at least";
+    } else {
+        num_expected = num_max;
+        more_or_less = "at most";
+    }
+    if (exact) {
+        more_or_less = "exactly";
+    }
+    PyErr_Format(PyExc_TypeError,
+                 "%s() takes %s %" CYTHON_FORMAT_SSIZE_T "d positional argument%s (%" CYTHON_FORMAT_SSIZE_T "d given)",
+                 func_name, more_or_less, num_expected,
+                 (num_expected == 1) ? "" : "s", num_found);
+}
+
+static void __Pyx_RaiseDoubleKeywordsError(
+    const char* func_name,
+    PyObject* kw_name)
+{
+    PyErr_Format(PyExc_TypeError,
+        #if PY_MAJOR_VERSION >= 3
+        "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
+        #else
+        "%s() got multiple values for keyword argument '%s'", func_name,
+        PyString_AsString(kw_name));
+        #endif
+}
+
+static int __Pyx_ParseOptionalKeywords(
+    PyObject *kwds,
+    PyObject **argnames[],
+    PyObject *kwds2,
+    PyObject *values[],
+    Py_ssize_t num_pos_args,
+    const char* function_name)
+{
+    PyObject *key = 0, *value = 0;
+    Py_ssize_t pos = 0;
+    PyObject*** name;
+    PyObject*** first_kw_arg = argnames + num_pos_args;
+    while (PyDict_Next(kwds, &pos, &key, &value)) {
+        name = first_kw_arg;
+        while (*name && (**name != key)) name++;
+        if (*name) {
+            values[name-argnames] = value;
+            continue;
+        }
+        name = first_kw_arg;
+        #if PY_MAJOR_VERSION < 3
+        if (likely(PyString_CheckExact(key)) || likely(PyString_Check(key))) {
+            while (*name) {
+                if ((CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**name) == PyString_GET_SIZE(key))
+                        && _PyString_Eq(**name, key)) {
+                    values[name-argnames] = value;
+                    break;
+                }
+                name++;
+            }
+            if (*name) continue;
+            else {
+                PyObject*** argname = argnames;
+                while (argname != first_kw_arg) {
+                    if ((**argname == key) || (
+                            (CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**argname) == PyString_GET_SIZE(key))
+                             && _PyString_Eq(**argname, key))) {
+                        goto arg_passed_twice;
+                    }
+                    argname++;
+                }
+            }
+        } else
+        #endif
+        if (likely(PyUnicode_Check(key))) {
+            while (*name) {
+                int cmp = (**name == key) ? 0 :
+                #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3
+                    (PyUnicode_GET_SIZE(**name) != PyUnicode_GET_SIZE(key)) ? 1 :
+                #endif
+                    PyUnicode_Compare(**name, key);
+                if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad;
+                if (cmp == 0) {
+                    values[name-argnames] = value;
+                    break;
+                }
+                name++;
+            }
+            if (*name) continue;
+            else {
+                PyObject*** argname = argnames;
+                while (argname != first_kw_arg) {
+                    int cmp = (**argname == key) ? 0 :
+                    #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3
+                        (PyUnicode_GET_SIZE(**argname) != PyUnicode_GET_SIZE(key)) ? 1 :
+                    #endif
+                        PyUnicode_Compare(**argname, key);
+                    if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad;
+                    if (cmp == 0) goto arg_passed_twice;
+                    argname++;
+                }
+            }
+        } else
+            goto invalid_keyword_type;
+        if (kwds2) {
+            if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
+        } else {
+            goto invalid_keyword;
+        }
+    }
+    return 0;
+arg_passed_twice:
+    __Pyx_RaiseDoubleKeywordsError(function_name, key);
+    goto bad;
+invalid_keyword_type:
+    PyErr_Format(PyExc_TypeError,
+        "%s() keywords must be strings", function_name);
+    goto bad;
+invalid_keyword:
+    PyErr_Format(PyExc_TypeError,
+    #if PY_MAJOR_VERSION < 3
+        "%s() got an unexpected keyword argument '%s'",
+        function_name, PyString_AsString(key));
+    #else
+        "%s() got an unexpected keyword argument '%U'",
+        function_name, key);
+    #endif
+bad:
+    return -1;
+}
+
+static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type) {
+    if (unlikely(!type)) {
+        PyErr_Format(PyExc_SystemError, "Missing type object");
+        return 0;
+    }
+    if (likely(PyObject_TypeCheck(obj, type)))
+        return 1;
+    PyErr_Format(PyExc_TypeError, "Cannot convert %.200s to %.200s",
+                 Py_TYPE(obj)->tp_name, type->tp_name);
+    return 0;
+}
+
+static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name) {
+    PyObject *result;
+    result = PyObject_GetAttr(dict, name);
+    if (!result) {
+        if (dict != __pyx_b) {
+            PyErr_Clear();
+            result = PyObject_GetAttr(__pyx_b, name);
+        }
+        if (!result) {
+            PyErr_SetObject(PyExc_NameError, name);
+        }
+    }
+    return result;
+}
+
+static CYTHON_INLINE int __Pyx_CheckKeywordStrings(
+    PyObject *kwdict,
+    const char* function_name,
+    int kw_allowed)
+{
+    PyObject* key = 0;
+    Py_ssize_t pos = 0;
+#if CPYTHON_COMPILING_IN_PYPY
+    if (!kw_allowed && PyDict_Next(kwdict, &pos, &key, 0))
+        goto invalid_keyword;
+    return 1;
+#else
+    while (PyDict_Next(kwdict, &pos, &key, 0)) {
+        #if PY_MAJOR_VERSION < 3
+        if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key)))
+        #endif
+            if (unlikely(!PyUnicode_Check(key)))
+                goto invalid_keyword_type;
+    }
+    if ((!kw_allowed) && unlikely(key))
+        goto invalid_keyword;
+    return 1;
+invalid_keyword_type:
+    PyErr_Format(PyExc_TypeError,
+        "%s() keywords must be strings", function_name);
+    return 0;
+#endif
+invalid_keyword:
+    PyErr_Format(PyExc_TypeError,
+    #if PY_MAJOR_VERSION < 3
+        "%s() got an unexpected keyword argument '%s'",
+        function_name, PyString_AsString(key));
+    #else
+        "%s() got an unexpected keyword argument '%U'",
+        function_name, key);
+    #endif
+    return 0;
+}
+
+static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level) {
+    PyObject *empty_list = 0;
+    PyObject *module = 0;
+    PyObject *global_dict = 0;
+    PyObject *empty_dict = 0;
+    PyObject *list;
+    #if PY_VERSION_HEX < 0x03030000
+    PyObject *py_import = 0;
+    py_import = __Pyx_GetAttrString(__pyx_b, "__import__");
+    if (!py_import)
+        goto bad;
+    #endif
+    if (from_list)
+        list = from_list;
+    else {
+        empty_list = PyList_New(0);
+        if (!empty_list)
+            goto bad;
+        list = empty_list;
+    }
+    global_dict = PyModule_GetDict(__pyx_m);
+    if (!global_dict)
+        goto bad;
+    empty_dict = PyDict_New();
+    if (!empty_dict)
+        goto bad;
+    #if PY_VERSION_HEX >= 0x02050000
+    {
+        #if PY_MAJOR_VERSION >= 3
+        if (level == -1) {
+            if (strchr(__Pyx_MODULE_NAME, '.')) {
+                #if PY_VERSION_HEX < 0x03030000
+                PyObject *py_level = PyInt_FromLong(1);
+                if (!py_level)
+                    goto bad;
+                module = PyObject_CallFunctionObjArgs(py_import,
+                    name, global_dict, empty_dict, list, py_level, NULL);
+                Py_DECREF(py_level);
+                #else
+                module = PyImport_ImportModuleLevelObject(
+                    name, global_dict, empty_dict, list, 1);
+                #endif
+                if (!module) {
+                    if (!PyErr_ExceptionMatches(PyExc_ImportError))
+                        goto bad;
+                    PyErr_Clear();
+                }
+            }
+            level = 0; /* try absolute import on failure */
+        }
+        #endif
+        if (!module) {
+            #if PY_VERSION_HEX < 0x03030000
+            PyObject *py_level = PyInt_FromLong(level);
+            if (!py_level)
+                goto bad;
+            module = PyObject_CallFunctionObjArgs(py_import,
+                name, global_dict, empty_dict, list, py_level, NULL);
+            Py_DECREF(py_level);
+            #else
+            module = PyImport_ImportModuleLevelObject(
+                name, global_dict, empty_dict, list, level);
+            #endif
+        }
+    }
+    #else
+    if (level>0) {
+        PyErr_SetString(PyExc_RuntimeError, "Relative import is not supported for Python <=2.4.");
+        goto bad;
+    }
+    module = PyObject_CallFunctionObjArgs(py_import,
+        name, global_dict, empty_dict, list, NULL);
+    #endif
+bad:
+    #if PY_VERSION_HEX < 0x03030000
+    Py_XDECREF(py_import);
+    #endif
+    Py_XDECREF(empty_list);
+    Py_XDECREF(empty_dict);
+    return module;
+}
+
+static CYTHON_INLINE unsigned char __Pyx_PyInt_AsUnsignedChar(PyObject* x) {
+    const unsigned char neg_one = (unsigned char)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(unsigned char) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(unsigned char)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to unsigned char" :
+                    "value too large to convert to unsigned char");
+            }
+            return (unsigned char)-1;
+        }
+        return (unsigned char)val;
+    }
+    return (unsigned char)__Pyx_PyInt_AsUnsignedLong(x);
+}
+
+static CYTHON_INLINE unsigned short __Pyx_PyInt_AsUnsignedShort(PyObject* x) {
+    const unsigned short neg_one = (unsigned short)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(unsigned short) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(unsigned short)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to unsigned short" :
+                    "value too large to convert to unsigned short");
+            }
+            return (unsigned short)-1;
+        }
+        return (unsigned short)val;
+    }
+    return (unsigned short)__Pyx_PyInt_AsUnsignedLong(x);
+}
+
+static CYTHON_INLINE unsigned int __Pyx_PyInt_AsUnsignedInt(PyObject* x) {
+    const unsigned int neg_one = (unsigned int)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(unsigned int) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(unsigned int)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to unsigned int" :
+                    "value too large to convert to unsigned int");
+            }
+            return (unsigned int)-1;
+        }
+        return (unsigned int)val;
+    }
+    return (unsigned int)__Pyx_PyInt_AsUnsignedLong(x);
+}
+
+static CYTHON_INLINE char __Pyx_PyInt_AsChar(PyObject* x) {
+    const char neg_one = (char)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(char) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(char)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to char" :
+                    "value too large to convert to char");
+            }
+            return (char)-1;
+        }
+        return (char)val;
+    }
+    return (char)__Pyx_PyInt_AsLong(x);
+}
+
+static CYTHON_INLINE short __Pyx_PyInt_AsShort(PyObject* x) {
+    const short neg_one = (short)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(short) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(short)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to short" :
+                    "value too large to convert to short");
+            }
+            return (short)-1;
+        }
+        return (short)val;
+    }
+    return (short)__Pyx_PyInt_AsLong(x);
+}
+
+static CYTHON_INLINE int __Pyx_PyInt_AsInt(PyObject* x) {
+    const int neg_one = (int)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(int) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(int)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to int" :
+                    "value too large to convert to int");
+            }
+            return (int)-1;
+        }
+        return (int)val;
+    }
+    return (int)__Pyx_PyInt_AsLong(x);
+}
+
+static CYTHON_INLINE signed char __Pyx_PyInt_AsSignedChar(PyObject* x) {
+    const signed char neg_one = (signed char)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(signed char) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(signed char)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to signed char" :
+                    "value too large to convert to signed char");
+            }
+            return (signed char)-1;
+        }
+        return (signed char)val;
+    }
+    return (signed char)__Pyx_PyInt_AsSignedLong(x);
+}
+
+static CYTHON_INLINE signed short __Pyx_PyInt_AsSignedShort(PyObject* x) {
+    const signed short neg_one = (signed short)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(signed short) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(signed short)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to signed short" :
+                    "value too large to convert to signed short");
+            }
+            return (signed short)-1;
+        }
+        return (signed short)val;
+    }
+    return (signed short)__Pyx_PyInt_AsSignedLong(x);
+}
+
+static CYTHON_INLINE signed int __Pyx_PyInt_AsSignedInt(PyObject* x) {
+    const signed int neg_one = (signed int)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(signed int) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(signed int)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to signed int" :
+                    "value too large to convert to signed int");
+            }
+            return (signed int)-1;
+        }
+        return (signed int)val;
+    }
+    return (signed int)__Pyx_PyInt_AsSignedLong(x);
+}
+
+static CYTHON_INLINE int __Pyx_PyInt_AsLongDouble(PyObject* x) {
+    const int neg_one = (int)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(int) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(int)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to int" :
+                    "value too large to convert to int");
+            }
+            return (int)-1;
+        }
+        return (int)val;
+    }
+    return (int)__Pyx_PyInt_AsLong(x);
+}
+
+static CYTHON_INLINE unsigned long __Pyx_PyInt_AsUnsignedLong(PyObject* x) {
+    const unsigned long neg_one = (unsigned long)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to unsigned long");
+            return (unsigned long)-1;
+        }
+        return (unsigned long)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to unsigned long");
+                return (unsigned long)-1;
+            }
+            return (unsigned long)PyLong_AsUnsignedLong(x);
+        } else {
+            return (unsigned long)PyLong_AsLong(x);
+        }
+    } else {
+        unsigned long val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (unsigned long)-1;
+        val = __Pyx_PyInt_AsUnsignedLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE unsigned PY_LONG_LONG __Pyx_PyInt_AsUnsignedLongLong(PyObject* x) {
+    const unsigned PY_LONG_LONG neg_one = (unsigned PY_LONG_LONG)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to unsigned PY_LONG_LONG");
+            return (unsigned PY_LONG_LONG)-1;
+        }
+        return (unsigned PY_LONG_LONG)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to unsigned PY_LONG_LONG");
+                return (unsigned PY_LONG_LONG)-1;
+            }
+            return (unsigned PY_LONG_LONG)PyLong_AsUnsignedLongLong(x);
+        } else {
+            return (unsigned PY_LONG_LONG)PyLong_AsLongLong(x);
+        }
+    } else {
+        unsigned PY_LONG_LONG val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (unsigned PY_LONG_LONG)-1;
+        val = __Pyx_PyInt_AsUnsignedLongLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE long __Pyx_PyInt_AsLong(PyObject* x) {
+    const long neg_one = (long)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to long");
+            return (long)-1;
+        }
+        return (long)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to long");
+                return (long)-1;
+            }
+            return (long)PyLong_AsUnsignedLong(x);
+        } else {
+            return (long)PyLong_AsLong(x);
+        }
+    } else {
+        long val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (long)-1;
+        val = __Pyx_PyInt_AsLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE PY_LONG_LONG __Pyx_PyInt_AsLongLong(PyObject* x) {
+    const PY_LONG_LONG neg_one = (PY_LONG_LONG)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to PY_LONG_LONG");
+            return (PY_LONG_LONG)-1;
+        }
+        return (PY_LONG_LONG)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to PY_LONG_LONG");
+                return (PY_LONG_LONG)-1;
+            }
+            return (PY_LONG_LONG)PyLong_AsUnsignedLongLong(x);
+        } else {
+            return (PY_LONG_LONG)PyLong_AsLongLong(x);
+        }
+    } else {
+        PY_LONG_LONG val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (PY_LONG_LONG)-1;
+        val = __Pyx_PyInt_AsLongLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE signed long __Pyx_PyInt_AsSignedLong(PyObject* x) {
+    const signed long neg_one = (signed long)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to signed long");
+            return (signed long)-1;
+        }
+        return (signed long)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to signed long");
+                return (signed long)-1;
+            }
+            return (signed long)PyLong_AsUnsignedLong(x);
+        } else {
+            return (signed long)PyLong_AsLong(x);
+        }
+    } else {
+        signed long val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (signed long)-1;
+        val = __Pyx_PyInt_AsSignedLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE signed PY_LONG_LONG __Pyx_PyInt_AsSignedLongLong(PyObject* x) {
+    const signed PY_LONG_LONG neg_one = (signed PY_LONG_LONG)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to signed PY_LONG_LONG");
+            return (signed PY_LONG_LONG)-1;
+        }
+        return (signed PY_LONG_LONG)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to signed PY_LONG_LONG");
+                return (signed PY_LONG_LONG)-1;
+            }
+            return (signed PY_LONG_LONG)PyLong_AsUnsignedLongLong(x);
+        } else {
+            return (signed PY_LONG_LONG)PyLong_AsLongLong(x);
+        }
+    } else {
+        signed PY_LONG_LONG val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (signed PY_LONG_LONG)-1;
+        val = __Pyx_PyInt_AsSignedLongLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    PyObject *tmp_type, *tmp_value, *tmp_tb;
+    PyThreadState *tstate = PyThreadState_GET();
+    tmp_type = tstate->curexc_type;
+    tmp_value = tstate->curexc_value;
+    tmp_tb = tstate->curexc_traceback;
+    tstate->curexc_type = type;
+    tstate->curexc_value = value;
+    tstate->curexc_traceback = tb;
+    Py_XDECREF(tmp_type);
+    Py_XDECREF(tmp_value);
+    Py_XDECREF(tmp_tb);
+#else
+    PyErr_Restore(type, value, tb);
+#endif
+}
+static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    PyThreadState *tstate = PyThreadState_GET();
+    *type = tstate->curexc_type;
+    *value = tstate->curexc_value;
+    *tb = tstate->curexc_traceback;
+    tstate->curexc_type = 0;
+    tstate->curexc_value = 0;
+    tstate->curexc_traceback = 0;
+#else
+    PyErr_Fetch(type, value, tb);
+#endif
+}
+
+static void __Pyx_WriteUnraisable(const char *name, CYTHON_UNUSED int clineno,
+                                  CYTHON_UNUSED int lineno, CYTHON_UNUSED const char *filename) {
+    PyObject *old_exc, *old_val, *old_tb;
+    PyObject *ctx;
+    __Pyx_ErrFetch(&old_exc, &old_val, &old_tb);
+    #if PY_MAJOR_VERSION < 3
+    ctx = PyString_FromString(name);
+    #else
+    ctx = PyUnicode_FromString(name);
+    #endif
+    __Pyx_ErrRestore(old_exc, old_val, old_tb);
+    if (!ctx) {
+        PyErr_WriteUnraisable(Py_None);
+    } else {
+        PyErr_WriteUnraisable(ctx);
+        Py_DECREF(ctx);
+    }
+}
+
+static int __Pyx_check_binary_version(void) {
+    char ctversion[4], rtversion[4];
+    PyOS_snprintf(ctversion, 4, "%d.%d", PY_MAJOR_VERSION, PY_MINOR_VERSION);
+    PyOS_snprintf(rtversion, 4, "%s", Py_GetVersion());
+    if (ctversion[0] != rtversion[0] || ctversion[2] != rtversion[2]) {
+        char message[200];
+        PyOS_snprintf(message, sizeof(message),
+                      "compiletime version %s of module '%.100s' "
+                      "does not match runtime version %s",
+                      ctversion, __Pyx_MODULE_NAME, rtversion);
+        #if PY_VERSION_HEX < 0x02050000
+        return PyErr_Warn(NULL, message);
+        #else
+        return PyErr_WarnEx(NULL, message, 1);
+        #endif
+    }
+    return 0;
+}
+
+static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
+#if PY_VERSION_HEX >= 0x02070000 && !(PY_MAJOR_VERSION==3&&PY_MINOR_VERSION==0)
+    PyObject *ob = PyCapsule_New(vtable, 0, 0);
+#else
+    PyObject *ob = PyCObject_FromVoidPtr(vtable, 0);
+#endif
+    if (!ob)
+        goto bad;
+    if (PyDict_SetItemString(dict, "__pyx_vtable__", ob) < 0)
+        goto bad;
+    Py_DECREF(ob);
+    return 0;
+bad:
+    Py_XDECREF(ob);
+    return -1;
+}
+
+static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) {
+    int start = 0, mid = 0, end = count - 1;
+    if (end >= 0 && code_line > entries[end].code_line) {
+        return count;
+    }
+    while (start < end) {
+        mid = (start + end) / 2;
+        if (code_line < entries[mid].code_line) {
+            end = mid;
+        } else if (code_line > entries[mid].code_line) {
+             start = mid + 1;
+        } else {
+            return mid;
+        }
+    }
+    if (code_line <= entries[mid].code_line) {
+        return mid;
+    } else {
+        return mid + 1;
+    }
+}
+static PyCodeObject *__pyx_find_code_object(int code_line) {
+    PyCodeObject* code_object;
+    int pos;
+    if (unlikely(!code_line) || unlikely(!__pyx_code_cache.entries)) {
+        return NULL;
+    }
+    pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line);
+    if (unlikely(pos >= __pyx_code_cache.count) || unlikely(__pyx_code_cache.entries[pos].code_line != code_line)) {
+        return NULL;
+    }
+    code_object = __pyx_code_cache.entries[pos].code_object;
+    Py_INCREF(code_object);
+    return code_object;
+}
+static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) {
+    int pos, i;
+    __Pyx_CodeObjectCacheEntry* entries = __pyx_code_cache.entries;
+    if (unlikely(!code_line)) {
+        return;
+    }
+    if (unlikely(!entries)) {
+        entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Malloc(64*sizeof(__Pyx_CodeObjectCacheEntry));
+        if (likely(entries)) {
+            __pyx_code_cache.entries = entries;
+            __pyx_code_cache.max_count = 64;
+            __pyx_code_cache.count = 1;
+            entries[0].code_line = code_line;
+            entries[0].code_object = code_object;
+            Py_INCREF(code_object);
+        }
+        return;
+    }
+    pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line);
+    if ((pos < __pyx_code_cache.count) && unlikely(__pyx_code_cache.entries[pos].code_line == code_line)) {
+        PyCodeObject* tmp = entries[pos].code_object;
+        entries[pos].code_object = code_object;
+        Py_DECREF(tmp);
+        return;
+    }
+    if (__pyx_code_cache.count == __pyx_code_cache.max_count) {
+        int new_max = __pyx_code_cache.max_count + 64;
+        entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Realloc(
+            __pyx_code_cache.entries, new_max*sizeof(__Pyx_CodeObjectCacheEntry));
+        if (unlikely(!entries)) {
+            return;
+        }
+        __pyx_code_cache.entries = entries;
+        __pyx_code_cache.max_count = new_max;
+    }
+    for (i=__pyx_code_cache.count; i>pos; i--) {
+        entries[i] = entries[i-1];
+    }
+    entries[pos].code_line = code_line;
+    entries[pos].code_object = code_object;
+    __pyx_code_cache.count++;
+    Py_INCREF(code_object);
+}
+
+#include "compile.h"
+#include "frameobject.h"
+#include "traceback.h"
+static PyCodeObject* __Pyx_CreateCodeObjectForTraceback(
+            const char *funcname, int c_line,
+            int py_line, const char *filename) {
+    PyCodeObject *py_code = 0;
+    PyObject *py_srcfile = 0;
+    PyObject *py_funcname = 0;
+    #if PY_MAJOR_VERSION < 3
+    py_srcfile = PyString_FromString(filename);
+    #else
+    py_srcfile = PyUnicode_FromString(filename);
+    #endif
+    if (!py_srcfile) goto bad;
+    if (c_line) {
+        #if PY_MAJOR_VERSION < 3
+        py_funcname = PyString_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line);
+        #else
+        py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line);
+        #endif
+    }
+    else {
+        #if PY_MAJOR_VERSION < 3
+        py_funcname = PyString_FromString(funcname);
+        #else
+        py_funcname = PyUnicode_FromString(funcname);
+        #endif
+    }
+    if (!py_funcname) goto bad;
+    py_code = __Pyx_PyCode_New(
+        0,            /*int argcount,*/
+        0,            /*int kwonlyargcount,*/
+        0,            /*int nlocals,*/
+        0,            /*int stacksize,*/
+        0,            /*int flags,*/
+        __pyx_empty_bytes, /*PyObject *code,*/
+        __pyx_empty_tuple, /*PyObject *consts,*/
+        __pyx_empty_tuple, /*PyObject *names,*/
+        __pyx_empty_tuple, /*PyObject *varnames,*/
+        __pyx_empty_tuple, /*PyObject *freevars,*/
+        __pyx_empty_tuple, /*PyObject *cellvars,*/
+        py_srcfile,   /*PyObject *filename,*/
+        py_funcname,  /*PyObject *name,*/
+        py_line,      /*int firstlineno,*/
+        __pyx_empty_bytes  /*PyObject *lnotab*/
+    );
+    Py_DECREF(py_srcfile);
+    Py_DECREF(py_funcname);
+    return py_code;
+bad:
+    Py_XDECREF(py_srcfile);
+    Py_XDECREF(py_funcname);
+    return NULL;
+}
+static void __Pyx_AddTraceback(const char *funcname, int c_line,
+                               int py_line, const char *filename) {
+    PyCodeObject *py_code = 0;
+    PyObject *py_globals = 0;
+    PyFrameObject *py_frame = 0;
+    py_code = __pyx_find_code_object(c_line ? c_line : py_line);
+    if (!py_code) {
+        py_code = __Pyx_CreateCodeObjectForTraceback(
+            funcname, c_line, py_line, filename);
+        if (!py_code) goto bad;
+        __pyx_insert_code_object(c_line ? c_line : py_line, py_code);
+    }
+    py_globals = PyModule_GetDict(__pyx_m);
+    if (!py_globals) goto bad;
+    py_frame = PyFrame_New(
+        PyThreadState_GET(), /*PyThreadState *tstate,*/
+        py_code,             /*PyCodeObject *code,*/
+        py_globals,          /*PyObject *globals,*/
+        0                    /*PyObject *locals*/
+    );
+    if (!py_frame) goto bad;
+    py_frame->f_lineno = py_line;
+    PyTraceBack_Here(py_frame);
+bad:
+    Py_XDECREF(py_code);
+    Py_XDECREF(py_frame);
+}
+
+static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
+    while (t->p) {
+        #if PY_MAJOR_VERSION < 3
+        if (t->is_unicode) {
+            *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
+        } else if (t->intern) {
+            *t->p = PyString_InternFromString(t->s);
+        } else {
+            *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
+        }
+        #else  /* Python 3+ has unicode identifiers */
+        if (t->is_unicode | t->is_str) {
+            if (t->intern) {
+                *t->p = PyUnicode_InternFromString(t->s);
+            } else if (t->encoding) {
+                *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL);
+            } else {
+                *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
+            }
+        } else {
+            *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
+        }
+        #endif
+        if (!*t->p)
+            return -1;
+        ++t;
+    }
+    return 0;
+}
+
+static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) {
+   int is_true = x == Py_True;
+   if (is_true | (x == Py_False) | (x == Py_None)) return is_true;
+   else return PyObject_IsTrue(x);
+}
+static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x) {
+  PyNumberMethods *m;
+  const char *name = NULL;
+  PyObject *res = NULL;
+#if PY_VERSION_HEX < 0x03000000
+  if (PyInt_Check(x) || PyLong_Check(x))
+#else
+  if (PyLong_Check(x))
+#endif
+    return Py_INCREF(x), x;
+  m = Py_TYPE(x)->tp_as_number;
+#if PY_VERSION_HEX < 0x03000000
+  if (m && m->nb_int) {
+    name = "int";
+    res = PyNumber_Int(x);
+  }
+  else if (m && m->nb_long) {
+    name = "long";
+    res = PyNumber_Long(x);
+  }
+#else
+  if (m && m->nb_int) {
+    name = "int";
+    res = PyNumber_Long(x);
+  }
+#endif
+  if (res) {
+#if PY_VERSION_HEX < 0x03000000
+    if (!PyInt_Check(res) && !PyLong_Check(res)) {
+#else
+    if (!PyLong_Check(res)) {
+#endif
+      PyErr_Format(PyExc_TypeError,
+                   "__%s__ returned non-%s (type %.200s)",
+                   name, name, Py_TYPE(res)->tp_name);
+      Py_DECREF(res);
+      return NULL;
+    }
+  }
+  else if (!PyErr_Occurred()) {
+    PyErr_SetString(PyExc_TypeError,
+                    "an integer is required");
+  }
+  return res;
+}
+static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) {
+  Py_ssize_t ival;
+  PyObject* x = PyNumber_Index(b);
+  if (!x) return -1;
+  ival = PyInt_AsSsize_t(x);
+  Py_DECREF(x);
+  return ival;
+}
+static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) {
+#if PY_VERSION_HEX < 0x02050000
+   if (ival <= LONG_MAX)
+       return PyInt_FromLong((long)ival);
+   else {
+       unsigned char *bytes = (unsigned char *) &ival;
+       int one = 1; int little = (int)*(unsigned char*)&one;
+       return _PyLong_FromByteArray(bytes, sizeof(size_t), little, 0);
+   }
+#else
+   return PyInt_FromSize_t(ival);
+#endif
+}
+static CYTHON_INLINE size_t __Pyx_PyInt_AsSize_t(PyObject* x) {
+   unsigned PY_LONG_LONG val = __Pyx_PyInt_AsUnsignedLongLong(x);
+   if (unlikely(val == (unsigned PY_LONG_LONG)-1 && PyErr_Occurred())) {
+       return (size_t)-1;
+   } else if (unlikely(val != (unsigned PY_LONG_LONG)(size_t)val)) {
+       PyErr_SetString(PyExc_OverflowError,
+                       "value too large to convert to size_t");
+       return (size_t)-1;
+   }
+   return (size_t)val;
+}
+
+
+#endif /* Py_PYTHON_H */
diff --git a/lib/bx/intervals/intersection.pyx b/lib/bx/intervals/intersection.pyx
new file mode 100644
index 0000000..f06df13
--- /dev/null
+++ b/lib/bx/intervals/intersection.pyx
@@ -0,0 +1,488 @@
+"""
+Data structure for performing intersect queries on a set of intervals which
+preserves all information about the intervals (unlike bitset projection methods).
+
+:Authors: James Taylor (james at jamestaylor.org),
+          Ian Schenk (ian.schenck at gmail.com),
+          Brent Pedersen (bpederse at gmail.com)
+"""
+
+# Historical note:
+#    This module original contained an implementation based on sorted endpoints
+#    and a binary search, using an idea from Scott Schwartz and Piotr Berman.
+#    Later an interval tree implementation was implemented by Ian for Galaxy's
+#    join tool (see `bx.intervals.operations.quicksect.py`). This was then
+#    converted to Cython by Brent, who also added support for
+#    upstream/downstream/neighbor queries. This was modified by James to
+#    handle half-open intervals strictly, to maintain sort order, and to
+#    implement the same interface as the original Intersecter.
+
+#cython: cdivision=True
+
+import operator
+
+cdef extern from "stdlib.h":
+    int ceil(float f)
+    float log(float f)
+    int RAND_MAX
+    int rand()
+    int strlen(char *)
+    int iabs(int)
+
+cdef inline int imax2(int a, int b):
+    if b > a: return b
+    return a
+
+cdef inline int imax3(int a, int b, int c):
+    if b > a:
+        if c > b:
+            return c
+        return b
+    if a > c:
+        return a
+    return c
+
+cdef inline int imin3(int a, int b, int c):
+    if b < a:
+        if c < b:
+            return c
+        return b
+    if a < c:
+        return a
+    return c
+
+cdef inline int imin2(int a, int b):
+    if b < a: return b
+    return a
+
+cdef float nlog = -1.0 / log(0.5)
+
+cdef class IntervalNode:
+    """
+    A single node of an `IntervalTree`.
+    
+    NOTE: Unless you really know what you are doing, you probably should us
+          `IntervalTree` rather than using this directly. 
+    """
+    cdef float priority
+    cdef public object interval
+    cdef public int start, end
+    cdef int minend, maxend, minstart
+    cdef IntervalNode cleft, cright, croot
+
+    property left_node:
+        def __get__(self):
+            return self.cleft if self.cleft is not EmptyNode else None
+    property right_node:
+        def __get__(self):
+            return self.cright if self.cright is not EmptyNode else None
+    property root_node:
+        def __get__(self):
+            return self.croot if self.croot is not EmptyNode else None
+    
+    def __repr__(self):
+        return "IntervalNode(%i, %i)" % (self.start, self.end)
+
+    def __cinit__(IntervalNode self, int start, int end, object interval):
+        # Python lacks the binomial distribution, so we convert a
+        # uniform into a binomial because it naturally scales with
+        # tree size.  Also, python's uniform is perfect since the
+        # upper limit is not inclusive, which gives us undefined here.
+        self.priority = ceil(nlog * log(-1.0/(1.0 * rand()/RAND_MAX - 1)))
+        self.start    = start
+        self.end      = end
+        self.interval = interval
+        self.maxend   = end
+        self.minstart = start
+        self.minend   = end
+        self.cleft    = EmptyNode
+        self.cright   = EmptyNode
+        self.croot    = EmptyNode
+        
+    cpdef IntervalNode insert(IntervalNode self, int start, int end, object interval):
+        """
+        Insert a new IntervalNode into the tree of which this node is
+        currently the root. The return value is the new root of the tree (which
+        may or may not be this node!)
+        """
+        cdef IntervalNode croot = self
+        # If starts are the same, decide which to add interval to based on
+        # end, thus maintaining sortedness relative to start/end
+        cdef int decision_endpoint = start
+        if start == self.start:
+            decision_endpoint = end
+        
+        if decision_endpoint > self.start:
+            # insert to cright tree
+            if self.cright is not EmptyNode:
+                self.cright = self.cright.insert( start, end, interval )
+            else:
+                self.cright = IntervalNode( start, end, interval )
+            # rebalance tree
+            if self.priority < self.cright.priority:
+                croot = self.rotate_left()
+        else:
+            # insert to cleft tree
+            if self.cleft is not EmptyNode:
+                self.cleft = self.cleft.insert( start, end, interval)
+            else:
+                self.cleft = IntervalNode( start, end, interval)
+            # rebalance tree
+            if self.priority < self.cleft.priority:
+                croot = self.rotate_right()
+    
+        croot.set_ends()
+        self.cleft.croot  = croot
+        self.cright.croot = croot
+        return croot
+
+    cdef IntervalNode rotate_right(IntervalNode self):
+        cdef IntervalNode croot = self.cleft
+        self.cleft  = self.cleft.cright
+        croot.cright = self
+        self.set_ends()
+        return croot
+
+    cdef IntervalNode rotate_left(IntervalNode self):
+        cdef IntervalNode croot = self.cright
+        self.cright = self.cright.cleft
+        croot.cleft  = self
+        self.set_ends()
+        return croot
+
+    cdef inline void set_ends(IntervalNode self):
+        if self.cright is not EmptyNode and self.cleft is not EmptyNode: 
+            self.maxend = imax3(self.end, self.cright.maxend, self.cleft.maxend)
+            self.minend = imin3(self.end, self.cright.minend, self.cleft.minend)
+            self.minstart = imin3(self.start, self.cright.minstart, self.cleft.minstart)
+        elif self.cright is not EmptyNode:
+            self.maxend = imax2(self.end, self.cright.maxend)
+            self.minend = imin2(self.end, self.cright.minend)
+            self.minstart = imin2(self.start, self.cright.minstart)
+        elif self.cleft is not EmptyNode:
+            self.maxend = imax2(self.end, self.cleft.maxend)
+            self.minend = imin2(self.end, self.cleft.minend)
+            self.minstart = imin2(self.start, self.cleft.minstart)
+        
+
+    def intersect( self, int start, int end, sort=True ):
+        """
+        given a start and a end, return a list of features
+        falling within that range
+        """
+        cdef list results = []
+        self._intersect( start, end, results )
+        return results
+
+    find = intersect
+        
+    cdef void _intersect( IntervalNode self, int start, int end, list results):
+        # Left subtree
+        if self.cleft is not EmptyNode and self.cleft.maxend > start:
+            self.cleft._intersect( start, end, results )
+        # This interval
+        if ( self.end > start ) and ( self.start < end ):
+            results.append( self.interval )
+        # Right subtree
+        if self.cright is not EmptyNode and self.start < end:
+            self.cright._intersect( start, end, results )
+    
+
+    cdef void _seek_left(IntervalNode self, int position, list results, int n, int max_dist):
+        # we know we can bail in these 2 cases.
+        if self.maxend + max_dist < position:
+            return
+        if self.minstart > position:
+            return
+
+        # the ordering of these 3 blocks makes it so the results are
+        # ordered nearest to farest from the query position
+        if self.cright is not EmptyNode:
+            self.cright._seek_left(position, results, n, max_dist)
+
+        if -1 < position - self.end < max_dist:
+            results.append(self.interval)
+
+        # TODO: can these conditionals be more stringent?
+        if self.cleft is not EmptyNode:
+                self.cleft._seek_left(position, results, n, max_dist)
+
+
+    
+    cdef void _seek_right(IntervalNode self, int position, list results, int n, int max_dist):
+        # we know we can bail in these 2 cases.
+        if self.maxend < position: return
+        if self.minstart - max_dist > position: return
+
+        #print "SEEK_RIGHT:",self, self.cleft, self.maxend, self.minstart, position
+
+        # the ordering of these 3 blocks makes it so the results are
+        # ordered nearest to farest from the query position
+        if self.cleft is not EmptyNode: 
+                self.cleft._seek_right(position, results, n, max_dist)
+
+        if -1 < self.start - position < max_dist:
+            results.append(self.interval)
+
+        if self.cright is not EmptyNode:
+                self.cright._seek_right(position, results, n, max_dist)
+
+    
+    cpdef left(self, position, int n=1, int max_dist=2500):
+        """
+        find n features with a start > than `position`
+        f: a Interval object (or anything with an `end` attribute)
+        n: the number of features to return
+        max_dist: the maximum distance to look before giving up.
+        """
+        cdef list results = []
+        # use start - 1 becuase .left() assumes strictly left-of
+        self._seek_left( position - 1, results, n, max_dist )
+        if len(results) == n: return results
+        r = results
+        r.sort(key=operator.attrgetter('end'), reverse=True)
+        return r[:n]
+
+    cpdef right(self, position, int n=1, int max_dist=2500):
+        """
+        find n features with a end < than position
+        f: a Interval object (or anything with a `start` attribute)
+        n: the number of features to return
+        max_dist: the maximum distance to look before giving up.
+        """
+        cdef list results = []
+        # use end + 1 becuase .right() assumes strictly right-of
+        self._seek_right(position + 1, results, n, max_dist)
+        if len(results) == n: return results
+        r = results
+        r.sort(key=operator.attrgetter('start'))
+        return r[:n]
+
+    def traverse(self, func):
+        self._traverse(func)
+
+    cdef void _traverse(IntervalNode self, object func):
+        if self.cleft is not EmptyNode: self.cleft._traverse(func)
+        func(self)
+        if self.cright is not EmptyNode: self.cright._traverse(func)
+
+cdef IntervalNode EmptyNode = IntervalNode( 0, 0, Interval(0, 0))
+
+## ---- Wrappers that retain the old interface -------------------------------
+
+cdef class Interval:
+    """
+    Basic feature, with required integer start and end properties.
+    Also accepts optional strand as +1 or -1 (used for up/downstream queries),
+    a name, and any arbitrary data is sent in on the info keyword argument
+
+    >>> from bx.intervals.intersection import Interval
+
+    >>> f1 = Interval(23, 36)
+    >>> f2 = Interval(34, 48, value={'chr':12, 'anno':'transposon'})
+    >>> f2
+    Interval(34, 48, value={'anno': 'transposon', 'chr': 12})
+
+    """
+    cdef public int start, end
+    cdef public object value, chrom, strand
+
+    def __init__(self, int start, int end, object value=None, object chrom=None, object strand=None ):
+        assert start <= end, "start must be less than end"
+        self.start  = start
+        self.end   = end
+        self.value = value
+        self.chrom = chrom
+        self.strand = strand
+
+    def __repr__(self):
+        fstr = "Interval(%d, %d" % (self.start, self.end)
+        if not self.value is None:
+            fstr += ", value=" + str(self.value)
+        fstr += ")"
+        return fstr
+
+    def __richcmp__(self, other, op):
+        if op == 0:
+            # <
+            return self.start < other.start or self.end < other.end
+        elif op == 1:
+            # <=
+            return self == other or self < other
+        elif op == 2:
+            # ==
+            return self.start == other.start and self.end == other.end
+        elif op == 3:
+            # !=
+            return self.start != other.start or self.end != other.end
+        elif op == 4:
+            # >
+            return self.start > other.start or self.end > other.end
+        elif op == 5:
+            # >=
+            return self == other or self > other
+
+cdef class IntervalTree:
+    """
+    Data structure for performing window intersect queries on a set of 
+    of possibly overlapping 1d intervals.
+    
+    Usage
+    =====
+    
+    Create an empty IntervalTree
+    
+    >>> from bx.intervals.intersection import Interval, IntervalTree
+    >>> intersecter = IntervalTree()
+    
+    An interval is a start and end position and a value (possibly None).
+    You can add any object as an interval:
+    
+    >>> intersecter.insert( 0, 10, "food" )
+    >>> intersecter.insert( 3, 7, dict(foo='bar') )
+    
+    >>> intersecter.find( 2, 5 )
+    ['food', {'foo': 'bar'}]
+    
+    If the object has start and end attributes (like the Interval class) there
+    is are some shortcuts:
+    
+    >>> intersecter = IntervalTree()
+    >>> intersecter.insert_interval( Interval( 0, 10 ) )
+    >>> intersecter.insert_interval( Interval( 3, 7 ) )
+    >>> intersecter.insert_interval( Interval( 3, 40 ) )
+    >>> intersecter.insert_interval( Interval( 13, 50 ) )
+    
+    >>> intersecter.find( 30, 50 )
+    [Interval(3, 40), Interval(13, 50)]
+    >>> intersecter.find( 100, 200 )
+    []
+    
+    Before/after for intervals
+    
+    >>> intersecter.before_interval( Interval( 10, 20 ) )
+    [Interval(3, 7)]
+    >>> intersecter.before_interval( Interval( 5, 20 ) )
+    []
+    
+    Upstream/downstream
+    
+    >>> intersecter.upstream_of_interval(Interval(11, 12))
+    [Interval(0, 10)]
+    >>> intersecter.upstream_of_interval(Interval(11, 12, strand="-"))
+    [Interval(13, 50)]
+
+    >>> intersecter.upstream_of_interval(Interval(1, 2, strand="-"), num_intervals=3)
+    [Interval(3, 7), Interval(3, 40), Interval(13, 50)]
+
+    
+    """
+    
+    cdef IntervalNode root
+    
+    def __cinit__( self ):
+        root = None
+    
+    # ---- Position based interfaces -----------------------------------------
+    
+    def insert( self, int start, int end, object value=None ):
+        """
+        Insert the interval [start,end) associated with value `value`.
+        """
+        if self.root is None:
+            self.root = IntervalNode( start, end, value )
+        else:
+            self.root = self.root.insert( start, end, value )
+        
+    add = insert
+
+
+    def find( self, start, end ):
+        """
+        Return a sorted list of all intervals overlapping [start,end).
+        """
+        if self.root is None:
+            return []
+        return self.root.find( start, end )
+    
+    def before( self, position, num_intervals=1, max_dist=2500 ):
+        """
+        Find `num_intervals` intervals that lie before `position` and are no
+        further than `max_dist` positions away
+        """
+        if self.root is None:
+            return []
+        return self.root.left( position, num_intervals, max_dist )
+
+    def after( self, position, num_intervals=1, max_dist=2500 ):
+        """
+        Find `num_intervals` intervals that lie after `position` and are no
+        further than `max_dist` positions away
+        """
+        if self.root is None:
+            return []
+        return self.root.right( position, num_intervals, max_dist )
+
+    # ---- Interval-like object based interfaces -----------------------------
+
+    def insert_interval( self, interval ):
+        """
+        Insert an "interval" like object (one with at least start and end
+        attributes)
+        """
+        self.insert( interval.start, interval.end, interval )
+
+    add_interval = insert_interval
+
+    def before_interval( self, interval, num_intervals=1, max_dist=2500 ):
+        """
+        Find `num_intervals` intervals that lie completely before `interval`
+        and are no further than `max_dist` positions away
+        """
+        if self.root is None:
+            return []
+        return self.root.left( interval.start, num_intervals, max_dist )
+
+    def after_interval( self, interval, num_intervals=1, max_dist=2500 ):
+        """
+        Find `num_intervals` intervals that lie completely after `interval` and
+        are no further than `max_dist` positions away
+        """
+        if self.root is None:
+            return []
+        return self.root.right( interval.end, num_intervals, max_dist )
+
+    def upstream_of_interval( self, interval, num_intervals=1, max_dist=2500 ):
+        """
+        Find `num_intervals` intervals that lie completely upstream of
+        `interval` and are no further than `max_dist` positions away
+        """
+        if self.root is None:
+            return []
+        if interval.strand == -1 or interval.strand == "-":
+            return self.root.right( interval.end, num_intervals, max_dist )
+        else:
+            return self.root.left( interval.start, num_intervals, max_dist )
+
+    def downstream_of_interval( self, interval, num_intervals=1, max_dist=2500 ):
+        """
+        Find `num_intervals` intervals that lie completely downstream of
+        `interval` and are no further than `max_dist` positions away
+        """
+        if self.root is None:
+            return []
+        if interval.strand == -1 or interval.strand == "-":
+            return self.root.left( interval.start, num_intervals, max_dist )
+        else:
+            return self.root.right( interval.end, num_intervals, max_dist )
+    
+    def traverse(self, fn):
+        """
+        call fn for each element in the tree
+        """
+        if self.root is None:
+            return None
+        return self.root.traverse(fn)
+
+# For backward compatibility
+Intersecter = IntervalTree
diff --git a/lib/bx/intervals/intersection_tests.py b/lib/bx/intervals/intersection_tests.py
new file mode 100644
index 0000000..b36fb35
--- /dev/null
+++ b/lib/bx/intervals/intersection_tests.py
@@ -0,0 +1,219 @@
+import sys, os
+import unittest
+try:
+    sys.path.insert(0, os.path.dirname(os.path.dirname(__file__)))
+except:
+    sys.path.insert(0, os.path.dirname(os.path.abspath(".")))
+
+from bx.intervals.intersection import Interval
+from bx.intervals.intersection import IntervalNode
+from bx.intervals.intersection import IntervalTree
+
+class NeighborTestCase(unittest.TestCase):
+
+    def setUp(self):
+        iv = IntervalNode( 50, 59, Interval(50, 59))
+        for i in range(0, 110, 10):
+            if i == 50: continue
+            f = Interval(i, i + 9)
+            iv = iv.insert( f.start, f.end, f)
+        self.intervals = iv
+
+    def test_left(self):
+        iv = self.intervals
+        self.assertEqual(str(iv.left(60, n=2)), str([Interval(50, 59), Interval(40, 49)]))
+
+        for i in range(10, 100, 10):
+            r = iv.left(i, max_dist=10, n=1)
+            self.assertEqual(r[0].end,  i - 1)
+
+    def test_toomany(self):
+        iv = self.intervals
+        self.assertEqual(len(iv.left(60, n=200)) , 6)
+
+
+    def test_right(self):
+        iv = self.intervals
+        self.assertEqual(str(iv.left(60, n=2)), str([Interval(50, 59), Interval(40, 49)]))
+
+        def get_right_start(b10):
+            r = iv.right(b10+1, n=1)
+            assert len(r) == 1
+            return r[0].start
+        
+        for i in range(10, 100, 10):
+            self.assertEqual(get_right_start(i), i + 10)
+
+        for i in range(0, 100, 10):
+            r = iv.right(i-1, max_dist=10, n=1)
+            print r
+            self.assertEqual(r[0].start, i)
+
+class UpDownStreamTestCase(unittest.TestCase):
+
+    def setUp(self):
+        iv = IntervalTree()
+        iv.add_interval(Interval(50, 59))
+        for i in range(0, 110, 10):
+            if i == 50: continue
+            f = Interval(i, i + 9)
+            iv.add_interval(f)
+        self.intervals = iv
+
+
+    def test_upstream(self):
+        iv = self.intervals 
+        upstreams = iv.upstream_of_interval(Interval(59, 60), num_intervals=200)
+        for u in upstreams:
+            self.assertTrue(u.end < 59)
+    
+        upstreams = iv.upstream_of_interval(Interval(60, 70, strand=-1),
+                num_intervals=200)
+        for u in upstreams:
+            self.assertTrue(u.start > 70)
+    
+    
+        upstreams = iv.upstream_of_interval(Interval(58, 58, strand=-1),
+                num_intervals=200)
+        for u in upstreams:
+            self.assertTrue(u.start > 59)
+    
+    
+    def test_downstream(self):
+        iv = self.intervals
+        downstreams = iv.downstream_of_interval(Interval(59, 60),
+                num_intervals=200)
+        for d in downstreams:
+            self.assertTrue(d.start > 60)
+    
+        downstreams = iv.downstream_of_interval(Interval(59, 60, strand=-1),
+                num_intervals=200)
+        for d in downstreams:
+            self.assertTrue(d.start < 59)
+        
+
+    def test_n(self):
+        iv = self.intervals
+        for i in range(0, 90, 10):
+            r = iv.after(i, max_dist=20, num_intervals=2)
+            self.assertEqual(r[0].start, i + 10)
+            self.assertEqual(r[1].start, i + 20)
+
+            r = iv.after_interval(Interval(i, i), max_dist=20, num_intervals=2)
+            self.assertEqual(r[0].start, i + 10)
+            self.assertEqual(r[1].start, i + 20)
+
+
+class LotsaTestCase(unittest.TestCase):
+    """ put lotsa data in the tree and make sure it works"""
+    def setUp(self):
+        iv = IntervalNode(1, 2, Interval(1, 2))
+        self.max = 1000000
+        for i in range(0, self.max, 10):
+            f = Interval(i, i)
+            iv = iv.insert(f.start, f.end, f)
+
+        for i in range(600):
+            iv = iv.insert( 0, 1, Interval(0, 1) )
+        self.intervals = iv
+
+
+
+    def test_count(self):
+        iv = self.intervals
+        
+        r = iv.right(1, n=33)
+        self.assertEqual(len(r), 33)
+
+        l = iv.left(1, n=33)
+        self.assertEqual(len(l), 1)
+
+        u = iv.right(1, n=9999)
+        self.assertEqual(len(u), 250)
+
+        # now increase max_dist
+        u = iv.right(1, n=9999, max_dist=99999)
+        self.assertEqual(len(u), 9999)
+
+
+    def test_max_dist(self):
+        iv = self.intervals
+        r = iv.right(1, max_dist=0, n=10)
+        self.assertEqual(len(r), 0)
+
+        for n, d in enumerate(range(10, 1000, 10)):
+            r = iv.right(1, max_dist=d, n=10000)
+            self.assertEqual(len(r), n + 1) 
+
+    def test_find(self):
+        iv = self.intervals
+        path = sys.path[:]
+        sys.path = sys.path[2:]
+        ## import random
+        random = __import__("random")
+        sys.path = path
+        for t in range(25):
+            start = random.randint(0, self.max - 10000)
+            end  = start + random.randint(100, 10000)
+
+            results = iv.find(start, end)
+            for feat in results:
+                self.assertTrue(
+                        (feat.end >= start and feat.end <= end) 
+                            or 
+                        (feat.start <= end and feat.start >= start)
+                        )
+
+
+class IntervalTreeTest(unittest.TestCase):
+    def setUp(self):
+
+        iv = IntervalTree()
+        n = 0
+        for i in range(1, 1000, 80):
+            iv.insert(i, i + 10, dict(value=i*i))
+            # add is synonym for insert.
+            iv.add(i + 20, i + 30, dict(astr=str(i*i)))
+
+            # or insert/add an interval object with start, end attrs.
+            iv.insert_interval(Interval(i + 40, i + 50,
+                value=dict(astr=str(i*i))))
+            iv.add_interval(Interval(i + 60, i + 70,
+                value=dict(astr=str(i*i))))
+
+            n += 4 
+        self.intervals = self.iv = iv
+        self.nintervals = n
+
+    
+    def test_find(self):
+
+        r = self.iv.find(100, 200)
+        self.assertEqual(len(r), 5)
+
+    def test_traverse(self):
+        a = []
+        fn = a.append
+
+        self.iv.traverse(fn)
+        self.assertEqual(len(a), self.nintervals)
+    
+    def test_empty(self):
+        iv = IntervalTree()
+        self.assertEqual([], iv.find(100, 300))
+        self.assertEqual([], iv.after(100))
+        self.assertEqual([], iv.before(100))
+        self.assertEqual([], iv.after_interval(100))
+        self.assertEqual([], iv.before_interval(100))
+        self.assertEqual([], iv.upstream_of_interval(100))
+        self.assertEqual([], iv.downstream_of_interval(100))
+        self.assertEqual(None, iv.traverse(lambda x: x.append(1)))
+
+    def test_public_interval(self):
+
+        fn = lambda ival: self.assert_(ival.interval)
+        self.iv.traverse(fn)
+
+if __name__ == "__main__":
+
+    unittest.main()
diff --git a/lib/bx/intervals/io.py b/lib/bx/intervals/io.py
new file mode 100644
index 0000000..0384b40
--- /dev/null
+++ b/lib/bx/intervals/io.py
@@ -0,0 +1,224 @@
+"""
+Support for reading and writing genomic intervals from delimited text files.
+"""
+
+import sys
+from itertools import *
+from bx.tabular.io import *
+from bx.bitset import *
+
+class MissingFieldError( ParseError ):
+    pass
+
+class FieldFormatError( ParseError ):
+    def __init__( self, *args, **kwargs):
+        ParseError.__init__( self, *args, **kwargs )
+        self.expected = kwargs.get("expected",None)
+    def __str__( self ):
+        if self.expected:
+            return ParseError.__str__( self ) + ", " + self.expected + " expected"
+        else:
+            return ParseError.__str__( self )
+
+class StrandFormatError( ParseError ):
+    pass
+
+class GenomicInterval( TableRow ):
+    """
+    A genomic interval stored in a set of fields (a row of a table)
+    """
+    def __init__( self, reader, fields, chrom_col, start_col, end_col, strand_col, default_strand, fix_strand=False ):
+        TableRow.__init__( self, reader, fields )
+        self.chrom_col = chrom_col
+        self.start_col = start_col
+        self.end_col = end_col
+        self.strand_col = strand_col
+        self.nfields = nfields = len( fields )
+        # Parse chrom/source column
+        if chrom_col >= nfields:
+            raise MissingFieldError( "No field for chrom_col (%d)" % chrom_col )
+        self.chrom = fields[chrom_col].strip()
+        # Parse start column and ensure it is an integer
+        if start_col >= nfields:
+            raise MissingFieldError( "No field for start_col (%d)" % start_col )
+        try:
+            self.start = int( fields[start_col] )
+        except ValueError, e:
+            raise FieldFormatError( "Could not parse start_col: " + str( e ), expected="integer" )
+        # Parse end column and ensure it is an integer
+        if end_col >= nfields:
+            raise MissingFieldError( "No field for end_col (%d)" % end_col )
+        try:
+            self.end = int( fields[end_col] )
+        except ValueError, e:
+            raise FieldFormatError( "Could not parse end_col: " + str( e ), expected="integer" )
+        # Ensure start <= end
+        if self.end < self.start:
+            raise ParseError( "Start is greater than End. Interval length is < 1." )
+        # Parse strand and ensure it is valid
+        if strand_col >= nfields or strand_col < 0:
+            # This should probable be immutable since the fields are 
+            # not updated when it is set
+            self.strand = default_strand
+        else:
+            strand = fields[strand_col]
+            if strand == ".":
+                strand = default_strand
+            elif strand not in ( "+", "-" ):
+                if fix_strand:
+                    strand = "+"
+                else:
+                    raise StrandFormatError( "Strand must be either '+' or '-'" )
+            self.strand = strand
+    def __setattr__( self, name, value ):
+        if name == "chrom":
+            self.fields[self.chrom_col] = str( value )
+        elif name == "start":
+            self.fields[self.start_col] = str( value )
+        elif name == "end":
+            self.fields[self.end_col] = str( value )
+        elif name == "strand":
+            if self.strand_col < self.nfields and self.strand_col >= 0:
+                self.fields[self.strand_col] = str( value )
+        object.__setattr__( self, name, value )
+    def __str__( self ):
+        return "\t".join( self.fields )
+    def copy( self ):
+        return GenomicInterval(self.reader, list( self.fields ), self.chrom_col, self.start_col, self.end_col, self.strand_col, self.strand)
+
+class GenomicIntervalReader( TableReader ):
+    """
+    Reader for iterating a set of intervals in a tab separated file. Can
+    also parse header and comment lines if requested.
+    
+    >>> r = GenomicIntervalReader( [ "#chrom\\tname\\tstart\\tend\\textra",
+    ...               "chr1\\tfoo\\t1\\t100\\txxx",
+    ...               "chr2\\tbar\\t20\\t300\\txxx",
+    ...               "#I am a comment",
+    ...               "chr2\\tbar\\t20\\t300\\txxx" ], start_col=2, end_col=3 )
+    >>> elements = list( r )
+    >>> assert type( elements[0] ) is Header
+    >>> str( elements[0] )
+    '#chrom\\tname\\tstart\\tend\\textra'
+    >>> assert type( elements[1] ) is GenomicInterval
+    >>> print elements[1].start, elements[1].end
+    1 100
+    >>> str( elements[1] )
+    'chr1\\tfoo\\t1\\t100\\txxx'
+    >>> elements[1].start = 30
+    >>> print elements[1].start, elements[1].end
+    30 100
+    >>> str( elements[1] )
+    'chr1\\tfoo\\t30\\t100\\txxx'
+    >>> assert type( elements[2] ) is GenomicInterval
+    >>> assert type( elements[3] ) is Comment
+    >>> assert type( elements[4] ) is GenomicInterval
+    """
+    def __init__( self, input, chrom_col=0, start_col=1, end_col=2, strand_col=5, 
+                  default_strand="+", return_header=True, return_comments=True, force_header=None, fix_strand=False, comment_lines_startswith = ["#", "track "], allow_spaces=False ):
+        TableReader.__init__( self, input, return_header, return_comments, force_header, comment_lines_startswith )
+        self.chrom_col = chrom_col
+        self.start_col = start_col
+        self.end_col = end_col
+        self.strand_col = strand_col
+        self.default_strand = default_strand
+        self.fix_strand = fix_strand
+        self.allow_spaces = allow_spaces
+    def parse_row( self, line ):
+        # Try multiple separators. First tab, our expected splitter, than
+        # just whitespace in the case of problematic files with space instead of
+        # tab separation
+        seps = ["\t"]
+        if self.allow_spaces:
+            seps.append(None)
+        for i, sep in enumerate(seps):
+            try:
+                return GenomicInterval( self, line.split( sep ), self.chrom_col,
+                                        self.start_col, self.end_col,
+                                        self.strand_col, self.default_strand,
+                                        fix_strand=self.fix_strand )
+            except Exception, e:
+                # Catch and store the initial error
+                if i == 0:
+                    err = e
+        # Ran out of separators and still have errors, raise our problem
+        raise err
+
+    def binned_bitsets( self , upstream_pad=0, downstream_pad=0, lens={} ):
+        # The incoming lens dictionary is a dictionary of chromosome lengths
+        # which are used to initialize the bitsets.
+        last_chrom = None
+        last_bitset = None
+        bitsets = dict()
+        for interval in self:
+            if isinstance(interval, GenomicInterval):
+                chrom = interval[self.chrom_col]
+                if chrom != last_chrom:
+                    if chrom not in bitsets:
+                        size = lens.get( chrom, MAX )
+                        try:
+                            bbs = BinnedBitSet( size )
+                        except ValueError, e:
+                            # We will only reach here when constructing this bitset from the lens dict
+                            # since the value of MAX is always safe.
+                            raise Exception( "Invalid chrom length %s in 'lens' dictionary. %s" % ( str( size ), str( e ) ) )
+                        bitsets[chrom] = bbs
+                    last_chrom = chrom
+                    last_bitset = bitsets[chrom]
+                start = max( int( interval[self.start_col] ), 0 )
+                end = min( int( interval[self.end_col] ), last_bitset.size)
+                last_bitset.set_range( start, end-start )
+        return bitsets
+
+class NiceReaderWrapper( GenomicIntervalReader ):
+    def __init__( self, reader, **kwargs ):
+        GenomicIntervalReader.__init__( self, reader, **kwargs )
+        self.outstream = kwargs.get("outstream", None)
+        self.print_delegate = kwargs.get("print_delegate", None)
+        self.input_wrapper = iter( self.input )
+        self.input_iter = self.iterwrapper()
+        self.skipped = 0
+        self.skipped_lines = []
+    def __iter__( self ):
+        return self
+    def next( self ):
+        while 1:
+            try:
+                nextitem = GenomicIntervalReader.next( self )
+                return nextitem
+            except ParseError, e:
+                if self.outstream:
+                    if self.print_delegate and hasattr(self.print_delegate,"__call__"):
+                        self.print_delegate( self.outstream, e, self )
+                self.skipped += 1
+                # no reason to stuff an entire bad file into memmory
+                if self.skipped < 10:
+                    self.skipped_lines.append( ( self.linenum, self.current_line, str( e ) ) )
+    def iterwrapper( self ):
+        while 1:
+            self.current_line = self.input_wrapper.next()
+            yield self.current_line
+
+class BitsetSafeReaderWrapper( NiceReaderWrapper ):
+    def __init__( self, reader, lens={} ):
+        # This class handles any ValueError, IndexError and OverflowError exceptions that may be thrown when
+        # the bitsets are being created by skipping the problem lines.
+        # The incoming lens dictionary is a dictionary of chromosome lengths
+        # which are used to initialize the bitsets.
+        # It is assumed that the reader is an interval reader, i.e. it has chr_col, start_col, end_col and strand_col attributes. 
+        NiceReaderWrapper.__init__( self, reader.input, chrom_col=reader.chrom_col, start_col=reader.start_col, end_col=reader.end_col, strand_col=reader.strand_col)
+        self.lens = lens
+    def next( self ):
+        while True:
+            rval = NiceReaderWrapper.next( self )
+            if isinstance(rval, GenomicInterval) and rval.end > self.lens.get( rval.chrom, MAX ): # MAX_INT is defined in bx.bitset
+                try:
+                    # This will only work if reader is a NiceReaderWrapper
+                    self.skipped += 1
+                    # no reason to stuff an entire bad file into memmory
+                    if self.skipped < 10:
+                        self.skipped_lines.append( ( self.linenum, self.current_line, str( e ) ) )
+                except:
+                    pass
+            else:
+                return rval
diff --git a/lib/bx/intervals/operations/__init__.py b/lib/bx/intervals/operations/__init__.py
new file mode 100644
index 0000000..ad50a6f
--- /dev/null
+++ b/lib/bx/intervals/operations/__init__.py
@@ -0,0 +1,39 @@
+"""
+High level operations on genomic intervals. Most accept and produce iterables
+of `bx.io.inervals.io.GenomicInterval` objects. 
+"""
+
+from bx.bitset import *
+from bx.filter import *
+
+def warn( msg ):
+    print >> sys.stderr, msg
+
+def fail( msg ):
+    print >> sys.stderr, msg
+    sys.exit(1)
+
+BED_DEFAULT_COLS = 0, 1, 2, 5
+MAX_END = 512*1024*1024
+
+def bits_set_in_range( bits, range_start, range_end ):
+    """
+    Yield start,end tuples for each span of set bits in [range_start,range_end)
+    """
+    end = range_start
+    while 1:
+        start = bits.next_set( end )
+        end = min( bits.next_clear( start ), range_end )
+        if start >= end: break
+        yield start, end
+        
+def bits_clear_in_range( bits, range_start, range_end ):
+    """
+    Yield start,end tuples for each span of clear bits in [range_start,range_end)
+    """
+    end = range_start
+    while 1:
+        start = bits.next_clear( end )
+        if start >= range_end: break
+        end = min( bits.next_set( start ), range_end )
+        yield start, end
diff --git a/lib/bx/intervals/operations/base_coverage.py b/lib/bx/intervals/operations/base_coverage.py
new file mode 100644
index 0000000..95a79da
--- /dev/null
+++ b/lib/bx/intervals/operations/base_coverage.py
@@ -0,0 +1,29 @@
+"""
+Determine the number of bases covered by a set of intervals.
+"""
+
+import psyco_full
+
+import traceback
+import fileinput
+from warnings import warn
+
+from bx.intervals.io import *
+from bx.intervals.operations import *
+
+def base_coverage( reader ):
+    # Handle any ValueError, IndexError and OverflowError exceptions that may be thrown when
+    # the bitsets are being created by skipping the problem lines
+    base_reader = BitsetSafeReaderWrapper( reader, lens={} )
+    bitsets = base_reader.binned_bitsets()
+    coverage = 0
+    for chrom in bitsets:
+        try:
+            coverage += bitsets[chrom].count_range(0, MAX_END)
+        except IndexError, e:
+            base_reader.skipped += 1
+            # no reason to stuff an entire bad file into memmory
+            if base_reader.skipped < 10:
+                base_reader.skipped_lines.append( ( base_reader.linenum, base_reader.current_line, str( e ) ) )
+            continue
+    return coverage
diff --git a/lib/bx/intervals/operations/complement.py b/lib/bx/intervals/operations/complement.py
new file mode 100644
index 0000000..0ff0804
--- /dev/null
+++ b/lib/bx/intervals/operations/complement.py
@@ -0,0 +1,55 @@
+"""
+Complement a set of intervals.
+"""
+
+import psyco_full
+
+import traceback
+import fileinput
+from warnings import warn
+
+from bx.intervals.io import *
+from bx.intervals.operations import *
+from bx.bitset import MAX
+
+def complement( reader, lens ):
+    # Handle any ValueError, IndexError and OverflowError exceptions that may be thrown when
+    # the bitsets are being created by skipping the problem lines
+    complement_reader = BitsetSafeReaderWrapper( reader, lens=lens )
+    bitsets = complement_reader.binned_bitsets( upstream_pad=0, downstream_pad=0, lens=lens )
+    # NOT them all
+    for key, value in bitsets.items():
+        value.invert()
+    # Read remaining intervals and subtract
+    for chrom in bitsets:
+        bitset = bitsets[chrom]
+        out_intervals = bits_set_in_range( bitset, 0, lens.get( chrom, MAX ) )
+        try:
+            # Write the intervals
+            for start, end in out_intervals:
+                fields = ["."  for x in range(max(complement_reader.chrom_col, complement_reader.start_col, complement_reader.end_col)+1)]
+                # default the column to a + if it exists
+                if complement_reader.strand_col < len( fields ) and complement_reader.strand_col >= 0:
+                    fields[complement_reader.strand_col] = "+"
+                fields[complement_reader.chrom_col] = chrom
+                fields[complement_reader.start_col] = start
+                fields[complement_reader.end_col] = end
+                new_interval = GenomicInterval(complement_reader, fields, complement_reader.chrom_col, complement_reader.start_col, complement_reader.end_col, complement_reader.strand_col, "+")
+                yield new_interval
+        except IndexError, e:
+            complement_reader.skipped += 1
+            # no reason to stuff an entire bad file into memmory
+            if complement_reader.skipped < 10:
+                complement_reader.skipped_lines.append( ( complement_reader.linenum, complement_reader.current_line, str( e ) ) )
+            continue
+
+
+# def main():
+#     # test it all out
+#     f1 = fileinput.FileInput("dataset_7.dat")
+#     g1 = GenomicIntervalReader(f1)
+#     for interval in complement(g1,{"chr":16000000}):
+#         print "\t".join(interval)
+# 
+# if __name__ == "__main__":
+#     main()
diff --git a/lib/bx/intervals/operations/concat.py b/lib/bx/intervals/operations/concat.py
new file mode 100644
index 0000000..ce660f6
--- /dev/null
+++ b/lib/bx/intervals/operations/concat.py
@@ -0,0 +1,61 @@
+"""
+Concatenate sets of intervals. 
+
+Preserves format of the first input -- it is possible to concat two files that
+have different column orders. Of course, the meta-data of the second will be
+lost (and filled with a "."). If all of the files (GenomicInteralReaders) are
+the same format, sameformat=True will preserve all columns of the first input,
+cuts extra columns on subsequent input, and pads missing columns. If
+sameformat=False then extra columns are filled with ".".
+"""
+
+import psyco_full
+
+import traceback
+import fileinput
+from warnings import warn
+
+from bx.intervals.io import *
+from bx.intervals.operations import *
+
+def concat(readers, comments=True, header=True, sameformat=True):
+    # Save columns from the first input
+    chrom_col = readers[0].chrom_col
+    start_col = readers[0].start_col
+    end_col = readers[0].end_col
+    strand_col = readers[0].strand_col
+    nfields = None
+    firstdataset = True
+    output = False
+    for intervals in readers:
+        for interval in intervals:
+            if isinstance(interval, GenomicInterval):
+                if not nfields: nfields = interval.nfields
+                out_interval = interval.copy()
+                if sameformat or firstdataset:
+                    # everything except the first input has to be
+                    # trimmed or padded to match the first input
+                    if len(out_interval.fields) > nfields:
+                        out_interval.fields = out_interval.fields[0:nfields]
+                        while len(out_interval.fields) < nfields:
+                            out_interval.fields.append(".")
+                    output = True
+                    yield out_interval
+                else:
+                    chrom = out_interval.chrom
+                    start = out_interval.start
+                    end = out_interval.end
+                    strand = out_interval.strand
+                    out_interval.fields = ["." for col in range(nfields)]  
+                    out_interval.fields[chrom_col] = chrom
+                    out_interval.fields[start_col] = str(start)
+                    out_interval.fields[end_col] = str(end)
+                    # Strand is optional, might not exist in output
+                    if strand_col < len( out_interval.fields ):
+                        out_interval.fields[strand_col] = strand
+                    yield out_interval
+            elif isinstance(interval, Header) and header:
+                yield interval
+            elif isinstance(interval, Comment) and comments:
+                yield interval
+        if output and firstdataset: firstdataset = False
diff --git a/lib/bx/intervals/operations/coverage.py b/lib/bx/intervals/operations/coverage.py
new file mode 100644
index 0000000..c106637
--- /dev/null
+++ b/lib/bx/intervals/operations/coverage.py
@@ -0,0 +1,72 @@
+"""
+Determine amount of each interval in one set covered by the intervals of 
+another set. Adds two columns to the first input, giving number of bases 
+covered and percent coverage on the second input.
+"""
+
+import traceback
+import fileinput
+from warnings import warn
+
+from bx.intervals.io import *
+from bx.intervals.operations import *
+
+def coverage(readers, comments=True):
+    # The incoming lens dictionary is a dictionary of chromosome lengths which are used to initialize the bitsets.
+    primary = readers[0]
+    intersect = readers[1:]
+    # Handle any ValueError, IndexError and OverflowError exceptions that may be thrown when
+    # the bitsets are being created by skipping the problem lines
+    intersect[0] = BitsetSafeReaderWrapper( intersect[0], lens={} )
+    bitsets = intersect[0].binned_bitsets()
+    intersect = intersect[1:]
+    for andset in intersect:
+        bitset2 = andset.binned_bitsets()
+        for chrom in bitsets:
+            if chrom not in bitset2: continue
+            bitsets[chrom].ior(bitset2[chrom])
+        intersect = intersect[1:]
+
+    # Read remaining intervals and give coverage
+    for interval in primary:
+        if isinstance(interval, Header):
+            yield interval
+        if isinstance(interval, Comment) and comments:
+            yield interval
+        elif isinstance(interval, GenomicInterval):
+            chrom = interval.chrom
+            start = int(interval.start)
+            end = int(interval.end)
+            if start > end:
+                try:
+                    # This will only work if primary is a NiceReaderWrapper
+                    primary.skipped += 1
+                    # no reason to stuff an entire bad file into memmory
+                    if primary.skipped < 10:
+                        primary.skipped_lines.append( ( primary.linenum, primary.current_line, "Interval start after end!" ) )
+                except:
+                    pass
+                continue
+            if chrom not in bitsets:
+                bases_covered = 0
+                percent = 0.0
+            else:
+                try:
+                    bases_covered = bitsets[ chrom ].count_range( start, end-start )
+                except IndexError, e:
+                    try:
+                        # This will only work if primary is a NiceReaderWrapper
+                        primary.skipped += 1
+                        # no reason to stuff an entire bad file into memmory
+                        if primary.skipped < 10:
+                            primary.skipped_lines.append( ( primary.linenum, primary.current_line, str( e ) ) )
+                    except:
+                        pass
+                    continue
+                if (end - start) == 0:
+                    percent = 0
+                else:
+                    percent = float(bases_covered) / float(end - start)
+            interval.fields.append(str(bases_covered))
+            interval.fields.append(str(percent))
+            yield interval
diff --git a/lib/bx/intervals/operations/find_clusters.py b/lib/bx/intervals/operations/find_clusters.py
new file mode 100644
index 0000000..819bb80
--- /dev/null
+++ b/lib/bx/intervals/operations/find_clusters.py
@@ -0,0 +1,162 @@
+"""
+Find clusters of intervals within a set of intervals.  A cluster is a
+group (of size minregions) of intervals within a specific distance (of
+mincols) of each other.
+
+Returns Cluster objects, which have a chrom, start, end, and lines (a
+list of linenumbers from the original file).  The original can then be
+ran through with the linenumbers to extract clustered regions without
+disturbing original order, or the clusters may themselves be written
+as intervals.
+"""
+
+import random
+import math
+
+import traceback
+import fileinput
+from warnings import warn
+
+from bx.intervals.cluster import *
+from bx.intervals.io import *
+from bx.intervals.operations import *
+
+
+def find_clusters(reader, mincols=1, minregions=2):
+    extra = dict()
+    chroms = dict()
+    linenum = -1
+    for interval in reader:
+        linenum += 1
+        if not isinstance(interval, GenomicInterval):
+            extra[linenum] = interval
+        else:
+            if interval.chrom not in chroms:
+                chroms[interval.chrom] = ClusterTree( mincols, minregions )
+            try:
+                chroms[interval.chrom].insert( interval.start, interval.end, linenum )
+            except OverflowError, e:
+                try:
+                    # This will work only if reader is a NiceReaderWrapper
+                    reader.skipped += 1
+                    if reader.skipped < 10:
+                        reader.skipped_lines.append( ( reader.linenum, reader.current_line, str( e ) ) )
+                except:
+                    pass
+                continue
+    return chroms, extra
+
+
+### DEPRECATED: Use the ClusterTree in bx.intervals.cluster for this.
+### It does the same thing, but is a C implementation.
+class ClusterNode( object ):
+    def __init__( self, start, end, linenum, mincols, minregions ):
+        # Python lacks the binomial distribution, so we convert a
+        # uniform into a binomial because it naturally scales with
+        # tree size.  Also, python's uniform is perfect since the
+        # upper limit is not inclusive, which gives us undefined here.
+        self.priority = math.ceil( (-1.0 / math.log(.5)) * math.log( -1.0 / (random.uniform(0,1) - 1)))
+        self.start = start
+        self.end = end
+        self.left = None
+        self.right = None
+        self.lines = [linenum]
+        self.mincols = mincols
+        self.minregions = minregions
+        
+    def insert( self, start, end, linenum ):
+        if start - self.mincols > self.end:
+            # insert to right tree
+            if self.right:
+                self.right = self.right.insert( start, end, linenum )
+            else:
+                self.right = ClusterNode(start, end, linenum, self.mincols, self.minregions)
+            # rebalance tree
+            if self.priority < self.right.priority:
+                return self.rotateleft()
+        elif end + self.mincols < self.start:
+            # insert to left tree
+            if self.left:
+                self.left = self.left.insert( start, end, linenum )
+            else:
+                self.left = ClusterNode(start, end, linenum, self.mincols, self.minregions)
+            # rebalance tree
+            if self.priority < self.left.priority:
+                return self.rotateright()
+        else:
+            # insert here
+            self.start = min(self.start, start)
+            self.end = max(self.end, end)
+            self.lines.append(linenum)
+            # recursive call to push nodes up
+            if self.left:
+                self.left = self.left.push_up(self)
+            if self.right:
+                self.right = self.right.push_up(self)
+        return self
+
+    def rotateright( self ):
+        root = self.left
+        self.left = self.left.right
+        root.right = self
+        return root
+        
+    def rotateleft( self ):
+        root = self.right
+        self.right = self.right.left
+        root.left = self
+        return root
+        
+    def push_up( self, topnode ):
+        # Note: this function does not affect heap property
+        # Distance method removed for inline, faster?
+        distance = max(self.start, topnode.start) - min(self.end, topnode.end)
+        if distance <= self.mincols:
+            topnode.start = min(self.start, topnode.start)
+            topnode.end = max(self.end, topnode.end)
+            for linenum in self.lines:
+                topnode.lines.append(linenum)
+            if self.right:
+                return self.right.push_up( topnode )
+            if self.left:
+                return self.left.push_up( topnode )
+            return None
+        if self.end < topnode.start and self.right:
+            self.right = self.right.push_up( topnode )
+        if self.start > topnode.end and self.left:
+            self.left = self.left.push_up( topnode )
+        return self
+
+    def getintervals( self ):
+        if self.left:
+            for start, end in self.left.getintervals(minregions):
+                yield start, end
+        if len(self.lines) >= minregions:
+            yield self.start, self.end
+        if self.right:
+            for start, end in self.right.getintervals(minregions):
+                yield start, end
+
+    def getlines( self ):
+        if self.left:
+            for line in self.left.getlines():
+                yield line
+        if len(self.lines) >= minregions:
+            for line in self.lines:
+                yield line
+        if self.right:
+            for line in self.right.getlines():
+                yield line
+                
+## def main():
+##     f1 = fileinput.FileInput("big.bed")
+##     g1 = GenomicIntervalReader(f1)
+##     returntree, extra = find_clusters(g1, mincols=50)
+##     print "All found"
+##     for chrom, value in returntree.items():
+##         for start, end in value.getregions():
+##             print chrom+"\t"+str(start)+"\t"+str(end)
+##         for line in value.getlines():
+##             print "Line:\t"+str(line)
+
+## main()
diff --git a/lib/bx/intervals/operations/intersect.py b/lib/bx/intervals/operations/intersect.py
new file mode 100644
index 0000000..6380eb1
--- /dev/null
+++ b/lib/bx/intervals/operations/intersect.py
@@ -0,0 +1,77 @@
+"""
+Compute the intersection of two sets of genomic intervals, either base-by-base
+or at the interval level. The returned GenomicIntervalReader will be in
+the order of the first set of intervals passed in, with the corresponding 
+additional fields.
+"""
+
+import traceback
+import fileinput
+from warnings import warn
+
+from bx.intervals.io import *
+from bx.intervals.operations import *
+
+def intersect(readers, mincols=1, upstream_pad=0, downstream_pad=0, pieces=True, lens={}, comments=True):
+    # The incoming lens dictionary is a dictionary of chromosome lengths which are used to initialize the bitsets.
+    # Read all but first into bitsets and intersect to one
+    primary = readers[0]
+    intersect = readers[1:]
+    # Handle any ValueError, IndexError and OverflowError exceptions that may be thrown when
+    # the bitsets are being created by skipping the problem lines
+    intersect[0] = BitsetSafeReaderWrapper( intersect[0], lens=lens )
+    bitsets = intersect[0].binned_bitsets( upstream_pad=upstream_pad, downstream_pad=downstream_pad, lens=lens )
+    intersect = intersect[1:]
+    for andset in intersect:
+        bitset2 = andset.binned_bitsets(upstream_pad = upstream_pad, downstream_pad = downstream_pad, lens = lens)
+        for chrom in bitsets:
+            if chrom not in bitset2: continue
+            bitsets[chrom].iand(bitset2[chrom])
+        intersect = intersect[1:]
+    
+    # Read remaining intervals and intersect
+    for interval in primary:
+        if isinstance(interval, Header):
+            yield interval
+        if isinstance(interval, Comment) and comments:
+            yield interval
+        elif isinstance(interval, GenomicInterval):
+            chrom = interval.chrom
+            start = int( interval.start )
+            end = int( interval.end )
+            if chrom not in bitsets:
+                continue
+            if start > end:
+                try:
+                    # This will only work if primary is a NiceReaderWrapper
+                    primary.skipped += 1
+                    # no reason to stuff an entire bad file into memmory
+                    if primary.skipped < 10:
+                        primary.skipped_lines.append( ( primary.linenum, primary.current_line, "Interval start after end!" ) )
+                except:
+                    pass
+                continue
+            out_intervals = []
+            # Intersect or Overlap
+            try:
+                if bitsets[ chrom ].count_range( start, end-start ) >= mincols:                
+                    if pieces:
+                        out_intervals = bits_set_in_range( bitsets[chrom], start, end )
+                    else:
+                        out_intervals = [ ( start, end ) ]
+                # Write the intervals
+                for start, end in out_intervals:
+                    new_interval = interval.copy()
+                    new_interval.start = start
+                    new_interval.end = end
+                    yield new_interval
+            except IndexError, e:
+                try:
+                    # This will only work if primary is a NiceReaderWrapper
+                    primary.skipped += 1
+                    # no reason to stuff an entire bad file into memmory
+                    if primary.skipped < 10:
+                        primary.skipped_lines.append( ( primary.linenum, primary.current_line, str( e ) ) )
+                except:
+                    pass
+                continue
diff --git a/lib/bx/intervals/operations/join.py b/lib/bx/intervals/operations/join.py
new file mode 100644
index 0000000..1ff7533
--- /dev/null
+++ b/lib/bx/intervals/operations/join.py
@@ -0,0 +1,137 @@
+"""
+Join two sets of intervals using their overlap as the key.  The
+intervals MUST be sorted by chrom(lexicographically),
+start(arithmetically) and end(arithmetically).  This works by simply
+walking through the inputs in O(n) time.
+"""
+
+import psyco_full
+
+import math
+import traceback
+import fileinput
+from warnings import warn
+
+from bx.intervals.io import *
+from bx.intervals.operations import *
+from quicksect import IntervalTree
+
+def join(leftSet, rightSet, mincols=1, leftfill=True, rightfill=True):
+    # Read rightSet into memory:
+    rightlen = 0
+    leftlen = 0
+    rightTree = IntervalTree()
+    for item in rightSet:
+        if isinstance(item, GenomicInterval):
+            rightTree.insert( item, rightSet.linenum, item.fields )
+            if rightlen == 0: rightlen = item.nfields
+
+    for interval in leftSet:
+        if leftlen == 0 and isinstance(interval, GenomicInterval):
+            leftlen = interval.nfields
+        if not isinstance(interval, GenomicInterval):
+            yield interval
+        else:
+            result = []
+            rightTree.intersect( interval, lambda node: result.append( node ) )
+            overlap_not_met = 0
+            for item in result:
+                if item.start in range(interval.start,interval.end+1) and item.end not in range(interval.start,interval.end+1):
+                    overlap = interval.end-item.start
+                elif item.end in range(interval.start,interval.end+1) and item.start not in range(interval.start,interval.end+1):
+                    overlap = item.end-interval.start
+                elif item.start in range(interval.start,interval.end+1) and item.end in range(interval.start,interval.end+1):
+                    overlap = item.end-item.start
+                else:   #the intersecting item's start and end are outside the interval range
+                    overlap = interval.end-interval.start
+                if overlap < mincols:
+                    overlap_not_met += 1
+                    continue
+                outfields = list(interval)
+                map(outfields.append, item.other)
+                setattr( item, "visited", True )
+                yield outfields
+            if (len(result) == 0 or overlap_not_met == len(result)) and rightfill:
+                outfields = list(interval)
+                for x in range(rightlen): outfields.append(".")
+                yield outfields
+
+    if leftfill:
+        def report_unvisited( node, results ):
+            if not hasattr(node, "visited"):
+                results.append( node )
+        results = []
+        rightTree.traverse( lambda x: report_unvisited( x, results ) )
+        for item in results:
+            outfields = list()
+            for x in range(leftlen): outfields.append(".")
+            map(outfields.append, item.other)
+            yield outfields
+
+
+def interval_cmp(a, b):
+    interval1 = a[0]
+    interval2 = b[0]
+    if not (isinstance(interval1, GenomicInterval) and isinstance(interval2, GenomicInterval)):
+        return 0
+    # Both are intervals
+    if interval1.chrom == interval2.chrom:
+        center1 = interval1.start + ((interval1.end - interval1.start) / 2)
+        center2 = interval2.start + ((interval2.end - interval2.start) / 2)
+        return center1 - center2
+    else:
+        if interval1.chrom > interval2.chrom:
+            return 1
+        else:
+            return -1
+
+    return 0
+
+def findintersect(interval, sortedlist, mincols):
+    # find range of intervals that intersect via a binary search
+    # find lower bound
+    x = len(sortedlist) / 2
+    n = int(math.pow(2,math.ceil(math.log(len(sortedlist),2))))
+
+    not_found = True
+    not_done = True
+    while not_found and not_done:
+        n = n / 2
+        if n == 0:
+            n = 1
+            not_done = False
+        if x >= len(sortedlist):
+            x -= n
+        elif x < 0:
+            x += n
+        else:
+            if findoverlap(sortedlist[x][0], interval) >= mincols:
+                not_found = False
+            else:
+                comp = interval_cmp(sortedlist[x], [interval, 0])
+                if comp > 0:
+                    x -= n
+                else:
+                    x += n
+
+    print "\t".join(sortedlist[x][0].fields)
+    print "not_found = " + str(not_found)
+    if not_found:
+        return 0,-1
+
+    lowerbound = x
+    middlebound = x
+    upperbound = x
+    while (lowerbound > -1) and (findoverlap(sortedlist[lowerbound-1][0],interval) >= mincols):
+        lowerbound -= 1
+    while (upperbound+1 < len(sortedlist)) and (findoverlap(sortedlist[upperbound+1][0],interval) >= mincols):
+        upperbound += 1
+
+    return lowerbound, upperbound
+
+def findoverlap(a, b):
+    # overlapping
+    if a.chrom == b.chrom:
+        return min(a.end, b.end) - max(a.start, b.start)
+    else:
+        return 0
diff --git a/lib/bx/intervals/operations/merge.py b/lib/bx/intervals/operations/merge.py
new file mode 100644
index 0000000..4ebbdb8
--- /dev/null
+++ b/lib/bx/intervals/operations/merge.py
@@ -0,0 +1,40 @@
+"""
+Merge overlapping regions in two sets of genomic intervals.
+"""
+
+import psyco_full
+
+import traceback
+import fileinput
+from warnings import warn
+
+from bx.intervals.io import *
+from bx.intervals.operations import *
+
+# sorting could make this a less memory intensive operation(?)
+def merge( interval, mincols=1 ):
+    # Handle any ValueError, IndexError and OverflowError exceptions that may be thrown when
+    # the bitsets are being created by skipping the problem lines
+    interval = BitsetSafeReaderWrapper( interval, lens={} )
+    bitsets = interval.binned_bitsets()
+    if interval.header:
+        yield interval.header
+    for chrom in bitsets:
+        bitset = bitsets[chrom]
+        output = ["."] * (max(interval.chrom_col, interval.start_col, interval.end_col) + 1)
+        output[interval.chrom_col] = chrom
+        try:
+            for start, end in bits_set_in_range(bitset,0, MAX_END):
+                output[interval.start_col] = str(start)
+                output[interval.end_col] = str(end)
+                yield output
+        except IndexError, e:
+            try:
+                # This will work only if interval is a NiceReaderWrapper
+                interval.skipped += 1
+                # no reason to stuff an entire bad file into memmory
+                if interval.skipped < 10:
+                    interval.skipped_lines.append( ( interval.linenum, interval.current_line, str( e ) ) )
+            except:
+                pass
+            continue
diff --git a/lib/bx/intervals/operations/quicksect.py b/lib/bx/intervals/operations/quicksect.py
new file mode 100644
index 0000000..de05158
--- /dev/null
+++ b/lib/bx/intervals/operations/quicksect.py
@@ -0,0 +1,155 @@
+"""
+Intersects ... faster.  Suports GenomicInterval datatype and multiple
+chromosomes.
+"""
+import math
+import time
+import sys
+import random
+
+class IntervalTree( object ):
+    def __init__( self ):
+        self.chroms = {}
+    def insert( self, interval, linenum=0, other=None ):
+        chrom = interval.chrom
+        start = interval.start
+        end = interval.end
+        if interval.chrom in self.chroms:
+            self.chroms[chrom] = self.chroms[chrom].insert( start, end, linenum, other )
+        else:
+            self.chroms[chrom] = IntervalNode( start, end, linenum, other )
+    def intersect( self, interval, report_func ):
+        chrom = interval.chrom
+        start = interval.start
+        end = interval.end
+        if chrom in self.chroms:
+            self.chroms[chrom].intersect( start, end, report_func )
+    def traverse( self, func ):
+        for item in self.chroms.itervalues():
+            item.traverse( func )
+
+class IntervalNode( object ):
+    def __init__( self, start, end, linenum=0, other=None ):
+        # Python lacks the binomial distribution, so we convert a
+        # uniform into a binomial because it naturally scales with
+        # tree size.  Also, python's uniform is perfect since the
+        # upper limit is not inclusive, which gives us undefined here.
+        self.priority = math.ceil( (-1.0 / math.log(.5)) * math.log( -1.0 / (random.uniform(0,1) - 1)))
+        self.start = start
+        self.end = end
+        self.maxend = self.end
+        self.minend = self.end
+        self.left = None
+        self.right = None
+        self.linenum = linenum
+        self.other = other
+    def insert( self, start, end, linenum=0, other=None ):
+        root = self
+        if start > self.start:
+            # insert to right tree
+            if self.right:
+                self.right = self.right.insert( start, end, linenum, other )
+            else:
+                self.right = IntervalNode(start, end, linenum, other )
+            # rebalance tree
+            if self.priority < self.right.priority:
+                root = self.rotateleft()
+        else:
+            # insert to left tree
+            if self.left:
+                self.left = self.left.insert( start, end, linenum, other )
+            else:
+                self.left = IntervalNode(start, end, linenum, other )
+            # rebalance tree
+            if self.priority < self.left.priority:
+                root = self.rotateright()
+        if root.right and root.left: 
+            root.maxend = max( root.end, root.right.maxend, root.left.maxend )
+            root.minend = min( root.end, root.right.minend, root.left.minend )
+        elif root.right: 
+            root.maxend = max( root.end, root.right.maxend )
+            root.minend = min( root.end, root.right.minend )
+        elif root.left:
+            root.maxend = max( root.end, root.left.maxend )
+            root.minend = min( root.end, root.left.minend )
+        return root
+
+    def rotateright( self ):
+        root = self.left
+        self.left = self.left.right
+        root.right = self
+        if self.right and self.left: 
+            self.maxend = max(self.end, self.right.maxend, self.left.maxend)
+            self.minend = min(self.end, self.right.minend, self.left.minend )
+        elif self.right:
+            self.maxend = max(self.end, self.right.maxend)
+            self.minend = min(self.end, self.right.minend)
+        elif self.left:
+            self.maxend = max(self.end, self.left.maxend)
+            self.minend = min(self.end, self.left.minend )
+        return root
+        
+    def rotateleft( self ):
+        root = self.right
+        self.right = self.right.left
+        root.left = self
+        if self.right and self.left: 
+            self.maxend = max(self.end, self.right.maxend, self.left.maxend)
+            self.minend = min(self.end, self.right.minend, self.left.minend )
+        elif self.right:
+            self.maxend = max(self.end, self.right.maxend)
+            self.minend = min(self.end, self.right.minend)
+        elif self.left:
+            self.maxend = max(self.end, self.left.maxend)
+            self.minend = min(self.end, self.left.minend )
+        return root
+
+    def intersect( self, start, end, report_func ):
+        if start < self.end and end > self.start: report_func( self )
+        if self.left and start < self.left.maxend:
+            self.left.intersect( start, end, report_func )
+        if self.right and end > self.start:
+            self.right.intersect( start, end, report_func )
+
+    def traverse( self, func ):
+        if self.left: self.left.traverse( func )
+        func( self )
+        if self.right: self.right.traverse( func )
+
+def main():
+    test = None
+    intlist = []
+    for x in range(20000):
+        start = random.randint(0,1000000)
+        end = start + random.randint(1, 1000)
+        if test: test = test.insert( start, end )
+        else: test = IntervalNode( start, end )
+        intlist.append( (start, end) )
+    starttime = time.clock()
+    for x in range(5000):
+        start = random.randint(0, 10000000)
+        end = start + random.randint(1, 1000)
+        result = []
+        test.intersect( start, end, lambda x: result.append(x.linenum) )
+    print "%f for tree method" % (time.clock() - starttime)
+    starttime = time.clock()
+    for x in range(5000):
+        start = random.randint(0, 10000000)
+        end = start + random.randint(1, 1000)
+        bad_sect( intlist, start, end)
+    print "%f for linear (bad) method" % (time.clock() - starttime)
+
+def test_func( node ):
+    print "[%d, %d), %d" % (node.start, node.end, node.maxend)
+
+def bad_sect( lst, int_start, int_end ):
+    intersection = []
+    for start, end in lst:
+        if int_start < end and int_end > start:
+            intersection.append( (start, end) )
+    return intersection
+
+if __name__ == "__main__":
+    main()
+
+
diff --git a/lib/bx/intervals/operations/subtract.py b/lib/bx/intervals/operations/subtract.py
new file mode 100644
index 0000000..75384e2
--- /dev/null
+++ b/lib/bx/intervals/operations/subtract.py
@@ -0,0 +1,72 @@
+#!/usr/bin/env python
+"""
+Subtract one set of genomic intervals from another (base-by-base or whole
+intervals). The returned GenomicIntervals will be in the order
+of the first set of intervals passed in, with the corresponding
+meta-data.
+"""
+
+import traceback
+import fileinput
+from warnings import warn
+
+from bx.intervals.io import *
+from bx.intervals.operations import *
+
+def subtract(readers, mincols=1, upstream_pad=0, downstream_pad=0, pieces=True, lens={}, comments=True):
+    # The incoming lens dictionary is a dictionary of chromosome lengths which are used to initialize the bitsets.
+    # Read all but first into bitsets and union to one (if confused, read DeMorgan's...)
+    primary = readers[0]
+    union = readers[1:]
+    # Handle any ValueError, IndexError and OverflowError exceptions that may be thrown when
+    # the bitsets are being created by skipping the problem lines
+    union[0] = BitsetSafeReaderWrapper( union[0], lens=lens )
+    bitsets = union[0].binned_bitsets( upstream_pad=upstream_pad, downstream_pad=downstream_pad, lens=lens )
+    union = union[1:]
+    for andset in union:
+        bitset2 = andset.binned_bitsets(upstream_pad = upstream_pad, downstream_pad = downstream_pad, lens = lens)
+        for chrom in bitset2:
+            if chrom not in bitsets:
+                bitsets[chrom] = bitset2[chrom]
+            else:
+                bitsets[chrom].ior(bitset2[chrom])
+    
+    # Read remaining intervals and subtract
+    for interval in primary:
+        if isinstance(interval, Header):
+            yield interval
+        if isinstance(interval, Comment) and comments:
+            yield interval
+        elif isinstance(interval, GenomicInterval):
+            chrom = interval.chrom
+            if chrom not in bitsets:
+                yield interval
+            else:
+                start = int(interval.start)
+                end = int(interval.end)
+                if start > end: warn( "Interval start after end!" )
+                out_intervals = []
+                # Find the intervals that meet the criteria (for the three sensible
+                # permutations of reverse and pieces)
+                try:
+                    if bitsets[ chrom ].count_range( start, end-start ) >= mincols:                
+                        if pieces:
+                            out_intervals = bits_clear_in_range( bitsets[chrom], start, end )
+                    else:
+                        out_intervals = [ ( start, end ) ]
+                    # Write the intervals
+                    for start, end in out_intervals:
+                        new_interval = interval.copy()
+                        new_interval.start = start
+                        new_interval.end = end
+                        yield new_interval
+                except IndexError, e:
+                    try:
+                        # This will work only if primary is a NiceReaderWrapper
+                        primary.skipped += 1
+                        # no reason to stuff an entire bad file into memmory
+                        if primary.skipped < 10:
+                            primary.skipped_lines.append( ( primary.linenum, primary.current_line, str( e ) ) )
+                    except:
+                        pass
+                    continue
diff --git a/lib/bx/intervals/random_intervals.py b/lib/bx/intervals/random_intervals.py
new file mode 100644
index 0000000..08e37bb
--- /dev/null
+++ b/lib/bx/intervals/random_intervals.py
@@ -0,0 +1,212 @@
+"""
+Classes for generating random sets of intervals over larger regions.
+"""
+
+from bx.bitset import *
+import bisect
+random = __import__( 'random' )
+
+class MaxtriesException( Exception ):
+    pass
+
+def throw_random_list( lengths, mask, allow_overlap=False ):
+    rval = []
+    throw_random_gap_list( lengths, mask, lambda s, e: rval.append( ( s, e ) ), allow_overlap )
+    assert sum( b - a for a, b in rval ) == sum( lengths )
+    return rval
+
+def throw_random_bits( lengths, mask, allow_overlap=False ):
+    rval = BitSet( mask.size )
+    throw_random_gap_list( lengths, mask, lambda s, e: rval.set_range( s, e - s ), allow_overlap )
+    if not allow_overlap:
+        assert rval.count_range( 0, rval.size ) == sum( lengths )
+    return rval
+
+def throw_random_gap_list( lengths, mask, save_interval_func, allow_overlap=False ):
+    """
+    Generates a set of non-overlapping random intervals from a length 
+    distribution.
+    
+    `lengths`: list containing the length of each interval to be generated.
+               We expect this to be sorted by decreasing length to minimize
+               the chance of failure (MaxtriesException) and for some
+               performance gains when allow_overlap==True and there are
+               duplicate lengths
+    `mask`: a BitSet in which set bits represent regions not to place 
+            intervals. The size of the region is also determined from the
+            mask.
+    """
+    # Use mask to find the gaps;  gaps is a list of (length,start,end)
+    lengths = [length for length in lengths if length > 0]
+    min_length = min( lengths )
+    gaps = []
+    start = end = 0
+    while 1:
+        start = mask.next_clear( end )
+        if start == mask.size: break
+        end = mask.next_set( start )
+        if end-start >= min_length:
+            gaps.append( ( end-start, start, None ) )
+    # Sort (long regions first)    
+    gaps.sort()
+    gaps.reverse()
+    # Throw
+    throw_random_private( lengths, gaps, save_interval_func, allow_overlap, three_args=False )
+
+def throw_random_intervals( lengths, regions, save_interval_func=None, allow_overlap=False ):
+    """
+    Generates a set of non-overlapping random intervals from a length 
+    distribution.
+    
+    `lengths`: list containing the length of each interval to be generated.
+               We expect this to be sorted by decreasing length to minimize
+               the chance of failure (MaxtriesException) and for some
+               performance gains when allow_overlap==True and there are
+               duplicate lengths.
+    `regions`: A list of regions in which intervals can be placed.  Elements
+               are tuples or lists of the form (start, end, ...), where ...
+               indicates any number of items (including zero).
+    `save_interval_func`: A function accepting three arguments which will be 
+                          passed the (start,stop,region) for each generated 
+                          interval, where region is an entry in the regions
+                          list.  If this is None, the generated intervals will
+                          be returned as a list of elements copied from the
+                          region with start and end modified.
+    """
+    # Copy regions
+    regions = [( x[1]-x[0], x[0], x ) for x in regions]
+    # Sort (long regions first)    
+    regions.sort()
+    regions.reverse()
+    # Throw
+    if (save_interval_func != None):
+        throw_random_private( lengths, regions, save_interval_func, allow_overlap )
+        return
+    else:
+        intervals = []
+        save_interval_func = lambda s, e, rgn: intervals.append( overwrite_start_end ( s, e, rgn ) )
+        throw_random_private( lengths, regions, save_interval_func, allow_overlap )
+        return intervals
+
+def overwrite_start_end(s,e,rgn):
+    rgn = list(rgn)
+    rgn[0] = s
+    rgn[1] = e
+    return tuple(rgn)
+
+
+def throw_random_private( lengths, regions, save_interval_func, allow_overlap=False, three_args=True ):
+    """
+    (Internal function;  we expect calls only through the interface functions
+    above)
+    
+    `lengths`: A list containing the length of each interval to be generated.
+    `regions`: A list of regions in which intervals can be placed, sorted by
+               decreasing length.  Elements are triples of the form (length,
+               start, extra), This list CAN BE MODIFIED by this function.
+    `save_interval_func`: A function accepting three arguments which will be 
+                          passed the (start,stop,extra) for each generated 
+                          interval.
+    """
+
+    # Implementation:
+    #   We keep a list of the regions, sorted from largest to smallest.  We then
+    #   place each length by following steps:
+    #     (1) construct a candidate counts array (cc array)
+    #     (2) choose a candidate at random
+    #     (3) find region containing that candidate
+    #     (4) map candidate to position in that region
+    #     (5) split region if not allowing overlaps
+    #     (6) report placed segment
+    #
+    #   The cc array is only constructed if there's a change (different length
+    #   to place, or the region list has changed).  It contains, for each
+    #   region, the total number of number of candidate positions in regions
+    #   *preceding* it in the region list:
+    #     cc[i] = sum over k in 0..(i-1) of length[i] - L + 1
+    #   where N is the number of regions and L is the length being thrown.
+    #   At the same time, we determine the total number of candidates (the total
+    #   number of places the current length can be placed) and the index range
+    #   of regions into which the length will fit.
+    #
+    #   example:
+    #     for L = 20
+    #     i =           0   1   2   3   4   5   6   7   8   9
+    #     length[i] =  96  66  56  50  48  40  29  17  11   8
+    #     cc[i] =       0  77 124 161 192 221 242   X   X   X
+    #     candidates = 252
+    #     lo_rgn = 0
+    #     hi_rgn = 6
+    #
+    #   The candidate is chosen in (0..candidates-1).  The candidate counts
+    #   array allows us to do a binary search to locate the region that holds that
+    #   candidate.  Continuing the example above, we choose a random candidate
+    #   s in (0..251).  If s happens to be in (124..160), it will be mapped to
+    #   region 2 at start position s-124.
+    #
+    #   During the binary search, if we are looking at region 3, if s < cc[3]
+    #   then the desired region is region 2 or lower.  Otherwise it is region 3 or
+    #   higher.
+
+    min_length = min( lengths )
+    prev_length = None # (force initial cc array construction)
+    cc = [0] * (len( regions ) + len(lengths) - 1)
+    num_thrown = 0
+    for length in lengths:
+        # construct cc array (only needed if length has changed or region list has
+        # changed)
+        if length != prev_length:
+            prev_length = length
+            assert len( cc ) >= len( regions )
+            candidates = 0
+            hi_rgn = 0
+            for region in regions:
+                rgn_len = region[0]
+                if rgn_len < length:
+                    break
+                cc[hi_rgn] = candidates
+                candidates += rgn_len - length + 1
+                hi_rgn += 1
+            if candidates == 0:
+                raise MaxtriesException( "No region can fit an interval of length %d (we threw %d of %d)" \
+                                       % ( length, num_thrown,len( lengths ) ) )
+            hi_rgn -= 1
+        # Select a candidate
+        s = random.randrange( candidates )
+        #..
+        #..for ix in range( len( regions ) ):
+        #..    region = regions[ix]
+        #..    if ix <= hi_rgn: print "%2s: %5s %5s %5s" % ( ix, region[1], region[0], cc[ix] )
+        #..    else:            print "%2s: %5s %5s %5s" % ( ix, region[1], region[0], "X" )
+        #..print "s = %s (of %s candidates)" % ( s, candidates )
+        # Locate region containing that candidate, by binary search
+        lo = 0
+        hi = hi_rgn
+        while hi > lo:
+            mid = (lo + hi + 1) / 2     # (we round up to prevent infinite loop)
+            if s < cc[mid]: hi = mid-1  # (s <  num candidates from 0..mid-1)
+            else:           lo = mid    # (s >= num candidates from 0..mid-1)
+        s -= cc[lo]
+        # If we are not allowing overlaps we will remove the placed interval
+        # from the region list
+        if allow_overlap:
+            rgn_length, rgn_start, rgn_extra = regions[lo]
+        else:
+            # Remove the chosen region and split
+            rgn_length, rgn_start, rgn_extra = regions.pop( lo )
+            rgn_end = rgn_start + rgn_length
+            assert s >= 0
+            assert rgn_start + s + length <= rgn_end, "Expected: %d + %d + %d == %d <= %d" % ( rgn_start, s, length, rgn_start + s + length, rgn_end )
+            regions.reverse()
+            if s >= min_length:
+                bisect.insort( regions, ( s, rgn_start, rgn_extra ) )
+            if s + length <= rgn_length - min_length:
+                bisect.insort( regions, ( rgn_length - ( s + length ), rgn_start + s + length, rgn_extra ) )
+            regions.reverse()
+            prev_length = None # (force cc array construction)
+        # Save the new interval
+        if (three_args):
+            save_interval_func( rgn_start + s, rgn_start + s + length, rgn_extra )
+        else:
+            save_interval_func( rgn_start + s, rgn_start + s + length )
+        num_thrown += 1
diff --git a/lib/bx/intseq/__init__.py b/lib/bx/intseq/__init__.py
new file mode 100644
index 0000000..9f07e65
--- /dev/null
+++ b/lib/bx/intseq/__init__.py
@@ -0,0 +1,3 @@
+"""
+Tools for working with strings over interger alphabets efficiently. 
+"""
\ No newline at end of file
diff --git a/lib/bx/intseq/ngramcount.c b/lib/bx/intseq/ngramcount.c
new file mode 100644
index 0000000..c75b3a4
--- /dev/null
+++ b/lib/bx/intseq/ngramcount.c
@@ -0,0 +1,2711 @@
+/* Generated by Cython 0.18 on Mon Jul 15 13:25:44 2013 */
+
+#define PY_SSIZE_T_CLEAN
+#include "Python.h"
+#ifndef Py_PYTHON_H
+    #error Python headers needed to compile C extensions, please install development version of Python.
+#elif PY_VERSION_HEX < 0x02040000
+    #error Cython requires Python 2.4+.
+#else
+#include <stddef.h> /* For offsetof */
+#ifndef offsetof
+#define offsetof(type, member) ( (size_t) & ((type*)0) -> member )
+#endif
+#if !defined(WIN32) && !defined(MS_WINDOWS)
+  #ifndef __stdcall
+    #define __stdcall
+  #endif
+  #ifndef __cdecl
+    #define __cdecl
+  #endif
+  #ifndef __fastcall
+    #define __fastcall
+  #endif
+#endif
+#ifndef DL_IMPORT
+  #define DL_IMPORT(t) t
+#endif
+#ifndef DL_EXPORT
+  #define DL_EXPORT(t) t
+#endif
+#ifndef PY_LONG_LONG
+  #define PY_LONG_LONG LONG_LONG
+#endif
+#ifndef Py_HUGE_VAL
+  #define Py_HUGE_VAL HUGE_VAL
+#endif
+#ifdef PYPY_VERSION
+#define CYTHON_COMPILING_IN_PYPY 1
+#define CYTHON_COMPILING_IN_CPYTHON 0
+#else
+#define CYTHON_COMPILING_IN_PYPY 0
+#define CYTHON_COMPILING_IN_CPYTHON 1
+#endif
+#if PY_VERSION_HEX < 0x02050000
+  typedef int Py_ssize_t;
+  #define PY_SSIZE_T_MAX INT_MAX
+  #define PY_SSIZE_T_MIN INT_MIN
+  #define PY_FORMAT_SIZE_T ""
+  #define CYTHON_FORMAT_SSIZE_T ""
+  #define PyInt_FromSsize_t(z) PyInt_FromLong(z)
+  #define PyInt_AsSsize_t(o)   __Pyx_PyInt_AsInt(o)
+  #define PyNumber_Index(o)    ((PyNumber_Check(o) && !PyFloat_Check(o)) ? PyNumber_Int(o) : \
+                                (PyErr_Format(PyExc_TypeError, \
+                                              "expected index value, got %.200s", Py_TYPE(o)->tp_name), \
+                                 (PyObject*)0))
+  #define __Pyx_PyIndex_Check(o) (PyNumber_Check(o) && !PyFloat_Check(o) && \
+                                  !PyComplex_Check(o))
+  #define PyIndex_Check __Pyx_PyIndex_Check
+  #define PyErr_WarnEx(category, message, stacklevel) PyErr_Warn(category, message)
+  #define __PYX_BUILD_PY_SSIZE_T "i"
+#else
+  #define __PYX_BUILD_PY_SSIZE_T "n"
+  #define CYTHON_FORMAT_SSIZE_T "z"
+  #define __Pyx_PyIndex_Check PyIndex_Check
+#endif
+#if PY_VERSION_HEX < 0x02060000
+  #define Py_REFCNT(ob) (((PyObject*)(ob))->ob_refcnt)
+  #define Py_TYPE(ob)   (((PyObject*)(ob))->ob_type)
+  #define Py_SIZE(ob)   (((PyVarObject*)(ob))->ob_size)
+  #define PyVarObject_HEAD_INIT(type, size) \
+          PyObject_HEAD_INIT(type) size,
+  #define PyType_Modified(t)
+  typedef struct {
+     void *buf;
+     PyObject *obj;
+     Py_ssize_t len;
+     Py_ssize_t itemsize;
+     int readonly;
+     int ndim;
+     char *format;
+     Py_ssize_t *shape;
+     Py_ssize_t *strides;
+     Py_ssize_t *suboffsets;
+     void *internal;
+  } Py_buffer;
+  #define PyBUF_SIMPLE 0
+  #define PyBUF_WRITABLE 0x0001
+  #define PyBUF_FORMAT 0x0004
+  #define PyBUF_ND 0x0008
+  #define PyBUF_STRIDES (0x0010 | PyBUF_ND)
+  #define PyBUF_C_CONTIGUOUS (0x0020 | PyBUF_STRIDES)
+  #define PyBUF_F_CONTIGUOUS (0x0040 | PyBUF_STRIDES)
+  #define PyBUF_ANY_CONTIGUOUS (0x0080 | PyBUF_STRIDES)
+  #define PyBUF_INDIRECT (0x0100 | PyBUF_STRIDES)
+  #define PyBUF_RECORDS (PyBUF_STRIDES | PyBUF_FORMAT | PyBUF_WRITABLE)
+  #define PyBUF_FULL (PyBUF_INDIRECT | PyBUF_FORMAT | PyBUF_WRITABLE)
+  typedef int (*getbufferproc)(PyObject *, Py_buffer *, int);
+  typedef void (*releasebufferproc)(PyObject *, Py_buffer *);
+#endif
+#if PY_MAJOR_VERSION < 3
+  #define __Pyx_BUILTIN_MODULE_NAME "__builtin__"
+  #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \
+          PyCode_New(a, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
+#else
+  #define __Pyx_BUILTIN_MODULE_NAME "builtins"
+  #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \
+          PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
+#endif
+#if PY_MAJOR_VERSION < 3 && PY_MINOR_VERSION < 6
+  #define PyUnicode_FromString(s) PyUnicode_Decode(s, strlen(s), "UTF-8", "strict")
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define Py_TPFLAGS_CHECKTYPES 0
+  #define Py_TPFLAGS_HAVE_INDEX 0
+#endif
+#if (PY_VERSION_HEX < 0x02060000) || (PY_MAJOR_VERSION >= 3)
+  #define Py_TPFLAGS_HAVE_NEWBUFFER 0
+#endif
+#if PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND)
+  #define CYTHON_PEP393_ENABLED 1
+  #define __Pyx_PyUnicode_READY(op)       (likely(PyUnicode_IS_READY(op)) ? \
+                                              0 : _PyUnicode_Ready((PyObject *)(op)))
+  #define __Pyx_PyUnicode_GET_LENGTH(u)   PyUnicode_GET_LENGTH(u)
+  #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_READ_CHAR(u, i)
+  #define __Pyx_PyUnicode_READ(k, d, i)   PyUnicode_READ(k, d, i)
+#else
+  #define CYTHON_PEP393_ENABLED 0
+  #define __Pyx_PyUnicode_READY(op)       (0)
+  #define __Pyx_PyUnicode_GET_LENGTH(u)   PyUnicode_GET_SIZE(u)
+  #define __Pyx_PyUnicode_READ_CHAR(u, i) ((Py_UCS4)(PyUnicode_AS_UNICODE(u)[i]))
+  #define __Pyx_PyUnicode_READ(k, d, i)   ((k=k), (Py_UCS4)(((Py_UNICODE*)d)[i]))
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define PyBaseString_Type            PyUnicode_Type
+  #define PyStringObject               PyUnicodeObject
+  #define PyString_Type                PyUnicode_Type
+  #define PyString_Check               PyUnicode_Check
+  #define PyString_CheckExact          PyUnicode_CheckExact
+#endif
+#if PY_VERSION_HEX < 0x02060000
+  #define PyBytesObject                PyStringObject
+  #define PyBytes_Type                 PyString_Type
+  #define PyBytes_Check                PyString_Check
+  #define PyBytes_CheckExact           PyString_CheckExact
+  #define PyBytes_FromString           PyString_FromString
+  #define PyBytes_FromStringAndSize    PyString_FromStringAndSize
+  #define PyBytes_FromFormat           PyString_FromFormat
+  #define PyBytes_DecodeEscape         PyString_DecodeEscape
+  #define PyBytes_AsString             PyString_AsString
+  #define PyBytes_AsStringAndSize      PyString_AsStringAndSize
+  #define PyBytes_Size                 PyString_Size
+  #define PyBytes_AS_STRING            PyString_AS_STRING
+  #define PyBytes_GET_SIZE             PyString_GET_SIZE
+  #define PyBytes_Repr                 PyString_Repr
+  #define PyBytes_Concat               PyString_Concat
+  #define PyBytes_ConcatAndDel         PyString_ConcatAndDel
+#endif
+#if PY_VERSION_HEX < 0x02060000
+  #define PySet_Check(obj)             PyObject_TypeCheck(obj, &PySet_Type)
+  #define PyFrozenSet_Check(obj)       PyObject_TypeCheck(obj, &PyFrozenSet_Type)
+#endif
+#ifndef PySet_CheckExact
+  #define PySet_CheckExact(obj)        (Py_TYPE(obj) == &PySet_Type)
+#endif
+#define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type)
+#if PY_MAJOR_VERSION >= 3
+  #define PyIntObject                  PyLongObject
+  #define PyInt_Type                   PyLong_Type
+  #define PyInt_Check(op)              PyLong_Check(op)
+  #define PyInt_CheckExact(op)         PyLong_CheckExact(op)
+  #define PyInt_FromString             PyLong_FromString
+  #define PyInt_FromUnicode            PyLong_FromUnicode
+  #define PyInt_FromLong               PyLong_FromLong
+  #define PyInt_FromSize_t             PyLong_FromSize_t
+  #define PyInt_FromSsize_t            PyLong_FromSsize_t
+  #define PyInt_AsLong                 PyLong_AsLong
+  #define PyInt_AS_LONG                PyLong_AS_LONG
+  #define PyInt_AsSsize_t              PyLong_AsSsize_t
+  #define PyInt_AsUnsignedLongMask     PyLong_AsUnsignedLongMask
+  #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define PyBoolObject                 PyLongObject
+#endif
+#if PY_VERSION_HEX < 0x03020000
+  typedef long Py_hash_t;
+  #define __Pyx_PyInt_FromHash_t PyInt_FromLong
+  #define __Pyx_PyInt_AsHash_t   PyInt_AsLong
+#else
+  #define __Pyx_PyInt_FromHash_t PyInt_FromSsize_t
+  #define __Pyx_PyInt_AsHash_t   PyInt_AsSsize_t
+#endif
+#if (PY_MAJOR_VERSION < 3) || (PY_VERSION_HEX >= 0x03010300)
+  #define __Pyx_PySequence_GetSlice(obj, a, b) PySequence_GetSlice(obj, a, b)
+  #define __Pyx_PySequence_SetSlice(obj, a, b, value) PySequence_SetSlice(obj, a, b, value)
+  #define __Pyx_PySequence_DelSlice(obj, a, b) PySequence_DelSlice(obj, a, b)
+#else
+  #define __Pyx_PySequence_GetSlice(obj, a, b) (unlikely(!(obj)) ? \
+        (PyErr_SetString(PyExc_SystemError, "null argument to internal routine"), (PyObject*)0) : \
+        (likely((obj)->ob_type->tp_as_mapping) ? (PySequence_GetSlice(obj, a, b)) : \
+            (PyErr_Format(PyExc_TypeError, "'%.200s' object is unsliceable", (obj)->ob_type->tp_name), (PyObject*)0)))
+  #define __Pyx_PySequence_SetSlice(obj, a, b, value) (unlikely(!(obj)) ? \
+        (PyErr_SetString(PyExc_SystemError, "null argument to internal routine"), -1) : \
+        (likely((obj)->ob_type->tp_as_mapping) ? (PySequence_SetSlice(obj, a, b, value)) : \
+            (PyErr_Format(PyExc_TypeError, "'%.200s' object doesn't support slice assignment", (obj)->ob_type->tp_name), -1)))
+  #define __Pyx_PySequence_DelSlice(obj, a, b) (unlikely(!(obj)) ? \
+        (PyErr_SetString(PyExc_SystemError, "null argument to internal routine"), -1) : \
+        (likely((obj)->ob_type->tp_as_mapping) ? (PySequence_DelSlice(obj, a, b)) : \
+            (PyErr_Format(PyExc_TypeError, "'%.200s' object doesn't support slice deletion", (obj)->ob_type->tp_name), -1)))
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define PyMethod_New(func, self, klass) ((self) ? PyMethod_New(func, self) : PyInstanceMethod_New(func))
+#endif
+#if PY_VERSION_HEX < 0x02050000
+  #define __Pyx_GetAttrString(o,n)   PyObject_GetAttrString((o),((char *)(n)))
+  #define __Pyx_SetAttrString(o,n,a) PyObject_SetAttrString((o),((char *)(n)),(a))
+  #define __Pyx_DelAttrString(o,n)   PyObject_DelAttrString((o),((char *)(n)))
+#else
+  #define __Pyx_GetAttrString(o,n)   PyObject_GetAttrString((o),(n))
+  #define __Pyx_SetAttrString(o,n,a) PyObject_SetAttrString((o),(n),(a))
+  #define __Pyx_DelAttrString(o,n)   PyObject_DelAttrString((o),(n))
+#endif
+#if PY_VERSION_HEX < 0x02050000
+  #define __Pyx_NAMESTR(n) ((char *)(n))
+  #define __Pyx_DOCSTR(n)  ((char *)(n))
+#else
+  #define __Pyx_NAMESTR(n) (n)
+  #define __Pyx_DOCSTR(n)  (n)
+#endif
+
+
+#if PY_MAJOR_VERSION >= 3
+  #define __Pyx_PyNumber_Divide(x,y)         PyNumber_TrueDivide(x,y)
+  #define __Pyx_PyNumber_InPlaceDivide(x,y)  PyNumber_InPlaceTrueDivide(x,y)
+#else
+  #define __Pyx_PyNumber_Divide(x,y)         PyNumber_Divide(x,y)
+  #define __Pyx_PyNumber_InPlaceDivide(x,y)  PyNumber_InPlaceDivide(x,y)
+#endif
+
+#ifndef __PYX_EXTERN_C
+  #ifdef __cplusplus
+    #define __PYX_EXTERN_C extern "C"
+  #else
+    #define __PYX_EXTERN_C extern
+  #endif
+#endif
+
+#if defined(WIN32) || defined(MS_WINDOWS)
+#define _USE_MATH_DEFINES
+#endif
+#include <math.h>
+#define __PYX_HAVE__bx__intseq__ngramcount
+#define __PYX_HAVE_API__bx__intseq__ngramcount
+#ifdef _OPENMP
+#include <omp.h>
+#endif /* _OPENMP */
+
+#ifdef PYREX_WITHOUT_ASSERTIONS
+#define CYTHON_WITHOUT_ASSERTIONS
+#endif
+
+#ifndef CYTHON_INLINE
+  #if defined(__GNUC__)
+    #define CYTHON_INLINE __inline__
+  #elif defined(_MSC_VER)
+    #define CYTHON_INLINE __inline
+  #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+    #define CYTHON_INLINE inline
+  #else
+    #define CYTHON_INLINE
+  #endif
+#endif
+#ifndef CYTHON_UNUSED
+# if defined(__GNUC__)
+#   if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
+#     define CYTHON_UNUSED __attribute__ ((__unused__))
+#   else
+#     define CYTHON_UNUSED
+#   endif
+# elif defined(__ICC) || (defined(__INTEL_COMPILER) && !defined(_MSC_VER))
+#   define CYTHON_UNUSED __attribute__ ((__unused__))
+# else
+#   define CYTHON_UNUSED
+# endif
+#endif
+typedef struct {PyObject **p; char *s; const long n; const char* encoding; const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry; /*proto*/
+
+#define __Pyx_PyBytes_FromUString(s) PyBytes_FromString((char*)s)
+#define __Pyx_PyBytes_AsUString(s)   ((unsigned char*) PyBytes_AsString(s))
+#define __Pyx_Owned_Py_None(b) (Py_INCREF(Py_None), Py_None)
+#define __Pyx_PyBool_FromLong(b) ((b) ? (Py_INCREF(Py_True), Py_True) : (Py_INCREF(Py_False), Py_False))
+static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*);
+static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x);
+static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*);
+static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t);
+static CYTHON_INLINE size_t __Pyx_PyInt_AsSize_t(PyObject*);
+#if CYTHON_COMPILING_IN_CPYTHON
+#define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x))
+#else
+#define __pyx_PyFloat_AsDouble(x) PyFloat_AsDouble(x)
+#endif
+#define __pyx_PyFloat_AsFloat(x) ((float) __pyx_PyFloat_AsDouble(x))
+
+
+#ifdef __GNUC__
+  /* Test for GCC > 2.95 */
+  #if __GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))
+    #define likely(x)   __builtin_expect(!!(x), 1)
+    #define unlikely(x) __builtin_expect(!!(x), 0)
+  #else /* __GNUC__ > 2 ... */
+    #define likely(x)   (x)
+    #define unlikely(x) (x)
+  #endif /* __GNUC__ > 2 ... */
+#else /* __GNUC__ */
+  #define likely(x)   (x)
+  #define unlikely(x) (x)
+#endif /* __GNUC__ */
+    
+static PyObject *__pyx_m;
+static PyObject *__pyx_b;
+static PyObject *__pyx_empty_tuple;
+static PyObject *__pyx_empty_bytes;
+static int __pyx_lineno;
+static int __pyx_clineno = 0;
+static const char * __pyx_cfilenm= __FILE__;
+static const char *__pyx_filename;
+
+
+static const char *__pyx_f[] = {
+  "ngramcount.pyx",
+};
+
+/*--- Type declarations ---*/
+struct __pyx_t_2bx_6intseq_10ngramcount_PyArrayInterface;
+typedef struct __pyx_t_2bx_6intseq_10ngramcount_PyArrayInterface __pyx_t_2bx_6intseq_10ngramcount_PyArrayInterface;
+
+/* "bx/intseq/ngramcount.pyx":21
+ * WRITEABLE=0x400
+ * 
+ * ctypedef struct PyArrayInterface:             # <<<<<<<<<<<<<<
+ *     int two              # contains the integer 2 as a sanity check
+ *     int nd               # number of dimensions
+ */
+struct __pyx_t_2bx_6intseq_10ngramcount_PyArrayInterface {
+  int two;
+  int nd;
+  char typekind;
+  int itemsize;
+  int flags;
+  Py_intptr_t *shape;
+  Py_intptr_t *strides;
+  void *data;
+};
+#ifndef CYTHON_REFNANNY
+  #define CYTHON_REFNANNY 0
+#endif
+#if CYTHON_REFNANNY
+  typedef struct {
+    void (*INCREF)(void*, PyObject*, int);
+    void (*DECREF)(void*, PyObject*, int);
+    void (*GOTREF)(void*, PyObject*, int);
+    void (*GIVEREF)(void*, PyObject*, int);
+    void* (*SetupContext)(const char*, int, const char*);
+    void (*FinishContext)(void**);
+  } __Pyx_RefNannyAPIStruct;
+  static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL;
+  static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname); /*proto*/
+  #define __Pyx_RefNannyDeclarations void *__pyx_refnanny = NULL;
+#ifdef WITH_THREAD
+  #define __Pyx_RefNannySetupContext(name, acquire_gil) \
+          if (acquire_gil) { \
+              PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure(); \
+              __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__); \
+              PyGILState_Release(__pyx_gilstate_save); \
+          } else { \
+              __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__); \
+          }
+#else
+  #define __Pyx_RefNannySetupContext(name, acquire_gil) \
+          __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__)
+#endif
+  #define __Pyx_RefNannyFinishContext() \
+          __Pyx_RefNanny->FinishContext(&__pyx_refnanny)
+  #define __Pyx_INCREF(r)  __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_DECREF(r)  __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_GOTREF(r)  __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_XINCREF(r)  do { if((r) != NULL) {__Pyx_INCREF(r); }} while(0)
+  #define __Pyx_XDECREF(r)  do { if((r) != NULL) {__Pyx_DECREF(r); }} while(0)
+  #define __Pyx_XGOTREF(r)  do { if((r) != NULL) {__Pyx_GOTREF(r); }} while(0)
+  #define __Pyx_XGIVEREF(r) do { if((r) != NULL) {__Pyx_GIVEREF(r);}} while(0)
+#else
+  #define __Pyx_RefNannyDeclarations
+  #define __Pyx_RefNannySetupContext(name, acquire_gil)
+  #define __Pyx_RefNannyFinishContext()
+  #define __Pyx_INCREF(r) Py_INCREF(r)
+  #define __Pyx_DECREF(r) Py_DECREF(r)
+  #define __Pyx_GOTREF(r)
+  #define __Pyx_GIVEREF(r)
+  #define __Pyx_XINCREF(r) Py_XINCREF(r)
+  #define __Pyx_XDECREF(r) Py_XDECREF(r)
+  #define __Pyx_XGOTREF(r)
+  #define __Pyx_XGIVEREF(r)
+#endif /* CYTHON_REFNANNY */
+#define __Pyx_CLEAR(r)    do { PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);} while(0)
+#define __Pyx_XCLEAR(r)   do { if((r) != NULL) {PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);}} while(0)
+
+static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
+    Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/
+
+static void __Pyx_RaiseDoubleKeywordsError(const char* func_name, PyObject* kw_name); /*proto*/
+
+static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
+    PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
+    const char* function_name); /*proto*/
+
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j) {
+    PyObject *r;
+    if (!j) return NULL;
+    r = PyObject_GetItem(o, j);
+    Py_DECREF(j);
+    return r;
+}
+#define __Pyx_GetItemInt_List(o, i, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \
+                                                    __Pyx_GetItemInt_List_Fast(o, i) : \
+                                                    __Pyx_GetItemInt_Generic(o, to_py_func(i)))
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    if (likely((0 <= i) & (i < PyList_GET_SIZE(o)))) {
+        PyObject *r = PyList_GET_ITEM(o, i);
+        Py_INCREF(r);
+        return r;
+    }
+    else if ((-PyList_GET_SIZE(o) <= i) & (i < 0)) {
+        PyObject *r = PyList_GET_ITEM(o, PyList_GET_SIZE(o) + i);
+        Py_INCREF(r);
+        return r;
+    }
+    return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
+#else
+    return PySequence_GetItem(o, i);
+#endif
+}
+#define __Pyx_GetItemInt_Tuple(o, i, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \
+                                                    __Pyx_GetItemInt_Tuple_Fast(o, i) : \
+                                                    __Pyx_GetItemInt_Generic(o, to_py_func(i)))
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    if (likely((0 <= i) & (i < PyTuple_GET_SIZE(o)))) {
+        PyObject *r = PyTuple_GET_ITEM(o, i);
+        Py_INCREF(r);
+        return r;
+    }
+    else if ((-PyTuple_GET_SIZE(o) <= i) & (i < 0)) {
+        PyObject *r = PyTuple_GET_ITEM(o, PyTuple_GET_SIZE(o) + i);
+        Py_INCREF(r);
+        return r;
+    }
+    return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
+#else
+    return PySequence_GetItem(o, i);
+#endif
+}
+#define __Pyx_GetItemInt(o, i, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \
+                                                    __Pyx_GetItemInt_Fast(o, i) : \
+                                                    __Pyx_GetItemInt_Generic(o, to_py_func(i)))
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    if (PyList_CheckExact(o)) {
+        Py_ssize_t n = (likely(i >= 0)) ? i : i + PyList_GET_SIZE(o);
+        if (likely((n >= 0) & (n < PyList_GET_SIZE(o)))) {
+            PyObject *r = PyList_GET_ITEM(o, n);
+            Py_INCREF(r);
+            return r;
+        }
+    }
+    else if (PyTuple_CheckExact(o)) {
+        Py_ssize_t n = (likely(i >= 0)) ? i : i + PyTuple_GET_SIZE(o);
+        if (likely((n >= 0) & (n < PyTuple_GET_SIZE(o)))) {
+            PyObject *r = PyTuple_GET_ITEM(o, n);
+            Py_INCREF(r);
+            return r;
+        }
+    } else {  /* inlined PySequence_GetItem() */
+        PySequenceMethods *m = Py_TYPE(o)->tp_as_sequence;
+        if (likely(m && m->sq_item)) {
+            if (unlikely(i < 0) && likely(m->sq_length)) {
+                Py_ssize_t l = m->sq_length(o);
+                if (unlikely(l < 0)) return NULL;
+                i += l;
+            }
+            return m->sq_item(o, i);
+        }
+    }
+#else
+    if (PySequence_Check(o)) {
+        return PySequence_GetItem(o, i);
+    }
+#endif
+    return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
+}
+
+static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/
+
+static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level); /*proto*/
+
+static int __Pyx_Print(PyObject*, PyObject *, int); /*proto*/
+#if CYTHON_COMPILING_IN_PYPY || PY_MAJOR_VERSION >= 3
+static PyObject* __pyx_print = 0;
+static PyObject* __pyx_print_kwargs = 0;
+#endif
+
+static int __Pyx_PrintOne(PyObject* stream, PyObject *o); /*proto*/
+
+static CYTHON_INLINE unsigned char __Pyx_PyInt_AsUnsignedChar(PyObject *);
+
+static CYTHON_INLINE unsigned short __Pyx_PyInt_AsUnsignedShort(PyObject *);
+
+static CYTHON_INLINE unsigned int __Pyx_PyInt_AsUnsignedInt(PyObject *);
+
+static CYTHON_INLINE char __Pyx_PyInt_AsChar(PyObject *);
+
+static CYTHON_INLINE short __Pyx_PyInt_AsShort(PyObject *);
+
+static CYTHON_INLINE int __Pyx_PyInt_AsInt(PyObject *);
+
+static CYTHON_INLINE signed char __Pyx_PyInt_AsSignedChar(PyObject *);
+
+static CYTHON_INLINE signed short __Pyx_PyInt_AsSignedShort(PyObject *);
+
+static CYTHON_INLINE signed int __Pyx_PyInt_AsSignedInt(PyObject *);
+
+static CYTHON_INLINE int __Pyx_PyInt_AsLongDouble(PyObject *);
+
+static CYTHON_INLINE unsigned long __Pyx_PyInt_AsUnsignedLong(PyObject *);
+
+static CYTHON_INLINE unsigned PY_LONG_LONG __Pyx_PyInt_AsUnsignedLongLong(PyObject *);
+
+static CYTHON_INLINE long __Pyx_PyInt_AsLong(PyObject *);
+
+static CYTHON_INLINE PY_LONG_LONG __Pyx_PyInt_AsLongLong(PyObject *);
+
+static CYTHON_INLINE signed long __Pyx_PyInt_AsSignedLong(PyObject *);
+
+static CYTHON_INLINE signed PY_LONG_LONG __Pyx_PyInt_AsSignedLongLong(PyObject *);
+
+static int __Pyx_check_binary_version(void);
+
+typedef struct {
+    int code_line;
+    PyCodeObject* code_object;
+} __Pyx_CodeObjectCacheEntry;
+struct __Pyx_CodeObjectCache {
+    int count;
+    int max_count;
+    __Pyx_CodeObjectCacheEntry* entries;
+};
+static struct __Pyx_CodeObjectCache __pyx_code_cache = {0,0,NULL};
+static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line);
+static PyCodeObject *__pyx_find_code_object(int code_line);
+static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object);
+
+static void __Pyx_AddTraceback(const char *funcname, int c_line,
+                               int py_line, const char *filename); /*proto*/
+
+static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
+
+
+/* Module declarations from 'bx.intseq.ngramcount' */
+static PyObject *__pyx_f_2bx_6intseq_10ngramcount__count_ngrams(int *, int, int *, int, int); /*proto*/
+#define __Pyx_MODULE_NAME "bx.intseq.ngramcount"
+int __pyx_module_is_main_bx__intseq__ngramcount = 0;
+
+/* Implementation of 'bx.intseq.ngramcount' */
+static PyObject *__pyx_pf_2bx_6intseq_10ngramcount_count_ngrams(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_ints, int __pyx_v_n, int __pyx_v_radix); /* proto */
+static char __pyx_k_1[] = "Array interface sanity check failed, got %d";
+static char __pyx_k_2[] = "Input array must be 1d";
+static char __pyx_k_3[] = "Input array must contain integers";
+static char __pyx_k_4[] = "Input array must contain 32bit integers";
+static char __pyx_k_5[] = "Input array must be contiguous";
+static char __pyx_k_6[] = "Input array must be aligned";
+static char __pyx_k_7[] = "Input array must not be byteswapped";
+static char __pyx_k_8[] = "Array interface sanity check failed";
+static char __pyx_k_9[] = "breaking, letter";
+static char __pyx_k_10[] = "\nTools for counting words (n-grams) in integer sequences.\n";
+static char __pyx_k_13[] = "/aut/proj/odenas/software/bx-python/lib/bx/intseq/ngramcount.pyx";
+static char __pyx_k_14[] = "bx.intseq.ngramcount";
+static char __pyx_k__i[] = "i";
+static char __pyx_k__n[] = "n";
+static char __pyx_k__ints[] = "ints";
+static char __pyx_k__rval[] = "rval";
+static char __pyx_k__dtype[] = "dtype";
+static char __pyx_k__int32[] = "int32";
+static char __pyx_k__numpy[] = "numpy";
+static char __pyx_k__radix[] = "radix";
+static char __pyx_k__zeros[] = "zeros";
+static char __pyx_k__ALIGNED[] = "ALIGNED";
+static char __pyx_k__FORTRAN[] = "FORTRAN";
+static char __pyx_k____main__[] = "__main__";
+static char __pyx_k____test__[] = "__test__";
+static char __pyx_k__WRITEABLE[] = "WRITEABLE";
+static char __pyx_k__ints_desc[] = "ints_desc";
+static char __pyx_k__rval_desc[] = "rval_desc";
+static char __pyx_k__CONTIGUOUS[] = "CONTIGUOUS";
+static char __pyx_k__NOTSWAPPED[] = "NOTSWAPPED";
+static char __pyx_k__count_ngrams[] = "count_ngrams";
+static char __pyx_k__ints_desc_obj[] = "ints_desc_obj";
+static char __pyx_k__rval_desc_obj[] = "rval_desc_obj";
+static char __pyx_k____array_struct__[] = "__array_struct__";
+static PyObject *__pyx_kp_s_1;
+static PyObject *__pyx_kp_s_13;
+static PyObject *__pyx_n_s_14;
+static PyObject *__pyx_kp_s_2;
+static PyObject *__pyx_kp_s_3;
+static PyObject *__pyx_kp_s_4;
+static PyObject *__pyx_kp_s_5;
+static PyObject *__pyx_kp_s_6;
+static PyObject *__pyx_kp_s_7;
+static PyObject *__pyx_kp_s_8;
+static PyObject *__pyx_kp_s_9;
+static PyObject *__pyx_n_s__ALIGNED;
+static PyObject *__pyx_n_s__CONTIGUOUS;
+static PyObject *__pyx_n_s__FORTRAN;
+static PyObject *__pyx_n_s__NOTSWAPPED;
+static PyObject *__pyx_n_s__WRITEABLE;
+static PyObject *__pyx_n_s____array_struct__;
+static PyObject *__pyx_n_s____main__;
+static PyObject *__pyx_n_s____test__;
+static PyObject *__pyx_n_s__count_ngrams;
+static PyObject *__pyx_n_s__dtype;
+static PyObject *__pyx_n_s__i;
+static PyObject *__pyx_n_s__int32;
+static PyObject *__pyx_n_s__ints;
+static PyObject *__pyx_n_s__ints_desc;
+static PyObject *__pyx_n_s__ints_desc_obj;
+static PyObject *__pyx_n_s__n;
+static PyObject *__pyx_n_s__numpy;
+static PyObject *__pyx_n_s__radix;
+static PyObject *__pyx_n_s__rval;
+static PyObject *__pyx_n_s__rval_desc;
+static PyObject *__pyx_n_s__rval_desc_obj;
+static PyObject *__pyx_n_s__zeros;
+static PyObject *__pyx_int_0;
+static PyObject *__pyx_int_1;
+static PyObject *__pyx_int_2;
+static PyObject *__pyx_int_256;
+static PyObject *__pyx_int_512;
+static PyObject *__pyx_int_1024;
+static PyObject *__pyx_k_tuple_11;
+static PyObject *__pyx_k_codeobj_12;
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_6intseq_10ngramcount_1count_ngrams(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_2bx_6intseq_10ngramcount_count_ngrams[] = "\n    Count the number of occurrences of each possible length `n` word in \n    `ints` (which contains values from 0 to `radix`). Returns an array\n    of length `radix` ** `n` containing the counts.\n    ";
+static PyMethodDef __pyx_mdef_2bx_6intseq_10ngramcount_1count_ngrams = {__Pyx_NAMESTR("count_ngrams"), (PyCFunction)__pyx_pw_2bx_6intseq_10ngramcount_1count_ngrams, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(__pyx_doc_2bx_6intseq_10ngramcount_count_ngrams)};
+static PyObject *__pyx_pw_2bx_6intseq_10ngramcount_1count_ngrams(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_ints = 0;
+  int __pyx_v_n;
+  int __pyx_v_radix;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("count_ngrams (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__ints,&__pyx_n_s__n,&__pyx_n_s__radix,0};
+    PyObject* values[3] = {0,0,0};
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__ints)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__n)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("count_ngrams", 1, 3, 3, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 31; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+        case  2:
+        if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__radix)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("count_ngrams", 1, 3, 3, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 31; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "count_ngrams") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 31; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else if (PyTuple_GET_SIZE(__pyx_args) != 3) {
+      goto __pyx_L5_argtuple_error;
+    } else {
+      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+      values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+    }
+    __pyx_v_ints = values[0];
+    __pyx_v_n = __Pyx_PyInt_AsInt(values[1]); if (unlikely((__pyx_v_n == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 31; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_radix = __Pyx_PyInt_AsInt(values[2]); if (unlikely((__pyx_v_radix == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 31; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("count_ngrams", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 31; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.intseq.ngramcount.count_ngrams", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_6intseq_10ngramcount_count_ngrams(__pyx_self, __pyx_v_ints, __pyx_v_n, __pyx_v_radix);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/intseq/ngramcount.pyx":31
+ *     void *data           # A pointer to the first element of the array
+ * 
+ * def count_ngrams( object ints, int n, int radix ):             # <<<<<<<<<<<<<<
+ *     """
+ *     Count the number of occurrences of each possible length `n` word in
+ */
+
+static PyObject *__pyx_pf_2bx_6intseq_10ngramcount_count_ngrams(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_ints, int __pyx_v_n, int __pyx_v_radix) {
+  __pyx_t_2bx_6intseq_10ngramcount_PyArrayInterface *__pyx_v_ints_desc;
+  __pyx_t_2bx_6intseq_10ngramcount_PyArrayInterface *__pyx_v_rval_desc;
+  PyObject *__pyx_v_ints_desc_obj = NULL;
+  PyObject *__pyx_v_rval = NULL;
+  PyObject *__pyx_v_rval_desc_obj = NULL;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  int __pyx_t_4;
+  PyObject *__pyx_t_5 = NULL;
+  PyObject *__pyx_t_6 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("count_ngrams", 0);
+
+  /* "bx/intseq/ngramcount.pyx":39
+ *     cdef PyArrayInterface * ints_desc, * rval_desc
+ *     # Get array interface for input string and validate
+ *     ints_desc_obj = ints.__array_struct__             # <<<<<<<<<<<<<<
+ *     ints_desc = <PyArrayInterface *> PyCObject_AsVoidPtr( ints_desc_obj )
+ *     assert ints_desc.two == 2, "Array interface sanity check failed, got %d" % ints_desc.two
+ */
+  __pyx_t_1 = PyObject_GetAttr(__pyx_v_ints, __pyx_n_s____array_struct__); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 39; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_v_ints_desc_obj = __pyx_t_1;
+  __pyx_t_1 = 0;
+
+  /* "bx/intseq/ngramcount.pyx":40
+ *     # Get array interface for input string and validate
+ *     ints_desc_obj = ints.__array_struct__
+ *     ints_desc = <PyArrayInterface *> PyCObject_AsVoidPtr( ints_desc_obj )             # <<<<<<<<<<<<<<
+ *     assert ints_desc.two == 2, "Array interface sanity check failed, got %d" % ints_desc.two
+ *     assert ints_desc.nd == 1, "Input array must be 1d"
+ */
+  __pyx_v_ints_desc = ((__pyx_t_2bx_6intseq_10ngramcount_PyArrayInterface *)PyCObject_AsVoidPtr(__pyx_v_ints_desc_obj));
+
+  /* "bx/intseq/ngramcount.pyx":41
+ *     ints_desc_obj = ints.__array_struct__
+ *     ints_desc = <PyArrayInterface *> PyCObject_AsVoidPtr( ints_desc_obj )
+ *     assert ints_desc.two == 2, "Array interface sanity check failed, got %d" % ints_desc.two             # <<<<<<<<<<<<<<
+ *     assert ints_desc.nd == 1, "Input array must be 1d"
+ *     assert ints_desc.typekind == 'i'[0], "Input array must contain integers"
+ */
+  #ifndef CYTHON_WITHOUT_ASSERTIONS
+  if (unlikely(!(__pyx_v_ints_desc->two == 2))) {
+    __pyx_t_1 = PyInt_FromLong(__pyx_v_ints_desc->two); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 41; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __pyx_t_2 = PyNumber_Remainder(((PyObject *)__pyx_kp_s_1), __pyx_t_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 41; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(((PyObject *)__pyx_t_2));
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    PyErr_SetObject(PyExc_AssertionError, ((PyObject *)__pyx_t_2));
+    __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 41; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  #endif
+
+  /* "bx/intseq/ngramcount.pyx":42
+ *     ints_desc = <PyArrayInterface *> PyCObject_AsVoidPtr( ints_desc_obj )
+ *     assert ints_desc.two == 2, "Array interface sanity check failed, got %d" % ints_desc.two
+ *     assert ints_desc.nd == 1, "Input array must be 1d"             # <<<<<<<<<<<<<<
+ *     assert ints_desc.typekind == 'i'[0], "Input array must contain integers"
+ *     assert ints_desc.itemsize == 4, "Input array must contain 32bit integers"
+ */
+  #ifndef CYTHON_WITHOUT_ASSERTIONS
+  if (unlikely(!(__pyx_v_ints_desc->nd == 1))) {
+    PyErr_SetObject(PyExc_AssertionError, ((PyObject *)__pyx_kp_s_2));
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 42; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  #endif
+
+  /* "bx/intseq/ngramcount.pyx":43
+ *     assert ints_desc.two == 2, "Array interface sanity check failed, got %d" % ints_desc.two
+ *     assert ints_desc.nd == 1, "Input array must be 1d"
+ *     assert ints_desc.typekind == 'i'[0], "Input array must contain integers"             # <<<<<<<<<<<<<<
+ *     assert ints_desc.itemsize == 4, "Input array must contain 32bit integers"
+ *     assert ints_desc.flags & CONTIGUOUS > 0, "Input array must be contiguous"
+ */
+  #ifndef CYTHON_WITHOUT_ASSERTIONS
+  __pyx_t_2 = PyInt_FromLong(__pyx_v_ints_desc->typekind); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 43; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_1 = __Pyx_GetItemInt(((PyObject *)__pyx_n_s__i), 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 43; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_3 = PyObject_RichCompare(__pyx_t_2, __pyx_t_1, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 43; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 43; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  if (unlikely(!__pyx_t_4)) {
+    PyErr_SetObject(PyExc_AssertionError, ((PyObject *)__pyx_kp_s_3));
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 43; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  #endif
+
+  /* "bx/intseq/ngramcount.pyx":44
+ *     assert ints_desc.nd == 1, "Input array must be 1d"
+ *     assert ints_desc.typekind == 'i'[0], "Input array must contain integers"
+ *     assert ints_desc.itemsize == 4, "Input array must contain 32bit integers"             # <<<<<<<<<<<<<<
+ *     assert ints_desc.flags & CONTIGUOUS > 0, "Input array must be contiguous"
+ *     assert ints_desc.flags & ALIGNED > 0, "Input array must be aligned"
+ */
+  #ifndef CYTHON_WITHOUT_ASSERTIONS
+  if (unlikely(!(__pyx_v_ints_desc->itemsize == 4))) {
+    PyErr_SetObject(PyExc_AssertionError, ((PyObject *)__pyx_kp_s_4));
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 44; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  #endif
+
+  /* "bx/intseq/ngramcount.pyx":45
+ *     assert ints_desc.typekind == 'i'[0], "Input array must contain integers"
+ *     assert ints_desc.itemsize == 4, "Input array must contain 32bit integers"
+ *     assert ints_desc.flags & CONTIGUOUS > 0, "Input array must be contiguous"             # <<<<<<<<<<<<<<
+ *     assert ints_desc.flags & ALIGNED > 0, "Input array must be aligned"
+ *     assert ints_desc.flags & NOTSWAPPED > 0, "Input array must not be byteswapped"
+ */
+  #ifndef CYTHON_WITHOUT_ASSERTIONS
+  __pyx_t_3 = PyInt_FromLong(__pyx_v_ints_desc->flags); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 45; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__CONTIGUOUS); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 45; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = PyNumber_And(__pyx_t_3, __pyx_t_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 45; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_1 = PyObject_RichCompare(__pyx_t_2, __pyx_int_0, Py_GT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 45; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 45; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  if (unlikely(!__pyx_t_4)) {
+    PyErr_SetObject(PyExc_AssertionError, ((PyObject *)__pyx_kp_s_5));
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 45; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  #endif
+
+  /* "bx/intseq/ngramcount.pyx":46
+ *     assert ints_desc.itemsize == 4, "Input array must contain 32bit integers"
+ *     assert ints_desc.flags & CONTIGUOUS > 0, "Input array must be contiguous"
+ *     assert ints_desc.flags & ALIGNED > 0, "Input array must be aligned"             # <<<<<<<<<<<<<<
+ *     assert ints_desc.flags & NOTSWAPPED > 0, "Input array must not be byteswapped"
+ *     # Create numpy array for return value, get array interface and validate
+ */
+  #ifndef CYTHON_WITHOUT_ASSERTIONS
+  __pyx_t_1 = PyInt_FromLong(__pyx_v_ints_desc->flags); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 46; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = __Pyx_GetName(__pyx_m, __pyx_n_s__ALIGNED); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 46; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = PyNumber_And(__pyx_t_1, __pyx_t_2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 46; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_2 = PyObject_RichCompare(__pyx_t_3, __pyx_int_0, Py_GT); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 46; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 46; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  if (unlikely(!__pyx_t_4)) {
+    PyErr_SetObject(PyExc_AssertionError, ((PyObject *)__pyx_kp_s_6));
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 46; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  #endif
+
+  /* "bx/intseq/ngramcount.pyx":47
+ *     assert ints_desc.flags & CONTIGUOUS > 0, "Input array must be contiguous"
+ *     assert ints_desc.flags & ALIGNED > 0, "Input array must be aligned"
+ *     assert ints_desc.flags & NOTSWAPPED > 0, "Input array must not be byteswapped"             # <<<<<<<<<<<<<<
+ *     # Create numpy array for return value, get array interface and validate
+ *     rval = numpy.zeros( <int> ( ( <float> radix ) ** n ), dtype=numpy.int32 )
+ */
+  #ifndef CYTHON_WITHOUT_ASSERTIONS
+  __pyx_t_2 = PyInt_FromLong(__pyx_v_ints_desc->flags); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 47; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = __Pyx_GetName(__pyx_m, __pyx_n_s__NOTSWAPPED); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 47; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_1 = PyNumber_And(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 47; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __pyx_t_3 = PyObject_RichCompare(__pyx_t_1, __pyx_int_0, Py_GT); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 47; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 47; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  if (unlikely(!__pyx_t_4)) {
+    PyErr_SetObject(PyExc_AssertionError, ((PyObject *)__pyx_kp_s_7));
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 47; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  #endif
+
+  /* "bx/intseq/ngramcount.pyx":49
+ *     assert ints_desc.flags & NOTSWAPPED > 0, "Input array must not be byteswapped"
+ *     # Create numpy array for return value, get array interface and validate
+ *     rval = numpy.zeros( <int> ( ( <float> radix ) ** n ), dtype=numpy.int32 )             # <<<<<<<<<<<<<<
+ *     assert ints_desc.two == 2, "Array interface sanity check failed, got %d" % ints_desc.two
+ *     rval_desc_obj = rval.__array_struct__
+ */
+  __pyx_t_3 = __Pyx_GetName(__pyx_m, __pyx_n_s__numpy); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 49; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_1 = PyObject_GetAttr(__pyx_t_3, __pyx_n_s__zeros); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 49; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __pyx_t_3 = PyInt_FromLong(((int)powf(((float)__pyx_v_radix), ((float)__pyx_v_n)))); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 49; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 49; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_3);
+  __Pyx_GIVEREF(__pyx_t_3);
+  __pyx_t_3 = 0;
+  __pyx_t_3 = PyDict_New(); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 49; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(((PyObject *)__pyx_t_3));
+  __pyx_t_5 = __Pyx_GetName(__pyx_m, __pyx_n_s__numpy); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 49; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __pyx_t_6 = PyObject_GetAttr(__pyx_t_5, __pyx_n_s__int32); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 49; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_6);
+  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+  if (PyDict_SetItem(__pyx_t_3, ((PyObject *)__pyx_n_s__dtype), __pyx_t_6) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 49; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+  __pyx_t_6 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_2), ((PyObject *)__pyx_t_3)); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 49; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_6);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
+  __pyx_v_rval = __pyx_t_6;
+  __pyx_t_6 = 0;
+
+  /* "bx/intseq/ngramcount.pyx":50
+ *     # Create numpy array for return value, get array interface and validate
+ *     rval = numpy.zeros( <int> ( ( <float> radix ) ** n ), dtype=numpy.int32 )
+ *     assert ints_desc.two == 2, "Array interface sanity check failed, got %d" % ints_desc.two             # <<<<<<<<<<<<<<
+ *     rval_desc_obj = rval.__array_struct__
+ *     rval_desc = <PyArrayInterface *> PyCObject_AsVoidPtr( rval_desc_obj )
+ */
+  #ifndef CYTHON_WITHOUT_ASSERTIONS
+  if (unlikely(!(__pyx_v_ints_desc->two == 2))) {
+    __pyx_t_6 = PyInt_FromLong(__pyx_v_ints_desc->two); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 50; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_6);
+    __pyx_t_3 = PyNumber_Remainder(((PyObject *)__pyx_kp_s_1), __pyx_t_6); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 50; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(((PyObject *)__pyx_t_3));
+    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+    PyErr_SetObject(PyExc_AssertionError, ((PyObject *)__pyx_t_3));
+    __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 50; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  #endif
+
+  /* "bx/intseq/ngramcount.pyx":51
+ *     rval = numpy.zeros( <int> ( ( <float> radix ) ** n ), dtype=numpy.int32 )
+ *     assert ints_desc.two == 2, "Array interface sanity check failed, got %d" % ints_desc.two
+ *     rval_desc_obj = rval.__array_struct__             # <<<<<<<<<<<<<<
+ *     rval_desc = <PyArrayInterface *> PyCObject_AsVoidPtr( rval_desc_obj )
+ *     assert rval_desc.two == 2, "Array interface sanity check failed"
+ */
+  __pyx_t_3 = PyObject_GetAttr(__pyx_v_rval, __pyx_n_s____array_struct__); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 51; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_v_rval_desc_obj = __pyx_t_3;
+  __pyx_t_3 = 0;
+
+  /* "bx/intseq/ngramcount.pyx":52
+ *     assert ints_desc.two == 2, "Array interface sanity check failed, got %d" % ints_desc.two
+ *     rval_desc_obj = rval.__array_struct__
+ *     rval_desc = <PyArrayInterface *> PyCObject_AsVoidPtr( rval_desc_obj )             # <<<<<<<<<<<<<<
+ *     assert rval_desc.two == 2, "Array interface sanity check failed"
+ *     assert rval_desc.nd == 1, "Input array must be 1d"
+ */
+  __pyx_v_rval_desc = ((__pyx_t_2bx_6intseq_10ngramcount_PyArrayInterface *)PyCObject_AsVoidPtr(__pyx_v_rval_desc_obj));
+
+  /* "bx/intseq/ngramcount.pyx":53
+ *     rval_desc_obj = rval.__array_struct__
+ *     rval_desc = <PyArrayInterface *> PyCObject_AsVoidPtr( rval_desc_obj )
+ *     assert rval_desc.two == 2, "Array interface sanity check failed"             # <<<<<<<<<<<<<<
+ *     assert rval_desc.nd == 1, "Input array must be 1d"
+ *     assert rval_desc.typekind == 'i'[0], "Input array must contain integers"
+ */
+  #ifndef CYTHON_WITHOUT_ASSERTIONS
+  if (unlikely(!(__pyx_v_rval_desc->two == 2))) {
+    PyErr_SetObject(PyExc_AssertionError, ((PyObject *)__pyx_kp_s_8));
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 53; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  #endif
+
+  /* "bx/intseq/ngramcount.pyx":54
+ *     rval_desc = <PyArrayInterface *> PyCObject_AsVoidPtr( rval_desc_obj )
+ *     assert rval_desc.two == 2, "Array interface sanity check failed"
+ *     assert rval_desc.nd == 1, "Input array must be 1d"             # <<<<<<<<<<<<<<
+ *     assert rval_desc.typekind == 'i'[0], "Input array must contain integers"
+ *     assert rval_desc.itemsize == 4, "Input array must contain 32bit integers"
+ */
+  #ifndef CYTHON_WITHOUT_ASSERTIONS
+  if (unlikely(!(__pyx_v_rval_desc->nd == 1))) {
+    PyErr_SetObject(PyExc_AssertionError, ((PyObject *)__pyx_kp_s_2));
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 54; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  #endif
+
+  /* "bx/intseq/ngramcount.pyx":55
+ *     assert rval_desc.two == 2, "Array interface sanity check failed"
+ *     assert rval_desc.nd == 1, "Input array must be 1d"
+ *     assert rval_desc.typekind == 'i'[0], "Input array must contain integers"             # <<<<<<<<<<<<<<
+ *     assert rval_desc.itemsize == 4, "Input array must contain 32bit integers"
+ *     assert rval_desc.flags & CONTIGUOUS > 0, "Input array must be contiguous"
+ */
+  #ifndef CYTHON_WITHOUT_ASSERTIONS
+  __pyx_t_3 = PyInt_FromLong(__pyx_v_rval_desc->typekind); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 55; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_6 = __Pyx_GetItemInt(((PyObject *)__pyx_n_s__i), 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_6) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 55; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_6);
+  __pyx_t_2 = PyObject_RichCompare(__pyx_t_3, __pyx_t_6, Py_EQ); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 55; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+  __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 55; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  if (unlikely(!__pyx_t_4)) {
+    PyErr_SetObject(PyExc_AssertionError, ((PyObject *)__pyx_kp_s_3));
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 55; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  #endif
+
+  /* "bx/intseq/ngramcount.pyx":56
+ *     assert rval_desc.nd == 1, "Input array must be 1d"
+ *     assert rval_desc.typekind == 'i'[0], "Input array must contain integers"
+ *     assert rval_desc.itemsize == 4, "Input array must contain 32bit integers"             # <<<<<<<<<<<<<<
+ *     assert rval_desc.flags & CONTIGUOUS > 0, "Input array must be contiguous"
+ *     assert rval_desc.flags & ALIGNED > 0, "Input array must be aligned"
+ */
+  #ifndef CYTHON_WITHOUT_ASSERTIONS
+  if (unlikely(!(__pyx_v_rval_desc->itemsize == 4))) {
+    PyErr_SetObject(PyExc_AssertionError, ((PyObject *)__pyx_kp_s_4));
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 56; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  #endif
+
+  /* "bx/intseq/ngramcount.pyx":57
+ *     assert rval_desc.typekind == 'i'[0], "Input array must contain integers"
+ *     assert rval_desc.itemsize == 4, "Input array must contain 32bit integers"
+ *     assert rval_desc.flags & CONTIGUOUS > 0, "Input array must be contiguous"             # <<<<<<<<<<<<<<
+ *     assert rval_desc.flags & ALIGNED > 0, "Input array must be aligned"
+ *     assert rval_desc.flags & NOTSWAPPED > 0, "Input array must not be byteswapped"
+ */
+  #ifndef CYTHON_WITHOUT_ASSERTIONS
+  __pyx_t_2 = PyInt_FromLong(__pyx_v_rval_desc->flags); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 57; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_6 = __Pyx_GetName(__pyx_m, __pyx_n_s__CONTIGUOUS); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 57; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_6);
+  __pyx_t_3 = PyNumber_And(__pyx_t_2, __pyx_t_6); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 57; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+  __pyx_t_6 = PyObject_RichCompare(__pyx_t_3, __pyx_int_0, Py_GT); __Pyx_XGOTREF(__pyx_t_6); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 57; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_6); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 57; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+  if (unlikely(!__pyx_t_4)) {
+    PyErr_SetObject(PyExc_AssertionError, ((PyObject *)__pyx_kp_s_5));
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 57; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  #endif
+
+  /* "bx/intseq/ngramcount.pyx":58
+ *     assert rval_desc.itemsize == 4, "Input array must contain 32bit integers"
+ *     assert rval_desc.flags & CONTIGUOUS > 0, "Input array must be contiguous"
+ *     assert rval_desc.flags & ALIGNED > 0, "Input array must be aligned"             # <<<<<<<<<<<<<<
+ *     assert rval_desc.flags & NOTSWAPPED > 0, "Input array must not be byteswapped"
+ *     # Do it
+ */
+  #ifndef CYTHON_WITHOUT_ASSERTIONS
+  __pyx_t_6 = PyInt_FromLong(__pyx_v_rval_desc->flags); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 58; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_6);
+  __pyx_t_3 = __Pyx_GetName(__pyx_m, __pyx_n_s__ALIGNED); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 58; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_2 = PyNumber_And(__pyx_t_6, __pyx_t_3); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 58; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __pyx_t_3 = PyObject_RichCompare(__pyx_t_2, __pyx_int_0, Py_GT); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 58; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 58; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  if (unlikely(!__pyx_t_4)) {
+    PyErr_SetObject(PyExc_AssertionError, ((PyObject *)__pyx_kp_s_6));
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 58; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  #endif
+
+  /* "bx/intseq/ngramcount.pyx":59
+ *     assert rval_desc.flags & CONTIGUOUS > 0, "Input array must be contiguous"
+ *     assert rval_desc.flags & ALIGNED > 0, "Input array must be aligned"
+ *     assert rval_desc.flags & NOTSWAPPED > 0, "Input array must not be byteswapped"             # <<<<<<<<<<<<<<
+ *     # Do it
+ *     _count_ngrams( <int*> ints_desc.data, ints_desc.shape[0], <int*> rval_desc.data, n, radix )
+ */
+  #ifndef CYTHON_WITHOUT_ASSERTIONS
+  __pyx_t_3 = PyInt_FromLong(__pyx_v_rval_desc->flags); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 59; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_2 = __Pyx_GetName(__pyx_m, __pyx_n_s__NOTSWAPPED); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 59; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_6 = PyNumber_And(__pyx_t_3, __pyx_t_2); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 59; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_6);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_2 = PyObject_RichCompare(__pyx_t_6, __pyx_int_0, Py_GT); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 59; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+  __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 59; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  if (unlikely(!__pyx_t_4)) {
+    PyErr_SetObject(PyExc_AssertionError, ((PyObject *)__pyx_kp_s_7));
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 59; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  #endif
+
+  /* "bx/intseq/ngramcount.pyx":61
+ *     assert rval_desc.flags & NOTSWAPPED > 0, "Input array must not be byteswapped"
+ *     # Do it
+ *     _count_ngrams( <int*> ints_desc.data, ints_desc.shape[0], <int*> rval_desc.data, n, radix )             # <<<<<<<<<<<<<<
+ *     return rval
+ * 
+ */
+  __pyx_t_2 = __pyx_f_2bx_6intseq_10ngramcount__count_ngrams(((int *)__pyx_v_ints_desc->data), (__pyx_v_ints_desc->shape[0]), ((int *)__pyx_v_rval_desc->data), __pyx_v_n, __pyx_v_radix); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 61; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+  /* "bx/intseq/ngramcount.pyx":62
+ *     # Do it
+ *     _count_ngrams( <int*> ints_desc.data, ints_desc.shape[0], <int*> rval_desc.data, n, radix )
+ *     return rval             # <<<<<<<<<<<<<<
+ * 
+ * cdef _count_ngrams( int* ints, int n_ints, int* rval, int n, int radix ):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __Pyx_INCREF(__pyx_v_rval);
+  __pyx_r = __pyx_v_rval;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_5);
+  __Pyx_XDECREF(__pyx_t_6);
+  __Pyx_AddTraceback("bx.intseq.ngramcount.count_ngrams", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_ints_desc_obj);
+  __Pyx_XDECREF(__pyx_v_rval);
+  __Pyx_XDECREF(__pyx_v_rval_desc_obj);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/intseq/ngramcount.pyx":64
+ *     return rval
+ * 
+ * cdef _count_ngrams( int* ints, int n_ints, int* rval, int n, int radix ):             # <<<<<<<<<<<<<<
+ *     cdef int i, j, index, factor, letter
+ *     # Loop over each word in the string
+ */
+
+static PyObject *__pyx_f_2bx_6intseq_10ngramcount__count_ngrams(int *__pyx_v_ints, int __pyx_v_n_ints, int *__pyx_v_rval, int __pyx_v_n, int __pyx_v_radix) {
+  int __pyx_v_i;
+  int __pyx_v_j;
+  int __pyx_v_index;
+  int __pyx_v_factor;
+  int __pyx_v_letter;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  int __pyx_t_2;
+  int __pyx_t_3;
+  int __pyx_t_4;
+  int __pyx_t_5;
+  PyObject *__pyx_t_6 = NULL;
+  PyObject *__pyx_t_7 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("_count_ngrams", 0);
+
+  /* "bx/intseq/ngramcount.pyx":67
+ *     cdef int i, j, index, factor, letter
+ *     # Loop over each word in the string
+ *     for i from 0 <= i < ( n_ints - n ):             # <<<<<<<<<<<<<<
+ *         # Walk back to build index into count array
+ *         index = 0
+ */
+  __pyx_t_1 = (__pyx_v_n_ints - __pyx_v_n);
+  for (__pyx_v_i = 0; __pyx_v_i < __pyx_t_1; __pyx_v_i++) {
+
+    /* "bx/intseq/ngramcount.pyx":69
+ *     for i from 0 <= i < ( n_ints - n ):
+ *         # Walk back to build index into count array
+ *         index = 0             # <<<<<<<<<<<<<<
+ *         factor = 1
+ *         for j from 0 <= j < n:
+ */
+    __pyx_v_index = 0;
+
+    /* "bx/intseq/ngramcount.pyx":70
+ *         # Walk back to build index into count array
+ *         index = 0
+ *         factor = 1             # <<<<<<<<<<<<<<
+ *         for j from 0 <= j < n:
+ *             letter = ints[ i + j ]
+ */
+    __pyx_v_factor = 1;
+
+    /* "bx/intseq/ngramcount.pyx":71
+ *         index = 0
+ *         factor = 1
+ *         for j from 0 <= j < n:             # <<<<<<<<<<<<<<
+ *             letter = ints[ i + j ]
+ *             if letter < 0 or letter >= radix:
+ */
+    __pyx_t_2 = __pyx_v_n;
+    for (__pyx_v_j = 0; __pyx_v_j < __pyx_t_2; __pyx_v_j++) {
+
+      /* "bx/intseq/ngramcount.pyx":72
+ *         factor = 1
+ *         for j from 0 <= j < n:
+ *             letter = ints[ i + j ]             # <<<<<<<<<<<<<<
+ *             if letter < 0 or letter >= radix:
+ *                 # This word is bad, break out and do not increment counts
+ */
+      __pyx_v_letter = (__pyx_v_ints[(__pyx_v_i + __pyx_v_j)]);
+
+      /* "bx/intseq/ngramcount.pyx":73
+ *         for j from 0 <= j < n:
+ *             letter = ints[ i + j ]
+ *             if letter < 0 or letter >= radix:             # <<<<<<<<<<<<<<
+ *                 # This word is bad, break out and do not increment counts
+ *                 print "breaking, letter", letter
+ */
+      __pyx_t_3 = (__pyx_v_letter < 0);
+      if (!__pyx_t_3) {
+        __pyx_t_4 = (__pyx_v_letter >= __pyx_v_radix);
+        __pyx_t_5 = __pyx_t_4;
+      } else {
+        __pyx_t_5 = __pyx_t_3;
+      }
+      if (__pyx_t_5) {
+
+        /* "bx/intseq/ngramcount.pyx":75
+ *             if letter < 0 or letter >= radix:
+ *                 # This word is bad, break out and do not increment counts
+ *                 print "breaking, letter", letter             # <<<<<<<<<<<<<<
+ *                 break
+ *             index = index + letter * factor
+ */
+        __pyx_t_6 = PyInt_FromLong(__pyx_v_letter); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 75; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_6);
+        __pyx_t_7 = PyTuple_New(2); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 75; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_7);
+        __Pyx_INCREF(((PyObject *)__pyx_kp_s_9));
+        PyTuple_SET_ITEM(__pyx_t_7, 0, ((PyObject *)__pyx_kp_s_9));
+        __Pyx_GIVEREF(((PyObject *)__pyx_kp_s_9));
+        PyTuple_SET_ITEM(__pyx_t_7, 1, __pyx_t_6);
+        __Pyx_GIVEREF(__pyx_t_6);
+        __pyx_t_6 = 0;
+        if (__Pyx_Print(0, ((PyObject *)__pyx_t_7), 1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 75; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_DECREF(((PyObject *)__pyx_t_7)); __pyx_t_7 = 0;
+
+        /* "bx/intseq/ngramcount.pyx":76
+ *                 # This word is bad, break out and do not increment counts
+ *                 print "breaking, letter", letter
+ *                 break             # <<<<<<<<<<<<<<
+ *             index = index + letter * factor
+ *             factor = factor * radix
+ */
+        goto __pyx_L6_break;
+        goto __pyx_L7;
+      }
+      __pyx_L7:;
+
+      /* "bx/intseq/ngramcount.pyx":77
+ *                 print "breaking, letter", letter
+ *                 break
+ *             index = index + letter * factor             # <<<<<<<<<<<<<<
+ *             factor = factor * radix
+ *         else:
+ */
+      __pyx_v_index = (__pyx_v_index + (__pyx_v_letter * __pyx_v_factor));
+
+      /* "bx/intseq/ngramcount.pyx":78
+ *                 break
+ *             index = index + letter * factor
+ *             factor = factor * radix             # <<<<<<<<<<<<<<
+ *         else:
+ *             print index
+ */
+      __pyx_v_factor = (__pyx_v_factor * __pyx_v_radix);
+    }
+    /*else*/ {
+
+      /* "bx/intseq/ngramcount.pyx":80
+ *             factor = factor * radix
+ *         else:
+ *             print index             # <<<<<<<<<<<<<<
+ *             rval[ index ] = rval[ index ] + 1
+ * 
+ */
+      __pyx_t_7 = PyInt_FromLong(__pyx_v_index); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 80; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_7);
+      if (__Pyx_PrintOne(0, __pyx_t_7) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 80; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+
+      /* "bx/intseq/ngramcount.pyx":81
+ *         else:
+ *             print index
+ *             rval[ index ] = rval[ index ] + 1             # <<<<<<<<<<<<<<
+ * 
+ */
+      (__pyx_v_rval[__pyx_v_index]) = ((__pyx_v_rval[__pyx_v_index]) + 1);
+    }
+    __pyx_L6_break:;
+  }
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_6);
+  __Pyx_XDECREF(__pyx_t_7);
+  __Pyx_AddTraceback("bx.intseq.ngramcount._count_ngrams", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyMethodDef __pyx_methods[] = {
+  {0, 0, 0, 0}
+};
+
+#if PY_MAJOR_VERSION >= 3
+static struct PyModuleDef __pyx_moduledef = {
+  #if PY_VERSION_HEX < 0x03020000
+    { PyObject_HEAD_INIT(NULL) NULL, 0, NULL },
+  #else
+    PyModuleDef_HEAD_INIT,
+  #endif
+    __Pyx_NAMESTR("ngramcount"),
+    __Pyx_DOCSTR(__pyx_k_10), /* m_doc */
+    -1, /* m_size */
+    __pyx_methods /* m_methods */,
+    NULL, /* m_reload */
+    NULL, /* m_traverse */
+    NULL, /* m_clear */
+    NULL /* m_free */
+};
+#endif
+
+static __Pyx_StringTabEntry __pyx_string_tab[] = {
+  {&__pyx_kp_s_1, __pyx_k_1, sizeof(__pyx_k_1), 0, 0, 1, 0},
+  {&__pyx_kp_s_13, __pyx_k_13, sizeof(__pyx_k_13), 0, 0, 1, 0},
+  {&__pyx_n_s_14, __pyx_k_14, sizeof(__pyx_k_14), 0, 0, 1, 1},
+  {&__pyx_kp_s_2, __pyx_k_2, sizeof(__pyx_k_2), 0, 0, 1, 0},
+  {&__pyx_kp_s_3, __pyx_k_3, sizeof(__pyx_k_3), 0, 0, 1, 0},
+  {&__pyx_kp_s_4, __pyx_k_4, sizeof(__pyx_k_4), 0, 0, 1, 0},
+  {&__pyx_kp_s_5, __pyx_k_5, sizeof(__pyx_k_5), 0, 0, 1, 0},
+  {&__pyx_kp_s_6, __pyx_k_6, sizeof(__pyx_k_6), 0, 0, 1, 0},
+  {&__pyx_kp_s_7, __pyx_k_7, sizeof(__pyx_k_7), 0, 0, 1, 0},
+  {&__pyx_kp_s_8, __pyx_k_8, sizeof(__pyx_k_8), 0, 0, 1, 0},
+  {&__pyx_kp_s_9, __pyx_k_9, sizeof(__pyx_k_9), 0, 0, 1, 0},
+  {&__pyx_n_s__ALIGNED, __pyx_k__ALIGNED, sizeof(__pyx_k__ALIGNED), 0, 0, 1, 1},
+  {&__pyx_n_s__CONTIGUOUS, __pyx_k__CONTIGUOUS, sizeof(__pyx_k__CONTIGUOUS), 0, 0, 1, 1},
+  {&__pyx_n_s__FORTRAN, __pyx_k__FORTRAN, sizeof(__pyx_k__FORTRAN), 0, 0, 1, 1},
+  {&__pyx_n_s__NOTSWAPPED, __pyx_k__NOTSWAPPED, sizeof(__pyx_k__NOTSWAPPED), 0, 0, 1, 1},
+  {&__pyx_n_s__WRITEABLE, __pyx_k__WRITEABLE, sizeof(__pyx_k__WRITEABLE), 0, 0, 1, 1},
+  {&__pyx_n_s____array_struct__, __pyx_k____array_struct__, sizeof(__pyx_k____array_struct__), 0, 0, 1, 1},
+  {&__pyx_n_s____main__, __pyx_k____main__, sizeof(__pyx_k____main__), 0, 0, 1, 1},
+  {&__pyx_n_s____test__, __pyx_k____test__, sizeof(__pyx_k____test__), 0, 0, 1, 1},
+  {&__pyx_n_s__count_ngrams, __pyx_k__count_ngrams, sizeof(__pyx_k__count_ngrams), 0, 0, 1, 1},
+  {&__pyx_n_s__dtype, __pyx_k__dtype, sizeof(__pyx_k__dtype), 0, 0, 1, 1},
+  {&__pyx_n_s__i, __pyx_k__i, sizeof(__pyx_k__i), 0, 0, 1, 1},
+  {&__pyx_n_s__int32, __pyx_k__int32, sizeof(__pyx_k__int32), 0, 0, 1, 1},
+  {&__pyx_n_s__ints, __pyx_k__ints, sizeof(__pyx_k__ints), 0, 0, 1, 1},
+  {&__pyx_n_s__ints_desc, __pyx_k__ints_desc, sizeof(__pyx_k__ints_desc), 0, 0, 1, 1},
+  {&__pyx_n_s__ints_desc_obj, __pyx_k__ints_desc_obj, sizeof(__pyx_k__ints_desc_obj), 0, 0, 1, 1},
+  {&__pyx_n_s__n, __pyx_k__n, sizeof(__pyx_k__n), 0, 0, 1, 1},
+  {&__pyx_n_s__numpy, __pyx_k__numpy, sizeof(__pyx_k__numpy), 0, 0, 1, 1},
+  {&__pyx_n_s__radix, __pyx_k__radix, sizeof(__pyx_k__radix), 0, 0, 1, 1},
+  {&__pyx_n_s__rval, __pyx_k__rval, sizeof(__pyx_k__rval), 0, 0, 1, 1},
+  {&__pyx_n_s__rval_desc, __pyx_k__rval_desc, sizeof(__pyx_k__rval_desc), 0, 0, 1, 1},
+  {&__pyx_n_s__rval_desc_obj, __pyx_k__rval_desc_obj, sizeof(__pyx_k__rval_desc_obj), 0, 0, 1, 1},
+  {&__pyx_n_s__zeros, __pyx_k__zeros, sizeof(__pyx_k__zeros), 0, 0, 1, 1},
+  {0, 0, 0, 0, 0, 0, 0}
+};
+static int __Pyx_InitCachedBuiltins(void) {
+  return 0;
+}
+
+static int __Pyx_InitCachedConstants(void) {
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0);
+
+  /* "bx/intseq/ngramcount.pyx":31
+ *     void *data           # A pointer to the first element of the array
+ * 
+ * def count_ngrams( object ints, int n, int radix ):             # <<<<<<<<<<<<<<
+ *     """
+ *     Count the number of occurrences of each possible length `n` word in
+ */
+  __pyx_k_tuple_11 = PyTuple_Pack(8, ((PyObject *)__pyx_n_s__ints), ((PyObject *)__pyx_n_s__n), ((PyObject *)__pyx_n_s__radix), ((PyObject *)__pyx_n_s__ints_desc), ((PyObject *)__pyx_n_s__rval_desc), ((PyObject *)__pyx_n_s__ints_desc_obj), ((PyObject *)__pyx_n_s__rval), ((PyObject *)__pyx_n_s__rval_desc_obj)); if (unlikely(!__pyx_k_tuple_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 31; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_k_tuple_11);
+  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_11));
+  __pyx_k_codeobj_12 = (PyObject*)__Pyx_PyCode_New(3, 0, 8, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_k_tuple_11, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_13, __pyx_n_s__count_ngrams, 31, __pyx_empty_bytes); if (unlikely(!__pyx_k_codeobj_12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 31; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_RefNannyFinishContext();
+  return 0;
+  __pyx_L1_error:;
+  __Pyx_RefNannyFinishContext();
+  return -1;
+}
+
+static int __Pyx_InitGlobals(void) {
+  if (__Pyx_InitStrings(__pyx_string_tab) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  __pyx_int_0 = PyInt_FromLong(0); if (unlikely(!__pyx_int_0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  __pyx_int_1 = PyInt_FromLong(1); if (unlikely(!__pyx_int_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  __pyx_int_2 = PyInt_FromLong(2); if (unlikely(!__pyx_int_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  __pyx_int_256 = PyInt_FromLong(256); if (unlikely(!__pyx_int_256)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  __pyx_int_512 = PyInt_FromLong(512); if (unlikely(!__pyx_int_512)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  __pyx_int_1024 = PyInt_FromLong(1024); if (unlikely(!__pyx_int_1024)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  return 0;
+  __pyx_L1_error:;
+  return -1;
+}
+
+#if PY_MAJOR_VERSION < 3
+PyMODINIT_FUNC initngramcount(void); /*proto*/
+PyMODINIT_FUNC initngramcount(void)
+#else
+PyMODINIT_FUNC PyInit_ngramcount(void); /*proto*/
+PyMODINIT_FUNC PyInit_ngramcount(void)
+#endif
+{
+  PyObject *__pyx_t_1 = NULL;
+  __Pyx_RefNannyDeclarations
+  #if CYTHON_REFNANNY
+  __Pyx_RefNanny = __Pyx_RefNannyImportAPI("refnanny");
+  if (!__Pyx_RefNanny) {
+      PyErr_Clear();
+      __Pyx_RefNanny = __Pyx_RefNannyImportAPI("Cython.Runtime.refnanny");
+      if (!__Pyx_RefNanny)
+          Py_FatalError("failed to import 'refnanny' module");
+  }
+  #endif
+  __Pyx_RefNannySetupContext("PyMODINIT_FUNC PyInit_ngramcount(void)", 0);
+  if ( __Pyx_check_binary_version() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_bytes)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #ifdef __Pyx_CyFunction_USED
+  if (__Pyx_CyFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #endif
+  #ifdef __Pyx_FusedFunction_USED
+  if (__pyx_FusedFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #endif
+  #ifdef __Pyx_Generator_USED
+  if (__pyx_Generator_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #endif
+  /*--- Library function declarations ---*/
+  /*--- Threads initialization code ---*/
+  #if defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS
+  #ifdef WITH_THREAD /* Python build with threading support? */
+  PyEval_InitThreads();
+  #endif
+  #endif
+  /*--- Module creation code ---*/
+  #if PY_MAJOR_VERSION < 3
+  __pyx_m = Py_InitModule4(__Pyx_NAMESTR("ngramcount"), __pyx_methods, __Pyx_DOCSTR(__pyx_k_10), 0, PYTHON_API_VERSION); Py_XINCREF(__pyx_m);
+  #else
+  __pyx_m = PyModule_Create(&__pyx_moduledef);
+  #endif
+  if (unlikely(!__pyx_m)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #if PY_MAJOR_VERSION >= 3
+  {
+    PyObject *modules = PyImport_GetModuleDict(); if (unlikely(!modules)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (!PyDict_GetItemString(modules, "bx.intseq.ngramcount")) {
+      if (unlikely(PyDict_SetItemString(modules, "bx.intseq.ngramcount", __pyx_m) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+  }
+  #endif
+  __pyx_b = PyImport_AddModule(__Pyx_NAMESTR(__Pyx_BUILTIN_MODULE_NAME)); if (unlikely(!__pyx_b)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #if CYTHON_COMPILING_IN_PYPY
+  Py_INCREF(__pyx_b);
+  #endif
+  if (__Pyx_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  /*--- Initialize various global constants etc. ---*/
+  if (unlikely(__Pyx_InitGlobals() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (__pyx_module_is_main_bx__intseq__ngramcount) {
+    if (__Pyx_SetAttrString(__pyx_m, "__name__", __pyx_n_s____main__) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  }
+  /*--- Builtin init code ---*/
+  if (unlikely(__Pyx_InitCachedBuiltins() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  /*--- Constants init code ---*/
+  if (unlikely(__Pyx_InitCachedConstants() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  /*--- Global init code ---*/
+  /*--- Variable export code ---*/
+  /*--- Function export code ---*/
+  /*--- Type init code ---*/
+  /*--- Type import code ---*/
+  /*--- Variable import code ---*/
+  /*--- Function import code ---*/
+  /*--- Execution code ---*/
+
+  /* "bx/intseq/ngramcount.pyx":5
+ * """
+ * 
+ * import numpy             # <<<<<<<<<<<<<<
+ * 
+ * cdef extern from "Python.h":
+ */
+  __pyx_t_1 = __Pyx_Import(((PyObject *)__pyx_n_s__numpy), 0, -1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 5; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s__numpy, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 5; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "bx/intseq/ngramcount.pyx":15
+ * 
+ * # for PyArrayInterface:
+ * CONTIGUOUS=0x01             # <<<<<<<<<<<<<<
+ * FORTRAN=0x02
+ * ALIGNED=0x100
+ */
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s__CONTIGUOUS, __pyx_int_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 15; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "bx/intseq/ngramcount.pyx":16
+ * # for PyArrayInterface:
+ * CONTIGUOUS=0x01
+ * FORTRAN=0x02             # <<<<<<<<<<<<<<
+ * ALIGNED=0x100
+ * NOTSWAPPED=0x200
+ */
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s__FORTRAN, __pyx_int_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 16; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "bx/intseq/ngramcount.pyx":17
+ * CONTIGUOUS=0x01
+ * FORTRAN=0x02
+ * ALIGNED=0x100             # <<<<<<<<<<<<<<
+ * NOTSWAPPED=0x200
+ * WRITEABLE=0x400
+ */
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s__ALIGNED, __pyx_int_256) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "bx/intseq/ngramcount.pyx":18
+ * FORTRAN=0x02
+ * ALIGNED=0x100
+ * NOTSWAPPED=0x200             # <<<<<<<<<<<<<<
+ * WRITEABLE=0x400
+ * 
+ */
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s__NOTSWAPPED, __pyx_int_512) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 18; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "bx/intseq/ngramcount.pyx":19
+ * ALIGNED=0x100
+ * NOTSWAPPED=0x200
+ * WRITEABLE=0x400             # <<<<<<<<<<<<<<
+ * 
+ * ctypedef struct PyArrayInterface:
+ */
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s__WRITEABLE, __pyx_int_1024) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 19; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "bx/intseq/ngramcount.pyx":31
+ *     void *data           # A pointer to the first element of the array
+ * 
+ * def count_ngrams( object ints, int n, int radix ):             # <<<<<<<<<<<<<<
+ *     """
+ *     Count the number of occurrences of each possible length `n` word in
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_2bx_6intseq_10ngramcount_1count_ngrams, NULL, __pyx_n_s_14); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 31; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s__count_ngrams, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 31; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "bx/intseq/ngramcount.pyx":1
+ * """             # <<<<<<<<<<<<<<
+ * Tools for counting words (n-grams) in integer sequences.
+ * """
+ */
+  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(((PyObject *)__pyx_t_1));
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s____test__, ((PyObject *)__pyx_t_1)) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  if (__pyx_m) {
+    __Pyx_AddTraceback("init bx.intseq.ngramcount", __pyx_clineno, __pyx_lineno, __pyx_filename);
+    Py_DECREF(__pyx_m); __pyx_m = 0;
+  } else if (!PyErr_Occurred()) {
+    PyErr_SetString(PyExc_ImportError, "init bx.intseq.ngramcount");
+  }
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  #if PY_MAJOR_VERSION < 3
+  return;
+  #else
+  return __pyx_m;
+  #endif
+}
+
+/* Runtime support code */
+#if CYTHON_REFNANNY
+static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) {
+    PyObject *m = NULL, *p = NULL;
+    void *r = NULL;
+    m = PyImport_ImportModule((char *)modname);
+    if (!m) goto end;
+    p = PyObject_GetAttrString(m, (char *)"RefNannyAPI");
+    if (!p) goto end;
+    r = PyLong_AsVoidPtr(p);
+end:
+    Py_XDECREF(p);
+    Py_XDECREF(m);
+    return (__Pyx_RefNannyAPIStruct *)r;
+}
+#endif /* CYTHON_REFNANNY */
+
+static void __Pyx_RaiseArgtupleInvalid(
+    const char* func_name,
+    int exact,
+    Py_ssize_t num_min,
+    Py_ssize_t num_max,
+    Py_ssize_t num_found)
+{
+    Py_ssize_t num_expected;
+    const char *more_or_less;
+    if (num_found < num_min) {
+        num_expected = num_min;
+        more_or_less = "at least";
+    } else {
+        num_expected = num_max;
+        more_or_less = "at most";
+    }
+    if (exact) {
+        more_or_less = "exactly";
+    }
+    PyErr_Format(PyExc_TypeError,
+                 "%s() takes %s %" CYTHON_FORMAT_SSIZE_T "d positional argument%s (%" CYTHON_FORMAT_SSIZE_T "d given)",
+                 func_name, more_or_less, num_expected,
+                 (num_expected == 1) ? "" : "s", num_found);
+}
+
+static void __Pyx_RaiseDoubleKeywordsError(
+    const char* func_name,
+    PyObject* kw_name)
+{
+    PyErr_Format(PyExc_TypeError,
+        #if PY_MAJOR_VERSION >= 3
+        "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
+        #else
+        "%s() got multiple values for keyword argument '%s'", func_name,
+        PyString_AsString(kw_name));
+        #endif
+}
+
+static int __Pyx_ParseOptionalKeywords(
+    PyObject *kwds,
+    PyObject **argnames[],
+    PyObject *kwds2,
+    PyObject *values[],
+    Py_ssize_t num_pos_args,
+    const char* function_name)
+{
+    PyObject *key = 0, *value = 0;
+    Py_ssize_t pos = 0;
+    PyObject*** name;
+    PyObject*** first_kw_arg = argnames + num_pos_args;
+    while (PyDict_Next(kwds, &pos, &key, &value)) {
+        name = first_kw_arg;
+        while (*name && (**name != key)) name++;
+        if (*name) {
+            values[name-argnames] = value;
+            continue;
+        }
+        name = first_kw_arg;
+        #if PY_MAJOR_VERSION < 3
+        if (likely(PyString_CheckExact(key)) || likely(PyString_Check(key))) {
+            while (*name) {
+                if ((CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**name) == PyString_GET_SIZE(key))
+                        && _PyString_Eq(**name, key)) {
+                    values[name-argnames] = value;
+                    break;
+                }
+                name++;
+            }
+            if (*name) continue;
+            else {
+                PyObject*** argname = argnames;
+                while (argname != first_kw_arg) {
+                    if ((**argname == key) || (
+                            (CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**argname) == PyString_GET_SIZE(key))
+                             && _PyString_Eq(**argname, key))) {
+                        goto arg_passed_twice;
+                    }
+                    argname++;
+                }
+            }
+        } else
+        #endif
+        if (likely(PyUnicode_Check(key))) {
+            while (*name) {
+                int cmp = (**name == key) ? 0 :
+                #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3
+                    (PyUnicode_GET_SIZE(**name) != PyUnicode_GET_SIZE(key)) ? 1 :
+                #endif
+                    PyUnicode_Compare(**name, key);
+                if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad;
+                if (cmp == 0) {
+                    values[name-argnames] = value;
+                    break;
+                }
+                name++;
+            }
+            if (*name) continue;
+            else {
+                PyObject*** argname = argnames;
+                while (argname != first_kw_arg) {
+                    int cmp = (**argname == key) ? 0 :
+                    #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3
+                        (PyUnicode_GET_SIZE(**argname) != PyUnicode_GET_SIZE(key)) ? 1 :
+                    #endif
+                        PyUnicode_Compare(**argname, key);
+                    if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad;
+                    if (cmp == 0) goto arg_passed_twice;
+                    argname++;
+                }
+            }
+        } else
+            goto invalid_keyword_type;
+        if (kwds2) {
+            if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
+        } else {
+            goto invalid_keyword;
+        }
+    }
+    return 0;
+arg_passed_twice:
+    __Pyx_RaiseDoubleKeywordsError(function_name, key);
+    goto bad;
+invalid_keyword_type:
+    PyErr_Format(PyExc_TypeError,
+        "%s() keywords must be strings", function_name);
+    goto bad;
+invalid_keyword:
+    PyErr_Format(PyExc_TypeError,
+    #if PY_MAJOR_VERSION < 3
+        "%s() got an unexpected keyword argument '%s'",
+        function_name, PyString_AsString(key));
+    #else
+        "%s() got an unexpected keyword argument '%U'",
+        function_name, key);
+    #endif
+bad:
+    return -1;
+}
+
+static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name) {
+    PyObject *result;
+    result = PyObject_GetAttr(dict, name);
+    if (!result) {
+        if (dict != __pyx_b) {
+            PyErr_Clear();
+            result = PyObject_GetAttr(__pyx_b, name);
+        }
+        if (!result) {
+            PyErr_SetObject(PyExc_NameError, name);
+        }
+    }
+    return result;
+}
+
+static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level) {
+    PyObject *empty_list = 0;
+    PyObject *module = 0;
+    PyObject *global_dict = 0;
+    PyObject *empty_dict = 0;
+    PyObject *list;
+    #if PY_VERSION_HEX < 0x03030000
+    PyObject *py_import = 0;
+    py_import = __Pyx_GetAttrString(__pyx_b, "__import__");
+    if (!py_import)
+        goto bad;
+    #endif
+    if (from_list)
+        list = from_list;
+    else {
+        empty_list = PyList_New(0);
+        if (!empty_list)
+            goto bad;
+        list = empty_list;
+    }
+    global_dict = PyModule_GetDict(__pyx_m);
+    if (!global_dict)
+        goto bad;
+    empty_dict = PyDict_New();
+    if (!empty_dict)
+        goto bad;
+    #if PY_VERSION_HEX >= 0x02050000
+    {
+        #if PY_MAJOR_VERSION >= 3
+        if (level == -1) {
+            if (strchr(__Pyx_MODULE_NAME, '.')) {
+                #if PY_VERSION_HEX < 0x03030000
+                PyObject *py_level = PyInt_FromLong(1);
+                if (!py_level)
+                    goto bad;
+                module = PyObject_CallFunctionObjArgs(py_import,
+                    name, global_dict, empty_dict, list, py_level, NULL);
+                Py_DECREF(py_level);
+                #else
+                module = PyImport_ImportModuleLevelObject(
+                    name, global_dict, empty_dict, list, 1);
+                #endif
+                if (!module) {
+                    if (!PyErr_ExceptionMatches(PyExc_ImportError))
+                        goto bad;
+                    PyErr_Clear();
+                }
+            }
+            level = 0; /* try absolute import on failure */
+        }
+        #endif
+        if (!module) {
+            #if PY_VERSION_HEX < 0x03030000
+            PyObject *py_level = PyInt_FromLong(level);
+            if (!py_level)
+                goto bad;
+            module = PyObject_CallFunctionObjArgs(py_import,
+                name, global_dict, empty_dict, list, py_level, NULL);
+            Py_DECREF(py_level);
+            #else
+            module = PyImport_ImportModuleLevelObject(
+                name, global_dict, empty_dict, list, level);
+            #endif
+        }
+    }
+    #else
+    if (level>0) {
+        PyErr_SetString(PyExc_RuntimeError, "Relative import is not supported for Python <=2.4.");
+        goto bad;
+    }
+    module = PyObject_CallFunctionObjArgs(py_import,
+        name, global_dict, empty_dict, list, NULL);
+    #endif
+bad:
+    #if PY_VERSION_HEX < 0x03030000
+    Py_XDECREF(py_import);
+    #endif
+    Py_XDECREF(empty_list);
+    Py_XDECREF(empty_dict);
+    return module;
+}
+
+#if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION < 3
+static PyObject *__Pyx_GetStdout(void) {
+    PyObject *f = PySys_GetObject((char *)"stdout");
+    if (!f) {
+        PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout");
+    }
+    return f;
+}
+static int __Pyx_Print(PyObject* f, PyObject *arg_tuple, int newline) {
+    int i;
+    if (!f) {
+        if (!(f = __Pyx_GetStdout()))
+            return -1;
+    }
+    Py_INCREF(f);
+    for (i=0; i < PyTuple_GET_SIZE(arg_tuple); i++) {
+        PyObject* v;
+        if (PyFile_SoftSpace(f, 1)) {
+            if (PyFile_WriteString(" ", f) < 0)
+                goto error;
+        }
+        v = PyTuple_GET_ITEM(arg_tuple, i);
+        if (PyFile_WriteObject(v, f, Py_PRINT_RAW) < 0)
+            goto error;
+        if (PyString_Check(v)) {
+            char *s = PyString_AsString(v);
+            Py_ssize_t len = PyString_Size(v);
+            if (len > 0 &&
+                isspace(Py_CHARMASK(s[len-1])) &&
+                s[len-1] != ' ')
+                    PyFile_SoftSpace(f, 0);
+        }
+    }
+    if (newline) {
+        if (PyFile_WriteString("\n", f) < 0)
+            goto error;
+        PyFile_SoftSpace(f, 0);
+    }
+    Py_DECREF(f);
+    return 0;
+error:
+    Py_DECREF(f);
+    return -1;
+}
+#else /* Python 3 has a print function */
+static int __Pyx_Print(PyObject* stream, PyObject *arg_tuple, int newline) {
+    PyObject* kwargs = 0;
+    PyObject* result = 0;
+    PyObject* end_string;
+    if (unlikely(!__pyx_print)) {
+        __pyx_print = __Pyx_GetAttrString(__pyx_b, "print");
+        if (!__pyx_print)
+            return -1;
+    }
+    if (stream) {
+        kwargs = PyDict_New();
+        if (unlikely(!kwargs))
+            return -1;
+        if (unlikely(PyDict_SetItemString(kwargs, "file", stream) < 0))
+            goto bad;
+        if (!newline) {
+            end_string = PyUnicode_FromStringAndSize(" ", 1);
+            if (unlikely(!end_string))
+                goto bad;
+            if (PyDict_SetItemString(kwargs, "end", end_string) < 0) {
+                Py_DECREF(end_string);
+                goto bad;
+            }
+            Py_DECREF(end_string);
+        }
+    } else if (!newline) {
+        if (unlikely(!__pyx_print_kwargs)) {
+            __pyx_print_kwargs = PyDict_New();
+            if (unlikely(!__pyx_print_kwargs))
+                return -1;
+            end_string = PyUnicode_FromStringAndSize(" ", 1);
+            if (unlikely(!end_string))
+                return -1;
+            if (PyDict_SetItemString(__pyx_print_kwargs, "end", end_string) < 0) {
+                Py_DECREF(end_string);
+                return -1;
+            }
+            Py_DECREF(end_string);
+        }
+        kwargs = __pyx_print_kwargs;
+    }
+    result = PyObject_Call(__pyx_print, arg_tuple, kwargs);
+    if (unlikely(kwargs) && (kwargs != __pyx_print_kwargs))
+        Py_DECREF(kwargs);
+    if (!result)
+        return -1;
+    Py_DECREF(result);
+    return 0;
+bad:
+    if (kwargs != __pyx_print_kwargs)
+        Py_XDECREF(kwargs);
+    return -1;
+}
+#endif
+
+#if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION < 3
+static int __Pyx_PrintOne(PyObject* f, PyObject *o) {
+    if (!f) {
+        if (!(f = __Pyx_GetStdout()))
+            return -1;
+    }
+    Py_INCREF(f);
+    if (PyFile_SoftSpace(f, 0)) {
+        if (PyFile_WriteString(" ", f) < 0)
+            goto error;
+    }
+    if (PyFile_WriteObject(o, f, Py_PRINT_RAW) < 0)
+        goto error;
+    if (PyFile_WriteString("\n", f) < 0)
+        goto error;
+    Py_DECREF(f);
+    return 0;
+error:
+    Py_DECREF(f);
+    return -1;
+    /* the line below is just to avoid C compiler
+     * warnings about unused functions */
+    return __Pyx_Print(f, NULL, 0);
+}
+#else /* Python 3 has a print function */
+static int __Pyx_PrintOne(PyObject* stream, PyObject *o) {
+    int res;
+    PyObject* arg_tuple = PyTuple_Pack(1, o);
+    if (unlikely(!arg_tuple))
+        return -1;
+    res = __Pyx_Print(stream, arg_tuple, 1);
+    Py_DECREF(arg_tuple);
+    return res;
+}
+#endif
+
+static CYTHON_INLINE unsigned char __Pyx_PyInt_AsUnsignedChar(PyObject* x) {
+    const unsigned char neg_one = (unsigned char)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(unsigned char) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(unsigned char)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to unsigned char" :
+                    "value too large to convert to unsigned char");
+            }
+            return (unsigned char)-1;
+        }
+        return (unsigned char)val;
+    }
+    return (unsigned char)__Pyx_PyInt_AsUnsignedLong(x);
+}
+
+static CYTHON_INLINE unsigned short __Pyx_PyInt_AsUnsignedShort(PyObject* x) {
+    const unsigned short neg_one = (unsigned short)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(unsigned short) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(unsigned short)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to unsigned short" :
+                    "value too large to convert to unsigned short");
+            }
+            return (unsigned short)-1;
+        }
+        return (unsigned short)val;
+    }
+    return (unsigned short)__Pyx_PyInt_AsUnsignedLong(x);
+}
+
+static CYTHON_INLINE unsigned int __Pyx_PyInt_AsUnsignedInt(PyObject* x) {
+    const unsigned int neg_one = (unsigned int)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(unsigned int) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(unsigned int)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to unsigned int" :
+                    "value too large to convert to unsigned int");
+            }
+            return (unsigned int)-1;
+        }
+        return (unsigned int)val;
+    }
+    return (unsigned int)__Pyx_PyInt_AsUnsignedLong(x);
+}
+
+static CYTHON_INLINE char __Pyx_PyInt_AsChar(PyObject* x) {
+    const char neg_one = (char)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(char) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(char)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to char" :
+                    "value too large to convert to char");
+            }
+            return (char)-1;
+        }
+        return (char)val;
+    }
+    return (char)__Pyx_PyInt_AsLong(x);
+}
+
+static CYTHON_INLINE short __Pyx_PyInt_AsShort(PyObject* x) {
+    const short neg_one = (short)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(short) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(short)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to short" :
+                    "value too large to convert to short");
+            }
+            return (short)-1;
+        }
+        return (short)val;
+    }
+    return (short)__Pyx_PyInt_AsLong(x);
+}
+
+static CYTHON_INLINE int __Pyx_PyInt_AsInt(PyObject* x) {
+    const int neg_one = (int)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(int) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(int)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to int" :
+                    "value too large to convert to int");
+            }
+            return (int)-1;
+        }
+        return (int)val;
+    }
+    return (int)__Pyx_PyInt_AsLong(x);
+}
+
+static CYTHON_INLINE signed char __Pyx_PyInt_AsSignedChar(PyObject* x) {
+    const signed char neg_one = (signed char)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(signed char) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(signed char)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to signed char" :
+                    "value too large to convert to signed char");
+            }
+            return (signed char)-1;
+        }
+        return (signed char)val;
+    }
+    return (signed char)__Pyx_PyInt_AsSignedLong(x);
+}
+
+static CYTHON_INLINE signed short __Pyx_PyInt_AsSignedShort(PyObject* x) {
+    const signed short neg_one = (signed short)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(signed short) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(signed short)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to signed short" :
+                    "value too large to convert to signed short");
+            }
+            return (signed short)-1;
+        }
+        return (signed short)val;
+    }
+    return (signed short)__Pyx_PyInt_AsSignedLong(x);
+}
+
+static CYTHON_INLINE signed int __Pyx_PyInt_AsSignedInt(PyObject* x) {
+    const signed int neg_one = (signed int)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(signed int) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(signed int)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to signed int" :
+                    "value too large to convert to signed int");
+            }
+            return (signed int)-1;
+        }
+        return (signed int)val;
+    }
+    return (signed int)__Pyx_PyInt_AsSignedLong(x);
+}
+
+static CYTHON_INLINE int __Pyx_PyInt_AsLongDouble(PyObject* x) {
+    const int neg_one = (int)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(int) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(int)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to int" :
+                    "value too large to convert to int");
+            }
+            return (int)-1;
+        }
+        return (int)val;
+    }
+    return (int)__Pyx_PyInt_AsLong(x);
+}
+
+static CYTHON_INLINE unsigned long __Pyx_PyInt_AsUnsignedLong(PyObject* x) {
+    const unsigned long neg_one = (unsigned long)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to unsigned long");
+            return (unsigned long)-1;
+        }
+        return (unsigned long)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to unsigned long");
+                return (unsigned long)-1;
+            }
+            return (unsigned long)PyLong_AsUnsignedLong(x);
+        } else {
+            return (unsigned long)PyLong_AsLong(x);
+        }
+    } else {
+        unsigned long val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (unsigned long)-1;
+        val = __Pyx_PyInt_AsUnsignedLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE unsigned PY_LONG_LONG __Pyx_PyInt_AsUnsignedLongLong(PyObject* x) {
+    const unsigned PY_LONG_LONG neg_one = (unsigned PY_LONG_LONG)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to unsigned PY_LONG_LONG");
+            return (unsigned PY_LONG_LONG)-1;
+        }
+        return (unsigned PY_LONG_LONG)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to unsigned PY_LONG_LONG");
+                return (unsigned PY_LONG_LONG)-1;
+            }
+            return (unsigned PY_LONG_LONG)PyLong_AsUnsignedLongLong(x);
+        } else {
+            return (unsigned PY_LONG_LONG)PyLong_AsLongLong(x);
+        }
+    } else {
+        unsigned PY_LONG_LONG val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (unsigned PY_LONG_LONG)-1;
+        val = __Pyx_PyInt_AsUnsignedLongLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE long __Pyx_PyInt_AsLong(PyObject* x) {
+    const long neg_one = (long)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to long");
+            return (long)-1;
+        }
+        return (long)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to long");
+                return (long)-1;
+            }
+            return (long)PyLong_AsUnsignedLong(x);
+        } else {
+            return (long)PyLong_AsLong(x);
+        }
+    } else {
+        long val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (long)-1;
+        val = __Pyx_PyInt_AsLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE PY_LONG_LONG __Pyx_PyInt_AsLongLong(PyObject* x) {
+    const PY_LONG_LONG neg_one = (PY_LONG_LONG)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to PY_LONG_LONG");
+            return (PY_LONG_LONG)-1;
+        }
+        return (PY_LONG_LONG)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to PY_LONG_LONG");
+                return (PY_LONG_LONG)-1;
+            }
+            return (PY_LONG_LONG)PyLong_AsUnsignedLongLong(x);
+        } else {
+            return (PY_LONG_LONG)PyLong_AsLongLong(x);
+        }
+    } else {
+        PY_LONG_LONG val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (PY_LONG_LONG)-1;
+        val = __Pyx_PyInt_AsLongLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE signed long __Pyx_PyInt_AsSignedLong(PyObject* x) {
+    const signed long neg_one = (signed long)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to signed long");
+            return (signed long)-1;
+        }
+        return (signed long)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to signed long");
+                return (signed long)-1;
+            }
+            return (signed long)PyLong_AsUnsignedLong(x);
+        } else {
+            return (signed long)PyLong_AsLong(x);
+        }
+    } else {
+        signed long val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (signed long)-1;
+        val = __Pyx_PyInt_AsSignedLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE signed PY_LONG_LONG __Pyx_PyInt_AsSignedLongLong(PyObject* x) {
+    const signed PY_LONG_LONG neg_one = (signed PY_LONG_LONG)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to signed PY_LONG_LONG");
+            return (signed PY_LONG_LONG)-1;
+        }
+        return (signed PY_LONG_LONG)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to signed PY_LONG_LONG");
+                return (signed PY_LONG_LONG)-1;
+            }
+            return (signed PY_LONG_LONG)PyLong_AsUnsignedLongLong(x);
+        } else {
+            return (signed PY_LONG_LONG)PyLong_AsLongLong(x);
+        }
+    } else {
+        signed PY_LONG_LONG val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (signed PY_LONG_LONG)-1;
+        val = __Pyx_PyInt_AsSignedLongLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static int __Pyx_check_binary_version(void) {
+    char ctversion[4], rtversion[4];
+    PyOS_snprintf(ctversion, 4, "%d.%d", PY_MAJOR_VERSION, PY_MINOR_VERSION);
+    PyOS_snprintf(rtversion, 4, "%s", Py_GetVersion());
+    if (ctversion[0] != rtversion[0] || ctversion[2] != rtversion[2]) {
+        char message[200];
+        PyOS_snprintf(message, sizeof(message),
+                      "compiletime version %s of module '%.100s' "
+                      "does not match runtime version %s",
+                      ctversion, __Pyx_MODULE_NAME, rtversion);
+        #if PY_VERSION_HEX < 0x02050000
+        return PyErr_Warn(NULL, message);
+        #else
+        return PyErr_WarnEx(NULL, message, 1);
+        #endif
+    }
+    return 0;
+}
+
+static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) {
+    int start = 0, mid = 0, end = count - 1;
+    if (end >= 0 && code_line > entries[end].code_line) {
+        return count;
+    }
+    while (start < end) {
+        mid = (start + end) / 2;
+        if (code_line < entries[mid].code_line) {
+            end = mid;
+        } else if (code_line > entries[mid].code_line) {
+             start = mid + 1;
+        } else {
+            return mid;
+        }
+    }
+    if (code_line <= entries[mid].code_line) {
+        return mid;
+    } else {
+        return mid + 1;
+    }
+}
+static PyCodeObject *__pyx_find_code_object(int code_line) {
+    PyCodeObject* code_object;
+    int pos;
+    if (unlikely(!code_line) || unlikely(!__pyx_code_cache.entries)) {
+        return NULL;
+    }
+    pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line);
+    if (unlikely(pos >= __pyx_code_cache.count) || unlikely(__pyx_code_cache.entries[pos].code_line != code_line)) {
+        return NULL;
+    }
+    code_object = __pyx_code_cache.entries[pos].code_object;
+    Py_INCREF(code_object);
+    return code_object;
+}
+static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) {
+    int pos, i;
+    __Pyx_CodeObjectCacheEntry* entries = __pyx_code_cache.entries;
+    if (unlikely(!code_line)) {
+        return;
+    }
+    if (unlikely(!entries)) {
+        entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Malloc(64*sizeof(__Pyx_CodeObjectCacheEntry));
+        if (likely(entries)) {
+            __pyx_code_cache.entries = entries;
+            __pyx_code_cache.max_count = 64;
+            __pyx_code_cache.count = 1;
+            entries[0].code_line = code_line;
+            entries[0].code_object = code_object;
+            Py_INCREF(code_object);
+        }
+        return;
+    }
+    pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line);
+    if ((pos < __pyx_code_cache.count) && unlikely(__pyx_code_cache.entries[pos].code_line == code_line)) {
+        PyCodeObject* tmp = entries[pos].code_object;
+        entries[pos].code_object = code_object;
+        Py_DECREF(tmp);
+        return;
+    }
+    if (__pyx_code_cache.count == __pyx_code_cache.max_count) {
+        int new_max = __pyx_code_cache.max_count + 64;
+        entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Realloc(
+            __pyx_code_cache.entries, new_max*sizeof(__Pyx_CodeObjectCacheEntry));
+        if (unlikely(!entries)) {
+            return;
+        }
+        __pyx_code_cache.entries = entries;
+        __pyx_code_cache.max_count = new_max;
+    }
+    for (i=__pyx_code_cache.count; i>pos; i--) {
+        entries[i] = entries[i-1];
+    }
+    entries[pos].code_line = code_line;
+    entries[pos].code_object = code_object;
+    __pyx_code_cache.count++;
+    Py_INCREF(code_object);
+}
+
+#include "compile.h"
+#include "frameobject.h"
+#include "traceback.h"
+static PyCodeObject* __Pyx_CreateCodeObjectForTraceback(
+            const char *funcname, int c_line,
+            int py_line, const char *filename) {
+    PyCodeObject *py_code = 0;
+    PyObject *py_srcfile = 0;
+    PyObject *py_funcname = 0;
+    #if PY_MAJOR_VERSION < 3
+    py_srcfile = PyString_FromString(filename);
+    #else
+    py_srcfile = PyUnicode_FromString(filename);
+    #endif
+    if (!py_srcfile) goto bad;
+    if (c_line) {
+        #if PY_MAJOR_VERSION < 3
+        py_funcname = PyString_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line);
+        #else
+        py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line);
+        #endif
+    }
+    else {
+        #if PY_MAJOR_VERSION < 3
+        py_funcname = PyString_FromString(funcname);
+        #else
+        py_funcname = PyUnicode_FromString(funcname);
+        #endif
+    }
+    if (!py_funcname) goto bad;
+    py_code = __Pyx_PyCode_New(
+        0,            /*int argcount,*/
+        0,            /*int kwonlyargcount,*/
+        0,            /*int nlocals,*/
+        0,            /*int stacksize,*/
+        0,            /*int flags,*/
+        __pyx_empty_bytes, /*PyObject *code,*/
+        __pyx_empty_tuple, /*PyObject *consts,*/
+        __pyx_empty_tuple, /*PyObject *names,*/
+        __pyx_empty_tuple, /*PyObject *varnames,*/
+        __pyx_empty_tuple, /*PyObject *freevars,*/
+        __pyx_empty_tuple, /*PyObject *cellvars,*/
+        py_srcfile,   /*PyObject *filename,*/
+        py_funcname,  /*PyObject *name,*/
+        py_line,      /*int firstlineno,*/
+        __pyx_empty_bytes  /*PyObject *lnotab*/
+    );
+    Py_DECREF(py_srcfile);
+    Py_DECREF(py_funcname);
+    return py_code;
+bad:
+    Py_XDECREF(py_srcfile);
+    Py_XDECREF(py_funcname);
+    return NULL;
+}
+static void __Pyx_AddTraceback(const char *funcname, int c_line,
+                               int py_line, const char *filename) {
+    PyCodeObject *py_code = 0;
+    PyObject *py_globals = 0;
+    PyFrameObject *py_frame = 0;
+    py_code = __pyx_find_code_object(c_line ? c_line : py_line);
+    if (!py_code) {
+        py_code = __Pyx_CreateCodeObjectForTraceback(
+            funcname, c_line, py_line, filename);
+        if (!py_code) goto bad;
+        __pyx_insert_code_object(c_line ? c_line : py_line, py_code);
+    }
+    py_globals = PyModule_GetDict(__pyx_m);
+    if (!py_globals) goto bad;
+    py_frame = PyFrame_New(
+        PyThreadState_GET(), /*PyThreadState *tstate,*/
+        py_code,             /*PyCodeObject *code,*/
+        py_globals,          /*PyObject *globals,*/
+        0                    /*PyObject *locals*/
+    );
+    if (!py_frame) goto bad;
+    py_frame->f_lineno = py_line;
+    PyTraceBack_Here(py_frame);
+bad:
+    Py_XDECREF(py_code);
+    Py_XDECREF(py_frame);
+}
+
+static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
+    while (t->p) {
+        #if PY_MAJOR_VERSION < 3
+        if (t->is_unicode) {
+            *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
+        } else if (t->intern) {
+            *t->p = PyString_InternFromString(t->s);
+        } else {
+            *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
+        }
+        #else  /* Python 3+ has unicode identifiers */
+        if (t->is_unicode | t->is_str) {
+            if (t->intern) {
+                *t->p = PyUnicode_InternFromString(t->s);
+            } else if (t->encoding) {
+                *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL);
+            } else {
+                *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
+            }
+        } else {
+            *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
+        }
+        #endif
+        if (!*t->p)
+            return -1;
+        ++t;
+    }
+    return 0;
+}
+
+static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) {
+   int is_true = x == Py_True;
+   if (is_true | (x == Py_False) | (x == Py_None)) return is_true;
+   else return PyObject_IsTrue(x);
+}
+static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x) {
+  PyNumberMethods *m;
+  const char *name = NULL;
+  PyObject *res = NULL;
+#if PY_VERSION_HEX < 0x03000000
+  if (PyInt_Check(x) || PyLong_Check(x))
+#else
+  if (PyLong_Check(x))
+#endif
+    return Py_INCREF(x), x;
+  m = Py_TYPE(x)->tp_as_number;
+#if PY_VERSION_HEX < 0x03000000
+  if (m && m->nb_int) {
+    name = "int";
+    res = PyNumber_Int(x);
+  }
+  else if (m && m->nb_long) {
+    name = "long";
+    res = PyNumber_Long(x);
+  }
+#else
+  if (m && m->nb_int) {
+    name = "int";
+    res = PyNumber_Long(x);
+  }
+#endif
+  if (res) {
+#if PY_VERSION_HEX < 0x03000000
+    if (!PyInt_Check(res) && !PyLong_Check(res)) {
+#else
+    if (!PyLong_Check(res)) {
+#endif
+      PyErr_Format(PyExc_TypeError,
+                   "__%s__ returned non-%s (type %.200s)",
+                   name, name, Py_TYPE(res)->tp_name);
+      Py_DECREF(res);
+      return NULL;
+    }
+  }
+  else if (!PyErr_Occurred()) {
+    PyErr_SetString(PyExc_TypeError,
+                    "an integer is required");
+  }
+  return res;
+}
+static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) {
+  Py_ssize_t ival;
+  PyObject* x = PyNumber_Index(b);
+  if (!x) return -1;
+  ival = PyInt_AsSsize_t(x);
+  Py_DECREF(x);
+  return ival;
+}
+static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) {
+#if PY_VERSION_HEX < 0x02050000
+   if (ival <= LONG_MAX)
+       return PyInt_FromLong((long)ival);
+   else {
+       unsigned char *bytes = (unsigned char *) &ival;
+       int one = 1; int little = (int)*(unsigned char*)&one;
+       return _PyLong_FromByteArray(bytes, sizeof(size_t), little, 0);
+   }
+#else
+   return PyInt_FromSize_t(ival);
+#endif
+}
+static CYTHON_INLINE size_t __Pyx_PyInt_AsSize_t(PyObject* x) {
+   unsigned PY_LONG_LONG val = __Pyx_PyInt_AsUnsignedLongLong(x);
+   if (unlikely(val == (unsigned PY_LONG_LONG)-1 && PyErr_Occurred())) {
+       return (size_t)-1;
+   } else if (unlikely(val != (unsigned PY_LONG_LONG)(size_t)val)) {
+       PyErr_SetString(PyExc_OverflowError,
+                       "value too large to convert to size_t");
+       return (size_t)-1;
+   }
+   return (size_t)val;
+}
+
+
+#endif /* Py_PYTHON_H */
diff --git a/lib/bx/intseq/ngramcount.pyx b/lib/bx/intseq/ngramcount.pyx
new file mode 100644
index 0000000..4ae891e
--- /dev/null
+++ b/lib/bx/intseq/ngramcount.pyx
@@ -0,0 +1,82 @@
+"""
+Tools for counting words (n-grams) in integer sequences.
+"""
+
+import numpy
+
+cdef extern from "Python.h":
+    ctypedef int Py_intptr_t
+    long PyInt_AsLong(object)
+    void Py_INCREF(object)
+    void Py_DECREF(object)
+    void * PyCObject_AsVoidPtr(object cobj)
+    
+# for PyArrayInterface:
+CONTIGUOUS=0x01
+FORTRAN=0x02
+ALIGNED=0x100
+NOTSWAPPED=0x200
+WRITEABLE=0x400
+
+ctypedef struct PyArrayInterface:
+    int two              # contains the integer 2 as a sanity check
+    int nd               # number of dimensions
+    char typekind        # kind in array --- character code of typestr
+    int itemsize         # size of each element
+    int flags            # flags indicating how the data should be interpreted
+    Py_intptr_t *shape   # A length-nd array of shape information
+    Py_intptr_t *strides # A length-nd array of stride information
+    void *data           # A pointer to the first element of the array
+    
+def count_ngrams( object ints, int n, int radix ):
+    """
+    Count the number of occurrences of each possible length `n` word in 
+    `ints` (which contains values from 0 to `radix`). Returns an array
+    of length `radix` ** `n` containing the counts.
+    """
+    cdef PyArrayInterface * ints_desc, * rval_desc
+    # Get array interface for input string and validate
+    ints_desc_obj = ints.__array_struct__
+    ints_desc = <PyArrayInterface *> PyCObject_AsVoidPtr( ints_desc_obj )
+    assert ints_desc.two == 2, "Array interface sanity check failed, got %d" % ints_desc.two
+    assert ints_desc.nd == 1, "Input array must be 1d"
+    assert ints_desc.typekind == 'i'[0], "Input array must contain integers"
+    assert ints_desc.itemsize == 4, "Input array must contain 32bit integers"
+    assert ints_desc.flags & CONTIGUOUS > 0, "Input array must be contiguous"
+    assert ints_desc.flags & ALIGNED > 0, "Input array must be aligned"
+    assert ints_desc.flags & NOTSWAPPED > 0, "Input array must not be byteswapped"
+    # Create numpy array for return value, get array interface and validate
+    rval = numpy.zeros( <int> ( ( <float> radix ) ** n ), dtype=numpy.int32 )
+    assert ints_desc.two == 2, "Array interface sanity check failed, got %d" % ints_desc.two
+    rval_desc_obj = rval.__array_struct__
+    rval_desc = <PyArrayInterface *> PyCObject_AsVoidPtr( rval_desc_obj )
+    assert rval_desc.two == 2, "Array interface sanity check failed"
+    assert rval_desc.nd == 1, "Input array must be 1d"
+    assert rval_desc.typekind == 'i'[0], "Input array must contain integers"
+    assert rval_desc.itemsize == 4, "Input array must contain 32bit integers"
+    assert rval_desc.flags & CONTIGUOUS > 0, "Input array must be contiguous"
+    assert rval_desc.flags & ALIGNED > 0, "Input array must be aligned"
+    assert rval_desc.flags & NOTSWAPPED > 0, "Input array must not be byteswapped"
+    # Do it
+    _count_ngrams( <int*> ints_desc.data, ints_desc.shape[0], <int*> rval_desc.data, n, radix )
+    return rval
+    
+cdef _count_ngrams( int* ints, int n_ints, int* rval, int n, int radix ):
+    cdef int i, j, index, factor, letter
+    # Loop over each word in the string
+    for i from 0 <= i < ( n_ints - n ):
+        # Walk back to build index into count array
+        index = 0
+        factor = 1
+        for j from 0 <= j < n:
+            letter = ints[ i + j ]
+            if letter < 0 or letter >= radix:
+                # This word is bad, break out and do not increment counts
+                print "breaking, letter", letter
+                break
+            index = index + letter * factor
+            factor = factor * radix
+        else:
+            print index
+            rval[ index ] = rval[ index ] + 1
+            
\ No newline at end of file
diff --git a/lib/bx/misc/__init__.py b/lib/bx/misc/__init__.py
new file mode 100644
index 0000000..94a3b13
--- /dev/null
+++ b/lib/bx/misc/__init__.py
@@ -0,0 +1,13 @@
+"""
+Various utilities.
+"""
+
+import bz2, gzip
+
+def open_compressed( filename, mode='r' ):
+    if filename.endswith( ".bz2" ):
+        return bz2.BZ2File( filename, mode )
+    elif filename.endswith( ".gz" ):
+        return gzip.GzipFile( filename, mode )
+    else:
+        return file( filename, mode )
diff --git a/lib/bx/misc/_seekbzip2.c b/lib/bx/misc/_seekbzip2.c
new file mode 100644
index 0000000..8aa6cf3
--- /dev/null
+++ b/lib/bx/misc/_seekbzip2.c
@@ -0,0 +1,3194 @@
+/* Generated by Cython 0.18 on Mon Jul 15 13:25:44 2013 */
+
+#define PY_SSIZE_T_CLEAN
+#include "Python.h"
+#ifndef Py_PYTHON_H
+    #error Python headers needed to compile C extensions, please install development version of Python.
+#elif PY_VERSION_HEX < 0x02040000
+    #error Cython requires Python 2.4+.
+#else
+#include <stddef.h> /* For offsetof */
+#ifndef offsetof
+#define offsetof(type, member) ( (size_t) & ((type*)0) -> member )
+#endif
+#if !defined(WIN32) && !defined(MS_WINDOWS)
+  #ifndef __stdcall
+    #define __stdcall
+  #endif
+  #ifndef __cdecl
+    #define __cdecl
+  #endif
+  #ifndef __fastcall
+    #define __fastcall
+  #endif
+#endif
+#ifndef DL_IMPORT
+  #define DL_IMPORT(t) t
+#endif
+#ifndef DL_EXPORT
+  #define DL_EXPORT(t) t
+#endif
+#ifndef PY_LONG_LONG
+  #define PY_LONG_LONG LONG_LONG
+#endif
+#ifndef Py_HUGE_VAL
+  #define Py_HUGE_VAL HUGE_VAL
+#endif
+#ifdef PYPY_VERSION
+#define CYTHON_COMPILING_IN_PYPY 1
+#define CYTHON_COMPILING_IN_CPYTHON 0
+#else
+#define CYTHON_COMPILING_IN_PYPY 0
+#define CYTHON_COMPILING_IN_CPYTHON 1
+#endif
+#if PY_VERSION_HEX < 0x02050000
+  typedef int Py_ssize_t;
+  #define PY_SSIZE_T_MAX INT_MAX
+  #define PY_SSIZE_T_MIN INT_MIN
+  #define PY_FORMAT_SIZE_T ""
+  #define CYTHON_FORMAT_SSIZE_T ""
+  #define PyInt_FromSsize_t(z) PyInt_FromLong(z)
+  #define PyInt_AsSsize_t(o)   __Pyx_PyInt_AsInt(o)
+  #define PyNumber_Index(o)    ((PyNumber_Check(o) && !PyFloat_Check(o)) ? PyNumber_Int(o) : \
+                                (PyErr_Format(PyExc_TypeError, \
+                                              "expected index value, got %.200s", Py_TYPE(o)->tp_name), \
+                                 (PyObject*)0))
+  #define __Pyx_PyIndex_Check(o) (PyNumber_Check(o) && !PyFloat_Check(o) && \
+                                  !PyComplex_Check(o))
+  #define PyIndex_Check __Pyx_PyIndex_Check
+  #define PyErr_WarnEx(category, message, stacklevel) PyErr_Warn(category, message)
+  #define __PYX_BUILD_PY_SSIZE_T "i"
+#else
+  #define __PYX_BUILD_PY_SSIZE_T "n"
+  #define CYTHON_FORMAT_SSIZE_T "z"
+  #define __Pyx_PyIndex_Check PyIndex_Check
+#endif
+#if PY_VERSION_HEX < 0x02060000
+  #define Py_REFCNT(ob) (((PyObject*)(ob))->ob_refcnt)
+  #define Py_TYPE(ob)   (((PyObject*)(ob))->ob_type)
+  #define Py_SIZE(ob)   (((PyVarObject*)(ob))->ob_size)
+  #define PyVarObject_HEAD_INIT(type, size) \
+          PyObject_HEAD_INIT(type) size,
+  #define PyType_Modified(t)
+  typedef struct {
+     void *buf;
+     PyObject *obj;
+     Py_ssize_t len;
+     Py_ssize_t itemsize;
+     int readonly;
+     int ndim;
+     char *format;
+     Py_ssize_t *shape;
+     Py_ssize_t *strides;
+     Py_ssize_t *suboffsets;
+     void *internal;
+  } Py_buffer;
+  #define PyBUF_SIMPLE 0
+  #define PyBUF_WRITABLE 0x0001
+  #define PyBUF_FORMAT 0x0004
+  #define PyBUF_ND 0x0008
+  #define PyBUF_STRIDES (0x0010 | PyBUF_ND)
+  #define PyBUF_C_CONTIGUOUS (0x0020 | PyBUF_STRIDES)
+  #define PyBUF_F_CONTIGUOUS (0x0040 | PyBUF_STRIDES)
+  #define PyBUF_ANY_CONTIGUOUS (0x0080 | PyBUF_STRIDES)
+  #define PyBUF_INDIRECT (0x0100 | PyBUF_STRIDES)
+  #define PyBUF_RECORDS (PyBUF_STRIDES | PyBUF_FORMAT | PyBUF_WRITABLE)
+  #define PyBUF_FULL (PyBUF_INDIRECT | PyBUF_FORMAT | PyBUF_WRITABLE)
+  typedef int (*getbufferproc)(PyObject *, Py_buffer *, int);
+  typedef void (*releasebufferproc)(PyObject *, Py_buffer *);
+#endif
+#if PY_MAJOR_VERSION < 3
+  #define __Pyx_BUILTIN_MODULE_NAME "__builtin__"
+  #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \
+          PyCode_New(a, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
+#else
+  #define __Pyx_BUILTIN_MODULE_NAME "builtins"
+  #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \
+          PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
+#endif
+#if PY_MAJOR_VERSION < 3 && PY_MINOR_VERSION < 6
+  #define PyUnicode_FromString(s) PyUnicode_Decode(s, strlen(s), "UTF-8", "strict")
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define Py_TPFLAGS_CHECKTYPES 0
+  #define Py_TPFLAGS_HAVE_INDEX 0
+#endif
+#if (PY_VERSION_HEX < 0x02060000) || (PY_MAJOR_VERSION >= 3)
+  #define Py_TPFLAGS_HAVE_NEWBUFFER 0
+#endif
+#if PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND)
+  #define CYTHON_PEP393_ENABLED 1
+  #define __Pyx_PyUnicode_READY(op)       (likely(PyUnicode_IS_READY(op)) ? \
+                                              0 : _PyUnicode_Ready((PyObject *)(op)))
+  #define __Pyx_PyUnicode_GET_LENGTH(u)   PyUnicode_GET_LENGTH(u)
+  #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_READ_CHAR(u, i)
+  #define __Pyx_PyUnicode_READ(k, d, i)   PyUnicode_READ(k, d, i)
+#else
+  #define CYTHON_PEP393_ENABLED 0
+  #define __Pyx_PyUnicode_READY(op)       (0)
+  #define __Pyx_PyUnicode_GET_LENGTH(u)   PyUnicode_GET_SIZE(u)
+  #define __Pyx_PyUnicode_READ_CHAR(u, i) ((Py_UCS4)(PyUnicode_AS_UNICODE(u)[i]))
+  #define __Pyx_PyUnicode_READ(k, d, i)   ((k=k), (Py_UCS4)(((Py_UNICODE*)d)[i]))
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define PyBaseString_Type            PyUnicode_Type
+  #define PyStringObject               PyUnicodeObject
+  #define PyString_Type                PyUnicode_Type
+  #define PyString_Check               PyUnicode_Check
+  #define PyString_CheckExact          PyUnicode_CheckExact
+#endif
+#if PY_VERSION_HEX < 0x02060000
+  #define PyBytesObject                PyStringObject
+  #define PyBytes_Type                 PyString_Type
+  #define PyBytes_Check                PyString_Check
+  #define PyBytes_CheckExact           PyString_CheckExact
+  #define PyBytes_FromString           PyString_FromString
+  #define PyBytes_FromStringAndSize    PyString_FromStringAndSize
+  #define PyBytes_FromFormat           PyString_FromFormat
+  #define PyBytes_DecodeEscape         PyString_DecodeEscape
+  #define PyBytes_AsString             PyString_AsString
+  #define PyBytes_AsStringAndSize      PyString_AsStringAndSize
+  #define PyBytes_Size                 PyString_Size
+  #define PyBytes_AS_STRING            PyString_AS_STRING
+  #define PyBytes_GET_SIZE             PyString_GET_SIZE
+  #define PyBytes_Repr                 PyString_Repr
+  #define PyBytes_Concat               PyString_Concat
+  #define PyBytes_ConcatAndDel         PyString_ConcatAndDel
+#endif
+#if PY_VERSION_HEX < 0x02060000
+  #define PySet_Check(obj)             PyObject_TypeCheck(obj, &PySet_Type)
+  #define PyFrozenSet_Check(obj)       PyObject_TypeCheck(obj, &PyFrozenSet_Type)
+#endif
+#ifndef PySet_CheckExact
+  #define PySet_CheckExact(obj)        (Py_TYPE(obj) == &PySet_Type)
+#endif
+#define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type)
+#if PY_MAJOR_VERSION >= 3
+  #define PyIntObject                  PyLongObject
+  #define PyInt_Type                   PyLong_Type
+  #define PyInt_Check(op)              PyLong_Check(op)
+  #define PyInt_CheckExact(op)         PyLong_CheckExact(op)
+  #define PyInt_FromString             PyLong_FromString
+  #define PyInt_FromUnicode            PyLong_FromUnicode
+  #define PyInt_FromLong               PyLong_FromLong
+  #define PyInt_FromSize_t             PyLong_FromSize_t
+  #define PyInt_FromSsize_t            PyLong_FromSsize_t
+  #define PyInt_AsLong                 PyLong_AsLong
+  #define PyInt_AS_LONG                PyLong_AS_LONG
+  #define PyInt_AsSsize_t              PyLong_AsSsize_t
+  #define PyInt_AsUnsignedLongMask     PyLong_AsUnsignedLongMask
+  #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define PyBoolObject                 PyLongObject
+#endif
+#if PY_VERSION_HEX < 0x03020000
+  typedef long Py_hash_t;
+  #define __Pyx_PyInt_FromHash_t PyInt_FromLong
+  #define __Pyx_PyInt_AsHash_t   PyInt_AsLong
+#else
+  #define __Pyx_PyInt_FromHash_t PyInt_FromSsize_t
+  #define __Pyx_PyInt_AsHash_t   PyInt_AsSsize_t
+#endif
+#if (PY_MAJOR_VERSION < 3) || (PY_VERSION_HEX >= 0x03010300)
+  #define __Pyx_PySequence_GetSlice(obj, a, b) PySequence_GetSlice(obj, a, b)
+  #define __Pyx_PySequence_SetSlice(obj, a, b, value) PySequence_SetSlice(obj, a, b, value)
+  #define __Pyx_PySequence_DelSlice(obj, a, b) PySequence_DelSlice(obj, a, b)
+#else
+  #define __Pyx_PySequence_GetSlice(obj, a, b) (unlikely(!(obj)) ? \
+        (PyErr_SetString(PyExc_SystemError, "null argument to internal routine"), (PyObject*)0) : \
+        (likely((obj)->ob_type->tp_as_mapping) ? (PySequence_GetSlice(obj, a, b)) : \
+            (PyErr_Format(PyExc_TypeError, "'%.200s' object is unsliceable", (obj)->ob_type->tp_name), (PyObject*)0)))
+  #define __Pyx_PySequence_SetSlice(obj, a, b, value) (unlikely(!(obj)) ? \
+        (PyErr_SetString(PyExc_SystemError, "null argument to internal routine"), -1) : \
+        (likely((obj)->ob_type->tp_as_mapping) ? (PySequence_SetSlice(obj, a, b, value)) : \
+            (PyErr_Format(PyExc_TypeError, "'%.200s' object doesn't support slice assignment", (obj)->ob_type->tp_name), -1)))
+  #define __Pyx_PySequence_DelSlice(obj, a, b) (unlikely(!(obj)) ? \
+        (PyErr_SetString(PyExc_SystemError, "null argument to internal routine"), -1) : \
+        (likely((obj)->ob_type->tp_as_mapping) ? (PySequence_DelSlice(obj, a, b)) : \
+            (PyErr_Format(PyExc_TypeError, "'%.200s' object doesn't support slice deletion", (obj)->ob_type->tp_name), -1)))
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define PyMethod_New(func, self, klass) ((self) ? PyMethod_New(func, self) : PyInstanceMethod_New(func))
+#endif
+#if PY_VERSION_HEX < 0x02050000
+  #define __Pyx_GetAttrString(o,n)   PyObject_GetAttrString((o),((char *)(n)))
+  #define __Pyx_SetAttrString(o,n,a) PyObject_SetAttrString((o),((char *)(n)),(a))
+  #define __Pyx_DelAttrString(o,n)   PyObject_DelAttrString((o),((char *)(n)))
+#else
+  #define __Pyx_GetAttrString(o,n)   PyObject_GetAttrString((o),(n))
+  #define __Pyx_SetAttrString(o,n,a) PyObject_SetAttrString((o),(n),(a))
+  #define __Pyx_DelAttrString(o,n)   PyObject_DelAttrString((o),(n))
+#endif
+#if PY_VERSION_HEX < 0x02050000
+  #define __Pyx_NAMESTR(n) ((char *)(n))
+  #define __Pyx_DOCSTR(n)  ((char *)(n))
+#else
+  #define __Pyx_NAMESTR(n) (n)
+  #define __Pyx_DOCSTR(n)  (n)
+#endif
+
+
+#if PY_MAJOR_VERSION >= 3
+  #define __Pyx_PyNumber_Divide(x,y)         PyNumber_TrueDivide(x,y)
+  #define __Pyx_PyNumber_InPlaceDivide(x,y)  PyNumber_InPlaceTrueDivide(x,y)
+#else
+  #define __Pyx_PyNumber_Divide(x,y)         PyNumber_Divide(x,y)
+  #define __Pyx_PyNumber_InPlaceDivide(x,y)  PyNumber_InPlaceDivide(x,y)
+#endif
+
+#ifndef __PYX_EXTERN_C
+  #ifdef __cplusplus
+    #define __PYX_EXTERN_C extern "C"
+  #else
+    #define __PYX_EXTERN_C extern
+  #endif
+#endif
+
+#if defined(WIN32) || defined(MS_WINDOWS)
+#define _USE_MATH_DEFINES
+#endif
+#include <math.h>
+#define __PYX_HAVE__bx__misc___seekbzip2
+#define __PYX_HAVE_API__bx__misc___seekbzip2
+#include "micro-bunzip.h"
+#include "unistd.h"
+#include "stdlib.h"
+#ifdef _OPENMP
+#include <omp.h>
+#endif /* _OPENMP */
+
+#ifdef PYREX_WITHOUT_ASSERTIONS
+#define CYTHON_WITHOUT_ASSERTIONS
+#endif
+
+#ifndef CYTHON_INLINE
+  #if defined(__GNUC__)
+    #define CYTHON_INLINE __inline__
+  #elif defined(_MSC_VER)
+    #define CYTHON_INLINE __inline
+  #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+    #define CYTHON_INLINE inline
+  #else
+    #define CYTHON_INLINE
+  #endif
+#endif
+#ifndef CYTHON_UNUSED
+# if defined(__GNUC__)
+#   if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
+#     define CYTHON_UNUSED __attribute__ ((__unused__))
+#   else
+#     define CYTHON_UNUSED
+#   endif
+# elif defined(__ICC) || (defined(__INTEL_COMPILER) && !defined(_MSC_VER))
+#   define CYTHON_UNUSED __attribute__ ((__unused__))
+# else
+#   define CYTHON_UNUSED
+# endif
+#endif
+typedef struct {PyObject **p; char *s; const long n; const char* encoding; const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry; /*proto*/
+
+#define __Pyx_PyBytes_FromUString(s) PyBytes_FromString((char*)s)
+#define __Pyx_PyBytes_AsUString(s)   ((unsigned char*) PyBytes_AsString(s))
+#define __Pyx_Owned_Py_None(b) (Py_INCREF(Py_None), Py_None)
+#define __Pyx_PyBool_FromLong(b) ((b) ? (Py_INCREF(Py_True), Py_True) : (Py_INCREF(Py_False), Py_False))
+static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*);
+static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x);
+static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*);
+static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t);
+static CYTHON_INLINE size_t __Pyx_PyInt_AsSize_t(PyObject*);
+#if CYTHON_COMPILING_IN_CPYTHON
+#define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x))
+#else
+#define __pyx_PyFloat_AsDouble(x) PyFloat_AsDouble(x)
+#endif
+#define __pyx_PyFloat_AsFloat(x) ((float) __pyx_PyFloat_AsDouble(x))
+
+
+#ifdef __GNUC__
+  /* Test for GCC > 2.95 */
+  #if __GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))
+    #define likely(x)   __builtin_expect(!!(x), 1)
+    #define unlikely(x) __builtin_expect(!!(x), 0)
+  #else /* __GNUC__ > 2 ... */
+    #define likely(x)   (x)
+    #define unlikely(x) (x)
+  #endif /* __GNUC__ > 2 ... */
+#else /* __GNUC__ */
+  #define likely(x)   (x)
+  #define unlikely(x) (x)
+#endif /* __GNUC__ */
+    
+static PyObject *__pyx_m;
+static PyObject *__pyx_b;
+static PyObject *__pyx_empty_tuple;
+static PyObject *__pyx_empty_bytes;
+static int __pyx_lineno;
+static int __pyx_clineno = 0;
+static const char * __pyx_cfilenm= __FILE__;
+static const char *__pyx_filename;
+
+
+static const char *__pyx_f[] = {
+  "_seekbzip2.pyx",
+};
+
+/*--- Type declarations ---*/
+struct __pyx_obj_2bx_4misc_10_seekbzip2_SeekBzip2;
+
+/* "bx/misc/_seekbzip2.pyx":38
+ * import os
+ * 
+ * cdef class SeekBzip2:             # <<<<<<<<<<<<<<
+ * 
+ *     cdef bunzip_data * bd
+ */
+struct __pyx_obj_2bx_4misc_10_seekbzip2_SeekBzip2 {
+  PyObject_HEAD
+  bunzip_data *bd;
+  int file_fd;
+  int at_eof;
+};
+
+#ifndef CYTHON_REFNANNY
+  #define CYTHON_REFNANNY 0
+#endif
+#if CYTHON_REFNANNY
+  typedef struct {
+    void (*INCREF)(void*, PyObject*, int);
+    void (*DECREF)(void*, PyObject*, int);
+    void (*GOTREF)(void*, PyObject*, int);
+    void (*GIVEREF)(void*, PyObject*, int);
+    void* (*SetupContext)(const char*, int, const char*);
+    void (*FinishContext)(void**);
+  } __Pyx_RefNannyAPIStruct;
+  static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL;
+  static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname); /*proto*/
+  #define __Pyx_RefNannyDeclarations void *__pyx_refnanny = NULL;
+#ifdef WITH_THREAD
+  #define __Pyx_RefNannySetupContext(name, acquire_gil) \
+          if (acquire_gil) { \
+              PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure(); \
+              __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__); \
+              PyGILState_Release(__pyx_gilstate_save); \
+          } else { \
+              __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__); \
+          }
+#else
+  #define __Pyx_RefNannySetupContext(name, acquire_gil) \
+          __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__)
+#endif
+  #define __Pyx_RefNannyFinishContext() \
+          __Pyx_RefNanny->FinishContext(&__pyx_refnanny)
+  #define __Pyx_INCREF(r)  __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_DECREF(r)  __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_GOTREF(r)  __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_XINCREF(r)  do { if((r) != NULL) {__Pyx_INCREF(r); }} while(0)
+  #define __Pyx_XDECREF(r)  do { if((r) != NULL) {__Pyx_DECREF(r); }} while(0)
+  #define __Pyx_XGOTREF(r)  do { if((r) != NULL) {__Pyx_GOTREF(r); }} while(0)
+  #define __Pyx_XGIVEREF(r) do { if((r) != NULL) {__Pyx_GIVEREF(r);}} while(0)
+#else
+  #define __Pyx_RefNannyDeclarations
+  #define __Pyx_RefNannySetupContext(name, acquire_gil)
+  #define __Pyx_RefNannyFinishContext()
+  #define __Pyx_INCREF(r) Py_INCREF(r)
+  #define __Pyx_DECREF(r) Py_DECREF(r)
+  #define __Pyx_GOTREF(r)
+  #define __Pyx_GIVEREF(r)
+  #define __Pyx_XINCREF(r) Py_XINCREF(r)
+  #define __Pyx_XDECREF(r) Py_XDECREF(r)
+  #define __Pyx_XGOTREF(r)
+  #define __Pyx_XGIVEREF(r)
+#endif /* CYTHON_REFNANNY */
+#define __Pyx_CLEAR(r)    do { PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);} while(0)
+#define __Pyx_XCLEAR(r)   do { if((r) != NULL) {PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);}} while(0)
+
+static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/
+
+static void __Pyx_RaiseDoubleKeywordsError(const char* func_name, PyObject* kw_name); /*proto*/
+
+static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
+    PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
+    const char* function_name); /*proto*/
+
+static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
+    Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/
+
+static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
+static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
+
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause); /*proto*/
+
+static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level); /*proto*/
+
+static CYTHON_INLINE unsigned char __Pyx_PyInt_AsUnsignedChar(PyObject *);
+
+static CYTHON_INLINE unsigned short __Pyx_PyInt_AsUnsignedShort(PyObject *);
+
+static CYTHON_INLINE unsigned int __Pyx_PyInt_AsUnsignedInt(PyObject *);
+
+static CYTHON_INLINE char __Pyx_PyInt_AsChar(PyObject *);
+
+static CYTHON_INLINE short __Pyx_PyInt_AsShort(PyObject *);
+
+static CYTHON_INLINE int __Pyx_PyInt_AsInt(PyObject *);
+
+static CYTHON_INLINE signed char __Pyx_PyInt_AsSignedChar(PyObject *);
+
+static CYTHON_INLINE signed short __Pyx_PyInt_AsSignedShort(PyObject *);
+
+static CYTHON_INLINE signed int __Pyx_PyInt_AsSignedInt(PyObject *);
+
+static CYTHON_INLINE int __Pyx_PyInt_AsLongDouble(PyObject *);
+
+static CYTHON_INLINE unsigned long __Pyx_PyInt_AsUnsignedLong(PyObject *);
+
+static CYTHON_INLINE unsigned PY_LONG_LONG __Pyx_PyInt_AsUnsignedLongLong(PyObject *);
+
+static CYTHON_INLINE long __Pyx_PyInt_AsLong(PyObject *);
+
+static CYTHON_INLINE PY_LONG_LONG __Pyx_PyInt_AsLongLong(PyObject *);
+
+static CYTHON_INLINE signed long __Pyx_PyInt_AsSignedLong(PyObject *);
+
+static CYTHON_INLINE signed PY_LONG_LONG __Pyx_PyInt_AsSignedLongLong(PyObject *);
+
+static int __Pyx_check_binary_version(void);
+
+typedef struct {
+    int code_line;
+    PyCodeObject* code_object;
+} __Pyx_CodeObjectCacheEntry;
+struct __Pyx_CodeObjectCache {
+    int count;
+    int max_count;
+    __Pyx_CodeObjectCacheEntry* entries;
+};
+static struct __Pyx_CodeObjectCache __pyx_code_cache = {0,0,NULL};
+static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line);
+static PyCodeObject *__pyx_find_code_object(int code_line);
+static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object);
+
+static void __Pyx_AddTraceback(const char *funcname, int c_line,
+                               int py_line, const char *filename); /*proto*/
+
+static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
+
+
+/* Module declarations from 'bx.misc._seekbzip2' */
+static PyTypeObject *__pyx_ptype_2bx_4misc_10_seekbzip2_SeekBzip2 = 0;
+#define __Pyx_MODULE_NAME "bx.misc._seekbzip2"
+int __pyx_module_is_main_bx__misc___seekbzip2 = 0;
+
+/* Implementation of 'bx.misc._seekbzip2' */
+static PyObject *__pyx_builtin_Exception;
+static int __pyx_pf_2bx_4misc_10_seekbzip2_9SeekBzip2___init__(struct __pyx_obj_2bx_4misc_10_seekbzip2_SeekBzip2 *__pyx_v_self, PyObject *__pyx_v_filename); /* proto */
+static PyObject *__pyx_pf_2bx_4misc_10_seekbzip2_9SeekBzip2_2close(struct __pyx_obj_2bx_4misc_10_seekbzip2_SeekBzip2 *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_2bx_4misc_10_seekbzip2_9SeekBzip2_4seek(struct __pyx_obj_2bx_4misc_10_seekbzip2_SeekBzip2 *__pyx_v_self, unsigned PY_LONG_LONG __pyx_v_position); /* proto */
+static PyObject *__pyx_pf_2bx_4misc_10_seekbzip2_9SeekBzip2_6readline(struct __pyx_obj_2bx_4misc_10_seekbzip2_SeekBzip2 *__pyx_v_self, int __pyx_v_amount); /* proto */
+static PyObject *__pyx_pf_2bx_4misc_10_seekbzip2_9SeekBzip2_8read(struct __pyx_obj_2bx_4misc_10_seekbzip2_SeekBzip2 *__pyx_v_self, int __pyx_v_amount); /* proto */
+static char __pyx_k_1[] = "lseek of underlying file failed";
+static char __pyx_k_3[] = "read_bunzip error %d";
+static char __pyx_k_4[] = "";
+static char __pyx_k_5[] = "\nPyrex/C extension supporting `bx.misc.seekbzip2` (wrapping the low level\nfunctions in `micro-bunzip.c`).\n";
+static char __pyx_k__os[] = "os";
+static char __pyx_k__sys[] = "sys";
+static char __pyx_k__join[] = "join";
+static char __pyx_k__open[] = "open";
+static char __pyx_k__close[] = "close";
+static char __pyx_k__O_RDONLY[] = "O_RDONLY";
+static char __pyx_k____main__[] = "__main__";
+static char __pyx_k____test__[] = "__test__";
+static char __pyx_k__filename[] = "filename";
+static char __pyx_k__Exception[] = "Exception";
+static PyObject *__pyx_kp_s_1;
+static PyObject *__pyx_kp_s_3;
+static PyObject *__pyx_kp_s_4;
+static PyObject *__pyx_n_s__Exception;
+static PyObject *__pyx_n_s__O_RDONLY;
+static PyObject *__pyx_n_s____main__;
+static PyObject *__pyx_n_s____test__;
+static PyObject *__pyx_n_s__close;
+static PyObject *__pyx_n_s__filename;
+static PyObject *__pyx_n_s__join;
+static PyObject *__pyx_n_s__open;
+static PyObject *__pyx_n_s__os;
+static PyObject *__pyx_n_s__sys;
+static PyObject *__pyx_k_tuple_2;
+
+/* Python wrapper */
+static int __pyx_pw_2bx_4misc_10_seekbzip2_9SeekBzip2_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static int __pyx_pw_2bx_4misc_10_seekbzip2_9SeekBzip2_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_filename = 0;
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__init__ (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__filename,0};
+    PyObject* values[1] = {0};
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__filename)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 44; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else if (PyTuple_GET_SIZE(__pyx_args) != 1) {
+      goto __pyx_L5_argtuple_error;
+    } else {
+      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+    }
+    __pyx_v_filename = values[0];
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("__init__", 1, 1, 1, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 44; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.misc._seekbzip2.SeekBzip2.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return -1;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_4misc_10_seekbzip2_9SeekBzip2___init__(((struct __pyx_obj_2bx_4misc_10_seekbzip2_SeekBzip2 *)__pyx_v_self), __pyx_v_filename);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/misc/_seekbzip2.pyx":44
+ *     cdef int at_eof
+ * 
+ *     def __init__( self, filename ):             # <<<<<<<<<<<<<<
+ *         self.at_eof = 0
+ *         self.file_fd = os.open( filename, os.O_RDONLY )
+ */
+
+static int __pyx_pf_2bx_4misc_10_seekbzip2_9SeekBzip2___init__(struct __pyx_obj_2bx_4misc_10_seekbzip2_SeekBzip2 *__pyx_v_self, PyObject *__pyx_v_filename) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  int __pyx_t_4;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__init__", 0);
+
+  /* "bx/misc/_seekbzip2.pyx":45
+ * 
+ *     def __init__( self, filename ):
+ *         self.at_eof = 0             # <<<<<<<<<<<<<<
+ *         self.file_fd = os.open( filename, os.O_RDONLY )
+ *         # Initialize bunzip_data from the file
+ */
+  __pyx_v_self->at_eof = 0;
+
+  /* "bx/misc/_seekbzip2.pyx":46
+ *     def __init__( self, filename ):
+ *         self.at_eof = 0
+ *         self.file_fd = os.open( filename, os.O_RDONLY )             # <<<<<<<<<<<<<<
+ *         # Initialize bunzip_data from the file
+ *         start_bunzip( &( self.bd ), self.file_fd, NULL, 0 )
+ */
+  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__os); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 46; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = PyObject_GetAttr(__pyx_t_1, __pyx_n_s__open); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 46; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__os); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 46; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_3 = PyObject_GetAttr(__pyx_t_1, __pyx_n_s__O_RDONLY); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 46; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 46; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_INCREF(__pyx_v_filename);
+  PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_filename);
+  __Pyx_GIVEREF(__pyx_v_filename);
+  PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_t_3);
+  __Pyx_GIVEREF(__pyx_t_3);
+  __pyx_t_3 = 0;
+  __pyx_t_3 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 46; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+  __pyx_t_4 = __Pyx_PyInt_AsInt(__pyx_t_3); if (unlikely((__pyx_t_4 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 46; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __pyx_v_self->file_fd = __pyx_t_4;
+
+  /* "bx/misc/_seekbzip2.pyx":48
+ *         self.file_fd = os.open( filename, os.O_RDONLY )
+ *         # Initialize bunzip_data from the file
+ *         start_bunzip( &( self.bd ), self.file_fd, NULL, 0 )             # <<<<<<<<<<<<<<
+ * 
+ *     def close( self ):
+ */
+  start_bunzip((&__pyx_v_self->bd), __pyx_v_self->file_fd, NULL, 0);
+
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_AddTraceback("bx.misc._seekbzip2.SeekBzip2.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = -1;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_4misc_10_seekbzip2_9SeekBzip2_3close(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static PyObject *__pyx_pw_2bx_4misc_10_seekbzip2_9SeekBzip2_3close(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("close (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_4misc_10_seekbzip2_9SeekBzip2_2close(((struct __pyx_obj_2bx_4misc_10_seekbzip2_SeekBzip2 *)__pyx_v_self));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/misc/_seekbzip2.pyx":50
+ *         start_bunzip( &( self.bd ), self.file_fd, NULL, 0 )
+ * 
+ *     def close( self ):             # <<<<<<<<<<<<<<
+ *         free( self.bd.dbuf )
+ *         free( self.bd )
+ */
+
+static PyObject *__pyx_pf_2bx_4misc_10_seekbzip2_9SeekBzip2_2close(struct __pyx_obj_2bx_4misc_10_seekbzip2_SeekBzip2 *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("close", 0);
+
+  /* "bx/misc/_seekbzip2.pyx":51
+ * 
+ *     def close( self ):
+ *         free( self.bd.dbuf )             # <<<<<<<<<<<<<<
+ *         free( self.bd )
+ *         os.close( self.file_fd )
+ */
+  free(__pyx_v_self->bd->dbuf);
+
+  /* "bx/misc/_seekbzip2.pyx":52
+ *     def close( self ):
+ *         free( self.bd.dbuf )
+ *         free( self.bd )             # <<<<<<<<<<<<<<
+ *         os.close( self.file_fd )
+ * 
+ */
+  free(__pyx_v_self->bd);
+
+  /* "bx/misc/_seekbzip2.pyx":53
+ *         free( self.bd.dbuf )
+ *         free( self.bd )
+ *         os.close( self.file_fd )             # <<<<<<<<<<<<<<
+ * 
+ *     def seek( self, unsigned long long position ):
+ */
+  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__os); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 53; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = PyObject_GetAttr(__pyx_t_1, __pyx_n_s__close); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 53; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_1 = PyInt_FromLong(__pyx_v_self->file_fd); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 53; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 53; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1);
+  __Pyx_GIVEREF(__pyx_t_1);
+  __pyx_t_1 = 0;
+  __pyx_t_1 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 53; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_AddTraceback("bx.misc._seekbzip2.SeekBzip2.close", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_4misc_10_seekbzip2_9SeekBzip2_5seek(PyObject *__pyx_v_self, PyObject *__pyx_arg_position); /*proto*/
+static char __pyx_doc_2bx_4misc_10_seekbzip2_9SeekBzip2_4seek[] = "\n        Seek the bunzip_data to a specific chunk (position must correspond to\n        that start of a compressed data block).\n        ";
+static PyObject *__pyx_pw_2bx_4misc_10_seekbzip2_9SeekBzip2_5seek(PyObject *__pyx_v_self, PyObject *__pyx_arg_position) {
+  unsigned PY_LONG_LONG __pyx_v_position;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("seek (wrapper)", 0);
+  assert(__pyx_arg_position); {
+    __pyx_v_position = __Pyx_PyInt_AsUnsignedLongLong(__pyx_arg_position); if (unlikely((__pyx_v_position == (unsigned PY_LONG_LONG)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 55; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.misc._seekbzip2.SeekBzip2.seek", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_4misc_10_seekbzip2_9SeekBzip2_4seek(((struct __pyx_obj_2bx_4misc_10_seekbzip2_SeekBzip2 *)__pyx_v_self), ((unsigned PY_LONG_LONG)__pyx_v_position));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/misc/_seekbzip2.pyx":55
+ *         os.close( self.file_fd )
+ * 
+ *     def seek( self, unsigned long long position ):             # <<<<<<<<<<<<<<
+ *         """
+ *         Seek the bunzip_data to a specific chunk (position must correspond to
+ */
+
+static PyObject *__pyx_pf_2bx_4misc_10_seekbzip2_9SeekBzip2_4seek(struct __pyx_obj_2bx_4misc_10_seekbzip2_SeekBzip2 *__pyx_v_self, unsigned PY_LONG_LONG __pyx_v_position) {
+  off_t __pyx_v_n_byte;
+  int __pyx_v_n_bit;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("seek", 0);
+
+  /* "bx/misc/_seekbzip2.pyx":64
+ *         # Break position into bit and byte offsets
+ *         ## sys.stderr.write( "arg pos: %d\n" % position )
+ *         n_byte = position / 8;             # <<<<<<<<<<<<<<
+ *         n_bit = position % 8;
+ *         ## sys.stderr.write( "byte pos: %d\n" % n_byte )
+ */
+  __pyx_v_n_byte = (__pyx_v_position / 8);
+
+  /* "bx/misc/_seekbzip2.pyx":65
+ *         ## sys.stderr.write( "arg pos: %d\n" % position )
+ *         n_byte = position / 8;
+ *         n_bit = position % 8;             # <<<<<<<<<<<<<<
+ *         ## sys.stderr.write( "byte pos: %d\n" % n_byte )
+ *         ## sys.stderr.write( "bit pos: %d\n" % n_bit )
+ */
+  __pyx_v_n_bit = (__pyx_v_position % 8);
+
+  /* "bx/misc/_seekbzip2.pyx":70
+ *         ## sys.stderr.flush()
+ *         # Seek the underlying file descriptor
+ *         if ( lseek( self.file_fd, n_byte, 0 ) != n_byte ):             # <<<<<<<<<<<<<<
+ *             raise Exception( "lseek of underlying file failed" )
+ *         # Init the buffer at the right bit position
+ */
+  __pyx_t_1 = (lseek(__pyx_v_self->file_fd, __pyx_v_n_byte, 0) != __pyx_v_n_byte);
+  if (__pyx_t_1) {
+
+    /* "bx/misc/_seekbzip2.pyx":71
+ *         # Seek the underlying file descriptor
+ *         if ( lseek( self.file_fd, n_byte, 0 ) != n_byte ):
+ *             raise Exception( "lseek of underlying file failed" )             # <<<<<<<<<<<<<<
+ *         # Init the buffer at the right bit position
+ *         self.bd.inbufBitCount = self.bd.inbufPos = self.bd.inbufCount = 0
+ */
+    __pyx_t_2 = PyObject_Call(__pyx_builtin_Exception, ((PyObject *)__pyx_k_tuple_2), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 71; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __Pyx_Raise(__pyx_t_2, 0, 0, 0);
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 71; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  /* "bx/misc/_seekbzip2.pyx":73
+ *             raise Exception( "lseek of underlying file failed" )
+ *         # Init the buffer at the right bit position
+ *         self.bd.inbufBitCount = self.bd.inbufPos = self.bd.inbufCount = 0             # <<<<<<<<<<<<<<
+ *         get_bits( self.bd, n_bit )
+ *         # This ensures that the next read call will return 0, causing the
+ */
+  __pyx_v_self->bd->inbufBitCount = 0;
+  __pyx_v_self->bd->inbufPos = 0;
+  __pyx_v_self->bd->inbufCount = 0;
+
+  /* "bx/misc/_seekbzip2.pyx":74
+ *         # Init the buffer at the right bit position
+ *         self.bd.inbufBitCount = self.bd.inbufPos = self.bd.inbufCount = 0
+ *         get_bits( self.bd, n_bit )             # <<<<<<<<<<<<<<
+ *         # This ensures that the next read call will return 0, causing the
+ *         # buffer to be re-initialized
+ */
+  get_bits(__pyx_v_self->bd, __pyx_v_n_bit);
+
+  /* "bx/misc/_seekbzip2.pyx":77
+ *         # This ensures that the next read call will return 0, causing the
+ *         # buffer to be re-initialized
+ *         self.bd.writeCount = -1             # <<<<<<<<<<<<<<
+ *         # Reset EOF tracking
+ *         self.at_eof = 0
+ */
+  __pyx_v_self->bd->writeCount = -1;
+
+  /* "bx/misc/_seekbzip2.pyx":79
+ *         self.bd.writeCount = -1
+ *         # Reset EOF tracking
+ *         self.at_eof = 0             # <<<<<<<<<<<<<<
+ * 
+ *     def readline( self, int amount ):
+ */
+  __pyx_v_self->at_eof = 0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_AddTraceback("bx.misc._seekbzip2.SeekBzip2.seek", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_4misc_10_seekbzip2_9SeekBzip2_7readline(PyObject *__pyx_v_self, PyObject *__pyx_arg_amount); /*proto*/
+static PyObject *__pyx_pw_2bx_4misc_10_seekbzip2_9SeekBzip2_7readline(PyObject *__pyx_v_self, PyObject *__pyx_arg_amount) {
+  int __pyx_v_amount;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("readline (wrapper)", 0);
+  assert(__pyx_arg_amount); {
+    __pyx_v_amount = __Pyx_PyInt_AsInt(__pyx_arg_amount); if (unlikely((__pyx_v_amount == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 81; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.misc._seekbzip2.SeekBzip2.readline", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_4misc_10_seekbzip2_9SeekBzip2_6readline(((struct __pyx_obj_2bx_4misc_10_seekbzip2_SeekBzip2 *)__pyx_v_self), ((int)__pyx_v_amount));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/misc/_seekbzip2.pyx":81
+ *         self.at_eof = 0
+ * 
+ *     def readline( self, int amount ):             # <<<<<<<<<<<<<<
+ *         cdef object rval
+ *         cdef char * p_rval
+ */
+
+static PyObject *__pyx_pf_2bx_4misc_10_seekbzip2_9SeekBzip2_6readline(struct __pyx_obj_2bx_4misc_10_seekbzip2_SeekBzip2 *__pyx_v_self, int __pyx_v_amount) {
+  PyObject *__pyx_v_rval = 0;
+  char *__pyx_v_p_rval;
+  int __pyx_v_gotcount;
+  CYTHON_UNUSED int __pyx_v_totalcount;
+  int __pyx_v_status;
+  int __pyx_v_spaceleft;
+  int __pyx_v_desired;
+  PyObject *__pyx_v_chunks = NULL;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_t_2;
+  int __pyx_t_3;
+  int __pyx_t_4;
+  int __pyx_t_5;
+  PyObject *__pyx_t_6 = NULL;
+  PyObject *__pyx_t_7 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("readline", 0);
+
+  /* "bx/misc/_seekbzip2.pyx":89
+ *         cdef int spaceleft
+ *         cdef int desired
+ *         gotcount = 0             # <<<<<<<<<<<<<<
+ *         totalcount = 0
+ *         # If already at EOF return None
+ */
+  __pyx_v_gotcount = 0;
+
+  /* "bx/misc/_seekbzip2.pyx":90
+ *         cdef int desired
+ *         gotcount = 0
+ *         totalcount = 0             # <<<<<<<<<<<<<<
+ *         # If already at EOF return None
+ *         if self.at_eof:
+ */
+  __pyx_v_totalcount = 0;
+
+  /* "bx/misc/_seekbzip2.pyx":92
+ *         totalcount = 0
+ *         # If already at EOF return None
+ *         if self.at_eof:             # <<<<<<<<<<<<<<
+ *             return None
+ *         chunks = []
+ */
+  if (__pyx_v_self->at_eof) {
+
+    /* "bx/misc/_seekbzip2.pyx":93
+ *         # If already at EOF return None
+ *         if self.at_eof:
+ *             return None             # <<<<<<<<<<<<<<
+ *         chunks = []
+ *         # We have great difficulty resizing buffers, so we'll just create
+ */
+    __Pyx_XDECREF(__pyx_r);
+    __Pyx_INCREF(Py_None);
+    __pyx_r = Py_None;
+    goto __pyx_L0;
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  /* "bx/misc/_seekbzip2.pyx":94
+ *         if self.at_eof:
+ *             return None
+ *         chunks = []             # <<<<<<<<<<<<<<
+ *         # We have great difficulty resizing buffers, so we'll just create
+ *         # one 8k string at a time
+ */
+  __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 94; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_v_chunks = ((PyObject*)__pyx_t_1);
+  __pyx_t_1 = 0;
+
+  /* "bx/misc/_seekbzip2.pyx":97
+ *         # We have great difficulty resizing buffers, so we'll just create
+ *         # one 8k string at a time
+ *         rval = PyString_FromStringAndSize( NULL, 8192 )             # <<<<<<<<<<<<<<
+ *         p_rval = PyString_AsString( rval )
+ *         spaceleft = 8192
+ */
+  __pyx_t_1 = PyString_FromStringAndSize(NULL, 8192); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 97; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_v_rval = __pyx_t_1;
+  __pyx_t_1 = 0;
+
+  /* "bx/misc/_seekbzip2.pyx":98
+ *         # one 8k string at a time
+ *         rval = PyString_FromStringAndSize( NULL, 8192 )
+ *         p_rval = PyString_AsString( rval )             # <<<<<<<<<<<<<<
+ *         spaceleft = 8192
+ *         while amount != 0:
+ */
+  __pyx_v_p_rval = PyString_AsString(__pyx_v_rval);
+
+  /* "bx/misc/_seekbzip2.pyx":99
+ *         rval = PyString_FromStringAndSize( NULL, 8192 )
+ *         p_rval = PyString_AsString( rval )
+ *         spaceleft = 8192             # <<<<<<<<<<<<<<
+ *         while amount != 0:
+ *             if amount > 0 and amount < spaceleft:
+ */
+  __pyx_v_spaceleft = 8192;
+
+  /* "bx/misc/_seekbzip2.pyx":100
+ *         p_rval = PyString_AsString( rval )
+ *         spaceleft = 8192
+ *         while amount != 0:             # <<<<<<<<<<<<<<
+ *             if amount > 0 and amount < spaceleft:
+ *                 desired = amount
+ */
+  while (1) {
+    __pyx_t_2 = (__pyx_v_amount != 0);
+    if (!__pyx_t_2) break;
+
+    /* "bx/misc/_seekbzip2.pyx":101
+ *         spaceleft = 8192
+ *         while amount != 0:
+ *             if amount > 0 and amount < spaceleft:             # <<<<<<<<<<<<<<
+ *                 desired = amount
+ *             else:
+ */
+    __pyx_t_2 = (__pyx_v_amount > 0);
+    if (__pyx_t_2) {
+      __pyx_t_3 = (__pyx_v_amount < __pyx_v_spaceleft);
+      __pyx_t_4 = __pyx_t_3;
+    } else {
+      __pyx_t_4 = __pyx_t_2;
+    }
+    if (__pyx_t_4) {
+
+      /* "bx/misc/_seekbzip2.pyx":102
+ *         while amount != 0:
+ *             if amount > 0 and amount < spaceleft:
+ *                 desired = amount             # <<<<<<<<<<<<<<
+ *             else:
+ *                 desired = spaceleft
+ */
+      __pyx_v_desired = __pyx_v_amount;
+      goto __pyx_L6;
+    }
+    /*else*/ {
+
+      /* "bx/misc/_seekbzip2.pyx":104
+ *                 desired = amount
+ *             else:
+ *                 desired = spaceleft             # <<<<<<<<<<<<<<
+ *             ## sys.stderr.write( "readline, amount: %d\n" % amount )
+ *             ## sys.stderr.write( "buffer: %r" % rval[:100] )
+ */
+      __pyx_v_desired = __pyx_v_spaceleft;
+    }
+    __pyx_L6:;
+
+    /* "bx/misc/_seekbzip2.pyx":110
+ *             ## sys.stderr.flush()
+ *             # ord( "\n" ) = 10
+ *             status = read_bunzip_to_char( self.bd, p_rval, desired, &gotcount, 10 );             # <<<<<<<<<<<<<<
+ *             ## sys.stderr.write( "readline, desired: %d, gotcount: %d\n" % ( desired, gotcount ) );
+ *             ## sys.stderr.write( "buffer: %r" % rval[:100] )
+ */
+    __pyx_v_status = read_bunzip_to_char(__pyx_v_self->bd, __pyx_v_p_rval, __pyx_v_desired, (&__pyx_v_gotcount), 10);
+
+    /* "bx/misc/_seekbzip2.pyx":133
+ *                 p_rval = PyString_AsString( rval )
+ *                 spaceleft = 8192
+ *             elif status == -8:             # <<<<<<<<<<<<<<
+ *                 ## sys.stderr.write( "readline, END_OF_BLOCK\n" ); sys.stderr.flush()
+ *                 # No more data in the decomp buffer (RETVAL_END_OF_BLOCK == -10)
+ */
+    switch (__pyx_v_status) {
+
+      /* "bx/misc/_seekbzip2.pyx":115
+ *             ## sys.stderr.write( "\n" )
+ *             ## sys.stderr.flush()
+ *             if status == -9:             # <<<<<<<<<<<<<<
+ *                 ## sys.stderr.write( "readline, STOP_CHAR\n" ); sys.stderr.flush()
+ *                 # Reached the stop character (RETVAL_STOPCHAR == -9), so
+ */
+      case -9:
+
+      /* "bx/misc/_seekbzip2.pyx":119
+ *                 # Reached the stop character (RETVAL_STOPCHAR == -9), so
+ *                 # we can stop
+ *                 chunks.append( rval[:8192-spaceleft+gotcount] )             # <<<<<<<<<<<<<<
+ *                 break
+ *             elif status == -10:
+ */
+      __pyx_t_1 = __Pyx_PySequence_GetSlice(__pyx_v_rval, 0, ((8192 - __pyx_v_spaceleft) + __pyx_v_gotcount)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_1);
+      __pyx_t_5 = PyList_Append(__pyx_v_chunks, __pyx_t_1); if (unlikely(__pyx_t_5 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+      /* "bx/misc/_seekbzip2.pyx":120
+ *                 # we can stop
+ *                 chunks.append( rval[:8192-spaceleft+gotcount] )
+ *                 break             # <<<<<<<<<<<<<<
+ *             elif status == -10:
+ *                 ## sys.stderr.write( "readline, BUFFER_FULL\n" ); sys.stderr.flush()
+ */
+      goto __pyx_L5_break;
+      break;
+
+      /* "bx/misc/_seekbzip2.pyx":121
+ *                 chunks.append( rval[:8192-spaceleft+gotcount] )
+ *                 break
+ *             elif status == -10:             # <<<<<<<<<<<<<<
+ *                 ## sys.stderr.write( "readline, BUFFER_FULL\n" ); sys.stderr.flush()
+ *                 # Filled the buffer (RETVAL_BUFFER_FULL == -10), so create
+ */
+      case -10:
+
+      /* "bx/misc/_seekbzip2.pyx":125
+ *                 # Filled the buffer (RETVAL_BUFFER_FULL == -10), so create
+ *                 # new buffer and keep going
+ *                 chunks.append( rval )             # <<<<<<<<<<<<<<
+ *                 amount = amount - gotcount
+ *                 if amount == 0:
+ */
+      __pyx_t_5 = PyList_Append(__pyx_v_chunks, __pyx_v_rval); if (unlikely(__pyx_t_5 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+      /* "bx/misc/_seekbzip2.pyx":126
+ *                 # new buffer and keep going
+ *                 chunks.append( rval )
+ *                 amount = amount - gotcount             # <<<<<<<<<<<<<<
+ *                 if amount == 0:
+ *                     # Got the desired amount
+ */
+      __pyx_v_amount = (__pyx_v_amount - __pyx_v_gotcount);
+
+      /* "bx/misc/_seekbzip2.pyx":127
+ *                 chunks.append( rval )
+ *                 amount = amount - gotcount
+ *                 if amount == 0:             # <<<<<<<<<<<<<<
+ *                     # Got the desired amount
+ *                     break
+ */
+      __pyx_t_4 = (__pyx_v_amount == 0);
+      if (__pyx_t_4) {
+
+        /* "bx/misc/_seekbzip2.pyx":129
+ *                 if amount == 0:
+ *                     # Got the desired amount
+ *                     break             # <<<<<<<<<<<<<<
+ *                 rval = PyString_FromStringAndSize( NULL, 8192 )
+ *                 p_rval = PyString_AsString( rval )
+ */
+        goto __pyx_L5_break;
+        goto __pyx_L7;
+      }
+      __pyx_L7:;
+
+      /* "bx/misc/_seekbzip2.pyx":130
+ *                     # Got the desired amount
+ *                     break
+ *                 rval = PyString_FromStringAndSize( NULL, 8192 )             # <<<<<<<<<<<<<<
+ *                 p_rval = PyString_AsString( rval )
+ *                 spaceleft = 8192
+ */
+      __pyx_t_1 = PyString_FromStringAndSize(NULL, 8192); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_1);
+      __Pyx_DECREF(__pyx_v_rval);
+      __pyx_v_rval = __pyx_t_1;
+      __pyx_t_1 = 0;
+
+      /* "bx/misc/_seekbzip2.pyx":131
+ *                     break
+ *                 rval = PyString_FromStringAndSize( NULL, 8192 )
+ *                 p_rval = PyString_AsString( rval )             # <<<<<<<<<<<<<<
+ *                 spaceleft = 8192
+ *             elif status == -8:
+ */
+      __pyx_v_p_rval = PyString_AsString(__pyx_v_rval);
+
+      /* "bx/misc/_seekbzip2.pyx":132
+ *                 rval = PyString_FromStringAndSize( NULL, 8192 )
+ *                 p_rval = PyString_AsString( rval )
+ *                 spaceleft = 8192             # <<<<<<<<<<<<<<
+ *             elif status == -8:
+ *                 ## sys.stderr.write( "readline, END_OF_BLOCK\n" ); sys.stderr.flush()
+ */
+      __pyx_v_spaceleft = 8192;
+      break;
+
+      /* "bx/misc/_seekbzip2.pyx":133
+ *                 p_rval = PyString_AsString( rval )
+ *                 spaceleft = 8192
+ *             elif status == -8:             # <<<<<<<<<<<<<<
+ *                 ## sys.stderr.write( "readline, END_OF_BLOCK\n" ); sys.stderr.flush()
+ *                 # No more data in the decomp buffer (RETVAL_END_OF_BLOCK == -10)
+ */
+      case -8:
+
+      /* "bx/misc/_seekbzip2.pyx":136
+ *                 ## sys.stderr.write( "readline, END_OF_BLOCK\n" ); sys.stderr.flush()
+ *                 # No more data in the decomp buffer (RETVAL_END_OF_BLOCK == -10)
+ *                 if gotcount and p_rval[ gotcount - 1 ] == 10:             # <<<<<<<<<<<<<<
+ *                     chunks.append( rval[:8192-spaceleft+gotcount] )
+ *                     break
+ */
+      if (__pyx_v_gotcount) {
+        __pyx_t_4 = ((__pyx_v_p_rval[(__pyx_v_gotcount - 1)]) == 10);
+        __pyx_t_2 = __pyx_t_4;
+      } else {
+        __pyx_t_2 = __pyx_v_gotcount;
+      }
+      if (__pyx_t_2) {
+
+        /* "bx/misc/_seekbzip2.pyx":137
+ *                 # No more data in the decomp buffer (RETVAL_END_OF_BLOCK == -10)
+ *                 if gotcount and p_rval[ gotcount - 1 ] == 10:
+ *                     chunks.append( rval[:8192-spaceleft+gotcount] )             # <<<<<<<<<<<<<<
+ *                     break
+ *                 # Update buffer info
+ */
+        __pyx_t_1 = __Pyx_PySequence_GetSlice(__pyx_v_rval, 0, ((8192 - __pyx_v_spaceleft) + __pyx_v_gotcount)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 137; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_1);
+        __pyx_t_5 = PyList_Append(__pyx_v_chunks, __pyx_t_1); if (unlikely(__pyx_t_5 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 137; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+        /* "bx/misc/_seekbzip2.pyx":138
+ *                 if gotcount and p_rval[ gotcount - 1 ] == 10:
+ *                     chunks.append( rval[:8192-spaceleft+gotcount] )
+ *                     break             # <<<<<<<<<<<<<<
+ *                 # Update buffer info
+ *                 p_rval = p_rval + gotcount
+ */
+        goto __pyx_L5_break;
+        goto __pyx_L8;
+      }
+      __pyx_L8:;
+
+      /* "bx/misc/_seekbzip2.pyx":140
+ *                     break
+ *                 # Update buffer info
+ *                 p_rval = p_rval + gotcount             # <<<<<<<<<<<<<<
+ *                 spaceleft = spaceleft - gotcount
+ *                 amount = amount - gotcount
+ */
+      __pyx_v_p_rval = (__pyx_v_p_rval + __pyx_v_gotcount);
+
+      /* "bx/misc/_seekbzip2.pyx":141
+ *                 # Update buffer info
+ *                 p_rval = p_rval + gotcount
+ *                 spaceleft = spaceleft - gotcount             # <<<<<<<<<<<<<<
+ *                 amount = amount - gotcount
+ *                 # Get the next block
+ */
+      __pyx_v_spaceleft = (__pyx_v_spaceleft - __pyx_v_gotcount);
+
+      /* "bx/misc/_seekbzip2.pyx":142
+ *                 p_rval = p_rval + gotcount
+ *                 spaceleft = spaceleft - gotcount
+ *                 amount = amount - gotcount             # <<<<<<<<<<<<<<
+ *                 # Get the next block
+ *                 status = get_next_block( self.bd )
+ */
+      __pyx_v_amount = (__pyx_v_amount - __pyx_v_gotcount);
+
+      /* "bx/misc/_seekbzip2.pyx":144
+ *                 amount = amount - gotcount
+ *                 # Get the next block
+ *                 status = get_next_block( self.bd )             # <<<<<<<<<<<<<<
+ *                 if status == -1:
+ *                     # Block is end of stream block (RETVAL_LAST_BLOCK == -1)
+ */
+      __pyx_v_status = get_next_block(__pyx_v_self->bd);
+
+      /* "bx/misc/_seekbzip2.pyx":145
+ *                 # Get the next block
+ *                 status = get_next_block( self.bd )
+ *                 if status == -1:             # <<<<<<<<<<<<<<
+ *                     # Block is end of stream block (RETVAL_LAST_BLOCK == -1)
+ *                     self.at_eof = 1
+ */
+      __pyx_t_2 = (__pyx_v_status == -1);
+      if (__pyx_t_2) {
+
+        /* "bx/misc/_seekbzip2.pyx":147
+ *                 if status == -1:
+ *                     # Block is end of stream block (RETVAL_LAST_BLOCK == -1)
+ *                     self.at_eof = 1             # <<<<<<<<<<<<<<
+ *                     chunks.append( rval[:gotcount] )
+ *                     break
+ */
+        __pyx_v_self->at_eof = 1;
+
+        /* "bx/misc/_seekbzip2.pyx":148
+ *                     # Block is end of stream block (RETVAL_LAST_BLOCK == -1)
+ *                     self.at_eof = 1
+ *                     chunks.append( rval[:gotcount] )             # <<<<<<<<<<<<<<
+ *                     break
+ *                 self.bd.writeCRC = 0xffffffff
+ */
+        __pyx_t_1 = __Pyx_PySequence_GetSlice(__pyx_v_rval, 0, __pyx_v_gotcount); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 148; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_1);
+        __pyx_t_5 = PyList_Append(__pyx_v_chunks, __pyx_t_1); if (unlikely(__pyx_t_5 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 148; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+        /* "bx/misc/_seekbzip2.pyx":149
+ *                     self.at_eof = 1
+ *                     chunks.append( rval[:gotcount] )
+ *                     break             # <<<<<<<<<<<<<<
+ *                 self.bd.writeCRC = 0xffffffff
+ *                 self.bd.writeCopies = 0
+ */
+        goto __pyx_L5_break;
+        goto __pyx_L9;
+      }
+      __pyx_L9:;
+
+      /* "bx/misc/_seekbzip2.pyx":150
+ *                     chunks.append( rval[:gotcount] )
+ *                     break
+ *                 self.bd.writeCRC = 0xffffffff             # <<<<<<<<<<<<<<
+ *                 self.bd.writeCopies = 0
+ *             else:
+ */
+      __pyx_v_self->bd->writeCRC = 0xffffffff;
+
+      /* "bx/misc/_seekbzip2.pyx":151
+ *                     break
+ *                 self.bd.writeCRC = 0xffffffff
+ *                 self.bd.writeCopies = 0             # <<<<<<<<<<<<<<
+ *             else:
+ *                 # Some other status
+ */
+      __pyx_v_self->bd->writeCopies = 0;
+      break;
+      default:
+
+      /* "bx/misc/_seekbzip2.pyx":154
+ *             else:
+ *                 # Some other status
+ *                 raise Exception( "read_bunzip error %d" % status )             # <<<<<<<<<<<<<<
+ *         # Return whatever we read
+ *         return "".join( chunks )
+ */
+      __pyx_t_1 = PyInt_FromLong(__pyx_v_status); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 154; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_1);
+      __pyx_t_6 = PyNumber_Remainder(((PyObject *)__pyx_kp_s_3), __pyx_t_1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 154; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(((PyObject *)__pyx_t_6));
+      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+      __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 154; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_1);
+      PyTuple_SET_ITEM(__pyx_t_1, 0, ((PyObject *)__pyx_t_6));
+      __Pyx_GIVEREF(((PyObject *)__pyx_t_6));
+      __pyx_t_6 = 0;
+      __pyx_t_6 = PyObject_Call(__pyx_builtin_Exception, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 154; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_6);
+      __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+      __Pyx_Raise(__pyx_t_6, 0, 0, 0);
+      __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 154; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      break;
+    }
+  }
+  __pyx_L5_break:;
+
+  /* "bx/misc/_seekbzip2.pyx":156
+ *                 raise Exception( "read_bunzip error %d" % status )
+ *         # Return whatever we read
+ *         return "".join( chunks )             # <<<<<<<<<<<<<<
+ * 
+ *     def read( self, int amount ):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_6 = PyObject_GetAttr(((PyObject *)__pyx_kp_s_4), __pyx_n_s__join); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_6);
+  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_INCREF(((PyObject *)__pyx_v_chunks));
+  PyTuple_SET_ITEM(__pyx_t_1, 0, ((PyObject *)__pyx_v_chunks));
+  __Pyx_GIVEREF(((PyObject *)__pyx_v_chunks));
+  __pyx_t_7 = PyObject_Call(__pyx_t_6, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_7);
+  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+  __pyx_r = __pyx_t_7;
+  __pyx_t_7 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_6);
+  __Pyx_XDECREF(__pyx_t_7);
+  __Pyx_AddTraceback("bx.misc._seekbzip2.SeekBzip2.readline", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_rval);
+  __Pyx_XDECREF(__pyx_v_chunks);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_4misc_10_seekbzip2_9SeekBzip2_9read(PyObject *__pyx_v_self, PyObject *__pyx_arg_amount); /*proto*/
+static PyObject *__pyx_pw_2bx_4misc_10_seekbzip2_9SeekBzip2_9read(PyObject *__pyx_v_self, PyObject *__pyx_arg_amount) {
+  int __pyx_v_amount;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("read (wrapper)", 0);
+  assert(__pyx_arg_amount); {
+    __pyx_v_amount = __Pyx_PyInt_AsInt(__pyx_arg_amount); if (unlikely((__pyx_v_amount == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 158; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.misc._seekbzip2.SeekBzip2.read", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_4misc_10_seekbzip2_9SeekBzip2_8read(((struct __pyx_obj_2bx_4misc_10_seekbzip2_SeekBzip2 *)__pyx_v_self), ((int)__pyx_v_amount));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/misc/_seekbzip2.pyx":158
+ *         return "".join( chunks )
+ * 
+ *     def read( self, int amount ):             # <<<<<<<<<<<<<<
+ *         cdef object rval
+ *         cdef char * p_rval
+ */
+
+static PyObject *__pyx_pf_2bx_4misc_10_seekbzip2_9SeekBzip2_8read(struct __pyx_obj_2bx_4misc_10_seekbzip2_SeekBzip2 *__pyx_v_self, int __pyx_v_amount) {
+  PyObject *__pyx_v_rval = 0;
+  char *__pyx_v_p_rval;
+  int __pyx_v_gotcount;
+  int __pyx_v_totalcount;
+  int __pyx_v_status;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_t_2;
+  PyObject *__pyx_t_3 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("read", 0);
+
+  /* "bx/misc/_seekbzip2.pyx":164
+ *         cdef int totalcount
+ *         cdef int status
+ *         totalcount = 0             # <<<<<<<<<<<<<<
+ *         # If already at EOF return None
+ *         if self.at_eof:
+ */
+  __pyx_v_totalcount = 0;
+
+  /* "bx/misc/_seekbzip2.pyx":166
+ *         totalcount = 0
+ *         # If already at EOF return None
+ *         if self.at_eof:             # <<<<<<<<<<<<<<
+ *             return None
+ *         # Create a new python string large enough to hold the result
+ */
+  if (__pyx_v_self->at_eof) {
+
+    /* "bx/misc/_seekbzip2.pyx":167
+ *         # If already at EOF return None
+ *         if self.at_eof:
+ *             return None             # <<<<<<<<<<<<<<
+ *         # Create a new python string large enough to hold the result
+ *         rval = PyString_FromStringAndSize( NULL, amount )
+ */
+    __Pyx_XDECREF(__pyx_r);
+    __Pyx_INCREF(Py_None);
+    __pyx_r = Py_None;
+    goto __pyx_L0;
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  /* "bx/misc/_seekbzip2.pyx":169
+ *             return None
+ *         # Create a new python string large enough to hold the result
+ *         rval = PyString_FromStringAndSize( NULL, amount )             # <<<<<<<<<<<<<<
+ *         p_rval = PyString_AsString( rval )
+ *         # Read into it
+ */
+  __pyx_t_1 = PyString_FromStringAndSize(NULL, __pyx_v_amount); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_v_rval = __pyx_t_1;
+  __pyx_t_1 = 0;
+
+  /* "bx/misc/_seekbzip2.pyx":170
+ *         # Create a new python string large enough to hold the result
+ *         rval = PyString_FromStringAndSize( NULL, amount )
+ *         p_rval = PyString_AsString( rval )             # <<<<<<<<<<<<<<
+ *         # Read into it
+ *         ## sys.stderr.write( "read called, bd.current: %x\n" % self.bd.writeCurrent ); sys.stderr.flush()
+ */
+  __pyx_v_p_rval = PyString_AsString(__pyx_v_rval);
+
+  /* "bx/misc/_seekbzip2.pyx":173
+ *         # Read into it
+ *         ## sys.stderr.write( "read called, bd.current: %x\n" % self.bd.writeCurrent ); sys.stderr.flush()
+ *         while amount > 0:             # <<<<<<<<<<<<<<
+ *             gotcount = read_bunzip( self.bd, p_rval, amount );
+ *             if gotcount < 0:
+ */
+  while (1) {
+    __pyx_t_2 = (__pyx_v_amount > 0);
+    if (!__pyx_t_2) break;
+
+    /* "bx/misc/_seekbzip2.pyx":174
+ *         ## sys.stderr.write( "read called, bd.current: %x\n" % self.bd.writeCurrent ); sys.stderr.flush()
+ *         while amount > 0:
+ *             gotcount = read_bunzip( self.bd, p_rval, amount );             # <<<<<<<<<<<<<<
+ *             if gotcount < 0:
+ *                 raise Exception( "read_bunzip error %d" % gotcount )
+ */
+    __pyx_v_gotcount = read_bunzip(__pyx_v_self->bd, __pyx_v_p_rval, __pyx_v_amount);
+
+    /* "bx/misc/_seekbzip2.pyx":175
+ *         while amount > 0:
+ *             gotcount = read_bunzip( self.bd, p_rval, amount );
+ *             if gotcount < 0:             # <<<<<<<<<<<<<<
+ *                 raise Exception( "read_bunzip error %d" % gotcount )
+ *             elif gotcount == 0:
+ */
+    __pyx_t_2 = (__pyx_v_gotcount < 0);
+    if (__pyx_t_2) {
+
+      /* "bx/misc/_seekbzip2.pyx":176
+ *             gotcount = read_bunzip( self.bd, p_rval, amount );
+ *             if gotcount < 0:
+ *                 raise Exception( "read_bunzip error %d" % gotcount )             # <<<<<<<<<<<<<<
+ *             elif gotcount == 0:
+ *                 status = get_next_block( self.bd )
+ */
+      __pyx_t_1 = PyInt_FromLong(__pyx_v_gotcount); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_1);
+      __pyx_t_3 = PyNumber_Remainder(((PyObject *)__pyx_kp_s_3), __pyx_t_1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(((PyObject *)__pyx_t_3));
+      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+      __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_1);
+      PyTuple_SET_ITEM(__pyx_t_1, 0, ((PyObject *)__pyx_t_3));
+      __Pyx_GIVEREF(((PyObject *)__pyx_t_3));
+      __pyx_t_3 = 0;
+      __pyx_t_3 = PyObject_Call(__pyx_builtin_Exception, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+      __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      goto __pyx_L6;
+    }
+
+    /* "bx/misc/_seekbzip2.pyx":177
+ *             if gotcount < 0:
+ *                 raise Exception( "read_bunzip error %d" % gotcount )
+ *             elif gotcount == 0:             # <<<<<<<<<<<<<<
+ *                 status = get_next_block( self.bd )
+ *                 if status == -1:
+ */
+    __pyx_t_2 = (__pyx_v_gotcount == 0);
+    if (__pyx_t_2) {
+
+      /* "bx/misc/_seekbzip2.pyx":178
+ *                 raise Exception( "read_bunzip error %d" % gotcount )
+ *             elif gotcount == 0:
+ *                 status = get_next_block( self.bd )             # <<<<<<<<<<<<<<
+ *                 if status == -1:
+ *                     self.at_eof = 1
+ */
+      __pyx_v_status = get_next_block(__pyx_v_self->bd);
+
+      /* "bx/misc/_seekbzip2.pyx":179
+ *             elif gotcount == 0:
+ *                 status = get_next_block( self.bd )
+ *                 if status == -1:             # <<<<<<<<<<<<<<
+ *                     self.at_eof = 1
+ *                     break
+ */
+      __pyx_t_2 = (__pyx_v_status == -1);
+      if (__pyx_t_2) {
+
+        /* "bx/misc/_seekbzip2.pyx":180
+ *                 status = get_next_block( self.bd )
+ *                 if status == -1:
+ *                     self.at_eof = 1             # <<<<<<<<<<<<<<
+ *                     break
+ *                 self.bd.writeCRC = 0xffffffff
+ */
+        __pyx_v_self->at_eof = 1;
+
+        /* "bx/misc/_seekbzip2.pyx":181
+ *                 if status == -1:
+ *                     self.at_eof = 1
+ *                     break             # <<<<<<<<<<<<<<
+ *                 self.bd.writeCRC = 0xffffffff
+ *                 self.bd.writeCopies = 0
+ */
+        goto __pyx_L5_break;
+        goto __pyx_L7;
+      }
+      __pyx_L7:;
+
+      /* "bx/misc/_seekbzip2.pyx":182
+ *                     self.at_eof = 1
+ *                     break
+ *                 self.bd.writeCRC = 0xffffffff             # <<<<<<<<<<<<<<
+ *                 self.bd.writeCopies = 0
+ *             else:
+ */
+      __pyx_v_self->bd->writeCRC = 0xffffffff;
+
+      /* "bx/misc/_seekbzip2.pyx":183
+ *                     break
+ *                 self.bd.writeCRC = 0xffffffff
+ *                 self.bd.writeCopies = 0             # <<<<<<<<<<<<<<
+ *             else:
+ *                 totalcount = totalcount + gotcount
+ */
+      __pyx_v_self->bd->writeCopies = 0;
+      goto __pyx_L6;
+    }
+    /*else*/ {
+
+      /* "bx/misc/_seekbzip2.pyx":185
+ *                 self.bd.writeCopies = 0
+ *             else:
+ *                 totalcount = totalcount + gotcount             # <<<<<<<<<<<<<<
+ *                 amount = amount - gotcount
+ *                 p_rval = p_rval + gotcount
+ */
+      __pyx_v_totalcount = (__pyx_v_totalcount + __pyx_v_gotcount);
+
+      /* "bx/misc/_seekbzip2.pyx":186
+ *             else:
+ *                 totalcount = totalcount + gotcount
+ *                 amount = amount - gotcount             # <<<<<<<<<<<<<<
+ *                 p_rval = p_rval + gotcount
+ *         # Return whatever we read
+ */
+      __pyx_v_amount = (__pyx_v_amount - __pyx_v_gotcount);
+
+      /* "bx/misc/_seekbzip2.pyx":187
+ *                 totalcount = totalcount + gotcount
+ *                 amount = amount - gotcount
+ *                 p_rval = p_rval + gotcount             # <<<<<<<<<<<<<<
+ *         # Return whatever we read
+ *         return rval[:totalcount]
+ */
+      __pyx_v_p_rval = (__pyx_v_p_rval + __pyx_v_gotcount);
+    }
+    __pyx_L6:;
+  }
+  __pyx_L5_break:;
+
+  /* "bx/misc/_seekbzip2.pyx":189
+ *                 p_rval = p_rval + gotcount
+ *         # Return whatever we read
+ *         return rval[:totalcount]             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_3 = __Pyx_PySequence_GetSlice(__pyx_v_rval, 0, __pyx_v_totalcount); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 189; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_r = __pyx_t_3;
+  __pyx_t_3 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_AddTraceback("bx.misc._seekbzip2.SeekBzip2.read", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_rval);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_tp_new_2bx_4misc_10_seekbzip2_SeekBzip2(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) {
+  PyObject *o = (*t->tp_alloc)(t, 0);
+  if (!o) return 0;
+  return o;
+}
+
+static void __pyx_tp_dealloc_2bx_4misc_10_seekbzip2_SeekBzip2(PyObject *o) {
+  (*Py_TYPE(o)->tp_free)(o);
+}
+
+static PyMethodDef __pyx_methods_2bx_4misc_10_seekbzip2_SeekBzip2[] = {
+  {__Pyx_NAMESTR("close"), (PyCFunction)__pyx_pw_2bx_4misc_10_seekbzip2_9SeekBzip2_3close, METH_NOARGS, __Pyx_DOCSTR(0)},
+  {__Pyx_NAMESTR("seek"), (PyCFunction)__pyx_pw_2bx_4misc_10_seekbzip2_9SeekBzip2_5seek, METH_O, __Pyx_DOCSTR(__pyx_doc_2bx_4misc_10_seekbzip2_9SeekBzip2_4seek)},
+  {__Pyx_NAMESTR("readline"), (PyCFunction)__pyx_pw_2bx_4misc_10_seekbzip2_9SeekBzip2_7readline, METH_O, __Pyx_DOCSTR(0)},
+  {__Pyx_NAMESTR("read"), (PyCFunction)__pyx_pw_2bx_4misc_10_seekbzip2_9SeekBzip2_9read, METH_O, __Pyx_DOCSTR(0)},
+  {0, 0, 0, 0}
+};
+
+static PyNumberMethods __pyx_tp_as_number_SeekBzip2 = {
+  0, /*nb_add*/
+  0, /*nb_subtract*/
+  0, /*nb_multiply*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_divide*/
+  #endif
+  0, /*nb_remainder*/
+  0, /*nb_divmod*/
+  0, /*nb_power*/
+  0, /*nb_negative*/
+  0, /*nb_positive*/
+  0, /*nb_absolute*/
+  0, /*nb_nonzero*/
+  0, /*nb_invert*/
+  0, /*nb_lshift*/
+  0, /*nb_rshift*/
+  0, /*nb_and*/
+  0, /*nb_xor*/
+  0, /*nb_or*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_coerce*/
+  #endif
+  0, /*nb_int*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_long*/
+  #else
+  0, /*reserved*/
+  #endif
+  0, /*nb_float*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_oct*/
+  #endif
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_hex*/
+  #endif
+  0, /*nb_inplace_add*/
+  0, /*nb_inplace_subtract*/
+  0, /*nb_inplace_multiply*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_inplace_divide*/
+  #endif
+  0, /*nb_inplace_remainder*/
+  0, /*nb_inplace_power*/
+  0, /*nb_inplace_lshift*/
+  0, /*nb_inplace_rshift*/
+  0, /*nb_inplace_and*/
+  0, /*nb_inplace_xor*/
+  0, /*nb_inplace_or*/
+  0, /*nb_floor_divide*/
+  0, /*nb_true_divide*/
+  0, /*nb_inplace_floor_divide*/
+  0, /*nb_inplace_true_divide*/
+  #if PY_VERSION_HEX >= 0x02050000
+  0, /*nb_index*/
+  #endif
+};
+
+static PySequenceMethods __pyx_tp_as_sequence_SeekBzip2 = {
+  0, /*sq_length*/
+  0, /*sq_concat*/
+  0, /*sq_repeat*/
+  0, /*sq_item*/
+  0, /*sq_slice*/
+  0, /*sq_ass_item*/
+  0, /*sq_ass_slice*/
+  0, /*sq_contains*/
+  0, /*sq_inplace_concat*/
+  0, /*sq_inplace_repeat*/
+};
+
+static PyMappingMethods __pyx_tp_as_mapping_SeekBzip2 = {
+  0, /*mp_length*/
+  0, /*mp_subscript*/
+  0, /*mp_ass_subscript*/
+};
+
+static PyBufferProcs __pyx_tp_as_buffer_SeekBzip2 = {
+  #if PY_MAJOR_VERSION < 3
+  0, /*bf_getreadbuffer*/
+  #endif
+  #if PY_MAJOR_VERSION < 3
+  0, /*bf_getwritebuffer*/
+  #endif
+  #if PY_MAJOR_VERSION < 3
+  0, /*bf_getsegcount*/
+  #endif
+  #if PY_MAJOR_VERSION < 3
+  0, /*bf_getcharbuffer*/
+  #endif
+  #if PY_VERSION_HEX >= 0x02060000
+  0, /*bf_getbuffer*/
+  #endif
+  #if PY_VERSION_HEX >= 0x02060000
+  0, /*bf_releasebuffer*/
+  #endif
+};
+
+static PyTypeObject __pyx_type_2bx_4misc_10_seekbzip2_SeekBzip2 = {
+  PyVarObject_HEAD_INIT(0, 0)
+  __Pyx_NAMESTR("bx.misc._seekbzip2.SeekBzip2"), /*tp_name*/
+  sizeof(struct __pyx_obj_2bx_4misc_10_seekbzip2_SeekBzip2), /*tp_basicsize*/
+  0, /*tp_itemsize*/
+  __pyx_tp_dealloc_2bx_4misc_10_seekbzip2_SeekBzip2, /*tp_dealloc*/
+  0, /*tp_print*/
+  0, /*tp_getattr*/
+  0, /*tp_setattr*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*tp_compare*/
+  #else
+  0, /*reserved*/
+  #endif
+  0, /*tp_repr*/
+  &__pyx_tp_as_number_SeekBzip2, /*tp_as_number*/
+  &__pyx_tp_as_sequence_SeekBzip2, /*tp_as_sequence*/
+  &__pyx_tp_as_mapping_SeekBzip2, /*tp_as_mapping*/
+  0, /*tp_hash*/
+  0, /*tp_call*/
+  0, /*tp_str*/
+  0, /*tp_getattro*/
+  0, /*tp_setattro*/
+  &__pyx_tp_as_buffer_SeekBzip2, /*tp_as_buffer*/
+  Py_TPFLAGS_DEFAULT|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE, /*tp_flags*/
+  0, /*tp_doc*/
+  0, /*tp_traverse*/
+  0, /*tp_clear*/
+  0, /*tp_richcompare*/
+  0, /*tp_weaklistoffset*/
+  0, /*tp_iter*/
+  0, /*tp_iternext*/
+  __pyx_methods_2bx_4misc_10_seekbzip2_SeekBzip2, /*tp_methods*/
+  0, /*tp_members*/
+  0, /*tp_getset*/
+  0, /*tp_base*/
+  0, /*tp_dict*/
+  0, /*tp_descr_get*/
+  0, /*tp_descr_set*/
+  0, /*tp_dictoffset*/
+  __pyx_pw_2bx_4misc_10_seekbzip2_9SeekBzip2_1__init__, /*tp_init*/
+  0, /*tp_alloc*/
+  __pyx_tp_new_2bx_4misc_10_seekbzip2_SeekBzip2, /*tp_new*/
+  0, /*tp_free*/
+  0, /*tp_is_gc*/
+  0, /*tp_bases*/
+  0, /*tp_mro*/
+  0, /*tp_cache*/
+  0, /*tp_subclasses*/
+  0, /*tp_weaklist*/
+  0, /*tp_del*/
+  #if PY_VERSION_HEX >= 0x02060000
+  0, /*tp_version_tag*/
+  #endif
+};
+
+static PyMethodDef __pyx_methods[] = {
+  {0, 0, 0, 0}
+};
+
+#if PY_MAJOR_VERSION >= 3
+static struct PyModuleDef __pyx_moduledef = {
+  #if PY_VERSION_HEX < 0x03020000
+    { PyObject_HEAD_INIT(NULL) NULL, 0, NULL },
+  #else
+    PyModuleDef_HEAD_INIT,
+  #endif
+    __Pyx_NAMESTR("_seekbzip2"),
+    __Pyx_DOCSTR(__pyx_k_5), /* m_doc */
+    -1, /* m_size */
+    __pyx_methods /* m_methods */,
+    NULL, /* m_reload */
+    NULL, /* m_traverse */
+    NULL, /* m_clear */
+    NULL /* m_free */
+};
+#endif
+
+static __Pyx_StringTabEntry __pyx_string_tab[] = {
+  {&__pyx_kp_s_1, __pyx_k_1, sizeof(__pyx_k_1), 0, 0, 1, 0},
+  {&__pyx_kp_s_3, __pyx_k_3, sizeof(__pyx_k_3), 0, 0, 1, 0},
+  {&__pyx_kp_s_4, __pyx_k_4, sizeof(__pyx_k_4), 0, 0, 1, 0},
+  {&__pyx_n_s__Exception, __pyx_k__Exception, sizeof(__pyx_k__Exception), 0, 0, 1, 1},
+  {&__pyx_n_s__O_RDONLY, __pyx_k__O_RDONLY, sizeof(__pyx_k__O_RDONLY), 0, 0, 1, 1},
+  {&__pyx_n_s____main__, __pyx_k____main__, sizeof(__pyx_k____main__), 0, 0, 1, 1},
+  {&__pyx_n_s____test__, __pyx_k____test__, sizeof(__pyx_k____test__), 0, 0, 1, 1},
+  {&__pyx_n_s__close, __pyx_k__close, sizeof(__pyx_k__close), 0, 0, 1, 1},
+  {&__pyx_n_s__filename, __pyx_k__filename, sizeof(__pyx_k__filename), 0, 0, 1, 1},
+  {&__pyx_n_s__join, __pyx_k__join, sizeof(__pyx_k__join), 0, 0, 1, 1},
+  {&__pyx_n_s__open, __pyx_k__open, sizeof(__pyx_k__open), 0, 0, 1, 1},
+  {&__pyx_n_s__os, __pyx_k__os, sizeof(__pyx_k__os), 0, 0, 1, 1},
+  {&__pyx_n_s__sys, __pyx_k__sys, sizeof(__pyx_k__sys), 0, 0, 1, 1},
+  {0, 0, 0, 0, 0, 0, 0}
+};
+static int __Pyx_InitCachedBuiltins(void) {
+  __pyx_builtin_Exception = __Pyx_GetName(__pyx_b, __pyx_n_s__Exception); if (!__pyx_builtin_Exception) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 71; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  return 0;
+  __pyx_L1_error:;
+  return -1;
+}
+
+static int __Pyx_InitCachedConstants(void) {
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0);
+
+  /* "bx/misc/_seekbzip2.pyx":71
+ *         # Seek the underlying file descriptor
+ *         if ( lseek( self.file_fd, n_byte, 0 ) != n_byte ):
+ *             raise Exception( "lseek of underlying file failed" )             # <<<<<<<<<<<<<<
+ *         # Init the buffer at the right bit position
+ *         self.bd.inbufBitCount = self.bd.inbufPos = self.bd.inbufCount = 0
+ */
+  __pyx_k_tuple_2 = PyTuple_Pack(1, ((PyObject *)__pyx_kp_s_1)); if (unlikely(!__pyx_k_tuple_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 71; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_k_tuple_2);
+  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_2));
+  __Pyx_RefNannyFinishContext();
+  return 0;
+  __pyx_L1_error:;
+  __Pyx_RefNannyFinishContext();
+  return -1;
+}
+
+static int __Pyx_InitGlobals(void) {
+  if (__Pyx_InitStrings(__pyx_string_tab) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  return 0;
+  __pyx_L1_error:;
+  return -1;
+}
+
+#if PY_MAJOR_VERSION < 3
+PyMODINIT_FUNC init_seekbzip2(void); /*proto*/
+PyMODINIT_FUNC init_seekbzip2(void)
+#else
+PyMODINIT_FUNC PyInit__seekbzip2(void); /*proto*/
+PyMODINIT_FUNC PyInit__seekbzip2(void)
+#endif
+{
+  PyObject *__pyx_t_1 = NULL;
+  __Pyx_RefNannyDeclarations
+  #if CYTHON_REFNANNY
+  __Pyx_RefNanny = __Pyx_RefNannyImportAPI("refnanny");
+  if (!__Pyx_RefNanny) {
+      PyErr_Clear();
+      __Pyx_RefNanny = __Pyx_RefNannyImportAPI("Cython.Runtime.refnanny");
+      if (!__Pyx_RefNanny)
+          Py_FatalError("failed to import 'refnanny' module");
+  }
+  #endif
+  __Pyx_RefNannySetupContext("PyMODINIT_FUNC PyInit__seekbzip2(void)", 0);
+  if ( __Pyx_check_binary_version() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_bytes)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #ifdef __Pyx_CyFunction_USED
+  if (__Pyx_CyFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #endif
+  #ifdef __Pyx_FusedFunction_USED
+  if (__pyx_FusedFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #endif
+  #ifdef __Pyx_Generator_USED
+  if (__pyx_Generator_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #endif
+  /*--- Library function declarations ---*/
+  /*--- Threads initialization code ---*/
+  #if defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS
+  #ifdef WITH_THREAD /* Python build with threading support? */
+  PyEval_InitThreads();
+  #endif
+  #endif
+  /*--- Module creation code ---*/
+  #if PY_MAJOR_VERSION < 3
+  __pyx_m = Py_InitModule4(__Pyx_NAMESTR("_seekbzip2"), __pyx_methods, __Pyx_DOCSTR(__pyx_k_5), 0, PYTHON_API_VERSION); Py_XINCREF(__pyx_m);
+  #else
+  __pyx_m = PyModule_Create(&__pyx_moduledef);
+  #endif
+  if (unlikely(!__pyx_m)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #if PY_MAJOR_VERSION >= 3
+  {
+    PyObject *modules = PyImport_GetModuleDict(); if (unlikely(!modules)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (!PyDict_GetItemString(modules, "bx.misc._seekbzip2")) {
+      if (unlikely(PyDict_SetItemString(modules, "bx.misc._seekbzip2", __pyx_m) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+  }
+  #endif
+  __pyx_b = PyImport_AddModule(__Pyx_NAMESTR(__Pyx_BUILTIN_MODULE_NAME)); if (unlikely(!__pyx_b)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #if CYTHON_COMPILING_IN_PYPY
+  Py_INCREF(__pyx_b);
+  #endif
+  if (__Pyx_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  /*--- Initialize various global constants etc. ---*/
+  if (unlikely(__Pyx_InitGlobals() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (__pyx_module_is_main_bx__misc___seekbzip2) {
+    if (__Pyx_SetAttrString(__pyx_m, "__name__", __pyx_n_s____main__) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  }
+  /*--- Builtin init code ---*/
+  if (unlikely(__Pyx_InitCachedBuiltins() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  /*--- Constants init code ---*/
+  if (unlikely(__Pyx_InitCachedConstants() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  /*--- Global init code ---*/
+  /*--- Variable export code ---*/
+  /*--- Function export code ---*/
+  /*--- Type init code ---*/
+  if (PyType_Ready(&__pyx_type_2bx_4misc_10_seekbzip2_SeekBzip2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 38; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (__Pyx_SetAttrString(__pyx_m, "SeekBzip2", (PyObject *)&__pyx_type_2bx_4misc_10_seekbzip2_SeekBzip2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 38; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_2bx_4misc_10_seekbzip2_SeekBzip2 = &__pyx_type_2bx_4misc_10_seekbzip2_SeekBzip2;
+  /*--- Type import code ---*/
+  /*--- Variable import code ---*/
+  /*--- Function import code ---*/
+  /*--- Execution code ---*/
+
+  /* "bx/misc/_seekbzip2.pyx":35
+ *     void free( void *ptr )
+ * 
+ * import sys             # <<<<<<<<<<<<<<
+ * import os
+ * 
+ */
+  __pyx_t_1 = __Pyx_Import(((PyObject *)__pyx_n_s__sys), 0, -1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 35; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s__sys, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 35; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "bx/misc/_seekbzip2.pyx":36
+ * 
+ * import sys
+ * import os             # <<<<<<<<<<<<<<
+ * 
+ * cdef class SeekBzip2:
+ */
+  __pyx_t_1 = __Pyx_Import(((PyObject *)__pyx_n_s__os), 0, -1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 36; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s__os, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 36; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "bx/misc/_seekbzip2.pyx":1
+ * """             # <<<<<<<<<<<<<<
+ * Pyrex/C extension supporting `bx.misc.seekbzip2` (wrapping the low level
+ * functions in `micro-bunzip.c`).
+ */
+  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(((PyObject *)__pyx_t_1));
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s____test__, ((PyObject *)__pyx_t_1)) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  if (__pyx_m) {
+    __Pyx_AddTraceback("init bx.misc._seekbzip2", __pyx_clineno, __pyx_lineno, __pyx_filename);
+    Py_DECREF(__pyx_m); __pyx_m = 0;
+  } else if (!PyErr_Occurred()) {
+    PyErr_SetString(PyExc_ImportError, "init bx.misc._seekbzip2");
+  }
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  #if PY_MAJOR_VERSION < 3
+  return;
+  #else
+  return __pyx_m;
+  #endif
+}
+
+/* Runtime support code */
+#if CYTHON_REFNANNY
+static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) {
+    PyObject *m = NULL, *p = NULL;
+    void *r = NULL;
+    m = PyImport_ImportModule((char *)modname);
+    if (!m) goto end;
+    p = PyObject_GetAttrString(m, (char *)"RefNannyAPI");
+    if (!p) goto end;
+    r = PyLong_AsVoidPtr(p);
+end:
+    Py_XDECREF(p);
+    Py_XDECREF(m);
+    return (__Pyx_RefNannyAPIStruct *)r;
+}
+#endif /* CYTHON_REFNANNY */
+
+static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name) {
+    PyObject *result;
+    result = PyObject_GetAttr(dict, name);
+    if (!result) {
+        if (dict != __pyx_b) {
+            PyErr_Clear();
+            result = PyObject_GetAttr(__pyx_b, name);
+        }
+        if (!result) {
+            PyErr_SetObject(PyExc_NameError, name);
+        }
+    }
+    return result;
+}
+
+static void __Pyx_RaiseDoubleKeywordsError(
+    const char* func_name,
+    PyObject* kw_name)
+{
+    PyErr_Format(PyExc_TypeError,
+        #if PY_MAJOR_VERSION >= 3
+        "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
+        #else
+        "%s() got multiple values for keyword argument '%s'", func_name,
+        PyString_AsString(kw_name));
+        #endif
+}
+
+static int __Pyx_ParseOptionalKeywords(
+    PyObject *kwds,
+    PyObject **argnames[],
+    PyObject *kwds2,
+    PyObject *values[],
+    Py_ssize_t num_pos_args,
+    const char* function_name)
+{
+    PyObject *key = 0, *value = 0;
+    Py_ssize_t pos = 0;
+    PyObject*** name;
+    PyObject*** first_kw_arg = argnames + num_pos_args;
+    while (PyDict_Next(kwds, &pos, &key, &value)) {
+        name = first_kw_arg;
+        while (*name && (**name != key)) name++;
+        if (*name) {
+            values[name-argnames] = value;
+            continue;
+        }
+        name = first_kw_arg;
+        #if PY_MAJOR_VERSION < 3
+        if (likely(PyString_CheckExact(key)) || likely(PyString_Check(key))) {
+            while (*name) {
+                if ((CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**name) == PyString_GET_SIZE(key))
+                        && _PyString_Eq(**name, key)) {
+                    values[name-argnames] = value;
+                    break;
+                }
+                name++;
+            }
+            if (*name) continue;
+            else {
+                PyObject*** argname = argnames;
+                while (argname != first_kw_arg) {
+                    if ((**argname == key) || (
+                            (CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**argname) == PyString_GET_SIZE(key))
+                             && _PyString_Eq(**argname, key))) {
+                        goto arg_passed_twice;
+                    }
+                    argname++;
+                }
+            }
+        } else
+        #endif
+        if (likely(PyUnicode_Check(key))) {
+            while (*name) {
+                int cmp = (**name == key) ? 0 :
+                #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3
+                    (PyUnicode_GET_SIZE(**name) != PyUnicode_GET_SIZE(key)) ? 1 :
+                #endif
+                    PyUnicode_Compare(**name, key);
+                if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad;
+                if (cmp == 0) {
+                    values[name-argnames] = value;
+                    break;
+                }
+                name++;
+            }
+            if (*name) continue;
+            else {
+                PyObject*** argname = argnames;
+                while (argname != first_kw_arg) {
+                    int cmp = (**argname == key) ? 0 :
+                    #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3
+                        (PyUnicode_GET_SIZE(**argname) != PyUnicode_GET_SIZE(key)) ? 1 :
+                    #endif
+                        PyUnicode_Compare(**argname, key);
+                    if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad;
+                    if (cmp == 0) goto arg_passed_twice;
+                    argname++;
+                }
+            }
+        } else
+            goto invalid_keyword_type;
+        if (kwds2) {
+            if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
+        } else {
+            goto invalid_keyword;
+        }
+    }
+    return 0;
+arg_passed_twice:
+    __Pyx_RaiseDoubleKeywordsError(function_name, key);
+    goto bad;
+invalid_keyword_type:
+    PyErr_Format(PyExc_TypeError,
+        "%s() keywords must be strings", function_name);
+    goto bad;
+invalid_keyword:
+    PyErr_Format(PyExc_TypeError,
+    #if PY_MAJOR_VERSION < 3
+        "%s() got an unexpected keyword argument '%s'",
+        function_name, PyString_AsString(key));
+    #else
+        "%s() got an unexpected keyword argument '%U'",
+        function_name, key);
+    #endif
+bad:
+    return -1;
+}
+
+static void __Pyx_RaiseArgtupleInvalid(
+    const char* func_name,
+    int exact,
+    Py_ssize_t num_min,
+    Py_ssize_t num_max,
+    Py_ssize_t num_found)
+{
+    Py_ssize_t num_expected;
+    const char *more_or_less;
+    if (num_found < num_min) {
+        num_expected = num_min;
+        more_or_less = "at least";
+    } else {
+        num_expected = num_max;
+        more_or_less = "at most";
+    }
+    if (exact) {
+        more_or_less = "exactly";
+    }
+    PyErr_Format(PyExc_TypeError,
+                 "%s() takes %s %" CYTHON_FORMAT_SSIZE_T "d positional argument%s (%" CYTHON_FORMAT_SSIZE_T "d given)",
+                 func_name, more_or_less, num_expected,
+                 (num_expected == 1) ? "" : "s", num_found);
+}
+
+static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    PyObject *tmp_type, *tmp_value, *tmp_tb;
+    PyThreadState *tstate = PyThreadState_GET();
+    tmp_type = tstate->curexc_type;
+    tmp_value = tstate->curexc_value;
+    tmp_tb = tstate->curexc_traceback;
+    tstate->curexc_type = type;
+    tstate->curexc_value = value;
+    tstate->curexc_traceback = tb;
+    Py_XDECREF(tmp_type);
+    Py_XDECREF(tmp_value);
+    Py_XDECREF(tmp_tb);
+#else
+    PyErr_Restore(type, value, tb);
+#endif
+}
+static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    PyThreadState *tstate = PyThreadState_GET();
+    *type = tstate->curexc_type;
+    *value = tstate->curexc_value;
+    *tb = tstate->curexc_traceback;
+    tstate->curexc_type = 0;
+    tstate->curexc_value = 0;
+    tstate->curexc_traceback = 0;
+#else
+    PyErr_Fetch(type, value, tb);
+#endif
+}
+
+#if PY_MAJOR_VERSION < 3
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb,
+                        CYTHON_UNUSED PyObject *cause) {
+    Py_XINCREF(type);
+    if (!value || value == Py_None)
+        value = NULL;
+    else
+        Py_INCREF(value);
+    if (!tb || tb == Py_None)
+        tb = NULL;
+    else {
+        Py_INCREF(tb);
+        if (!PyTraceBack_Check(tb)) {
+            PyErr_SetString(PyExc_TypeError,
+                "raise: arg 3 must be a traceback or None");
+            goto raise_error;
+        }
+    }
+    #if PY_VERSION_HEX < 0x02050000
+    if (PyClass_Check(type)) {
+    #else
+    if (PyType_Check(type)) {
+    #endif
+#if CYTHON_COMPILING_IN_PYPY
+        if (!value) {
+            Py_INCREF(Py_None);
+            value = Py_None;
+        }
+#endif
+        PyErr_NormalizeException(&type, &value, &tb);
+    } else {
+        if (value) {
+            PyErr_SetString(PyExc_TypeError,
+                "instance exception may not have a separate value");
+            goto raise_error;
+        }
+        value = type;
+        #if PY_VERSION_HEX < 0x02050000
+            if (PyInstance_Check(type)) {
+                type = (PyObject*) ((PyInstanceObject*)type)->in_class;
+                Py_INCREF(type);
+            }
+            else {
+                type = 0;
+                PyErr_SetString(PyExc_TypeError,
+                    "raise: exception must be an old-style class or instance");
+                goto raise_error;
+            }
+        #else
+            type = (PyObject*) Py_TYPE(type);
+            Py_INCREF(type);
+            if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
+                PyErr_SetString(PyExc_TypeError,
+                    "raise: exception class must be a subclass of BaseException");
+                goto raise_error;
+            }
+        #endif
+    }
+    __Pyx_ErrRestore(type, value, tb);
+    return;
+raise_error:
+    Py_XDECREF(value);
+    Py_XDECREF(type);
+    Py_XDECREF(tb);
+    return;
+}
+#else /* Python 3+ */
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause) {
+    PyObject* owned_instance = NULL;
+    if (tb == Py_None) {
+        tb = 0;
+    } else if (tb && !PyTraceBack_Check(tb)) {
+        PyErr_SetString(PyExc_TypeError,
+            "raise: arg 3 must be a traceback or None");
+        goto bad;
+    }
+    if (value == Py_None)
+        value = 0;
+    if (PyExceptionInstance_Check(type)) {
+        if (value) {
+            PyErr_SetString(PyExc_TypeError,
+                "instance exception may not have a separate value");
+            goto bad;
+        }
+        value = type;
+        type = (PyObject*) Py_TYPE(value);
+    } else if (PyExceptionClass_Check(type)) {
+        PyObject *args;
+        if (!value)
+            args = PyTuple_New(0);
+        else if (PyTuple_Check(value)) {
+            Py_INCREF(value);
+            args = value;
+        }
+        else
+            args = PyTuple_Pack(1, value);
+        if (!args)
+            goto bad;
+        owned_instance = PyEval_CallObject(type, args);
+        Py_DECREF(args);
+        if (!owned_instance)
+            goto bad;
+        value = owned_instance;
+        if (!PyExceptionInstance_Check(value)) {
+            PyErr_Format(PyExc_TypeError,
+                         "calling %R should have returned an instance of "
+                         "BaseException, not %R",
+                         type, Py_TYPE(value));
+            goto bad;
+        }
+    } else {
+        PyErr_SetString(PyExc_TypeError,
+            "raise: exception class must be a subclass of BaseException");
+        goto bad;
+    }
+    if (cause && cause != Py_None) {
+        PyObject *fixed_cause;
+        if (PyExceptionClass_Check(cause)) {
+            fixed_cause = PyObject_CallObject(cause, NULL);
+            if (fixed_cause == NULL)
+                goto bad;
+        }
+        else if (PyExceptionInstance_Check(cause)) {
+            fixed_cause = cause;
+            Py_INCREF(fixed_cause);
+        }
+        else {
+            PyErr_SetString(PyExc_TypeError,
+                            "exception causes must derive from "
+                            "BaseException");
+            goto bad;
+        }
+        PyException_SetCause(value, fixed_cause);
+    }
+    PyErr_SetObject(type, value);
+    if (tb) {
+        PyThreadState *tstate = PyThreadState_GET();
+        PyObject* tmp_tb = tstate->curexc_traceback;
+        if (tb != tmp_tb) {
+            Py_INCREF(tb);
+            tstate->curexc_traceback = tb;
+            Py_XDECREF(tmp_tb);
+        }
+    }
+bad:
+    Py_XDECREF(owned_instance);
+    return;
+}
+#endif
+
+static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level) {
+    PyObject *empty_list = 0;
+    PyObject *module = 0;
+    PyObject *global_dict = 0;
+    PyObject *empty_dict = 0;
+    PyObject *list;
+    #if PY_VERSION_HEX < 0x03030000
+    PyObject *py_import = 0;
+    py_import = __Pyx_GetAttrString(__pyx_b, "__import__");
+    if (!py_import)
+        goto bad;
+    #endif
+    if (from_list)
+        list = from_list;
+    else {
+        empty_list = PyList_New(0);
+        if (!empty_list)
+            goto bad;
+        list = empty_list;
+    }
+    global_dict = PyModule_GetDict(__pyx_m);
+    if (!global_dict)
+        goto bad;
+    empty_dict = PyDict_New();
+    if (!empty_dict)
+        goto bad;
+    #if PY_VERSION_HEX >= 0x02050000
+    {
+        #if PY_MAJOR_VERSION >= 3
+        if (level == -1) {
+            if (strchr(__Pyx_MODULE_NAME, '.')) {
+                #if PY_VERSION_HEX < 0x03030000
+                PyObject *py_level = PyInt_FromLong(1);
+                if (!py_level)
+                    goto bad;
+                module = PyObject_CallFunctionObjArgs(py_import,
+                    name, global_dict, empty_dict, list, py_level, NULL);
+                Py_DECREF(py_level);
+                #else
+                module = PyImport_ImportModuleLevelObject(
+                    name, global_dict, empty_dict, list, 1);
+                #endif
+                if (!module) {
+                    if (!PyErr_ExceptionMatches(PyExc_ImportError))
+                        goto bad;
+                    PyErr_Clear();
+                }
+            }
+            level = 0; /* try absolute import on failure */
+        }
+        #endif
+        if (!module) {
+            #if PY_VERSION_HEX < 0x03030000
+            PyObject *py_level = PyInt_FromLong(level);
+            if (!py_level)
+                goto bad;
+            module = PyObject_CallFunctionObjArgs(py_import,
+                name, global_dict, empty_dict, list, py_level, NULL);
+            Py_DECREF(py_level);
+            #else
+            module = PyImport_ImportModuleLevelObject(
+                name, global_dict, empty_dict, list, level);
+            #endif
+        }
+    }
+    #else
+    if (level>0) {
+        PyErr_SetString(PyExc_RuntimeError, "Relative import is not supported for Python <=2.4.");
+        goto bad;
+    }
+    module = PyObject_CallFunctionObjArgs(py_import,
+        name, global_dict, empty_dict, list, NULL);
+    #endif
+bad:
+    #if PY_VERSION_HEX < 0x03030000
+    Py_XDECREF(py_import);
+    #endif
+    Py_XDECREF(empty_list);
+    Py_XDECREF(empty_dict);
+    return module;
+}
+
+static CYTHON_INLINE unsigned char __Pyx_PyInt_AsUnsignedChar(PyObject* x) {
+    const unsigned char neg_one = (unsigned char)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(unsigned char) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(unsigned char)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to unsigned char" :
+                    "value too large to convert to unsigned char");
+            }
+            return (unsigned char)-1;
+        }
+        return (unsigned char)val;
+    }
+    return (unsigned char)__Pyx_PyInt_AsUnsignedLong(x);
+}
+
+static CYTHON_INLINE unsigned short __Pyx_PyInt_AsUnsignedShort(PyObject* x) {
+    const unsigned short neg_one = (unsigned short)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(unsigned short) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(unsigned short)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to unsigned short" :
+                    "value too large to convert to unsigned short");
+            }
+            return (unsigned short)-1;
+        }
+        return (unsigned short)val;
+    }
+    return (unsigned short)__Pyx_PyInt_AsUnsignedLong(x);
+}
+
+static CYTHON_INLINE unsigned int __Pyx_PyInt_AsUnsignedInt(PyObject* x) {
+    const unsigned int neg_one = (unsigned int)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(unsigned int) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(unsigned int)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to unsigned int" :
+                    "value too large to convert to unsigned int");
+            }
+            return (unsigned int)-1;
+        }
+        return (unsigned int)val;
+    }
+    return (unsigned int)__Pyx_PyInt_AsUnsignedLong(x);
+}
+
+static CYTHON_INLINE char __Pyx_PyInt_AsChar(PyObject* x) {
+    const char neg_one = (char)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(char) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(char)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to char" :
+                    "value too large to convert to char");
+            }
+            return (char)-1;
+        }
+        return (char)val;
+    }
+    return (char)__Pyx_PyInt_AsLong(x);
+}
+
+static CYTHON_INLINE short __Pyx_PyInt_AsShort(PyObject* x) {
+    const short neg_one = (short)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(short) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(short)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to short" :
+                    "value too large to convert to short");
+            }
+            return (short)-1;
+        }
+        return (short)val;
+    }
+    return (short)__Pyx_PyInt_AsLong(x);
+}
+
+static CYTHON_INLINE int __Pyx_PyInt_AsInt(PyObject* x) {
+    const int neg_one = (int)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(int) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(int)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to int" :
+                    "value too large to convert to int");
+            }
+            return (int)-1;
+        }
+        return (int)val;
+    }
+    return (int)__Pyx_PyInt_AsLong(x);
+}
+
+static CYTHON_INLINE signed char __Pyx_PyInt_AsSignedChar(PyObject* x) {
+    const signed char neg_one = (signed char)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(signed char) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(signed char)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to signed char" :
+                    "value too large to convert to signed char");
+            }
+            return (signed char)-1;
+        }
+        return (signed char)val;
+    }
+    return (signed char)__Pyx_PyInt_AsSignedLong(x);
+}
+
+static CYTHON_INLINE signed short __Pyx_PyInt_AsSignedShort(PyObject* x) {
+    const signed short neg_one = (signed short)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(signed short) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(signed short)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to signed short" :
+                    "value too large to convert to signed short");
+            }
+            return (signed short)-1;
+        }
+        return (signed short)val;
+    }
+    return (signed short)__Pyx_PyInt_AsSignedLong(x);
+}
+
+static CYTHON_INLINE signed int __Pyx_PyInt_AsSignedInt(PyObject* x) {
+    const signed int neg_one = (signed int)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(signed int) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(signed int)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to signed int" :
+                    "value too large to convert to signed int");
+            }
+            return (signed int)-1;
+        }
+        return (signed int)val;
+    }
+    return (signed int)__Pyx_PyInt_AsSignedLong(x);
+}
+
+static CYTHON_INLINE int __Pyx_PyInt_AsLongDouble(PyObject* x) {
+    const int neg_one = (int)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(int) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(int)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to int" :
+                    "value too large to convert to int");
+            }
+            return (int)-1;
+        }
+        return (int)val;
+    }
+    return (int)__Pyx_PyInt_AsLong(x);
+}
+
+static CYTHON_INLINE unsigned long __Pyx_PyInt_AsUnsignedLong(PyObject* x) {
+    const unsigned long neg_one = (unsigned long)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to unsigned long");
+            return (unsigned long)-1;
+        }
+        return (unsigned long)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to unsigned long");
+                return (unsigned long)-1;
+            }
+            return (unsigned long)PyLong_AsUnsignedLong(x);
+        } else {
+            return (unsigned long)PyLong_AsLong(x);
+        }
+    } else {
+        unsigned long val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (unsigned long)-1;
+        val = __Pyx_PyInt_AsUnsignedLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE unsigned PY_LONG_LONG __Pyx_PyInt_AsUnsignedLongLong(PyObject* x) {
+    const unsigned PY_LONG_LONG neg_one = (unsigned PY_LONG_LONG)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to unsigned PY_LONG_LONG");
+            return (unsigned PY_LONG_LONG)-1;
+        }
+        return (unsigned PY_LONG_LONG)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to unsigned PY_LONG_LONG");
+                return (unsigned PY_LONG_LONG)-1;
+            }
+            return (unsigned PY_LONG_LONG)PyLong_AsUnsignedLongLong(x);
+        } else {
+            return (unsigned PY_LONG_LONG)PyLong_AsLongLong(x);
+        }
+    } else {
+        unsigned PY_LONG_LONG val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (unsigned PY_LONG_LONG)-1;
+        val = __Pyx_PyInt_AsUnsignedLongLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE long __Pyx_PyInt_AsLong(PyObject* x) {
+    const long neg_one = (long)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to long");
+            return (long)-1;
+        }
+        return (long)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to long");
+                return (long)-1;
+            }
+            return (long)PyLong_AsUnsignedLong(x);
+        } else {
+            return (long)PyLong_AsLong(x);
+        }
+    } else {
+        long val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (long)-1;
+        val = __Pyx_PyInt_AsLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE PY_LONG_LONG __Pyx_PyInt_AsLongLong(PyObject* x) {
+    const PY_LONG_LONG neg_one = (PY_LONG_LONG)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to PY_LONG_LONG");
+            return (PY_LONG_LONG)-1;
+        }
+        return (PY_LONG_LONG)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to PY_LONG_LONG");
+                return (PY_LONG_LONG)-1;
+            }
+            return (PY_LONG_LONG)PyLong_AsUnsignedLongLong(x);
+        } else {
+            return (PY_LONG_LONG)PyLong_AsLongLong(x);
+        }
+    } else {
+        PY_LONG_LONG val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (PY_LONG_LONG)-1;
+        val = __Pyx_PyInt_AsLongLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE signed long __Pyx_PyInt_AsSignedLong(PyObject* x) {
+    const signed long neg_one = (signed long)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to signed long");
+            return (signed long)-1;
+        }
+        return (signed long)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to signed long");
+                return (signed long)-1;
+            }
+            return (signed long)PyLong_AsUnsignedLong(x);
+        } else {
+            return (signed long)PyLong_AsLong(x);
+        }
+    } else {
+        signed long val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (signed long)-1;
+        val = __Pyx_PyInt_AsSignedLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE signed PY_LONG_LONG __Pyx_PyInt_AsSignedLongLong(PyObject* x) {
+    const signed PY_LONG_LONG neg_one = (signed PY_LONG_LONG)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to signed PY_LONG_LONG");
+            return (signed PY_LONG_LONG)-1;
+        }
+        return (signed PY_LONG_LONG)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to signed PY_LONG_LONG");
+                return (signed PY_LONG_LONG)-1;
+            }
+            return (signed PY_LONG_LONG)PyLong_AsUnsignedLongLong(x);
+        } else {
+            return (signed PY_LONG_LONG)PyLong_AsLongLong(x);
+        }
+    } else {
+        signed PY_LONG_LONG val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (signed PY_LONG_LONG)-1;
+        val = __Pyx_PyInt_AsSignedLongLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static int __Pyx_check_binary_version(void) {
+    char ctversion[4], rtversion[4];
+    PyOS_snprintf(ctversion, 4, "%d.%d", PY_MAJOR_VERSION, PY_MINOR_VERSION);
+    PyOS_snprintf(rtversion, 4, "%s", Py_GetVersion());
+    if (ctversion[0] != rtversion[0] || ctversion[2] != rtversion[2]) {
+        char message[200];
+        PyOS_snprintf(message, sizeof(message),
+                      "compiletime version %s of module '%.100s' "
+                      "does not match runtime version %s",
+                      ctversion, __Pyx_MODULE_NAME, rtversion);
+        #if PY_VERSION_HEX < 0x02050000
+        return PyErr_Warn(NULL, message);
+        #else
+        return PyErr_WarnEx(NULL, message, 1);
+        #endif
+    }
+    return 0;
+}
+
+static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) {
+    int start = 0, mid = 0, end = count - 1;
+    if (end >= 0 && code_line > entries[end].code_line) {
+        return count;
+    }
+    while (start < end) {
+        mid = (start + end) / 2;
+        if (code_line < entries[mid].code_line) {
+            end = mid;
+        } else if (code_line > entries[mid].code_line) {
+             start = mid + 1;
+        } else {
+            return mid;
+        }
+    }
+    if (code_line <= entries[mid].code_line) {
+        return mid;
+    } else {
+        return mid + 1;
+    }
+}
+static PyCodeObject *__pyx_find_code_object(int code_line) {
+    PyCodeObject* code_object;
+    int pos;
+    if (unlikely(!code_line) || unlikely(!__pyx_code_cache.entries)) {
+        return NULL;
+    }
+    pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line);
+    if (unlikely(pos >= __pyx_code_cache.count) || unlikely(__pyx_code_cache.entries[pos].code_line != code_line)) {
+        return NULL;
+    }
+    code_object = __pyx_code_cache.entries[pos].code_object;
+    Py_INCREF(code_object);
+    return code_object;
+}
+static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) {
+    int pos, i;
+    __Pyx_CodeObjectCacheEntry* entries = __pyx_code_cache.entries;
+    if (unlikely(!code_line)) {
+        return;
+    }
+    if (unlikely(!entries)) {
+        entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Malloc(64*sizeof(__Pyx_CodeObjectCacheEntry));
+        if (likely(entries)) {
+            __pyx_code_cache.entries = entries;
+            __pyx_code_cache.max_count = 64;
+            __pyx_code_cache.count = 1;
+            entries[0].code_line = code_line;
+            entries[0].code_object = code_object;
+            Py_INCREF(code_object);
+        }
+        return;
+    }
+    pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line);
+    if ((pos < __pyx_code_cache.count) && unlikely(__pyx_code_cache.entries[pos].code_line == code_line)) {
+        PyCodeObject* tmp = entries[pos].code_object;
+        entries[pos].code_object = code_object;
+        Py_DECREF(tmp);
+        return;
+    }
+    if (__pyx_code_cache.count == __pyx_code_cache.max_count) {
+        int new_max = __pyx_code_cache.max_count + 64;
+        entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Realloc(
+            __pyx_code_cache.entries, new_max*sizeof(__Pyx_CodeObjectCacheEntry));
+        if (unlikely(!entries)) {
+            return;
+        }
+        __pyx_code_cache.entries = entries;
+        __pyx_code_cache.max_count = new_max;
+    }
+    for (i=__pyx_code_cache.count; i>pos; i--) {
+        entries[i] = entries[i-1];
+    }
+    entries[pos].code_line = code_line;
+    entries[pos].code_object = code_object;
+    __pyx_code_cache.count++;
+    Py_INCREF(code_object);
+}
+
+#include "compile.h"
+#include "frameobject.h"
+#include "traceback.h"
+static PyCodeObject* __Pyx_CreateCodeObjectForTraceback(
+            const char *funcname, int c_line,
+            int py_line, const char *filename) {
+    PyCodeObject *py_code = 0;
+    PyObject *py_srcfile = 0;
+    PyObject *py_funcname = 0;
+    #if PY_MAJOR_VERSION < 3
+    py_srcfile = PyString_FromString(filename);
+    #else
+    py_srcfile = PyUnicode_FromString(filename);
+    #endif
+    if (!py_srcfile) goto bad;
+    if (c_line) {
+        #if PY_MAJOR_VERSION < 3
+        py_funcname = PyString_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line);
+        #else
+        py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line);
+        #endif
+    }
+    else {
+        #if PY_MAJOR_VERSION < 3
+        py_funcname = PyString_FromString(funcname);
+        #else
+        py_funcname = PyUnicode_FromString(funcname);
+        #endif
+    }
+    if (!py_funcname) goto bad;
+    py_code = __Pyx_PyCode_New(
+        0,            /*int argcount,*/
+        0,            /*int kwonlyargcount,*/
+        0,            /*int nlocals,*/
+        0,            /*int stacksize,*/
+        0,            /*int flags,*/
+        __pyx_empty_bytes, /*PyObject *code,*/
+        __pyx_empty_tuple, /*PyObject *consts,*/
+        __pyx_empty_tuple, /*PyObject *names,*/
+        __pyx_empty_tuple, /*PyObject *varnames,*/
+        __pyx_empty_tuple, /*PyObject *freevars,*/
+        __pyx_empty_tuple, /*PyObject *cellvars,*/
+        py_srcfile,   /*PyObject *filename,*/
+        py_funcname,  /*PyObject *name,*/
+        py_line,      /*int firstlineno,*/
+        __pyx_empty_bytes  /*PyObject *lnotab*/
+    );
+    Py_DECREF(py_srcfile);
+    Py_DECREF(py_funcname);
+    return py_code;
+bad:
+    Py_XDECREF(py_srcfile);
+    Py_XDECREF(py_funcname);
+    return NULL;
+}
+static void __Pyx_AddTraceback(const char *funcname, int c_line,
+                               int py_line, const char *filename) {
+    PyCodeObject *py_code = 0;
+    PyObject *py_globals = 0;
+    PyFrameObject *py_frame = 0;
+    py_code = __pyx_find_code_object(c_line ? c_line : py_line);
+    if (!py_code) {
+        py_code = __Pyx_CreateCodeObjectForTraceback(
+            funcname, c_line, py_line, filename);
+        if (!py_code) goto bad;
+        __pyx_insert_code_object(c_line ? c_line : py_line, py_code);
+    }
+    py_globals = PyModule_GetDict(__pyx_m);
+    if (!py_globals) goto bad;
+    py_frame = PyFrame_New(
+        PyThreadState_GET(), /*PyThreadState *tstate,*/
+        py_code,             /*PyCodeObject *code,*/
+        py_globals,          /*PyObject *globals,*/
+        0                    /*PyObject *locals*/
+    );
+    if (!py_frame) goto bad;
+    py_frame->f_lineno = py_line;
+    PyTraceBack_Here(py_frame);
+bad:
+    Py_XDECREF(py_code);
+    Py_XDECREF(py_frame);
+}
+
+static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
+    while (t->p) {
+        #if PY_MAJOR_VERSION < 3
+        if (t->is_unicode) {
+            *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
+        } else if (t->intern) {
+            *t->p = PyString_InternFromString(t->s);
+        } else {
+            *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
+        }
+        #else  /* Python 3+ has unicode identifiers */
+        if (t->is_unicode | t->is_str) {
+            if (t->intern) {
+                *t->p = PyUnicode_InternFromString(t->s);
+            } else if (t->encoding) {
+                *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL);
+            } else {
+                *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
+            }
+        } else {
+            *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
+        }
+        #endif
+        if (!*t->p)
+            return -1;
+        ++t;
+    }
+    return 0;
+}
+
+static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) {
+   int is_true = x == Py_True;
+   if (is_true | (x == Py_False) | (x == Py_None)) return is_true;
+   else return PyObject_IsTrue(x);
+}
+static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x) {
+  PyNumberMethods *m;
+  const char *name = NULL;
+  PyObject *res = NULL;
+#if PY_VERSION_HEX < 0x03000000
+  if (PyInt_Check(x) || PyLong_Check(x))
+#else
+  if (PyLong_Check(x))
+#endif
+    return Py_INCREF(x), x;
+  m = Py_TYPE(x)->tp_as_number;
+#if PY_VERSION_HEX < 0x03000000
+  if (m && m->nb_int) {
+    name = "int";
+    res = PyNumber_Int(x);
+  }
+  else if (m && m->nb_long) {
+    name = "long";
+    res = PyNumber_Long(x);
+  }
+#else
+  if (m && m->nb_int) {
+    name = "int";
+    res = PyNumber_Long(x);
+  }
+#endif
+  if (res) {
+#if PY_VERSION_HEX < 0x03000000
+    if (!PyInt_Check(res) && !PyLong_Check(res)) {
+#else
+    if (!PyLong_Check(res)) {
+#endif
+      PyErr_Format(PyExc_TypeError,
+                   "__%s__ returned non-%s (type %.200s)",
+                   name, name, Py_TYPE(res)->tp_name);
+      Py_DECREF(res);
+      return NULL;
+    }
+  }
+  else if (!PyErr_Occurred()) {
+    PyErr_SetString(PyExc_TypeError,
+                    "an integer is required");
+  }
+  return res;
+}
+static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) {
+  Py_ssize_t ival;
+  PyObject* x = PyNumber_Index(b);
+  if (!x) return -1;
+  ival = PyInt_AsSsize_t(x);
+  Py_DECREF(x);
+  return ival;
+}
+static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) {
+#if PY_VERSION_HEX < 0x02050000
+   if (ival <= LONG_MAX)
+       return PyInt_FromLong((long)ival);
+   else {
+       unsigned char *bytes = (unsigned char *) &ival;
+       int one = 1; int little = (int)*(unsigned char*)&one;
+       return _PyLong_FromByteArray(bytes, sizeof(size_t), little, 0);
+   }
+#else
+   return PyInt_FromSize_t(ival);
+#endif
+}
+static CYTHON_INLINE size_t __Pyx_PyInt_AsSize_t(PyObject* x) {
+   unsigned PY_LONG_LONG val = __Pyx_PyInt_AsUnsignedLongLong(x);
+   if (unlikely(val == (unsigned PY_LONG_LONG)-1 && PyErr_Occurred())) {
+       return (size_t)-1;
+   } else if (unlikely(val != (unsigned PY_LONG_LONG)(size_t)val)) {
+       PyErr_SetString(PyExc_OverflowError,
+                       "value too large to convert to size_t");
+       return (size_t)-1;
+   }
+   return (size_t)val;
+}
+
+
+#endif /* Py_PYTHON_H */
diff --git a/lib/bx/misc/_seekbzip2.pyx b/lib/bx/misc/_seekbzip2.pyx
new file mode 100644
index 0000000..0862934
--- /dev/null
+++ b/lib/bx/misc/_seekbzip2.pyx
@@ -0,0 +1,191 @@
+"""
+Pyrex/C extension supporting `bx.misc.seekbzip2` (wrapping the low level
+functions in `micro-bunzip.c`).
+"""
+
+cdef extern from "Python.h":
+    char * PyString_AsString( object )
+    object PyString_FromStringAndSize( char *, int )
+
+cdef extern from "micro-bunzip.h":
+    ctypedef struct bunzip_data:
+        int in_fd
+        int inbufBitCount
+        int inbufPos
+        int inbufCount
+        int writeCount
+        unsigned int writeCRC
+        int writeCurrent
+        int writeCopies
+        unsigned int * dbuf
+    unsigned int get_bits(bunzip_data *bd, char bits_wanted)
+    int get_next_block( bunzip_data *bd )
+    int read_bunzip(bunzip_data *bd, char *outbuf, int len)
+    int start_bunzip(bunzip_data **bdp, int in_fd, char *inbuf, int len)
+    int read_bunzip_to_char(bunzip_data *bd, char *outbuf, int len, int* gotcount_out, char stopchar )
+    
+cdef extern from "unistd.h":
+    # Not really
+    ctypedef unsigned long long off_t
+    off_t lseek( int fildes, off_t offset, int whence )
+    
+cdef extern from "stdlib.h":
+    void free( void *ptr )
+ 
+import sys
+import os
+    
+cdef class SeekBzip2:
+
+    cdef bunzip_data * bd
+    cdef int file_fd
+    cdef int at_eof
+
+    def __init__( self, filename ):
+        self.at_eof = 0
+        self.file_fd = os.open( filename, os.O_RDONLY )
+        # Initialize bunzip_data from the file
+        start_bunzip( &( self.bd ), self.file_fd, NULL, 0 )
+        
+    def close( self ):
+        free( self.bd.dbuf )
+        free( self.bd )
+        os.close( self.file_fd )
+
+    def seek( self, unsigned long long position ):
+        """
+        Seek the bunzip_data to a specific chunk (position must correspond to
+        that start of a compressed data block).
+        """
+        cdef off_t n_byte
+        cdef int n_bit
+        # Break position into bit and byte offsets
+        ## sys.stderr.write( "arg pos: %d\n" % position )
+        n_byte = position / 8;
+        n_bit = position % 8;
+        ## sys.stderr.write( "byte pos: %d\n" % n_byte )
+        ## sys.stderr.write( "bit pos: %d\n" % n_bit )
+        ## sys.stderr.flush()
+        # Seek the underlying file descriptor
+        if ( lseek( self.file_fd, n_byte, 0 ) != n_byte ):
+            raise Exception( "lseek of underlying file failed" )
+        # Init the buffer at the right bit position
+        self.bd.inbufBitCount = self.bd.inbufPos = self.bd.inbufCount = 0
+        get_bits( self.bd, n_bit )
+        # This ensures that the next read call will return 0, causing the
+        # buffer to be re-initialized
+        self.bd.writeCount = -1
+        # Reset EOF tracking
+        self.at_eof = 0
+        
+    def readline( self, int amount ):
+        cdef object rval
+        cdef char * p_rval
+        cdef int gotcount
+        cdef int totalcount
+        cdef int status
+        cdef int spaceleft
+        cdef int desired
+        gotcount = 0
+        totalcount = 0
+        # If already at EOF return None
+        if self.at_eof:
+            return None
+        chunks = []
+        # We have great difficulty resizing buffers, so we'll just create
+        # one 8k string at a time
+        rval = PyString_FromStringAndSize( NULL, 8192 )
+        p_rval = PyString_AsString( rval )
+        spaceleft = 8192
+        while amount != 0:
+            if amount > 0 and amount < spaceleft:
+                desired = amount
+            else:
+                desired = spaceleft
+            ## sys.stderr.write( "readline, amount: %d\n" % amount )
+            ## sys.stderr.write( "buffer: %r" % rval[:100] )
+            ## sys.stderr.write( "\n" )
+            ## sys.stderr.flush()
+            # ord( "\n" ) = 10
+            status = read_bunzip_to_char( self.bd, p_rval, desired, &gotcount, 10 );
+            ## sys.stderr.write( "readline, desired: %d, gotcount: %d\n" % ( desired, gotcount ) ); 
+            ## sys.stderr.write( "buffer: %r" % rval[:100] )
+            ## sys.stderr.write( "\n" )
+            ## sys.stderr.flush()
+            if status == -9: 
+                ## sys.stderr.write( "readline, STOP_CHAR\n" ); sys.stderr.flush()
+                # Reached the stop character (RETVAL_STOPCHAR == -9), so 
+                # we can stop
+                chunks.append( rval[:8192-spaceleft+gotcount] )
+                break
+            elif status == -10:
+                ## sys.stderr.write( "readline, BUFFER_FULL\n" ); sys.stderr.flush()
+                # Filled the buffer (RETVAL_BUFFER_FULL == -10), so create
+                # new buffer and keep going
+                chunks.append( rval )
+                amount = amount - gotcount
+                if amount == 0:
+                    # Got the desired amount
+                    break
+                rval = PyString_FromStringAndSize( NULL, 8192 )
+                p_rval = PyString_AsString( rval )
+                spaceleft = 8192
+            elif status == -8:
+                ## sys.stderr.write( "readline, END_OF_BLOCK\n" ); sys.stderr.flush()
+                # No more data in the decomp buffer (RETVAL_END_OF_BLOCK == -10)
+                if gotcount and p_rval[ gotcount - 1 ] == 10:
+                    chunks.append( rval[:8192-spaceleft+gotcount] )
+                    break
+                # Update buffer info
+                p_rval = p_rval + gotcount
+                spaceleft = spaceleft - gotcount
+                amount = amount - gotcount
+                # Get the next block
+                status = get_next_block( self.bd )
+                if status == -1:
+                    # Block is end of stream block (RETVAL_LAST_BLOCK == -1)
+                    self.at_eof = 1
+                    chunks.append( rval[:gotcount] )
+                    break
+                self.bd.writeCRC = 0xffffffff
+                self.bd.writeCopies = 0
+            else:
+                # Some other status
+                raise Exception( "read_bunzip error %d" % status )
+        # Return whatever we read
+        return "".join( chunks )
+        
+    def read( self, int amount ):
+        cdef object rval
+        cdef char * p_rval
+        cdef int gotcount
+        cdef int totalcount
+        cdef int status
+        totalcount = 0
+        # If already at EOF return None
+        if self.at_eof:
+            return None
+        # Create a new python string large enough to hold the result
+        rval = PyString_FromStringAndSize( NULL, amount )
+        p_rval = PyString_AsString( rval )
+        # Read into it
+        ## sys.stderr.write( "read called, bd.current: %x\n" % self.bd.writeCurrent ); sys.stderr.flush()
+        while amount > 0:
+            gotcount = read_bunzip( self.bd, p_rval, amount );
+            if gotcount < 0:
+                raise Exception( "read_bunzip error %d" % gotcount )
+            elif gotcount == 0:
+                status = get_next_block( self.bd )
+                if status == -1:
+                    self.at_eof = 1
+                    break
+                self.bd.writeCRC = 0xffffffff
+                self.bd.writeCopies = 0
+            else:
+                totalcount = totalcount + gotcount
+                amount = amount - gotcount
+                p_rval = p_rval + gotcount
+        # Return whatever we read
+        return rval[:totalcount]
+    
+    
\ No newline at end of file
diff --git a/lib/bx/misc/bgzf.c b/lib/bx/misc/bgzf.c
new file mode 100644
index 0000000..76f75b9
--- /dev/null
+++ b/lib/bx/misc/bgzf.c
@@ -0,0 +1,2331 @@
+/* Generated by Cython 0.18 on Mon Jul 15 13:25:44 2013 */
+
+#define PY_SSIZE_T_CLEAN
+#include "Python.h"
+#ifndef Py_PYTHON_H
+    #error Python headers needed to compile C extensions, please install development version of Python.
+#elif PY_VERSION_HEX < 0x02040000
+    #error Cython requires Python 2.4+.
+#else
+#include <stddef.h> /* For offsetof */
+#ifndef offsetof
+#define offsetof(type, member) ( (size_t) & ((type*)0) -> member )
+#endif
+#if !defined(WIN32) && !defined(MS_WINDOWS)
+  #ifndef __stdcall
+    #define __stdcall
+  #endif
+  #ifndef __cdecl
+    #define __cdecl
+  #endif
+  #ifndef __fastcall
+    #define __fastcall
+  #endif
+#endif
+#ifndef DL_IMPORT
+  #define DL_IMPORT(t) t
+#endif
+#ifndef DL_EXPORT
+  #define DL_EXPORT(t) t
+#endif
+#ifndef PY_LONG_LONG
+  #define PY_LONG_LONG LONG_LONG
+#endif
+#ifndef Py_HUGE_VAL
+  #define Py_HUGE_VAL HUGE_VAL
+#endif
+#ifdef PYPY_VERSION
+#define CYTHON_COMPILING_IN_PYPY 1
+#define CYTHON_COMPILING_IN_CPYTHON 0
+#else
+#define CYTHON_COMPILING_IN_PYPY 0
+#define CYTHON_COMPILING_IN_CPYTHON 1
+#endif
+#if PY_VERSION_HEX < 0x02050000
+  typedef int Py_ssize_t;
+  #define PY_SSIZE_T_MAX INT_MAX
+  #define PY_SSIZE_T_MIN INT_MIN
+  #define PY_FORMAT_SIZE_T ""
+  #define CYTHON_FORMAT_SSIZE_T ""
+  #define PyInt_FromSsize_t(z) PyInt_FromLong(z)
+  #define PyInt_AsSsize_t(o)   __Pyx_PyInt_AsInt(o)
+  #define PyNumber_Index(o)    ((PyNumber_Check(o) && !PyFloat_Check(o)) ? PyNumber_Int(o) : \
+                                (PyErr_Format(PyExc_TypeError, \
+                                              "expected index value, got %.200s", Py_TYPE(o)->tp_name), \
+                                 (PyObject*)0))
+  #define __Pyx_PyIndex_Check(o) (PyNumber_Check(o) && !PyFloat_Check(o) && \
+                                  !PyComplex_Check(o))
+  #define PyIndex_Check __Pyx_PyIndex_Check
+  #define PyErr_WarnEx(category, message, stacklevel) PyErr_Warn(category, message)
+  #define __PYX_BUILD_PY_SSIZE_T "i"
+#else
+  #define __PYX_BUILD_PY_SSIZE_T "n"
+  #define CYTHON_FORMAT_SSIZE_T "z"
+  #define __Pyx_PyIndex_Check PyIndex_Check
+#endif
+#if PY_VERSION_HEX < 0x02060000
+  #define Py_REFCNT(ob) (((PyObject*)(ob))->ob_refcnt)
+  #define Py_TYPE(ob)   (((PyObject*)(ob))->ob_type)
+  #define Py_SIZE(ob)   (((PyVarObject*)(ob))->ob_size)
+  #define PyVarObject_HEAD_INIT(type, size) \
+          PyObject_HEAD_INIT(type) size,
+  #define PyType_Modified(t)
+  typedef struct {
+     void *buf;
+     PyObject *obj;
+     Py_ssize_t len;
+     Py_ssize_t itemsize;
+     int readonly;
+     int ndim;
+     char *format;
+     Py_ssize_t *shape;
+     Py_ssize_t *strides;
+     Py_ssize_t *suboffsets;
+     void *internal;
+  } Py_buffer;
+  #define PyBUF_SIMPLE 0
+  #define PyBUF_WRITABLE 0x0001
+  #define PyBUF_FORMAT 0x0004
+  #define PyBUF_ND 0x0008
+  #define PyBUF_STRIDES (0x0010 | PyBUF_ND)
+  #define PyBUF_C_CONTIGUOUS (0x0020 | PyBUF_STRIDES)
+  #define PyBUF_F_CONTIGUOUS (0x0040 | PyBUF_STRIDES)
+  #define PyBUF_ANY_CONTIGUOUS (0x0080 | PyBUF_STRIDES)
+  #define PyBUF_INDIRECT (0x0100 | PyBUF_STRIDES)
+  #define PyBUF_RECORDS (PyBUF_STRIDES | PyBUF_FORMAT | PyBUF_WRITABLE)
+  #define PyBUF_FULL (PyBUF_INDIRECT | PyBUF_FORMAT | PyBUF_WRITABLE)
+  typedef int (*getbufferproc)(PyObject *, Py_buffer *, int);
+  typedef void (*releasebufferproc)(PyObject *, Py_buffer *);
+#endif
+#if PY_MAJOR_VERSION < 3
+  #define __Pyx_BUILTIN_MODULE_NAME "__builtin__"
+  #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \
+          PyCode_New(a, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
+#else
+  #define __Pyx_BUILTIN_MODULE_NAME "builtins"
+  #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \
+          PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
+#endif
+#if PY_MAJOR_VERSION < 3 && PY_MINOR_VERSION < 6
+  #define PyUnicode_FromString(s) PyUnicode_Decode(s, strlen(s), "UTF-8", "strict")
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define Py_TPFLAGS_CHECKTYPES 0
+  #define Py_TPFLAGS_HAVE_INDEX 0
+#endif
+#if (PY_VERSION_HEX < 0x02060000) || (PY_MAJOR_VERSION >= 3)
+  #define Py_TPFLAGS_HAVE_NEWBUFFER 0
+#endif
+#if PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND)
+  #define CYTHON_PEP393_ENABLED 1
+  #define __Pyx_PyUnicode_READY(op)       (likely(PyUnicode_IS_READY(op)) ? \
+                                              0 : _PyUnicode_Ready((PyObject *)(op)))
+  #define __Pyx_PyUnicode_GET_LENGTH(u)   PyUnicode_GET_LENGTH(u)
+  #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_READ_CHAR(u, i)
+  #define __Pyx_PyUnicode_READ(k, d, i)   PyUnicode_READ(k, d, i)
+#else
+  #define CYTHON_PEP393_ENABLED 0
+  #define __Pyx_PyUnicode_READY(op)       (0)
+  #define __Pyx_PyUnicode_GET_LENGTH(u)   PyUnicode_GET_SIZE(u)
+  #define __Pyx_PyUnicode_READ_CHAR(u, i) ((Py_UCS4)(PyUnicode_AS_UNICODE(u)[i]))
+  #define __Pyx_PyUnicode_READ(k, d, i)   ((k=k), (Py_UCS4)(((Py_UNICODE*)d)[i]))
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define PyBaseString_Type            PyUnicode_Type
+  #define PyStringObject               PyUnicodeObject
+  #define PyString_Type                PyUnicode_Type
+  #define PyString_Check               PyUnicode_Check
+  #define PyString_CheckExact          PyUnicode_CheckExact
+#endif
+#if PY_VERSION_HEX < 0x02060000
+  #define PyBytesObject                PyStringObject
+  #define PyBytes_Type                 PyString_Type
+  #define PyBytes_Check                PyString_Check
+  #define PyBytes_CheckExact           PyString_CheckExact
+  #define PyBytes_FromString           PyString_FromString
+  #define PyBytes_FromStringAndSize    PyString_FromStringAndSize
+  #define PyBytes_FromFormat           PyString_FromFormat
+  #define PyBytes_DecodeEscape         PyString_DecodeEscape
+  #define PyBytes_AsString             PyString_AsString
+  #define PyBytes_AsStringAndSize      PyString_AsStringAndSize
+  #define PyBytes_Size                 PyString_Size
+  #define PyBytes_AS_STRING            PyString_AS_STRING
+  #define PyBytes_GET_SIZE             PyString_GET_SIZE
+  #define PyBytes_Repr                 PyString_Repr
+  #define PyBytes_Concat               PyString_Concat
+  #define PyBytes_ConcatAndDel         PyString_ConcatAndDel
+#endif
+#if PY_VERSION_HEX < 0x02060000
+  #define PySet_Check(obj)             PyObject_TypeCheck(obj, &PySet_Type)
+  #define PyFrozenSet_Check(obj)       PyObject_TypeCheck(obj, &PyFrozenSet_Type)
+#endif
+#ifndef PySet_CheckExact
+  #define PySet_CheckExact(obj)        (Py_TYPE(obj) == &PySet_Type)
+#endif
+#define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type)
+#if PY_MAJOR_VERSION >= 3
+  #define PyIntObject                  PyLongObject
+  #define PyInt_Type                   PyLong_Type
+  #define PyInt_Check(op)              PyLong_Check(op)
+  #define PyInt_CheckExact(op)         PyLong_CheckExact(op)
+  #define PyInt_FromString             PyLong_FromString
+  #define PyInt_FromUnicode            PyLong_FromUnicode
+  #define PyInt_FromLong               PyLong_FromLong
+  #define PyInt_FromSize_t             PyLong_FromSize_t
+  #define PyInt_FromSsize_t            PyLong_FromSsize_t
+  #define PyInt_AsLong                 PyLong_AsLong
+  #define PyInt_AS_LONG                PyLong_AS_LONG
+  #define PyInt_AsSsize_t              PyLong_AsSsize_t
+  #define PyInt_AsUnsignedLongMask     PyLong_AsUnsignedLongMask
+  #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define PyBoolObject                 PyLongObject
+#endif
+#if PY_VERSION_HEX < 0x03020000
+  typedef long Py_hash_t;
+  #define __Pyx_PyInt_FromHash_t PyInt_FromLong
+  #define __Pyx_PyInt_AsHash_t   PyInt_AsLong
+#else
+  #define __Pyx_PyInt_FromHash_t PyInt_FromSsize_t
+  #define __Pyx_PyInt_AsHash_t   PyInt_AsSsize_t
+#endif
+#if (PY_MAJOR_VERSION < 3) || (PY_VERSION_HEX >= 0x03010300)
+  #define __Pyx_PySequence_GetSlice(obj, a, b) PySequence_GetSlice(obj, a, b)
+  #define __Pyx_PySequence_SetSlice(obj, a, b, value) PySequence_SetSlice(obj, a, b, value)
+  #define __Pyx_PySequence_DelSlice(obj, a, b) PySequence_DelSlice(obj, a, b)
+#else
+  #define __Pyx_PySequence_GetSlice(obj, a, b) (unlikely(!(obj)) ? \
+        (PyErr_SetString(PyExc_SystemError, "null argument to internal routine"), (PyObject*)0) : \
+        (likely((obj)->ob_type->tp_as_mapping) ? (PySequence_GetSlice(obj, a, b)) : \
+            (PyErr_Format(PyExc_TypeError, "'%.200s' object is unsliceable", (obj)->ob_type->tp_name), (PyObject*)0)))
+  #define __Pyx_PySequence_SetSlice(obj, a, b, value) (unlikely(!(obj)) ? \
+        (PyErr_SetString(PyExc_SystemError, "null argument to internal routine"), -1) : \
+        (likely((obj)->ob_type->tp_as_mapping) ? (PySequence_SetSlice(obj, a, b, value)) : \
+            (PyErr_Format(PyExc_TypeError, "'%.200s' object doesn't support slice assignment", (obj)->ob_type->tp_name), -1)))
+  #define __Pyx_PySequence_DelSlice(obj, a, b) (unlikely(!(obj)) ? \
+        (PyErr_SetString(PyExc_SystemError, "null argument to internal routine"), -1) : \
+        (likely((obj)->ob_type->tp_as_mapping) ? (PySequence_DelSlice(obj, a, b)) : \
+            (PyErr_Format(PyExc_TypeError, "'%.200s' object doesn't support slice deletion", (obj)->ob_type->tp_name), -1)))
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define PyMethod_New(func, self, klass) ((self) ? PyMethod_New(func, self) : PyInstanceMethod_New(func))
+#endif
+#if PY_VERSION_HEX < 0x02050000
+  #define __Pyx_GetAttrString(o,n)   PyObject_GetAttrString((o),((char *)(n)))
+  #define __Pyx_SetAttrString(o,n,a) PyObject_SetAttrString((o),((char *)(n)),(a))
+  #define __Pyx_DelAttrString(o,n)   PyObject_DelAttrString((o),((char *)(n)))
+#else
+  #define __Pyx_GetAttrString(o,n)   PyObject_GetAttrString((o),(n))
+  #define __Pyx_SetAttrString(o,n,a) PyObject_SetAttrString((o),(n),(a))
+  #define __Pyx_DelAttrString(o,n)   PyObject_DelAttrString((o),(n))
+#endif
+#if PY_VERSION_HEX < 0x02050000
+  #define __Pyx_NAMESTR(n) ((char *)(n))
+  #define __Pyx_DOCSTR(n)  ((char *)(n))
+#else
+  #define __Pyx_NAMESTR(n) (n)
+  #define __Pyx_DOCSTR(n)  (n)
+#endif
+
+
+#if PY_MAJOR_VERSION >= 3
+  #define __Pyx_PyNumber_Divide(x,y)         PyNumber_TrueDivide(x,y)
+  #define __Pyx_PyNumber_InPlaceDivide(x,y)  PyNumber_InPlaceTrueDivide(x,y)
+#else
+  #define __Pyx_PyNumber_Divide(x,y)         PyNumber_Divide(x,y)
+  #define __Pyx_PyNumber_InPlaceDivide(x,y)  PyNumber_InPlaceDivide(x,y)
+#endif
+
+#ifndef __PYX_EXTERN_C
+  #ifdef __cplusplus
+    #define __PYX_EXTERN_C extern "C"
+  #else
+    #define __PYX_EXTERN_C extern
+  #endif
+#endif
+
+#if defined(WIN32) || defined(MS_WINDOWS)
+#define _USE_MATH_DEFINES
+#endif
+#include <math.h>
+#define __PYX_HAVE__bx__misc__bgzf
+#define __PYX_HAVE_API__bx__misc__bgzf
+#include "bgzf.h"
+#ifdef _OPENMP
+#include <omp.h>
+#endif /* _OPENMP */
+
+#ifdef PYREX_WITHOUT_ASSERTIONS
+#define CYTHON_WITHOUT_ASSERTIONS
+#endif
+
+#ifndef CYTHON_INLINE
+  #if defined(__GNUC__)
+    #define CYTHON_INLINE __inline__
+  #elif defined(_MSC_VER)
+    #define CYTHON_INLINE __inline
+  #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+    #define CYTHON_INLINE inline
+  #else
+    #define CYTHON_INLINE
+  #endif
+#endif
+#ifndef CYTHON_UNUSED
+# if defined(__GNUC__)
+#   if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
+#     define CYTHON_UNUSED __attribute__ ((__unused__))
+#   else
+#     define CYTHON_UNUSED
+#   endif
+# elif defined(__ICC) || (defined(__INTEL_COMPILER) && !defined(_MSC_VER))
+#   define CYTHON_UNUSED __attribute__ ((__unused__))
+# else
+#   define CYTHON_UNUSED
+# endif
+#endif
+typedef struct {PyObject **p; char *s; const long n; const char* encoding; const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry; /*proto*/
+
+#define __Pyx_PyBytes_FromUString(s) PyBytes_FromString((char*)s)
+#define __Pyx_PyBytes_AsUString(s)   ((unsigned char*) PyBytes_AsString(s))
+#define __Pyx_Owned_Py_None(b) (Py_INCREF(Py_None), Py_None)
+#define __Pyx_PyBool_FromLong(b) ((b) ? (Py_INCREF(Py_True), Py_True) : (Py_INCREF(Py_False), Py_False))
+static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*);
+static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x);
+static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*);
+static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t);
+static CYTHON_INLINE size_t __Pyx_PyInt_AsSize_t(PyObject*);
+#if CYTHON_COMPILING_IN_CPYTHON
+#define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x))
+#else
+#define __pyx_PyFloat_AsDouble(x) PyFloat_AsDouble(x)
+#endif
+#define __pyx_PyFloat_AsFloat(x) ((float) __pyx_PyFloat_AsDouble(x))
+
+
+#ifdef __GNUC__
+  /* Test for GCC > 2.95 */
+  #if __GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))
+    #define likely(x)   __builtin_expect(!!(x), 1)
+    #define unlikely(x) __builtin_expect(!!(x), 0)
+  #else /* __GNUC__ > 2 ... */
+    #define likely(x)   (x)
+    #define unlikely(x) (x)
+  #endif /* __GNUC__ > 2 ... */
+#else /* __GNUC__ */
+  #define likely(x)   (x)
+  #define unlikely(x) (x)
+#endif /* __GNUC__ */
+    
+static PyObject *__pyx_m;
+static PyObject *__pyx_b;
+static PyObject *__pyx_empty_tuple;
+static PyObject *__pyx_empty_bytes;
+static int __pyx_lineno;
+static int __pyx_clineno = 0;
+static const char * __pyx_cfilenm= __FILE__;
+static const char *__pyx_filename;
+
+
+static const char *__pyx_f[] = {
+  "bgzf.pyx",
+};
+
+/* "bx/misc/bgzf.pyx":6
+ * """
+ * 
+ * ctypedef unsigned long long int64_t             # <<<<<<<<<<<<<<
+ * 
+ * cdef extern from "Python.h":
+ */
+typedef unsigned PY_LONG_LONG __pyx_t_2bx_4misc_4bgzf_int64_t;
+
+/*--- Type declarations ---*/
+struct __pyx_obj_2bx_4misc_4bgzf_BGZFFile;
+
+/* "bx/misc/bgzf.pyx":20
+ *     int64_t bgzf_seek( BGZF * fp, int64_t pos, int where )
+ * 
+ * cdef class BGZFFile( object ):             # <<<<<<<<<<<<<<
+ *     cdef BGZF * bgzf
+ *     def __init__( self, path, mode="r" ):
+ */
+struct __pyx_obj_2bx_4misc_4bgzf_BGZFFile {
+  PyObject_HEAD
+  BGZF *bgzf;
+};
+
+#ifndef CYTHON_REFNANNY
+  #define CYTHON_REFNANNY 0
+#endif
+#if CYTHON_REFNANNY
+  typedef struct {
+    void (*INCREF)(void*, PyObject*, int);
+    void (*DECREF)(void*, PyObject*, int);
+    void (*GOTREF)(void*, PyObject*, int);
+    void (*GIVEREF)(void*, PyObject*, int);
+    void* (*SetupContext)(const char*, int, const char*);
+    void (*FinishContext)(void**);
+  } __Pyx_RefNannyAPIStruct;
+  static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL;
+  static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname); /*proto*/
+  #define __Pyx_RefNannyDeclarations void *__pyx_refnanny = NULL;
+#ifdef WITH_THREAD
+  #define __Pyx_RefNannySetupContext(name, acquire_gil) \
+          if (acquire_gil) { \
+              PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure(); \
+              __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__); \
+              PyGILState_Release(__pyx_gilstate_save); \
+          } else { \
+              __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__); \
+          }
+#else
+  #define __Pyx_RefNannySetupContext(name, acquire_gil) \
+          __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__)
+#endif
+  #define __Pyx_RefNannyFinishContext() \
+          __Pyx_RefNanny->FinishContext(&__pyx_refnanny)
+  #define __Pyx_INCREF(r)  __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_DECREF(r)  __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_GOTREF(r)  __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_XINCREF(r)  do { if((r) != NULL) {__Pyx_INCREF(r); }} while(0)
+  #define __Pyx_XDECREF(r)  do { if((r) != NULL) {__Pyx_DECREF(r); }} while(0)
+  #define __Pyx_XGOTREF(r)  do { if((r) != NULL) {__Pyx_GOTREF(r); }} while(0)
+  #define __Pyx_XGIVEREF(r) do { if((r) != NULL) {__Pyx_GIVEREF(r);}} while(0)
+#else
+  #define __Pyx_RefNannyDeclarations
+  #define __Pyx_RefNannySetupContext(name, acquire_gil)
+  #define __Pyx_RefNannyFinishContext()
+  #define __Pyx_INCREF(r) Py_INCREF(r)
+  #define __Pyx_DECREF(r) Py_DECREF(r)
+  #define __Pyx_GOTREF(r)
+  #define __Pyx_GIVEREF(r)
+  #define __Pyx_XINCREF(r) Py_XINCREF(r)
+  #define __Pyx_XDECREF(r) Py_XDECREF(r)
+  #define __Pyx_XGOTREF(r)
+  #define __Pyx_XGIVEREF(r)
+#endif /* CYTHON_REFNANNY */
+#define __Pyx_CLEAR(r)    do { PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);} while(0)
+#define __Pyx_XCLEAR(r)   do { if((r) != NULL) {PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);}} while(0)
+
+static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/
+
+static void __Pyx_RaiseDoubleKeywordsError(const char* func_name, PyObject* kw_name); /*proto*/
+
+static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
+    PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
+    const char* function_name); /*proto*/
+
+static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
+    Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/
+
+static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
+static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
+
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause); /*proto*/
+
+static CYTHON_INLINE unsigned char __Pyx_PyInt_AsUnsignedChar(PyObject *);
+
+static CYTHON_INLINE unsigned short __Pyx_PyInt_AsUnsignedShort(PyObject *);
+
+static CYTHON_INLINE unsigned int __Pyx_PyInt_AsUnsignedInt(PyObject *);
+
+static CYTHON_INLINE char __Pyx_PyInt_AsChar(PyObject *);
+
+static CYTHON_INLINE short __Pyx_PyInt_AsShort(PyObject *);
+
+static CYTHON_INLINE int __Pyx_PyInt_AsInt(PyObject *);
+
+static CYTHON_INLINE signed char __Pyx_PyInt_AsSignedChar(PyObject *);
+
+static CYTHON_INLINE signed short __Pyx_PyInt_AsSignedShort(PyObject *);
+
+static CYTHON_INLINE signed int __Pyx_PyInt_AsSignedInt(PyObject *);
+
+static CYTHON_INLINE int __Pyx_PyInt_AsLongDouble(PyObject *);
+
+static CYTHON_INLINE unsigned long __Pyx_PyInt_AsUnsignedLong(PyObject *);
+
+static CYTHON_INLINE unsigned PY_LONG_LONG __Pyx_PyInt_AsUnsignedLongLong(PyObject *);
+
+static CYTHON_INLINE long __Pyx_PyInt_AsLong(PyObject *);
+
+static CYTHON_INLINE PY_LONG_LONG __Pyx_PyInt_AsLongLong(PyObject *);
+
+static CYTHON_INLINE signed long __Pyx_PyInt_AsSignedLong(PyObject *);
+
+static CYTHON_INLINE signed PY_LONG_LONG __Pyx_PyInt_AsSignedLongLong(PyObject *);
+
+static int __Pyx_check_binary_version(void);
+
+typedef struct {
+    int code_line;
+    PyCodeObject* code_object;
+} __Pyx_CodeObjectCacheEntry;
+struct __Pyx_CodeObjectCache {
+    int count;
+    int max_count;
+    __Pyx_CodeObjectCacheEntry* entries;
+};
+static struct __Pyx_CodeObjectCache __pyx_code_cache = {0,0,NULL};
+static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line);
+static PyCodeObject *__pyx_find_code_object(int code_line);
+static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object);
+
+static void __Pyx_AddTraceback(const char *funcname, int c_line,
+                               int py_line, const char *filename); /*proto*/
+
+static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
+
+
+/* Module declarations from 'bx.misc.bgzf' */
+static PyTypeObject *__pyx_ptype_2bx_4misc_4bgzf_BGZFFile = 0;
+#define __Pyx_MODULE_NAME "bx.misc.bgzf"
+int __pyx_module_is_main_bx__misc__bgzf = 0;
+
+/* Implementation of 'bx.misc.bgzf' */
+static PyObject *__pyx_builtin_IOError;
+static int __pyx_pf_2bx_4misc_4bgzf_8BGZFFile___init__(struct __pyx_obj_2bx_4misc_4bgzf_BGZFFile *__pyx_v_self, PyObject *__pyx_v_path, PyObject *__pyx_v_mode); /* proto */
+static PyObject *__pyx_pf_2bx_4misc_4bgzf_8BGZFFile_2close(struct __pyx_obj_2bx_4misc_4bgzf_BGZFFile *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_2bx_4misc_4bgzf_8BGZFFile_4read(struct __pyx_obj_2bx_4misc_4bgzf_BGZFFile *__pyx_v_self, int __pyx_v_length); /* proto */
+static PyObject *__pyx_pf_2bx_4misc_4bgzf_8BGZFFile_6tell(struct __pyx_obj_2bx_4misc_4bgzf_BGZFFile *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_2bx_4misc_4bgzf_8BGZFFile_8seek(struct __pyx_obj_2bx_4misc_4bgzf_BGZFFile *__pyx_v_self, __pyx_t_2bx_4misc_4bgzf_int64_t __pyx_v_pos, int __pyx_v_where); /* proto */
+static char __pyx_k_1[] = "Could not open file";
+static char __pyx_k_3[] = "\nSeekable access to BGZ files based on samtools code. Does not yet implement\ncomplete file-like interface.\n";
+static char __pyx_k__r[] = "r";
+static char __pyx_k__pos[] = "pos";
+static char __pyx_k__mode[] = "mode";
+static char __pyx_k__path[] = "path";
+static char __pyx_k__where[] = "where";
+static char __pyx_k__IOError[] = "IOError";
+static char __pyx_k____main__[] = "__main__";
+static char __pyx_k____test__[] = "__test__";
+static PyObject *__pyx_kp_s_1;
+static PyObject *__pyx_n_s__IOError;
+static PyObject *__pyx_n_s____main__;
+static PyObject *__pyx_n_s____test__;
+static PyObject *__pyx_n_s__mode;
+static PyObject *__pyx_n_s__path;
+static PyObject *__pyx_n_s__pos;
+static PyObject *__pyx_n_s__r;
+static PyObject *__pyx_n_s__where;
+static PyObject *__pyx_k_tuple_2;
+
+/* Python wrapper */
+static int __pyx_pw_2bx_4misc_4bgzf_8BGZFFile_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static int __pyx_pw_2bx_4misc_4bgzf_8BGZFFile_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_path = 0;
+  PyObject *__pyx_v_mode = 0;
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__init__ (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__path,&__pyx_n_s__mode,0};
+    PyObject* values[2] = {0,0};
+    values[1] = ((PyObject *)__pyx_n_s__r);
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__path)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s__mode);
+          if (value) { values[1] = value; kw_args--; }
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 22; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else {
+      switch (PyTuple_GET_SIZE(__pyx_args)) {
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+    }
+    __pyx_v_path = values[0];
+    __pyx_v_mode = values[1];
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("__init__", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 22; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.misc.bgzf.BGZFFile.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return -1;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_4misc_4bgzf_8BGZFFile___init__(((struct __pyx_obj_2bx_4misc_4bgzf_BGZFFile *)__pyx_v_self), __pyx_v_path, __pyx_v_mode);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/misc/bgzf.pyx":22
+ * cdef class BGZFFile( object ):
+ *     cdef BGZF * bgzf
+ *     def __init__( self, path, mode="r" ):             # <<<<<<<<<<<<<<
+ *         self.bgzf = bgzf_open( path, mode )
+ *         if not self.bgzf:
+ */
+
+static int __pyx_pf_2bx_4misc_4bgzf_8BGZFFile___init__(struct __pyx_obj_2bx_4misc_4bgzf_BGZFFile *__pyx_v_self, PyObject *__pyx_v_path, PyObject *__pyx_v_mode) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  char *__pyx_t_1;
+  char *__pyx_t_2;
+  int __pyx_t_3;
+  PyObject *__pyx_t_4 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__init__", 0);
+
+  /* "bx/misc/bgzf.pyx":23
+ *     cdef BGZF * bgzf
+ *     def __init__( self, path, mode="r" ):
+ *         self.bgzf = bgzf_open( path, mode )             # <<<<<<<<<<<<<<
+ *         if not self.bgzf:
+ *             raise IOError( "Could not open file" )
+ */
+  __pyx_t_1 = PyBytes_AsString(__pyx_v_path); if (unlikely((!__pyx_t_1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 23; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyBytes_AsString(__pyx_v_mode); if (unlikely((!__pyx_t_2) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 23; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_v_self->bgzf = bgzf_open(__pyx_t_1, __pyx_t_2);
+
+  /* "bx/misc/bgzf.pyx":24
+ *     def __init__( self, path, mode="r" ):
+ *         self.bgzf = bgzf_open( path, mode )
+ *         if not self.bgzf:             # <<<<<<<<<<<<<<
+ *             raise IOError( "Could not open file" )
+ *     def close( self ):
+ */
+  __pyx_t_3 = (!(__pyx_v_self->bgzf != 0));
+  if (__pyx_t_3) {
+
+    /* "bx/misc/bgzf.pyx":25
+ *         self.bgzf = bgzf_open( path, mode )
+ *         if not self.bgzf:
+ *             raise IOError( "Could not open file" )             # <<<<<<<<<<<<<<
+ *     def close( self ):
+ *         if self.bgzf:
+ */
+    __pyx_t_4 = PyObject_Call(__pyx_builtin_IOError, ((PyObject *)__pyx_k_tuple_2), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 25; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    __Pyx_Raise(__pyx_t_4, 0, 0, 0);
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 25; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_AddTraceback("bx.misc.bgzf.BGZFFile.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = -1;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_4misc_4bgzf_8BGZFFile_3close(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static PyObject *__pyx_pw_2bx_4misc_4bgzf_8BGZFFile_3close(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("close (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_4misc_4bgzf_8BGZFFile_2close(((struct __pyx_obj_2bx_4misc_4bgzf_BGZFFile *)__pyx_v_self));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/misc/bgzf.pyx":26
+ *         if not self.bgzf:
+ *             raise IOError( "Could not open file" )
+ *     def close( self ):             # <<<<<<<<<<<<<<
+ *         if self.bgzf:
+ *             bgzf_close( self.bgzf )
+ */
+
+static PyObject *__pyx_pf_2bx_4misc_4bgzf_8BGZFFile_2close(struct __pyx_obj_2bx_4misc_4bgzf_BGZFFile *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("close", 0);
+
+  /* "bx/misc/bgzf.pyx":27
+ *             raise IOError( "Could not open file" )
+ *     def close( self ):
+ *         if self.bgzf:             # <<<<<<<<<<<<<<
+ *             bgzf_close( self.bgzf )
+ *     def read( self, int length ):
+ */
+  __pyx_t_1 = (__pyx_v_self->bgzf != 0);
+  if (__pyx_t_1) {
+
+    /* "bx/misc/bgzf.pyx":28
+ *     def close( self ):
+ *         if self.bgzf:
+ *             bgzf_close( self.bgzf )             # <<<<<<<<<<<<<<
+ *     def read( self, int length ):
+ *         cdef object rval = PyString_FromStringAndSize( NULL, length )
+ */
+    bgzf_close(__pyx_v_self->bgzf);
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_4misc_4bgzf_8BGZFFile_5read(PyObject *__pyx_v_self, PyObject *__pyx_arg_length); /*proto*/
+static PyObject *__pyx_pw_2bx_4misc_4bgzf_8BGZFFile_5read(PyObject *__pyx_v_self, PyObject *__pyx_arg_length) {
+  int __pyx_v_length;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("read (wrapper)", 0);
+  assert(__pyx_arg_length); {
+    __pyx_v_length = __Pyx_PyInt_AsInt(__pyx_arg_length); if (unlikely((__pyx_v_length == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 29; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.misc.bgzf.BGZFFile.read", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_4misc_4bgzf_8BGZFFile_4read(((struct __pyx_obj_2bx_4misc_4bgzf_BGZFFile *)__pyx_v_self), ((int)__pyx_v_length));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/misc/bgzf.pyx":29
+ *         if self.bgzf:
+ *             bgzf_close( self.bgzf )
+ *     def read( self, int length ):             # <<<<<<<<<<<<<<
+ *         cdef object rval = PyString_FromStringAndSize( NULL, length )
+ *         bgzf_read( self.bgzf, PyString_AsString( rval ), length )
+ */
+
+static PyObject *__pyx_pf_2bx_4misc_4bgzf_8BGZFFile_4read(struct __pyx_obj_2bx_4misc_4bgzf_BGZFFile *__pyx_v_self, int __pyx_v_length) {
+  PyObject *__pyx_v_rval = 0;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("read", 0);
+
+  /* "bx/misc/bgzf.pyx":30
+ *             bgzf_close( self.bgzf )
+ *     def read( self, int length ):
+ *         cdef object rval = PyString_FromStringAndSize( NULL, length )             # <<<<<<<<<<<<<<
+ *         bgzf_read( self.bgzf, PyString_AsString( rval ), length )
+ *         return rval
+ */
+  __pyx_t_1 = PyString_FromStringAndSize(NULL, __pyx_v_length); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 30; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_v_rval = __pyx_t_1;
+  __pyx_t_1 = 0;
+
+  /* "bx/misc/bgzf.pyx":31
+ *     def read( self, int length ):
+ *         cdef object rval = PyString_FromStringAndSize( NULL, length )
+ *         bgzf_read( self.bgzf, PyString_AsString( rval ), length )             # <<<<<<<<<<<<<<
+ *         return rval
+ *     def tell( self ):
+ */
+  bgzf_read(__pyx_v_self->bgzf, PyString_AsString(__pyx_v_rval), __pyx_v_length);
+
+  /* "bx/misc/bgzf.pyx":32
+ *         cdef object rval = PyString_FromStringAndSize( NULL, length )
+ *         bgzf_read( self.bgzf, PyString_AsString( rval ), length )
+ *         return rval             # <<<<<<<<<<<<<<
+ *     def tell( self ):
+ *         return bgzf_tell( self.bgzf )
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __Pyx_INCREF(__pyx_v_rval);
+  __pyx_r = __pyx_v_rval;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("bx.misc.bgzf.BGZFFile.read", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_rval);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_4misc_4bgzf_8BGZFFile_7tell(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static PyObject *__pyx_pw_2bx_4misc_4bgzf_8BGZFFile_7tell(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("tell (wrapper)", 0);
+  __pyx_r = __pyx_pf_2bx_4misc_4bgzf_8BGZFFile_6tell(((struct __pyx_obj_2bx_4misc_4bgzf_BGZFFile *)__pyx_v_self));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/misc/bgzf.pyx":33
+ *         bgzf_read( self.bgzf, PyString_AsString( rval ), length )
+ *         return rval
+ *     def tell( self ):             # <<<<<<<<<<<<<<
+ *         return bgzf_tell( self.bgzf )
+ *     def seek( self, int64_t pos, int where=0 ):
+ */
+
+static PyObject *__pyx_pf_2bx_4misc_4bgzf_8BGZFFile_6tell(struct __pyx_obj_2bx_4misc_4bgzf_BGZFFile *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("tell", 0);
+
+  /* "bx/misc/bgzf.pyx":34
+ *         return rval
+ *     def tell( self ):
+ *         return bgzf_tell( self.bgzf )             # <<<<<<<<<<<<<<
+ *     def seek( self, int64_t pos, int where=0 ):
+ *         return bgzf_seek( self.bgzf, pos, where )
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = PyLong_FromUnsignedLongLong(bgzf_tell(__pyx_v_self->bgzf)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 34; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("bx.misc.bgzf.BGZFFile.tell", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_4misc_4bgzf_8BGZFFile_9seek(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyObject *__pyx_pw_2bx_4misc_4bgzf_8BGZFFile_9seek(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  __pyx_t_2bx_4misc_4bgzf_int64_t __pyx_v_pos;
+  int __pyx_v_where;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("seek (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__pos,&__pyx_n_s__where,0};
+    PyObject* values[2] = {0,0};
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__pos)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s__where);
+          if (value) { values[1] = value; kw_args--; }
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "seek") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 35; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else {
+      switch (PyTuple_GET_SIZE(__pyx_args)) {
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+    }
+    __pyx_v_pos = __Pyx_PyInt_AsUnsignedLongLong(values[0]); if (unlikely((__pyx_v_pos == (unsigned PY_LONG_LONG)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 35; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    if (values[1]) {
+      __pyx_v_where = __Pyx_PyInt_AsInt(values[1]); if (unlikely((__pyx_v_where == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 35; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    } else {
+      __pyx_v_where = ((int)0);
+    }
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("seek", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 35; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.misc.bgzf.BGZFFile.seek", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_4misc_4bgzf_8BGZFFile_8seek(((struct __pyx_obj_2bx_4misc_4bgzf_BGZFFile *)__pyx_v_self), __pyx_v_pos, __pyx_v_where);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/misc/bgzf.pyx":35
+ *     def tell( self ):
+ *         return bgzf_tell( self.bgzf )
+ *     def seek( self, int64_t pos, int where=0 ):             # <<<<<<<<<<<<<<
+ *         return bgzf_seek( self.bgzf, pos, where )
+ */
+
+static PyObject *__pyx_pf_2bx_4misc_4bgzf_8BGZFFile_8seek(struct __pyx_obj_2bx_4misc_4bgzf_BGZFFile *__pyx_v_self, __pyx_t_2bx_4misc_4bgzf_int64_t __pyx_v_pos, int __pyx_v_where) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("seek", 0);
+
+  /* "bx/misc/bgzf.pyx":36
+ *         return bgzf_tell( self.bgzf )
+ *     def seek( self, int64_t pos, int where=0 ):
+ *         return bgzf_seek( self.bgzf, pos, where )             # <<<<<<<<<<<<<<
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = PyLong_FromUnsignedLongLong(bgzf_seek(__pyx_v_self->bgzf, __pyx_v_pos, __pyx_v_where)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 36; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("bx.misc.bgzf.BGZFFile.seek", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_tp_new_2bx_4misc_4bgzf_BGZFFile(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) {
+  PyObject *o = (*t->tp_alloc)(t, 0);
+  if (!o) return 0;
+  return o;
+}
+
+static void __pyx_tp_dealloc_2bx_4misc_4bgzf_BGZFFile(PyObject *o) {
+  (*Py_TYPE(o)->tp_free)(o);
+}
+
+static PyMethodDef __pyx_methods_2bx_4misc_4bgzf_BGZFFile[] = {
+  {__Pyx_NAMESTR("close"), (PyCFunction)__pyx_pw_2bx_4misc_4bgzf_8BGZFFile_3close, METH_NOARGS, __Pyx_DOCSTR(0)},
+  {__Pyx_NAMESTR("read"), (PyCFunction)__pyx_pw_2bx_4misc_4bgzf_8BGZFFile_5read, METH_O, __Pyx_DOCSTR(0)},
+  {__Pyx_NAMESTR("tell"), (PyCFunction)__pyx_pw_2bx_4misc_4bgzf_8BGZFFile_7tell, METH_NOARGS, __Pyx_DOCSTR(0)},
+  {__Pyx_NAMESTR("seek"), (PyCFunction)__pyx_pw_2bx_4misc_4bgzf_8BGZFFile_9seek, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(0)},
+  {0, 0, 0, 0}
+};
+
+static PyNumberMethods __pyx_tp_as_number_BGZFFile = {
+  0, /*nb_add*/
+  0, /*nb_subtract*/
+  0, /*nb_multiply*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_divide*/
+  #endif
+  0, /*nb_remainder*/
+  0, /*nb_divmod*/
+  0, /*nb_power*/
+  0, /*nb_negative*/
+  0, /*nb_positive*/
+  0, /*nb_absolute*/
+  0, /*nb_nonzero*/
+  0, /*nb_invert*/
+  0, /*nb_lshift*/
+  0, /*nb_rshift*/
+  0, /*nb_and*/
+  0, /*nb_xor*/
+  0, /*nb_or*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_coerce*/
+  #endif
+  0, /*nb_int*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_long*/
+  #else
+  0, /*reserved*/
+  #endif
+  0, /*nb_float*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_oct*/
+  #endif
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_hex*/
+  #endif
+  0, /*nb_inplace_add*/
+  0, /*nb_inplace_subtract*/
+  0, /*nb_inplace_multiply*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*nb_inplace_divide*/
+  #endif
+  0, /*nb_inplace_remainder*/
+  0, /*nb_inplace_power*/
+  0, /*nb_inplace_lshift*/
+  0, /*nb_inplace_rshift*/
+  0, /*nb_inplace_and*/
+  0, /*nb_inplace_xor*/
+  0, /*nb_inplace_or*/
+  0, /*nb_floor_divide*/
+  0, /*nb_true_divide*/
+  0, /*nb_inplace_floor_divide*/
+  0, /*nb_inplace_true_divide*/
+  #if PY_VERSION_HEX >= 0x02050000
+  0, /*nb_index*/
+  #endif
+};
+
+static PySequenceMethods __pyx_tp_as_sequence_BGZFFile = {
+  0, /*sq_length*/
+  0, /*sq_concat*/
+  0, /*sq_repeat*/
+  0, /*sq_item*/
+  0, /*sq_slice*/
+  0, /*sq_ass_item*/
+  0, /*sq_ass_slice*/
+  0, /*sq_contains*/
+  0, /*sq_inplace_concat*/
+  0, /*sq_inplace_repeat*/
+};
+
+static PyMappingMethods __pyx_tp_as_mapping_BGZFFile = {
+  0, /*mp_length*/
+  0, /*mp_subscript*/
+  0, /*mp_ass_subscript*/
+};
+
+static PyBufferProcs __pyx_tp_as_buffer_BGZFFile = {
+  #if PY_MAJOR_VERSION < 3
+  0, /*bf_getreadbuffer*/
+  #endif
+  #if PY_MAJOR_VERSION < 3
+  0, /*bf_getwritebuffer*/
+  #endif
+  #if PY_MAJOR_VERSION < 3
+  0, /*bf_getsegcount*/
+  #endif
+  #if PY_MAJOR_VERSION < 3
+  0, /*bf_getcharbuffer*/
+  #endif
+  #if PY_VERSION_HEX >= 0x02060000
+  0, /*bf_getbuffer*/
+  #endif
+  #if PY_VERSION_HEX >= 0x02060000
+  0, /*bf_releasebuffer*/
+  #endif
+};
+
+static PyTypeObject __pyx_type_2bx_4misc_4bgzf_BGZFFile = {
+  PyVarObject_HEAD_INIT(0, 0)
+  __Pyx_NAMESTR("bx.misc.bgzf.BGZFFile"), /*tp_name*/
+  sizeof(struct __pyx_obj_2bx_4misc_4bgzf_BGZFFile), /*tp_basicsize*/
+  0, /*tp_itemsize*/
+  __pyx_tp_dealloc_2bx_4misc_4bgzf_BGZFFile, /*tp_dealloc*/
+  0, /*tp_print*/
+  0, /*tp_getattr*/
+  0, /*tp_setattr*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*tp_compare*/
+  #else
+  0, /*reserved*/
+  #endif
+  0, /*tp_repr*/
+  &__pyx_tp_as_number_BGZFFile, /*tp_as_number*/
+  &__pyx_tp_as_sequence_BGZFFile, /*tp_as_sequence*/
+  &__pyx_tp_as_mapping_BGZFFile, /*tp_as_mapping*/
+  0, /*tp_hash*/
+  0, /*tp_call*/
+  0, /*tp_str*/
+  0, /*tp_getattro*/
+  0, /*tp_setattro*/
+  &__pyx_tp_as_buffer_BGZFFile, /*tp_as_buffer*/
+  Py_TPFLAGS_DEFAULT|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE, /*tp_flags*/
+  0, /*tp_doc*/
+  0, /*tp_traverse*/
+  0, /*tp_clear*/
+  0, /*tp_richcompare*/
+  0, /*tp_weaklistoffset*/
+  0, /*tp_iter*/
+  0, /*tp_iternext*/
+  __pyx_methods_2bx_4misc_4bgzf_BGZFFile, /*tp_methods*/
+  0, /*tp_members*/
+  0, /*tp_getset*/
+  0, /*tp_base*/
+  0, /*tp_dict*/
+  0, /*tp_descr_get*/
+  0, /*tp_descr_set*/
+  0, /*tp_dictoffset*/
+  __pyx_pw_2bx_4misc_4bgzf_8BGZFFile_1__init__, /*tp_init*/
+  0, /*tp_alloc*/
+  __pyx_tp_new_2bx_4misc_4bgzf_BGZFFile, /*tp_new*/
+  0, /*tp_free*/
+  0, /*tp_is_gc*/
+  0, /*tp_bases*/
+  0, /*tp_mro*/
+  0, /*tp_cache*/
+  0, /*tp_subclasses*/
+  0, /*tp_weaklist*/
+  0, /*tp_del*/
+  #if PY_VERSION_HEX >= 0x02060000
+  0, /*tp_version_tag*/
+  #endif
+};
+
+static PyMethodDef __pyx_methods[] = {
+  {0, 0, 0, 0}
+};
+
+#if PY_MAJOR_VERSION >= 3
+static struct PyModuleDef __pyx_moduledef = {
+  #if PY_VERSION_HEX < 0x03020000
+    { PyObject_HEAD_INIT(NULL) NULL, 0, NULL },
+  #else
+    PyModuleDef_HEAD_INIT,
+  #endif
+    __Pyx_NAMESTR("bgzf"),
+    __Pyx_DOCSTR(__pyx_k_3), /* m_doc */
+    -1, /* m_size */
+    __pyx_methods /* m_methods */,
+    NULL, /* m_reload */
+    NULL, /* m_traverse */
+    NULL, /* m_clear */
+    NULL /* m_free */
+};
+#endif
+
+static __Pyx_StringTabEntry __pyx_string_tab[] = {
+  {&__pyx_kp_s_1, __pyx_k_1, sizeof(__pyx_k_1), 0, 0, 1, 0},
+  {&__pyx_n_s__IOError, __pyx_k__IOError, sizeof(__pyx_k__IOError), 0, 0, 1, 1},
+  {&__pyx_n_s____main__, __pyx_k____main__, sizeof(__pyx_k____main__), 0, 0, 1, 1},
+  {&__pyx_n_s____test__, __pyx_k____test__, sizeof(__pyx_k____test__), 0, 0, 1, 1},
+  {&__pyx_n_s__mode, __pyx_k__mode, sizeof(__pyx_k__mode), 0, 0, 1, 1},
+  {&__pyx_n_s__path, __pyx_k__path, sizeof(__pyx_k__path), 0, 0, 1, 1},
+  {&__pyx_n_s__pos, __pyx_k__pos, sizeof(__pyx_k__pos), 0, 0, 1, 1},
+  {&__pyx_n_s__r, __pyx_k__r, sizeof(__pyx_k__r), 0, 0, 1, 1},
+  {&__pyx_n_s__where, __pyx_k__where, sizeof(__pyx_k__where), 0, 0, 1, 1},
+  {0, 0, 0, 0, 0, 0, 0}
+};
+static int __Pyx_InitCachedBuiltins(void) {
+  __pyx_builtin_IOError = __Pyx_GetName(__pyx_b, __pyx_n_s__IOError); if (!__pyx_builtin_IOError) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 25; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  return 0;
+  __pyx_L1_error:;
+  return -1;
+}
+
+static int __Pyx_InitCachedConstants(void) {
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0);
+
+  /* "bx/misc/bgzf.pyx":25
+ *         self.bgzf = bgzf_open( path, mode )
+ *         if not self.bgzf:
+ *             raise IOError( "Could not open file" )             # <<<<<<<<<<<<<<
+ *     def close( self ):
+ *         if self.bgzf:
+ */
+  __pyx_k_tuple_2 = PyTuple_Pack(1, ((PyObject *)__pyx_kp_s_1)); if (unlikely(!__pyx_k_tuple_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 25; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_k_tuple_2);
+  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_2));
+  __Pyx_RefNannyFinishContext();
+  return 0;
+  __pyx_L1_error:;
+  __Pyx_RefNannyFinishContext();
+  return -1;
+}
+
+static int __Pyx_InitGlobals(void) {
+  if (__Pyx_InitStrings(__pyx_string_tab) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  return 0;
+  __pyx_L1_error:;
+  return -1;
+}
+
+#if PY_MAJOR_VERSION < 3
+PyMODINIT_FUNC initbgzf(void); /*proto*/
+PyMODINIT_FUNC initbgzf(void)
+#else
+PyMODINIT_FUNC PyInit_bgzf(void); /*proto*/
+PyMODINIT_FUNC PyInit_bgzf(void)
+#endif
+{
+  PyObject *__pyx_t_1 = NULL;
+  __Pyx_RefNannyDeclarations
+  #if CYTHON_REFNANNY
+  __Pyx_RefNanny = __Pyx_RefNannyImportAPI("refnanny");
+  if (!__Pyx_RefNanny) {
+      PyErr_Clear();
+      __Pyx_RefNanny = __Pyx_RefNannyImportAPI("Cython.Runtime.refnanny");
+      if (!__Pyx_RefNanny)
+          Py_FatalError("failed to import 'refnanny' module");
+  }
+  #endif
+  __Pyx_RefNannySetupContext("PyMODINIT_FUNC PyInit_bgzf(void)", 0);
+  if ( __Pyx_check_binary_version() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_bytes)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #ifdef __Pyx_CyFunction_USED
+  if (__Pyx_CyFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #endif
+  #ifdef __Pyx_FusedFunction_USED
+  if (__pyx_FusedFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #endif
+  #ifdef __Pyx_Generator_USED
+  if (__pyx_Generator_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #endif
+  /*--- Library function declarations ---*/
+  /*--- Threads initialization code ---*/
+  #if defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS
+  #ifdef WITH_THREAD /* Python build with threading support? */
+  PyEval_InitThreads();
+  #endif
+  #endif
+  /*--- Module creation code ---*/
+  #if PY_MAJOR_VERSION < 3
+  __pyx_m = Py_InitModule4(__Pyx_NAMESTR("bgzf"), __pyx_methods, __Pyx_DOCSTR(__pyx_k_3), 0, PYTHON_API_VERSION); Py_XINCREF(__pyx_m);
+  #else
+  __pyx_m = PyModule_Create(&__pyx_moduledef);
+  #endif
+  if (unlikely(!__pyx_m)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #if PY_MAJOR_VERSION >= 3
+  {
+    PyObject *modules = PyImport_GetModuleDict(); if (unlikely(!modules)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (!PyDict_GetItemString(modules, "bx.misc.bgzf")) {
+      if (unlikely(PyDict_SetItemString(modules, "bx.misc.bgzf", __pyx_m) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+  }
+  #endif
+  __pyx_b = PyImport_AddModule(__Pyx_NAMESTR(__Pyx_BUILTIN_MODULE_NAME)); if (unlikely(!__pyx_b)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #if CYTHON_COMPILING_IN_PYPY
+  Py_INCREF(__pyx_b);
+  #endif
+  if (__Pyx_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  /*--- Initialize various global constants etc. ---*/
+  if (unlikely(__Pyx_InitGlobals() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (__pyx_module_is_main_bx__misc__bgzf) {
+    if (__Pyx_SetAttrString(__pyx_m, "__name__", __pyx_n_s____main__) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  }
+  /*--- Builtin init code ---*/
+  if (unlikely(__Pyx_InitCachedBuiltins() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  /*--- Constants init code ---*/
+  if (unlikely(__Pyx_InitCachedConstants() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  /*--- Global init code ---*/
+  /*--- Variable export code ---*/
+  /*--- Function export code ---*/
+  /*--- Type init code ---*/
+  if (PyType_Ready(&__pyx_type_2bx_4misc_4bgzf_BGZFFile) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 20; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (__Pyx_SetAttrString(__pyx_m, "BGZFFile", (PyObject *)&__pyx_type_2bx_4misc_4bgzf_BGZFFile) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 20; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_2bx_4misc_4bgzf_BGZFFile = &__pyx_type_2bx_4misc_4bgzf_BGZFFile;
+  /*--- Type import code ---*/
+  /*--- Variable import code ---*/
+  /*--- Function import code ---*/
+  /*--- Execution code ---*/
+
+  /* "bx/misc/bgzf.pyx":1
+ * """             # <<<<<<<<<<<<<<
+ * Seekable access to BGZ files based on samtools code. Does not yet implement
+ * complete file-like interface.
+ */
+  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(((PyObject *)__pyx_t_1));
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s____test__, ((PyObject *)__pyx_t_1)) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  if (__pyx_m) {
+    __Pyx_AddTraceback("init bx.misc.bgzf", __pyx_clineno, __pyx_lineno, __pyx_filename);
+    Py_DECREF(__pyx_m); __pyx_m = 0;
+  } else if (!PyErr_Occurred()) {
+    PyErr_SetString(PyExc_ImportError, "init bx.misc.bgzf");
+  }
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  #if PY_MAJOR_VERSION < 3
+  return;
+  #else
+  return __pyx_m;
+  #endif
+}
+
+/* Runtime support code */
+#if CYTHON_REFNANNY
+static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) {
+    PyObject *m = NULL, *p = NULL;
+    void *r = NULL;
+    m = PyImport_ImportModule((char *)modname);
+    if (!m) goto end;
+    p = PyObject_GetAttrString(m, (char *)"RefNannyAPI");
+    if (!p) goto end;
+    r = PyLong_AsVoidPtr(p);
+end:
+    Py_XDECREF(p);
+    Py_XDECREF(m);
+    return (__Pyx_RefNannyAPIStruct *)r;
+}
+#endif /* CYTHON_REFNANNY */
+
+static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name) {
+    PyObject *result;
+    result = PyObject_GetAttr(dict, name);
+    if (!result) {
+        if (dict != __pyx_b) {
+            PyErr_Clear();
+            result = PyObject_GetAttr(__pyx_b, name);
+        }
+        if (!result) {
+            PyErr_SetObject(PyExc_NameError, name);
+        }
+    }
+    return result;
+}
+
+static void __Pyx_RaiseDoubleKeywordsError(
+    const char* func_name,
+    PyObject* kw_name)
+{
+    PyErr_Format(PyExc_TypeError,
+        #if PY_MAJOR_VERSION >= 3
+        "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
+        #else
+        "%s() got multiple values for keyword argument '%s'", func_name,
+        PyString_AsString(kw_name));
+        #endif
+}
+
+static int __Pyx_ParseOptionalKeywords(
+    PyObject *kwds,
+    PyObject **argnames[],
+    PyObject *kwds2,
+    PyObject *values[],
+    Py_ssize_t num_pos_args,
+    const char* function_name)
+{
+    PyObject *key = 0, *value = 0;
+    Py_ssize_t pos = 0;
+    PyObject*** name;
+    PyObject*** first_kw_arg = argnames + num_pos_args;
+    while (PyDict_Next(kwds, &pos, &key, &value)) {
+        name = first_kw_arg;
+        while (*name && (**name != key)) name++;
+        if (*name) {
+            values[name-argnames] = value;
+            continue;
+        }
+        name = first_kw_arg;
+        #if PY_MAJOR_VERSION < 3
+        if (likely(PyString_CheckExact(key)) || likely(PyString_Check(key))) {
+            while (*name) {
+                if ((CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**name) == PyString_GET_SIZE(key))
+                        && _PyString_Eq(**name, key)) {
+                    values[name-argnames] = value;
+                    break;
+                }
+                name++;
+            }
+            if (*name) continue;
+            else {
+                PyObject*** argname = argnames;
+                while (argname != first_kw_arg) {
+                    if ((**argname == key) || (
+                            (CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**argname) == PyString_GET_SIZE(key))
+                             && _PyString_Eq(**argname, key))) {
+                        goto arg_passed_twice;
+                    }
+                    argname++;
+                }
+            }
+        } else
+        #endif
+        if (likely(PyUnicode_Check(key))) {
+            while (*name) {
+                int cmp = (**name == key) ? 0 :
+                #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3
+                    (PyUnicode_GET_SIZE(**name) != PyUnicode_GET_SIZE(key)) ? 1 :
+                #endif
+                    PyUnicode_Compare(**name, key);
+                if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad;
+                if (cmp == 0) {
+                    values[name-argnames] = value;
+                    break;
+                }
+                name++;
+            }
+            if (*name) continue;
+            else {
+                PyObject*** argname = argnames;
+                while (argname != first_kw_arg) {
+                    int cmp = (**argname == key) ? 0 :
+                    #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3
+                        (PyUnicode_GET_SIZE(**argname) != PyUnicode_GET_SIZE(key)) ? 1 :
+                    #endif
+                        PyUnicode_Compare(**argname, key);
+                    if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad;
+                    if (cmp == 0) goto arg_passed_twice;
+                    argname++;
+                }
+            }
+        } else
+            goto invalid_keyword_type;
+        if (kwds2) {
+            if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
+        } else {
+            goto invalid_keyword;
+        }
+    }
+    return 0;
+arg_passed_twice:
+    __Pyx_RaiseDoubleKeywordsError(function_name, key);
+    goto bad;
+invalid_keyword_type:
+    PyErr_Format(PyExc_TypeError,
+        "%s() keywords must be strings", function_name);
+    goto bad;
+invalid_keyword:
+    PyErr_Format(PyExc_TypeError,
+    #if PY_MAJOR_VERSION < 3
+        "%s() got an unexpected keyword argument '%s'",
+        function_name, PyString_AsString(key));
+    #else
+        "%s() got an unexpected keyword argument '%U'",
+        function_name, key);
+    #endif
+bad:
+    return -1;
+}
+
+static void __Pyx_RaiseArgtupleInvalid(
+    const char* func_name,
+    int exact,
+    Py_ssize_t num_min,
+    Py_ssize_t num_max,
+    Py_ssize_t num_found)
+{
+    Py_ssize_t num_expected;
+    const char *more_or_less;
+    if (num_found < num_min) {
+        num_expected = num_min;
+        more_or_less = "at least";
+    } else {
+        num_expected = num_max;
+        more_or_less = "at most";
+    }
+    if (exact) {
+        more_or_less = "exactly";
+    }
+    PyErr_Format(PyExc_TypeError,
+                 "%s() takes %s %" CYTHON_FORMAT_SSIZE_T "d positional argument%s (%" CYTHON_FORMAT_SSIZE_T "d given)",
+                 func_name, more_or_less, num_expected,
+                 (num_expected == 1) ? "" : "s", num_found);
+}
+
+static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    PyObject *tmp_type, *tmp_value, *tmp_tb;
+    PyThreadState *tstate = PyThreadState_GET();
+    tmp_type = tstate->curexc_type;
+    tmp_value = tstate->curexc_value;
+    tmp_tb = tstate->curexc_traceback;
+    tstate->curexc_type = type;
+    tstate->curexc_value = value;
+    tstate->curexc_traceback = tb;
+    Py_XDECREF(tmp_type);
+    Py_XDECREF(tmp_value);
+    Py_XDECREF(tmp_tb);
+#else
+    PyErr_Restore(type, value, tb);
+#endif
+}
+static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    PyThreadState *tstate = PyThreadState_GET();
+    *type = tstate->curexc_type;
+    *value = tstate->curexc_value;
+    *tb = tstate->curexc_traceback;
+    tstate->curexc_type = 0;
+    tstate->curexc_value = 0;
+    tstate->curexc_traceback = 0;
+#else
+    PyErr_Fetch(type, value, tb);
+#endif
+}
+
+#if PY_MAJOR_VERSION < 3
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb,
+                        CYTHON_UNUSED PyObject *cause) {
+    Py_XINCREF(type);
+    if (!value || value == Py_None)
+        value = NULL;
+    else
+        Py_INCREF(value);
+    if (!tb || tb == Py_None)
+        tb = NULL;
+    else {
+        Py_INCREF(tb);
+        if (!PyTraceBack_Check(tb)) {
+            PyErr_SetString(PyExc_TypeError,
+                "raise: arg 3 must be a traceback or None");
+            goto raise_error;
+        }
+    }
+    #if PY_VERSION_HEX < 0x02050000
+    if (PyClass_Check(type)) {
+    #else
+    if (PyType_Check(type)) {
+    #endif
+#if CYTHON_COMPILING_IN_PYPY
+        if (!value) {
+            Py_INCREF(Py_None);
+            value = Py_None;
+        }
+#endif
+        PyErr_NormalizeException(&type, &value, &tb);
+    } else {
+        if (value) {
+            PyErr_SetString(PyExc_TypeError,
+                "instance exception may not have a separate value");
+            goto raise_error;
+        }
+        value = type;
+        #if PY_VERSION_HEX < 0x02050000
+            if (PyInstance_Check(type)) {
+                type = (PyObject*) ((PyInstanceObject*)type)->in_class;
+                Py_INCREF(type);
+            }
+            else {
+                type = 0;
+                PyErr_SetString(PyExc_TypeError,
+                    "raise: exception must be an old-style class or instance");
+                goto raise_error;
+            }
+        #else
+            type = (PyObject*) Py_TYPE(type);
+            Py_INCREF(type);
+            if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
+                PyErr_SetString(PyExc_TypeError,
+                    "raise: exception class must be a subclass of BaseException");
+                goto raise_error;
+            }
+        #endif
+    }
+    __Pyx_ErrRestore(type, value, tb);
+    return;
+raise_error:
+    Py_XDECREF(value);
+    Py_XDECREF(type);
+    Py_XDECREF(tb);
+    return;
+}
+#else /* Python 3+ */
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause) {
+    PyObject* owned_instance = NULL;
+    if (tb == Py_None) {
+        tb = 0;
+    } else if (tb && !PyTraceBack_Check(tb)) {
+        PyErr_SetString(PyExc_TypeError,
+            "raise: arg 3 must be a traceback or None");
+        goto bad;
+    }
+    if (value == Py_None)
+        value = 0;
+    if (PyExceptionInstance_Check(type)) {
+        if (value) {
+            PyErr_SetString(PyExc_TypeError,
+                "instance exception may not have a separate value");
+            goto bad;
+        }
+        value = type;
+        type = (PyObject*) Py_TYPE(value);
+    } else if (PyExceptionClass_Check(type)) {
+        PyObject *args;
+        if (!value)
+            args = PyTuple_New(0);
+        else if (PyTuple_Check(value)) {
+            Py_INCREF(value);
+            args = value;
+        }
+        else
+            args = PyTuple_Pack(1, value);
+        if (!args)
+            goto bad;
+        owned_instance = PyEval_CallObject(type, args);
+        Py_DECREF(args);
+        if (!owned_instance)
+            goto bad;
+        value = owned_instance;
+        if (!PyExceptionInstance_Check(value)) {
+            PyErr_Format(PyExc_TypeError,
+                         "calling %R should have returned an instance of "
+                         "BaseException, not %R",
+                         type, Py_TYPE(value));
+            goto bad;
+        }
+    } else {
+        PyErr_SetString(PyExc_TypeError,
+            "raise: exception class must be a subclass of BaseException");
+        goto bad;
+    }
+    if (cause && cause != Py_None) {
+        PyObject *fixed_cause;
+        if (PyExceptionClass_Check(cause)) {
+            fixed_cause = PyObject_CallObject(cause, NULL);
+            if (fixed_cause == NULL)
+                goto bad;
+        }
+        else if (PyExceptionInstance_Check(cause)) {
+            fixed_cause = cause;
+            Py_INCREF(fixed_cause);
+        }
+        else {
+            PyErr_SetString(PyExc_TypeError,
+                            "exception causes must derive from "
+                            "BaseException");
+            goto bad;
+        }
+        PyException_SetCause(value, fixed_cause);
+    }
+    PyErr_SetObject(type, value);
+    if (tb) {
+        PyThreadState *tstate = PyThreadState_GET();
+        PyObject* tmp_tb = tstate->curexc_traceback;
+        if (tb != tmp_tb) {
+            Py_INCREF(tb);
+            tstate->curexc_traceback = tb;
+            Py_XDECREF(tmp_tb);
+        }
+    }
+bad:
+    Py_XDECREF(owned_instance);
+    return;
+}
+#endif
+
+static CYTHON_INLINE unsigned char __Pyx_PyInt_AsUnsignedChar(PyObject* x) {
+    const unsigned char neg_one = (unsigned char)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(unsigned char) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(unsigned char)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to unsigned char" :
+                    "value too large to convert to unsigned char");
+            }
+            return (unsigned char)-1;
+        }
+        return (unsigned char)val;
+    }
+    return (unsigned char)__Pyx_PyInt_AsUnsignedLong(x);
+}
+
+static CYTHON_INLINE unsigned short __Pyx_PyInt_AsUnsignedShort(PyObject* x) {
+    const unsigned short neg_one = (unsigned short)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(unsigned short) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(unsigned short)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to unsigned short" :
+                    "value too large to convert to unsigned short");
+            }
+            return (unsigned short)-1;
+        }
+        return (unsigned short)val;
+    }
+    return (unsigned short)__Pyx_PyInt_AsUnsignedLong(x);
+}
+
+static CYTHON_INLINE unsigned int __Pyx_PyInt_AsUnsignedInt(PyObject* x) {
+    const unsigned int neg_one = (unsigned int)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(unsigned int) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(unsigned int)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to unsigned int" :
+                    "value too large to convert to unsigned int");
+            }
+            return (unsigned int)-1;
+        }
+        return (unsigned int)val;
+    }
+    return (unsigned int)__Pyx_PyInt_AsUnsignedLong(x);
+}
+
+static CYTHON_INLINE char __Pyx_PyInt_AsChar(PyObject* x) {
+    const char neg_one = (char)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(char) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(char)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to char" :
+                    "value too large to convert to char");
+            }
+            return (char)-1;
+        }
+        return (char)val;
+    }
+    return (char)__Pyx_PyInt_AsLong(x);
+}
+
+static CYTHON_INLINE short __Pyx_PyInt_AsShort(PyObject* x) {
+    const short neg_one = (short)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(short) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(short)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to short" :
+                    "value too large to convert to short");
+            }
+            return (short)-1;
+        }
+        return (short)val;
+    }
+    return (short)__Pyx_PyInt_AsLong(x);
+}
+
+static CYTHON_INLINE int __Pyx_PyInt_AsInt(PyObject* x) {
+    const int neg_one = (int)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(int) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(int)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to int" :
+                    "value too large to convert to int");
+            }
+            return (int)-1;
+        }
+        return (int)val;
+    }
+    return (int)__Pyx_PyInt_AsLong(x);
+}
+
+static CYTHON_INLINE signed char __Pyx_PyInt_AsSignedChar(PyObject* x) {
+    const signed char neg_one = (signed char)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(signed char) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(signed char)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to signed char" :
+                    "value too large to convert to signed char");
+            }
+            return (signed char)-1;
+        }
+        return (signed char)val;
+    }
+    return (signed char)__Pyx_PyInt_AsSignedLong(x);
+}
+
+static CYTHON_INLINE signed short __Pyx_PyInt_AsSignedShort(PyObject* x) {
+    const signed short neg_one = (signed short)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(signed short) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(signed short)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to signed short" :
+                    "value too large to convert to signed short");
+            }
+            return (signed short)-1;
+        }
+        return (signed short)val;
+    }
+    return (signed short)__Pyx_PyInt_AsSignedLong(x);
+}
+
+static CYTHON_INLINE signed int __Pyx_PyInt_AsSignedInt(PyObject* x) {
+    const signed int neg_one = (signed int)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(signed int) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(signed int)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to signed int" :
+                    "value too large to convert to signed int");
+            }
+            return (signed int)-1;
+        }
+        return (signed int)val;
+    }
+    return (signed int)__Pyx_PyInt_AsSignedLong(x);
+}
+
+static CYTHON_INLINE int __Pyx_PyInt_AsLongDouble(PyObject* x) {
+    const int neg_one = (int)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(int) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(int)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to int" :
+                    "value too large to convert to int");
+            }
+            return (int)-1;
+        }
+        return (int)val;
+    }
+    return (int)__Pyx_PyInt_AsLong(x);
+}
+
+static CYTHON_INLINE unsigned long __Pyx_PyInt_AsUnsignedLong(PyObject* x) {
+    const unsigned long neg_one = (unsigned long)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to unsigned long");
+            return (unsigned long)-1;
+        }
+        return (unsigned long)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to unsigned long");
+                return (unsigned long)-1;
+            }
+            return (unsigned long)PyLong_AsUnsignedLong(x);
+        } else {
+            return (unsigned long)PyLong_AsLong(x);
+        }
+    } else {
+        unsigned long val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (unsigned long)-1;
+        val = __Pyx_PyInt_AsUnsignedLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE unsigned PY_LONG_LONG __Pyx_PyInt_AsUnsignedLongLong(PyObject* x) {
+    const unsigned PY_LONG_LONG neg_one = (unsigned PY_LONG_LONG)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to unsigned PY_LONG_LONG");
+            return (unsigned PY_LONG_LONG)-1;
+        }
+        return (unsigned PY_LONG_LONG)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to unsigned PY_LONG_LONG");
+                return (unsigned PY_LONG_LONG)-1;
+            }
+            return (unsigned PY_LONG_LONG)PyLong_AsUnsignedLongLong(x);
+        } else {
+            return (unsigned PY_LONG_LONG)PyLong_AsLongLong(x);
+        }
+    } else {
+        unsigned PY_LONG_LONG val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (unsigned PY_LONG_LONG)-1;
+        val = __Pyx_PyInt_AsUnsignedLongLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE long __Pyx_PyInt_AsLong(PyObject* x) {
+    const long neg_one = (long)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to long");
+            return (long)-1;
+        }
+        return (long)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to long");
+                return (long)-1;
+            }
+            return (long)PyLong_AsUnsignedLong(x);
+        } else {
+            return (long)PyLong_AsLong(x);
+        }
+    } else {
+        long val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (long)-1;
+        val = __Pyx_PyInt_AsLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE PY_LONG_LONG __Pyx_PyInt_AsLongLong(PyObject* x) {
+    const PY_LONG_LONG neg_one = (PY_LONG_LONG)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to PY_LONG_LONG");
+            return (PY_LONG_LONG)-1;
+        }
+        return (PY_LONG_LONG)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to PY_LONG_LONG");
+                return (PY_LONG_LONG)-1;
+            }
+            return (PY_LONG_LONG)PyLong_AsUnsignedLongLong(x);
+        } else {
+            return (PY_LONG_LONG)PyLong_AsLongLong(x);
+        }
+    } else {
+        PY_LONG_LONG val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (PY_LONG_LONG)-1;
+        val = __Pyx_PyInt_AsLongLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE signed long __Pyx_PyInt_AsSignedLong(PyObject* x) {
+    const signed long neg_one = (signed long)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to signed long");
+            return (signed long)-1;
+        }
+        return (signed long)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to signed long");
+                return (signed long)-1;
+            }
+            return (signed long)PyLong_AsUnsignedLong(x);
+        } else {
+            return (signed long)PyLong_AsLong(x);
+        }
+    } else {
+        signed long val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (signed long)-1;
+        val = __Pyx_PyInt_AsSignedLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE signed PY_LONG_LONG __Pyx_PyInt_AsSignedLongLong(PyObject* x) {
+    const signed PY_LONG_LONG neg_one = (signed PY_LONG_LONG)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to signed PY_LONG_LONG");
+            return (signed PY_LONG_LONG)-1;
+        }
+        return (signed PY_LONG_LONG)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to signed PY_LONG_LONG");
+                return (signed PY_LONG_LONG)-1;
+            }
+            return (signed PY_LONG_LONG)PyLong_AsUnsignedLongLong(x);
+        } else {
+            return (signed PY_LONG_LONG)PyLong_AsLongLong(x);
+        }
+    } else {
+        signed PY_LONG_LONG val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (signed PY_LONG_LONG)-1;
+        val = __Pyx_PyInt_AsSignedLongLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static int __Pyx_check_binary_version(void) {
+    char ctversion[4], rtversion[4];
+    PyOS_snprintf(ctversion, 4, "%d.%d", PY_MAJOR_VERSION, PY_MINOR_VERSION);
+    PyOS_snprintf(rtversion, 4, "%s", Py_GetVersion());
+    if (ctversion[0] != rtversion[0] || ctversion[2] != rtversion[2]) {
+        char message[200];
+        PyOS_snprintf(message, sizeof(message),
+                      "compiletime version %s of module '%.100s' "
+                      "does not match runtime version %s",
+                      ctversion, __Pyx_MODULE_NAME, rtversion);
+        #if PY_VERSION_HEX < 0x02050000
+        return PyErr_Warn(NULL, message);
+        #else
+        return PyErr_WarnEx(NULL, message, 1);
+        #endif
+    }
+    return 0;
+}
+
+static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) {
+    int start = 0, mid = 0, end = count - 1;
+    if (end >= 0 && code_line > entries[end].code_line) {
+        return count;
+    }
+    while (start < end) {
+        mid = (start + end) / 2;
+        if (code_line < entries[mid].code_line) {
+            end = mid;
+        } else if (code_line > entries[mid].code_line) {
+             start = mid + 1;
+        } else {
+            return mid;
+        }
+    }
+    if (code_line <= entries[mid].code_line) {
+        return mid;
+    } else {
+        return mid + 1;
+    }
+}
+static PyCodeObject *__pyx_find_code_object(int code_line) {
+    PyCodeObject* code_object;
+    int pos;
+    if (unlikely(!code_line) || unlikely(!__pyx_code_cache.entries)) {
+        return NULL;
+    }
+    pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line);
+    if (unlikely(pos >= __pyx_code_cache.count) || unlikely(__pyx_code_cache.entries[pos].code_line != code_line)) {
+        return NULL;
+    }
+    code_object = __pyx_code_cache.entries[pos].code_object;
+    Py_INCREF(code_object);
+    return code_object;
+}
+static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) {
+    int pos, i;
+    __Pyx_CodeObjectCacheEntry* entries = __pyx_code_cache.entries;
+    if (unlikely(!code_line)) {
+        return;
+    }
+    if (unlikely(!entries)) {
+        entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Malloc(64*sizeof(__Pyx_CodeObjectCacheEntry));
+        if (likely(entries)) {
+            __pyx_code_cache.entries = entries;
+            __pyx_code_cache.max_count = 64;
+            __pyx_code_cache.count = 1;
+            entries[0].code_line = code_line;
+            entries[0].code_object = code_object;
+            Py_INCREF(code_object);
+        }
+        return;
+    }
+    pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line);
+    if ((pos < __pyx_code_cache.count) && unlikely(__pyx_code_cache.entries[pos].code_line == code_line)) {
+        PyCodeObject* tmp = entries[pos].code_object;
+        entries[pos].code_object = code_object;
+        Py_DECREF(tmp);
+        return;
+    }
+    if (__pyx_code_cache.count == __pyx_code_cache.max_count) {
+        int new_max = __pyx_code_cache.max_count + 64;
+        entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Realloc(
+            __pyx_code_cache.entries, new_max*sizeof(__Pyx_CodeObjectCacheEntry));
+        if (unlikely(!entries)) {
+            return;
+        }
+        __pyx_code_cache.entries = entries;
+        __pyx_code_cache.max_count = new_max;
+    }
+    for (i=__pyx_code_cache.count; i>pos; i--) {
+        entries[i] = entries[i-1];
+    }
+    entries[pos].code_line = code_line;
+    entries[pos].code_object = code_object;
+    __pyx_code_cache.count++;
+    Py_INCREF(code_object);
+}
+
+#include "compile.h"
+#include "frameobject.h"
+#include "traceback.h"
+static PyCodeObject* __Pyx_CreateCodeObjectForTraceback(
+            const char *funcname, int c_line,
+            int py_line, const char *filename) {
+    PyCodeObject *py_code = 0;
+    PyObject *py_srcfile = 0;
+    PyObject *py_funcname = 0;
+    #if PY_MAJOR_VERSION < 3
+    py_srcfile = PyString_FromString(filename);
+    #else
+    py_srcfile = PyUnicode_FromString(filename);
+    #endif
+    if (!py_srcfile) goto bad;
+    if (c_line) {
+        #if PY_MAJOR_VERSION < 3
+        py_funcname = PyString_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line);
+        #else
+        py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line);
+        #endif
+    }
+    else {
+        #if PY_MAJOR_VERSION < 3
+        py_funcname = PyString_FromString(funcname);
+        #else
+        py_funcname = PyUnicode_FromString(funcname);
+        #endif
+    }
+    if (!py_funcname) goto bad;
+    py_code = __Pyx_PyCode_New(
+        0,            /*int argcount,*/
+        0,            /*int kwonlyargcount,*/
+        0,            /*int nlocals,*/
+        0,            /*int stacksize,*/
+        0,            /*int flags,*/
+        __pyx_empty_bytes, /*PyObject *code,*/
+        __pyx_empty_tuple, /*PyObject *consts,*/
+        __pyx_empty_tuple, /*PyObject *names,*/
+        __pyx_empty_tuple, /*PyObject *varnames,*/
+        __pyx_empty_tuple, /*PyObject *freevars,*/
+        __pyx_empty_tuple, /*PyObject *cellvars,*/
+        py_srcfile,   /*PyObject *filename,*/
+        py_funcname,  /*PyObject *name,*/
+        py_line,      /*int firstlineno,*/
+        __pyx_empty_bytes  /*PyObject *lnotab*/
+    );
+    Py_DECREF(py_srcfile);
+    Py_DECREF(py_funcname);
+    return py_code;
+bad:
+    Py_XDECREF(py_srcfile);
+    Py_XDECREF(py_funcname);
+    return NULL;
+}
+static void __Pyx_AddTraceback(const char *funcname, int c_line,
+                               int py_line, const char *filename) {
+    PyCodeObject *py_code = 0;
+    PyObject *py_globals = 0;
+    PyFrameObject *py_frame = 0;
+    py_code = __pyx_find_code_object(c_line ? c_line : py_line);
+    if (!py_code) {
+        py_code = __Pyx_CreateCodeObjectForTraceback(
+            funcname, c_line, py_line, filename);
+        if (!py_code) goto bad;
+        __pyx_insert_code_object(c_line ? c_line : py_line, py_code);
+    }
+    py_globals = PyModule_GetDict(__pyx_m);
+    if (!py_globals) goto bad;
+    py_frame = PyFrame_New(
+        PyThreadState_GET(), /*PyThreadState *tstate,*/
+        py_code,             /*PyCodeObject *code,*/
+        py_globals,          /*PyObject *globals,*/
+        0                    /*PyObject *locals*/
+    );
+    if (!py_frame) goto bad;
+    py_frame->f_lineno = py_line;
+    PyTraceBack_Here(py_frame);
+bad:
+    Py_XDECREF(py_code);
+    Py_XDECREF(py_frame);
+}
+
+static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
+    while (t->p) {
+        #if PY_MAJOR_VERSION < 3
+        if (t->is_unicode) {
+            *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
+        } else if (t->intern) {
+            *t->p = PyString_InternFromString(t->s);
+        } else {
+            *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
+        }
+        #else  /* Python 3+ has unicode identifiers */
+        if (t->is_unicode | t->is_str) {
+            if (t->intern) {
+                *t->p = PyUnicode_InternFromString(t->s);
+            } else if (t->encoding) {
+                *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL);
+            } else {
+                *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
+            }
+        } else {
+            *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
+        }
+        #endif
+        if (!*t->p)
+            return -1;
+        ++t;
+    }
+    return 0;
+}
+
+static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) {
+   int is_true = x == Py_True;
+   if (is_true | (x == Py_False) | (x == Py_None)) return is_true;
+   else return PyObject_IsTrue(x);
+}
+static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x) {
+  PyNumberMethods *m;
+  const char *name = NULL;
+  PyObject *res = NULL;
+#if PY_VERSION_HEX < 0x03000000
+  if (PyInt_Check(x) || PyLong_Check(x))
+#else
+  if (PyLong_Check(x))
+#endif
+    return Py_INCREF(x), x;
+  m = Py_TYPE(x)->tp_as_number;
+#if PY_VERSION_HEX < 0x03000000
+  if (m && m->nb_int) {
+    name = "int";
+    res = PyNumber_Int(x);
+  }
+  else if (m && m->nb_long) {
+    name = "long";
+    res = PyNumber_Long(x);
+  }
+#else
+  if (m && m->nb_int) {
+    name = "int";
+    res = PyNumber_Long(x);
+  }
+#endif
+  if (res) {
+#if PY_VERSION_HEX < 0x03000000
+    if (!PyInt_Check(res) && !PyLong_Check(res)) {
+#else
+    if (!PyLong_Check(res)) {
+#endif
+      PyErr_Format(PyExc_TypeError,
+                   "__%s__ returned non-%s (type %.200s)",
+                   name, name, Py_TYPE(res)->tp_name);
+      Py_DECREF(res);
+      return NULL;
+    }
+  }
+  else if (!PyErr_Occurred()) {
+    PyErr_SetString(PyExc_TypeError,
+                    "an integer is required");
+  }
+  return res;
+}
+static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) {
+  Py_ssize_t ival;
+  PyObject* x = PyNumber_Index(b);
+  if (!x) return -1;
+  ival = PyInt_AsSsize_t(x);
+  Py_DECREF(x);
+  return ival;
+}
+static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) {
+#if PY_VERSION_HEX < 0x02050000
+   if (ival <= LONG_MAX)
+       return PyInt_FromLong((long)ival);
+   else {
+       unsigned char *bytes = (unsigned char *) &ival;
+       int one = 1; int little = (int)*(unsigned char*)&one;
+       return _PyLong_FromByteArray(bytes, sizeof(size_t), little, 0);
+   }
+#else
+   return PyInt_FromSize_t(ival);
+#endif
+}
+static CYTHON_INLINE size_t __Pyx_PyInt_AsSize_t(PyObject* x) {
+   unsigned PY_LONG_LONG val = __Pyx_PyInt_AsUnsignedLongLong(x);
+   if (unlikely(val == (unsigned PY_LONG_LONG)-1 && PyErr_Occurred())) {
+       return (size_t)-1;
+   } else if (unlikely(val != (unsigned PY_LONG_LONG)(size_t)val)) {
+       PyErr_SetString(PyExc_OverflowError,
+                       "value too large to convert to size_t");
+       return (size_t)-1;
+   }
+   return (size_t)val;
+}
+
+
+#endif /* Py_PYTHON_H */
diff --git a/lib/bx/misc/bgzf.pyx b/lib/bx/misc/bgzf.pyx
new file mode 100644
index 0000000..003a948
--- /dev/null
+++ b/lib/bx/misc/bgzf.pyx
@@ -0,0 +1,36 @@
+"""
+Seekable access to BGZ files based on samtools code. Does not yet implement
+complete file-like interface.
+"""
+
+ctypedef unsigned long long int64_t
+
+cdef extern from "Python.h":
+    char * PyString_AsString( object )
+    object PyString_FromStringAndSize( char *, int )
+
+cdef extern from "bgzf.h":
+    ctypedef struct BGZF
+    BGZF * bgzf_open( char * path, char * mode )
+    int bgzf_close( BGZF * fp )
+    int bgzf_read( BGZF * fp, void * data, int length )
+    int64_t bgzf_tell( BGZF * fp )
+    int64_t bgzf_seek( BGZF * fp, int64_t pos, int where )
+    
+cdef class BGZFFile( object ):
+    cdef BGZF * bgzf
+    def __init__( self, path, mode="r" ):
+        self.bgzf = bgzf_open( path, mode )
+        if not self.bgzf:
+            raise IOError( "Could not open file" )
+    def close( self ):
+        if self.bgzf:
+            bgzf_close( self.bgzf )
+    def read( self, int length ):
+        cdef object rval = PyString_FromStringAndSize( NULL, length )
+        bgzf_read( self.bgzf, PyString_AsString( rval ), length )
+        return rval
+    def tell( self ):
+        return bgzf_tell( self.bgzf )
+    def seek( self, int64_t pos, int where=0 ):
+        return bgzf_seek( self.bgzf, pos, where )
\ No newline at end of file
diff --git a/lib/bx/misc/bgzf_tests.py b/lib/bx/misc/bgzf_tests.py
new file mode 100644
index 0000000..b4c5bfe
--- /dev/null
+++ b/lib/bx/misc/bgzf_tests.py
@@ -0,0 +1,7 @@
+import bx.misc.bgzf
+
+def test_bgzf():
+    f = bx.misc.bgzf.BGZFFile( "test_data/bgzf_tests/test.txt.gz" )
+    assert f.read( 10 ) == "begin 644 "
+    print f.seek( 0 )
+    assert f.read( 10 ) == "begin 644 "
\ No newline at end of file
diff --git a/lib/bx/misc/binary_file.py b/lib/bx/misc/binary_file.py
new file mode 100644
index 0000000..b6649da
--- /dev/null
+++ b/lib/bx/misc/binary_file.py
@@ -0,0 +1,169 @@
+"""
+Wrappers for doing binary IO on file-like objects
+"""
+
+import numpy
+import struct
+import sys
+
+## Standard size:
+## short is 8 bits
+## int and long are 32 bits
+## long long is 64 bits
+
+class BadMagicNumber( IOError ):
+    pass
+
+class BinaryFileReader( object ):
+    """
+    Wrapper for doing binary reads on any file like object.
+    
+    Currently this is not heavily optimized (it uses the `struct` module to
+    unpack)
+    """    
+    def __init__( self, file, magic = None, is_little_endian = False ):
+        self.is_little_endian = is_little_endian
+        self.file = file
+        if magic is not None:
+            # Attempt to read magic number and chuck endianess
+            bytes = file.read( 4 )
+            if struct.unpack( ">I", bytes )[0] == magic:
+                pass
+            elif struct.unpack( "<I", bytes )[0] == magic:
+                self.is_little_endian = True
+            else:
+                raise BadMagicNumber( "File does not have expected magic number: %x != %x or %x" \
+                        % ( magic, struct.unpack( ">I", bytes )[0], struct.unpack( "<I", bytes )[0] ) )
+        # Set endian code
+        if self.is_little_endian:
+            self.endian_code = "<"
+            self.byteswap_needed = ( sys.byteorder != "little" )
+        else:
+            self.endian_code = ">"
+            self.byteswap_needed = ( sys.byteorder != "big" )
+        
+    def unpack( self, format, buffer, byte_count=None ):
+        pattern = "%s%s" % ( self.endian_code, format )
+        if byte_count is None:
+            byte_count = struct.calcsize( pattern )
+        return struct.unpack( pattern, buffer )
+        
+    def read_and_unpack( self, format, byte_count=None ):
+        """
+        Read enough bytes to unpack according to `format` and return the
+        tuple of unpacked values.
+        """
+        pattern = "%s%s" % ( self.endian_code, format )
+        if byte_count is None:
+            byte_count = struct.calcsize( pattern )
+        return struct.unpack( pattern, self.file.read( byte_count ) )
+    
+    def read_c_string( self ):
+        """
+        Read a zero terminated (C style) string
+        """
+        rval = []
+        while 1:
+            ch = self.file.read(1)
+            assert len( ch ) == 1, "Unexpected end of file"
+            if ch == '\0':
+                break
+            rval.append( ch )
+        return ''.join( rval )
+        
+    def read_raw_array( self, dtype, size ):
+        a = numpy.fromfile( self.file, dtype=dtype, count=size )
+        if self.byteswap_needed:
+            a.byteswap()
+        return a
+    
+    def read( self, byte_count=1 ):
+        return self.file.read( byte_count )
+        
+    def tell( self ):
+        return self.file.tell()
+        
+    def skip( self, count ):
+        self.file.seek( count, 1 )
+        
+    def seek( self, pos, whence=0 ):
+        return self.file.seek( pos, whence )
+
+    def read_uint8( self ):
+        return self.read_and_unpack( "B", 1 )[0]
+    
+    def read_uint16( self ):
+        return self.read_and_unpack( "H", 2 )[0]
+        
+    def read_uint32( self ):
+        return self.read_and_unpack( "L", 4 )[0]
+        
+    def read_uint64( self ):
+        return self.read_and_unpack( "Q", 8 )[0]
+
+    def read_float( self ):
+        return self.read_and_unpack( "f", 4 )[0]
+        
+        
+class BinaryFileWriter( object ):
+    """
+    Wrapper for doing binary writes on any file like object.
+    
+    Currently this is not heavily optimized (it uses the `struct` module to
+    unpack)
+    """    
+    def __init__( self, file, magic = None, is_little_endian = False ):
+        self.is_little_endian = is_little_endian
+        if self.is_little_endian:
+            self.endian_code = "<"
+        else:
+            self.endian_code = ">"
+        self.file = file
+        if magic is not None:
+            self.write_uint32( magic )
+            
+    def pack( self, format, buffer ):
+        pattern = "%s%s" % ( self.endian_code, format )
+        return struct.pack( pattern, buffer )
+        
+    def pack_and_write( self, format, value ):
+        """
+        Read enough bytes to unpack according to `format` and return the
+        tuple of unpacked values.
+        """
+        pattern = "%s%s" % ( self.endian_code, format )
+        return self.file.write( struct.pack( pattern, value ) )
+    
+    def write_c_string( self, value ):
+        """
+        Read a zero terminated (C style) string
+        """
+        self.file.write( value )
+        self.file.write( '\0' )
+        
+    def write_raw_array( self, value ):
+        value.tofile( self.file )
+    
+    def write( self, value ):
+        return self.file.write( value )
+        
+    def skip( self, count ):
+        self.file.seek( count, 1 )
+        
+    def tell( self ):
+        return self.file.tell()
+        
+    def seek( self, pos, whence=0 ):
+        return self.file.seek( pos, whence )
+
+    def write_uint8( self, value ):
+        return self.pack_and_write( "B", value )
+    
+    def write_uint16( self, value ):
+        return self.pack_and_write( "H", value )
+
+    def write_uint32( self, value ):
+        return self.pack_and_write( "L", value )
+
+    def write_uint64( self, value ):
+        return self.pack_and_write( "Q", value )
diff --git a/lib/bx/misc/cdb.py b/lib/bx/misc/cdb.py
new file mode 100644
index 0000000..26bbc5b
--- /dev/null
+++ b/lib/bx/misc/cdb.py
@@ -0,0 +1,109 @@
+from UserDict import DictMixin
+
+from bx.misc.binary_file import BinaryFileReader, BinaryFileWriter
+import numpy
+import sys
+
+def cdbhash( s ):
+    return reduce( lambda h, c: (((h << 5) + h) ^ ord(c)) & 0xffffffffL, s, 5381 )
+
+class FileCDBDict( DictMixin ):
+    """
+    For accessing a CDB structure on disk. Read only. Currently only supports
+    access by key (getitem).
+    
+    NOTE: The keys method could be implemented by scanning the main table.
+    """
+    def __init__( self, file, is_little_endian=True ):
+        # TODO: Deal with endianess
+        self.io = BinaryFileReader( file, is_little_endian=is_little_endian )
+        self.header_offset = self.io.tell()
+        # Read the whole header (only 2k)
+        self.header = []
+        for i in range( 256 ):
+            self.header.append( ( self.io.read_uint32(), self.io.read_uint32() ) )
+    def __getitem__( self, key ):
+        hash = cdbhash( key )
+        # Find position of subtable using 8 LSBs of hash
+        subtable_offset = self.header[ hash % 256 ][0]
+        subtable_size = self.header[ hash % 256 ][1]
+        if subtable_size == 0:
+            raise KeyError
+        # Seek into subtable and look for match
+        start = ( hash >> 8 )
+        for i in range( subtable_size ):
+            offset = subtable_offset + ( ( start + i ) % subtable_size ) * 8
+            self.io.seek( offset )
+            h = self.io.read_uint32()
+            p = self.io.read_uint32()
+            # Hit an empty bin, no match for key
+            if p == 0:
+                raise KeyError
+            # Hash matches, need to check full key
+            if h == hash:
+                self.io.seek( p )
+                klen = self.io.read_uint32()
+                vlen = self.io.read_uint32()
+                k = self.io.read( klen )
+                if k == key:
+                    v = self.io.read( vlen )
+                    return v
+        else:
+            # Visited every slot and no match (should never happen since
+            # there are empty slots by contruction)
+            raise KeyError
+        
+    @classmethod
+    def to_file( Class, dict, file, is_little_endian=True ):
+        """
+        For constructing a CDB structure in a file. Able to calculate size on
+        disk and write to a file
+        """
+        io = BinaryFileWriter( file, is_little_endian=is_little_endian )
+        start_offset = io.tell()
+        # Header is of fixed length
+        io.seek( start_offset + ( 8 * 256 ) )
+        # For each item, key and value length (written as length prefixed
+        # strings). We also calculate the subtables on this pass.
+        # NOTE: This requires the key and value be byte strings, support for
+        #       dealing with encoding specific value types should be
+        #       added to this wrapper
+        subtables = [ [] for i in range(256) ]
+        for key, value in dict.iteritems():
+            pair_offset = io.tell()
+            io.write_uint32( len( key ) )
+            io.write_uint32( len( value ) )
+            io.write( key )
+            io.write( value )
+            hash = cdbhash( key )
+            subtables[ hash % 256 ].append( ( hash, pair_offset ) )
+        # Save the offset where the subtables will start
+        subtable_offset = io.tell()
+        # Write subtables
+        for subtable in subtables:
+            if len( subtable ) > 0:
+                # Construct hashtable to be twice the size of the number
+                # of items in the subtable, and built it in memory
+                ncells = len( subtable ) * 2
+                cells = [ (0,0) for i in range( ncells ) ]
+                for hash, pair_offset in subtable:
+                    index = ( hash >> 8 ) % ncells
+                    while cells[index][1] != 0:
+                        index = ( index + 1 ) % ncells
+                    # Guaranteed to find a non-empty cell
+                    cells[index] = ( hash, pair_offset )
+                # Write subtable
+                for hash, pair_offset in cells:
+                    io.write_uint32( hash )
+                    io.write_uint32( pair_offset )
+        # Go back and write the header
+        end_offset = io.tell()
+        io.seek( start_offset )
+        index = subtable_offset
+        for subtable in subtables:
+            io.write_uint32( index )
+            io.write_uint32( len( subtable * 2 ) )
+            # For each cell in the subtable, a hash and a pointer to a value
+            index += ( len( subtable ) * 2 ) * 8
+        # Leave fp at end of cdb
+        io.seek( end_offset )
\ No newline at end of file
diff --git a/lib/bx/misc/cdb_tests.py b/lib/bx/misc/cdb_tests.py
new file mode 100644
index 0000000..0fb5d1c
--- /dev/null
+++ b/lib/bx/misc/cdb_tests.py
@@ -0,0 +1,34 @@
+from bx.misc.cdb import *
+from tempfile import NamedTemporaryFile
+
+def test():
+
+    d = {}
+    for i in range( 10000 ):
+        d[ 'foo' + str( i ) ] = 'bar' + str( i )
+    
+    # Open temporary file and get name    
+    file = NamedTemporaryFile()
+    file_name = file.name
+        
+    # Write cdb to file
+    FileCDBDict.to_file( d, file )
+    file.flush()
+    
+    # Open on disk
+    file2 = open( file_name )
+    cdb = FileCDBDict( file2 )
+    
+    for key, value in d.iteritems():
+        assert cdb[key] == value
+    
+    try:
+        cdb['notin']
+        assert False, "KeyError was not raised"
+    except KeyError, e:
+        pass
+    
+    # Close everything (deletes the temporary file)
+    file2.close()
+    file.close()
+    
\ No newline at end of file
diff --git a/lib/bx/misc/filecache.py b/lib/bx/misc/filecache.py
new file mode 100644
index 0000000..f4c0b71
--- /dev/null
+++ b/lib/bx/misc/filecache.py
@@ -0,0 +1,105 @@
+from __future__ import division
+
+import sys
+from bx_extras.lrucache import LRUCache
+from cStringIO import StringIO
+
+DEFAULT_CACHE_SIZE=10
+DEFAULT_BLOCK_SIZE=1024*1024*2
+
+class FileCache( object ):
+    """
+    Wrapper for a file that cache blocks of data in memory. 
+    
+    **NOTE:** this is currently an incomplete file-like object, it only
+    supports seek, tell, and readline (plus iteration). Reading bytes is
+    currently not implemented.
+    """
+    def __init__( self, file, size, cache_size=DEFAULT_CACHE_SIZE, 
+                                    block_size=DEFAULT_BLOCK_SIZE ):
+        """
+        Create a new `FileCache` wrapping the file-like object `file` that
+        has total size `size` and caching blocks of size `block_size`.
+        """
+        self.file = file
+        self.size = size
+        self.cache_size = cache_size
+        self.block_size = block_size
+        # Setup the cache
+        self.nblocks = ( self.size // self.block_size ) + 1
+        self.cache = LRUCache( self.cache_size )
+        # Position in file
+        self.dirty = True
+        self.at_eof = False
+        self.file_pos = 0
+        self.current_block_index = -1
+        self.current_block = None
+    def fix_dirty( self ):
+        chunk, offset = self.get_block_and_offset( self.file_pos )
+        if self.current_block_index != chunk:
+            self.current_block = StringIO( self.load_block( chunk ) )
+            self.current_block.read( offset )
+            self.current_block_index = chunk
+        else:
+            self.current_block.seek( offset )
+        self.dirty = False
+    def get_block_and_offset( self, index ):
+        return int( index // self.block_size ), int( index % self.block_size )
+    def load_block( self, index ):
+        if index in self.cache:
+            return self.cache[index]
+        else:
+            real_offset = index * self.block_size
+            self.file.seek( real_offset )
+            block = self.file.read( self.block_size )
+            self.cache[index] = block
+            return block
+    def seek( self, offset, whence=0 ):
+        """
+        Move the file pointer to a particular offset.
+        """
+        # Determine absolute target position
+        if whence == 0:
+            target_pos = offset
+        elif whence == 1:
+            target_pos = self.file_pos + offset
+        elif whence == 2:
+            target_pos = self.size - offset
+        else:
+            raise Exception( "Invalid `whence` argument: %r", whence )
+        # Check if this is a noop
+        if target_pos == self.file_pos:
+            return    
+        # Verify it is valid
+        assert 0 <= target_pos < self.size, "Attempt to seek outside file"
+        # Move the position
+        self.file_pos = target_pos
+        # Mark as dirty, the next time a read is done we need to actually
+        # move the position in the bzip2 file
+        self.dirty = True
+    def readline( self ):
+        if self.dirty:
+            self.fix_dirty()
+        if self.at_eof:
+            return ""
+        rval = []
+        while 1:
+            line = self.current_block.readline()
+            rval.append( line )
+            if len( line ) > 0 and line[-1] == '\n':
+                break
+            elif self.current_block_index == self.nblocks - 1:
+                self.at_eof = True
+                break
+            else:
+                self.current_block_index += 1
+                self.current_block = StringIO( self.load_block( self.current_block_index ) )      
+        return "".join( rval )     
+    def next( self ):
+        line = self.readline()
+        if line == "":
+            raise StopIteration
+    def __iter__( self ):
+        return self
+    def close( self ):
+        self.file.close()
\ No newline at end of file
diff --git a/lib/bx/misc/filecache_tests.py b/lib/bx/misc/filecache_tests.py
new file mode 100644
index 0000000..b8ab1db
--- /dev/null
+++ b/lib/bx/misc/filecache_tests.py
@@ -0,0 +1,30 @@
+import filecache
+import os
+import random
+import sys
+
+"""
+T="/Users/james/cache/hg18/align/multiz28way/chr10.maf"
+
+def test():
+    s = os.stat( T ).st_size
+    real_f = open( T )
+    f = filecache.FileCache( real_f, s )
+    for i in range( 1000 ):
+        f.readline()
+        
+def test_random_seeking():
+    s = os.stat( T ).st_size
+    raw = open( T )
+    f = filecache.FileCache( open( T ), s )
+    for i in range( 10000 ):
+        seek_to = random.randrange( s )
+        
+        f.seek( seek_to )
+        raw.seek( seek_to )
+
+        l1 = f.readline()
+        l2 = raw.readline()
+        
+        assert l1 == l2
+"""
diff --git a/lib/bx/misc/readlengths.py b/lib/bx/misc/readlengths.py
new file mode 100644
index 0000000..757ceaa
--- /dev/null
+++ b/lib/bx/misc/readlengths.py
@@ -0,0 +1,29 @@
+"""
+Read sequence lengths from a file.  Each line is of the form <name> <length>
+where <name> is typically a chromsome name (e.g. chr12) and length is the
+number of bases the sequence.
+"""
+
+def read_lengths_file( name ):
+    """
+    Returns a hash from sequence name to length.
+    """
+
+    chrom_to_length = {}
+    f = file ( name, "rt" )
+    for line in f:
+        line = line.strip()
+        if line == '' or line[0] == '#': continue
+        try:
+            fields = line.split()
+            if len(fields) != 2: raise
+            chrom = fields[0]
+            length = int( fields[1] )
+        except:
+            raise ValueError("bad length file line: %s" % line)
+        if chrom in chrom_to_length and length != chrom_to_length[chrom]:
+            raise ValueError("%s has more than one length!" % chrom)
+        chrom_to_length[chrom] = length
+    f.close()
+    return chrom_to_length
+
diff --git a/lib/bx/misc/seekbzip2.py b/lib/bx/misc/seekbzip2.py
new file mode 100644
index 0000000..dcd28e3
--- /dev/null
+++ b/lib/bx/misc/seekbzip2.py
@@ -0,0 +1,148 @@
+"""
+Semi-random access to bz2 compressed data.
+"""
+
+import os
+import bisect
+import sys
+    
+from _seekbzip2 import SeekBzip2
+    
+class SeekableBzip2File( object ):
+    """
+    Filelike object supporting read-only semi-random access to bz2 compressed
+    files for which an offset table (bz2t) has been generated by `bzip-table`.
+    """
+    
+    def __init__( self, filename, table_filename, **kwargs ):
+        self.filename = filename
+        self.table_filename = table_filename
+        self.init_table()
+        self.init_bz2()
+        self.pos = 0
+        self.dirty = True
+        
+    def init_bz2( self ):
+        self.seek_bz2 = SeekBzip2( self.filename )
+        
+    def init_table( self ):
+        # Position in plaintext file
+        self.table_positions = []
+        # Position of corresponding block in bz2 file (bits)
+        self.table_bz2positions = []
+        pos = 0
+        for line in open( self.table_filename ):
+            fields = line.split()
+            # Position of the compressed block in the bz2 file
+            bz2_pos = int( fields[0] )
+            # print >> sys.stderr, fields[0], bz2_pos
+            # Length of the block when uncompressed
+            length = int( fields[1] )
+            self.table_positions.append( pos )
+            self.table_bz2positions.append( bz2_pos )
+            old_pos = pos
+            pos = pos + length
+            assert pos > old_pos
+        self.size = pos
+        #print >> sys.stderr, self.size
+        #print >> sys.stderr, self.table_bz2positions
+        
+    def close( self ):
+        self.seek_bz2.close()
+        
+    def fix_dirty( self ):
+        # Our virtual position in the uncompressed data is out of sync
+        # FIXME: If we're moving to a later position that is still in 
+        # the same block, we could just read and throw out bytes in the
+        # compressed stream, less wasteful then backtracking
+        chunk, offset = self.get_chunk_and_offset( self.pos )
+        # Get the seek position for that chunk and seek to it
+        bz2_seek_pos = self.table_bz2positions[chunk] 
+        # print >>sys.stderr, "bz2 seek pos:", bz2_seek_pos
+        self.seek_bz2.seek( bz2_seek_pos )
+        # Consume bytes to move to the correct position
+        assert len( self.seek_bz2.read( offset ) ) == offset
+        # Update state
+        self.dirty = False
+        
+    def read( self, sizehint=-1 ):
+        if sizehint < 0:
+            chunks = []
+            while 1:
+                self._read( 1024*1024 )
+                if val:
+                    chunks.append( val )
+                else:
+                    break
+            return "".join( chunks )
+        else:
+            return self._read( sizehint )
+        
+    def _read( self, size ):
+        if self.dirty: self.fix_dirty()
+        val = self.seek_bz2.read( size )
+        if val is None:
+            # EOF
+            self.pos = self.size
+            val = ""
+        else:
+            self.pos = self.pos + len( val )
+        return val
+        
+    def readline( self, size=-1 ):
+        if self.dirty: self.fix_dirty()
+        val = self.seek_bz2.readline( size )
+        if val is None:
+            # EOF
+            self.pos = self.size
+            val = ""
+        else:
+            self.pos = self.pos + len( val )
+        return val
+        
+    def tell( self ):
+        return self.pos
+            
+    def get_chunk_and_offset( self, position ):
+        # Find the chunk that position is in using a binary search
+        chunk = bisect.bisect( self.table_positions, position ) - 1
+        offset = position - self.table_positions[chunk]
+        return chunk, offset
+        
+    def seek( self, offset, whence=0 ):
+        # Determine absolute target position
+        if whence == 0:
+            target_pos = offset
+        elif whence == 1:
+            target_pos = self.pos + offset
+        elif whence == 2:
+            target_pos = self.size - offset
+        else:
+            raise Exception( "Invalid `whence` argument: %r", whence )
+        # Check if this is a noop
+        if target_pos == self.pos:
+            return    
+        # Verify it is valid
+        assert 0 <= target_pos < self.size, "Attempt to seek outside file"
+        # Move the position
+        self.pos = target_pos
+        # Mark as dirty, the next time a read is done we need to actually
+        # move the position in the bzip2 file
+        self.dirty = True
+        
+    # ---- File like methods ------------------------------------------------
+    
+    def next(self):
+        ln = self.readline()
+        if ln == "":
+            raise StopIteration()
+        return ln
+    
+    def __iter__(self):
+        return self
+        
+    def readlines(self,sizehint=-1):
+        return [ln for ln in self]
+
+    def xreadlines(self):
+        return iter(self)
diff --git a/lib/bx/misc/seekbzip2_tests.py b/lib/bx/misc/seekbzip2_tests.py
new file mode 100644
index 0000000..b8386bf
--- /dev/null
+++ b/lib/bx/misc/seekbzip2_tests.py
@@ -0,0 +1,86 @@
+"""
+Tests for `bx.misc.seekbzip2`.
+"""
+
+import tempfile
+import commands
+import os
+import random
+from itertools import *
+
+import seekbzip2
+import bz2
+
+F=None
+T=None
+
+#F="/Users/james/work/seek-bzip2/test_random.dat.bz2"
+#T="/Users/james/cache/hg18/align/multiz28way/chr10.maf.bz2"
+
+#F=/depot/data1/cache/human/hg18/align/multiz28way/chr1.maf.bz2
+
+import sys
+
+if F and os.path.exists( F ):
+
+    def test_linear_reading():
+        raw_data = bz2.BZ2File( F ).read()
+        f = seekbzip2.SeekableBzip2File( F, F + "t" )
+        chunk = 1221
+        pos = 0
+        for i in range( ( len(raw_data) // chunk ) + 1 ):
+            a = raw_data[pos:pos+chunk]
+            b = f.read( chunk )
+            assert a == b
+            pos += chunk
+            assert f.tell() == min( pos, len(raw_data) )
+        f.close()
+        
+    def test_random_seeking():
+        raw_data = bz2.BZ2File( F ).read()
+        f = seekbzip2.SeekableBzip2File( F, F + "t" )
+        for i in range( 10 ):
+            seek_to = random.randrange( len( raw_data ) - 100 )
+            chunk = random.randrange( 10, 20 )
+
+            f.seek( seek_to )
+            a = f.read( chunk )
+            b = raw_data[ seek_to : seek_to + chunk ]
+        
+            assert a == b, "'%s' != '%s' on %dth attempt" % ( a.encode("hex"), b.encode("hex"), i )
+
+            assert f.tell() == min( seek_to + chunk, len(raw_data) )
+        f.close()
+            
+if T and os.path.exists( T ):
+       
+    def test_text_reading():
+        #raw_data = bz2.BZ2File( T ).read()
+        #raw_lines = raw_data.split( "\n" )
+        raw_file = bz2.BZ2File( T )
+        f = seekbzip2.SeekableBzip2File( T, T + "t" )
+        pos = 0
+        for i, ( line, raw_line ) in enumerate( izip( f, raw_file ) ):
+            assert line == raw_line, "%d: %r != %r" % ( i, line.rstrip( "\n" ), raw_line )
+            pos += len( line )
+            ftell = f.tell()
+            assert ftell == pos, "%d != %d" % ( ftell, pos )
+        f.close()
+        
+  
+    def test_text_reading_2():
+        raw_data = bz2.BZ2File( T ).read()
+        f = seekbzip2.SeekableBzip2File( T, T + "t" )
+        raw_lines = raw_data.split( "\n" )
+        pos = 0
+        i = 0
+        while 1:
+            line = f.readline()
+            if line == "": break
+            assert line.rstrip( "\r\n" ) == raw_lines[i], "%r != %r" % ( line.rstrip( "\r\n" ), raw_lines[i] )
+            pos += len( line )
+            ftell = f.tell()
+            assert ftell == pos, "%d != %d" % ( ftell, pos )  
+            i += 1    
+        f.close()
+        
diff --git a/lib/bx/misc/seeklzop.py b/lib/bx/misc/seeklzop.py
new file mode 100644
index 0000000..830cb89
--- /dev/null
+++ b/lib/bx/misc/seeklzop.py
@@ -0,0 +1,167 @@
+"""
+Semi-random access to bz2 compressed data.
+"""
+
+import os
+import bisect
+import sys
+try:
+    import pkg_resources
+    pkg_resources.require( 'python_lzo' )
+    import lzo
+except:
+    pass
+
+import struct
+
+from bx_extras import lrucache   
+from cStringIO import StringIO
+    
+class SeekableLzopFile( object ):
+    """
+    Filelike object supporting read-only semi-random access to bz2 compressed
+    files for which an offset table (bz2t) has been generated by `bzip-table`.
+    """
+    
+    def __init__( self, filename, table_filename, block_cache_size=0, **kwargs ):
+        self.filename = filename
+        self.table_filename = table_filename
+        self.init_table()
+        self.file = open( self.filename, "r" )
+        self.dirty = True
+        self.at_eof = False
+        self.file_pos = 0
+        self.current_block_index = -1
+        self.current_block = None
+        if block_cache_size > 0:
+            self.cache = lrucache.LRUCache( block_cache_size )
+        else:
+            self.cache = None
+        
+    def init_table( self ):
+        self.block_size = None
+        self.block_info = []
+        # Position of corresponding block in compressed file (in bytes)
+        for line in open( self.table_filename ):
+            fields = line.split()
+            if fields[0] == "s":
+                self.block_size = int( fields[1] )
+            if fields[0] == "o":
+                offset = int( fields[1] )
+                compressed_size = int( fields[2] )
+                size = int( fields[3] )
+                self.block_info.append( ( offset, compressed_size, size ) )
+        self.nblocks = len( self.block_info )
+        
+    def close( self ):
+        self.file.close()
+        
+    def load_block( self, index ):
+        if self.cache is not None and index in self.cache:
+            return self.cache[index]
+        else:      
+            offset, csize, size = self.block_info[ index ]
+            # Get the block of compressed data
+            self.file.seek( offset )
+            data = self.file.read( csize )
+            # Need to prepend a header for python-lzo module (silly)
+            data = ''.join( ( '\xf0', struct.pack( "!I", size ), data ) )
+            value = lzo.decompress( data )
+            if self.cache is not None:
+                self.cache[index] = value
+            return value
+        
+    def fix_dirty( self ):
+        chunk, offset = self.get_block_and_offset( self.file_pos )
+        if self.current_block_index != chunk:
+            self.current_block = StringIO( self.load_block( chunk ) )
+            self.current_block.read( offset )
+            self.current_block_index = chunk
+        else:
+            self.current_block.seek( offset )
+        self.dirty = False
+        
+    def get_block_and_offset( self, index ):
+        return int( index // self.block_size ), int( index % self.block_size )
+
+    def seek( self, offset, whence=0 ):
+        """
+        Move the file pointer to a particular offset.
+        """
+        # Determine absolute target position
+        if whence == 0:
+            target_pos = offset
+        elif whence == 1:
+            target_pos = self.file_pos + offset
+        elif whence == 2:
+            raise Exception( "seek from end not supported" )
+            ## target_pos = self.size - offset
+        else:
+            raise Exception( "Invalid `whence` argument: %r", whence )
+        # Check if this is a noop
+        if target_pos == self.file_pos:
+            return    
+        # Verify it is valid
+        ## assert 0 <= target_pos < self.size, "Attempt to seek outside file"
+        # Move the position
+        self.file_pos = target_pos
+        # Mark as dirty, the next time a read is done we need to actually
+        # move the position in the bzip2 file
+        self.dirty = True
+        
+    def tell( self ):
+        return self.file_pos
+        
+    def readline( self ):
+        if self.dirty:
+            self.fix_dirty()
+        if self.at_eof:
+            return ""
+        rval = []
+        while 1:
+            line = self.current_block.readline()
+            self.file_pos += len( line )
+            rval.append( line )
+            if len( line ) > 0 and line[-1] == '\n':
+                break
+            elif self.current_block_index == self.nblocks - 1:
+                self.at_eof = True
+                break
+            else:
+                self.current_block_index += 1
+                self.current_block = StringIO( self.load_block( self.current_block_index ) )      
+        return "".join( rval ) 
+            
+    def next( self ):
+        line = self.readline()
+        if line == "":
+            raise StopIteration
+            
+    def __iter__( self ):
+        return self
+
+# --- Factor out ---        
+        
+MAGIC="\x89\x4c\x5a\x4f\x00\x0d\x0a\x1a\x0a"
+
+F_ADLER32_D     = 0x00000001L
+F_ADLER32_C     = 0x00000002L
+F_H_EXTRA_FIELD = 0x00000040L
+F_H_GMTDIFF     = 0x00000080L
+F_CRC32_D       = 0x00000100L
+F_CRC32_C       = 0x00000200L
+F_MULTIPART     = 0x00000400L
+F_H_FILTER      = 0x00000800L
+F_H_CRC32       = 0x00001000L
+
+assert struct.calcsize( "!H" ) == 2
+assert struct.calcsize( "!I" ) == 4
+
+class UnpackWrapper( object ):
+    def __init__( self, file ):
+        self.file = file
+    def read( self, amt ):
+        return self.file.read( amt )
+    def get( self, fmt ):
+        t = struct.unpack( fmt, self.file.read( struct.calcsize( fmt ) ) )
+        return t[0]
diff --git a/lib/bx/misc/seeklzop_tests.py b/lib/bx/misc/seeklzop_tests.py
new file mode 100644
index 0000000..3bf7e94
--- /dev/null
+++ b/lib/bx/misc/seeklzop_tests.py
@@ -0,0 +1,30 @@
+import seeklzop
+import os
+import random
+import sys
+
+"""
+T="/Users/james/cache/hg18/align/multiz28way/chr10.maf"
+C="/Users/james/cache/hg18/align/multiz28way/chr10.maf.lzo"
+
+def test():
+    f = seeklzop.SeekableLzopFile( C, C + "t", block_cache_size=20 )
+    for line in f:
+        pass
+        
+def test_random_seeking():
+    s = os.stat( T ).st_size
+    raw = open( T )
+    f = seeklzop.SeekableLzopFile( C, C + "t", block_cache_size=20 )
+    for i in range( 1000 ):
+        seek_to = random.randrange( s )
+        
+        f.seek( seek_to )
+        raw.seek( seek_to )
+
+        l1 = f.readline()
+        l2 = raw.readline()
+        
+        assert l1 == l2, "%r != %r" % ( l1, l2 )
+        assert raw.tell() == f.tell(), "tells not equal"
+"""
diff --git a/lib/bx/motif/__init__.py b/lib/bx/motif/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/lib/bx/motif/_pwm.c b/lib/bx/motif/_pwm.c
new file mode 100644
index 0000000..dc10599
--- /dev/null
+++ b/lib/bx/motif/_pwm.c
@@ -0,0 +1,2250 @@
+/* Generated by Cython 0.18 on Mon Jul 15 13:25:44 2013 */
+
+#define PY_SSIZE_T_CLEAN
+#include "Python.h"
+#ifndef Py_PYTHON_H
+    #error Python headers needed to compile C extensions, please install development version of Python.
+#elif PY_VERSION_HEX < 0x02040000
+    #error Cython requires Python 2.4+.
+#else
+#include <stddef.h> /* For offsetof */
+#ifndef offsetof
+#define offsetof(type, member) ( (size_t) & ((type*)0) -> member )
+#endif
+#if !defined(WIN32) && !defined(MS_WINDOWS)
+  #ifndef __stdcall
+    #define __stdcall
+  #endif
+  #ifndef __cdecl
+    #define __cdecl
+  #endif
+  #ifndef __fastcall
+    #define __fastcall
+  #endif
+#endif
+#ifndef DL_IMPORT
+  #define DL_IMPORT(t) t
+#endif
+#ifndef DL_EXPORT
+  #define DL_EXPORT(t) t
+#endif
+#ifndef PY_LONG_LONG
+  #define PY_LONG_LONG LONG_LONG
+#endif
+#ifndef Py_HUGE_VAL
+  #define Py_HUGE_VAL HUGE_VAL
+#endif
+#ifdef PYPY_VERSION
+#define CYTHON_COMPILING_IN_PYPY 1
+#define CYTHON_COMPILING_IN_CPYTHON 0
+#else
+#define CYTHON_COMPILING_IN_PYPY 0
+#define CYTHON_COMPILING_IN_CPYTHON 1
+#endif
+#if PY_VERSION_HEX < 0x02050000
+  typedef int Py_ssize_t;
+  #define PY_SSIZE_T_MAX INT_MAX
+  #define PY_SSIZE_T_MIN INT_MIN
+  #define PY_FORMAT_SIZE_T ""
+  #define CYTHON_FORMAT_SSIZE_T ""
+  #define PyInt_FromSsize_t(z) PyInt_FromLong(z)
+  #define PyInt_AsSsize_t(o)   __Pyx_PyInt_AsInt(o)
+  #define PyNumber_Index(o)    ((PyNumber_Check(o) && !PyFloat_Check(o)) ? PyNumber_Int(o) : \
+                                (PyErr_Format(PyExc_TypeError, \
+                                              "expected index value, got %.200s", Py_TYPE(o)->tp_name), \
+                                 (PyObject*)0))
+  #define __Pyx_PyIndex_Check(o) (PyNumber_Check(o) && !PyFloat_Check(o) && \
+                                  !PyComplex_Check(o))
+  #define PyIndex_Check __Pyx_PyIndex_Check
+  #define PyErr_WarnEx(category, message, stacklevel) PyErr_Warn(category, message)
+  #define __PYX_BUILD_PY_SSIZE_T "i"
+#else
+  #define __PYX_BUILD_PY_SSIZE_T "n"
+  #define CYTHON_FORMAT_SSIZE_T "z"
+  #define __Pyx_PyIndex_Check PyIndex_Check
+#endif
+#if PY_VERSION_HEX < 0x02060000
+  #define Py_REFCNT(ob) (((PyObject*)(ob))->ob_refcnt)
+  #define Py_TYPE(ob)   (((PyObject*)(ob))->ob_type)
+  #define Py_SIZE(ob)   (((PyVarObject*)(ob))->ob_size)
+  #define PyVarObject_HEAD_INIT(type, size) \
+          PyObject_HEAD_INIT(type) size,
+  #define PyType_Modified(t)
+  typedef struct {
+     void *buf;
+     PyObject *obj;
+     Py_ssize_t len;
+     Py_ssize_t itemsize;
+     int readonly;
+     int ndim;
+     char *format;
+     Py_ssize_t *shape;
+     Py_ssize_t *strides;
+     Py_ssize_t *suboffsets;
+     void *internal;
+  } Py_buffer;
+  #define PyBUF_SIMPLE 0
+  #define PyBUF_WRITABLE 0x0001
+  #define PyBUF_FORMAT 0x0004
+  #define PyBUF_ND 0x0008
+  #define PyBUF_STRIDES (0x0010 | PyBUF_ND)
+  #define PyBUF_C_CONTIGUOUS (0x0020 | PyBUF_STRIDES)
+  #define PyBUF_F_CONTIGUOUS (0x0040 | PyBUF_STRIDES)
+  #define PyBUF_ANY_CONTIGUOUS (0x0080 | PyBUF_STRIDES)
+  #define PyBUF_INDIRECT (0x0100 | PyBUF_STRIDES)
+  #define PyBUF_RECORDS (PyBUF_STRIDES | PyBUF_FORMAT | PyBUF_WRITABLE)
+  #define PyBUF_FULL (PyBUF_INDIRECT | PyBUF_FORMAT | PyBUF_WRITABLE)
+  typedef int (*getbufferproc)(PyObject *, Py_buffer *, int);
+  typedef void (*releasebufferproc)(PyObject *, Py_buffer *);
+#endif
+#if PY_MAJOR_VERSION < 3
+  #define __Pyx_BUILTIN_MODULE_NAME "__builtin__"
+  #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \
+          PyCode_New(a, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
+#else
+  #define __Pyx_BUILTIN_MODULE_NAME "builtins"
+  #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \
+          PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
+#endif
+#if PY_MAJOR_VERSION < 3 && PY_MINOR_VERSION < 6
+  #define PyUnicode_FromString(s) PyUnicode_Decode(s, strlen(s), "UTF-8", "strict")
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define Py_TPFLAGS_CHECKTYPES 0
+  #define Py_TPFLAGS_HAVE_INDEX 0
+#endif
+#if (PY_VERSION_HEX < 0x02060000) || (PY_MAJOR_VERSION >= 3)
+  #define Py_TPFLAGS_HAVE_NEWBUFFER 0
+#endif
+#if PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND)
+  #define CYTHON_PEP393_ENABLED 1
+  #define __Pyx_PyUnicode_READY(op)       (likely(PyUnicode_IS_READY(op)) ? \
+                                              0 : _PyUnicode_Ready((PyObject *)(op)))
+  #define __Pyx_PyUnicode_GET_LENGTH(u)   PyUnicode_GET_LENGTH(u)
+  #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_READ_CHAR(u, i)
+  #define __Pyx_PyUnicode_READ(k, d, i)   PyUnicode_READ(k, d, i)
+#else
+  #define CYTHON_PEP393_ENABLED 0
+  #define __Pyx_PyUnicode_READY(op)       (0)
+  #define __Pyx_PyUnicode_GET_LENGTH(u)   PyUnicode_GET_SIZE(u)
+  #define __Pyx_PyUnicode_READ_CHAR(u, i) ((Py_UCS4)(PyUnicode_AS_UNICODE(u)[i]))
+  #define __Pyx_PyUnicode_READ(k, d, i)   ((k=k), (Py_UCS4)(((Py_UNICODE*)d)[i]))
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define PyBaseString_Type            PyUnicode_Type
+  #define PyStringObject               PyUnicodeObject
+  #define PyString_Type                PyUnicode_Type
+  #define PyString_Check               PyUnicode_Check
+  #define PyString_CheckExact          PyUnicode_CheckExact
+#endif
+#if PY_VERSION_HEX < 0x02060000
+  #define PyBytesObject                PyStringObject
+  #define PyBytes_Type                 PyString_Type
+  #define PyBytes_Check                PyString_Check
+  #define PyBytes_CheckExact           PyString_CheckExact
+  #define PyBytes_FromString           PyString_FromString
+  #define PyBytes_FromStringAndSize    PyString_FromStringAndSize
+  #define PyBytes_FromFormat           PyString_FromFormat
+  #define PyBytes_DecodeEscape         PyString_DecodeEscape
+  #define PyBytes_AsString             PyString_AsString
+  #define PyBytes_AsStringAndSize      PyString_AsStringAndSize
+  #define PyBytes_Size                 PyString_Size
+  #define PyBytes_AS_STRING            PyString_AS_STRING
+  #define PyBytes_GET_SIZE             PyString_GET_SIZE
+  #define PyBytes_Repr                 PyString_Repr
+  #define PyBytes_Concat               PyString_Concat
+  #define PyBytes_ConcatAndDel         PyString_ConcatAndDel
+#endif
+#if PY_VERSION_HEX < 0x02060000
+  #define PySet_Check(obj)             PyObject_TypeCheck(obj, &PySet_Type)
+  #define PyFrozenSet_Check(obj)       PyObject_TypeCheck(obj, &PyFrozenSet_Type)
+#endif
+#ifndef PySet_CheckExact
+  #define PySet_CheckExact(obj)        (Py_TYPE(obj) == &PySet_Type)
+#endif
+#define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type)
+#if PY_MAJOR_VERSION >= 3
+  #define PyIntObject                  PyLongObject
+  #define PyInt_Type                   PyLong_Type
+  #define PyInt_Check(op)              PyLong_Check(op)
+  #define PyInt_CheckExact(op)         PyLong_CheckExact(op)
+  #define PyInt_FromString             PyLong_FromString
+  #define PyInt_FromUnicode            PyLong_FromUnicode
+  #define PyInt_FromLong               PyLong_FromLong
+  #define PyInt_FromSize_t             PyLong_FromSize_t
+  #define PyInt_FromSsize_t            PyLong_FromSsize_t
+  #define PyInt_AsLong                 PyLong_AsLong
+  #define PyInt_AS_LONG                PyLong_AS_LONG
+  #define PyInt_AsSsize_t              PyLong_AsSsize_t
+  #define PyInt_AsUnsignedLongMask     PyLong_AsUnsignedLongMask
+  #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define PyBoolObject                 PyLongObject
+#endif
+#if PY_VERSION_HEX < 0x03020000
+  typedef long Py_hash_t;
+  #define __Pyx_PyInt_FromHash_t PyInt_FromLong
+  #define __Pyx_PyInt_AsHash_t   PyInt_AsLong
+#else
+  #define __Pyx_PyInt_FromHash_t PyInt_FromSsize_t
+  #define __Pyx_PyInt_AsHash_t   PyInt_AsSsize_t
+#endif
+#if (PY_MAJOR_VERSION < 3) || (PY_VERSION_HEX >= 0x03010300)
+  #define __Pyx_PySequence_GetSlice(obj, a, b) PySequence_GetSlice(obj, a, b)
+  #define __Pyx_PySequence_SetSlice(obj, a, b, value) PySequence_SetSlice(obj, a, b, value)
+  #define __Pyx_PySequence_DelSlice(obj, a, b) PySequence_DelSlice(obj, a, b)
+#else
+  #define __Pyx_PySequence_GetSlice(obj, a, b) (unlikely(!(obj)) ? \
+        (PyErr_SetString(PyExc_SystemError, "null argument to internal routine"), (PyObject*)0) : \
+        (likely((obj)->ob_type->tp_as_mapping) ? (PySequence_GetSlice(obj, a, b)) : \
+            (PyErr_Format(PyExc_TypeError, "'%.200s' object is unsliceable", (obj)->ob_type->tp_name), (PyObject*)0)))
+  #define __Pyx_PySequence_SetSlice(obj, a, b, value) (unlikely(!(obj)) ? \
+        (PyErr_SetString(PyExc_SystemError, "null argument to internal routine"), -1) : \
+        (likely((obj)->ob_type->tp_as_mapping) ? (PySequence_SetSlice(obj, a, b, value)) : \
+            (PyErr_Format(PyExc_TypeError, "'%.200s' object doesn't support slice assignment", (obj)->ob_type->tp_name), -1)))
+  #define __Pyx_PySequence_DelSlice(obj, a, b) (unlikely(!(obj)) ? \
+        (PyErr_SetString(PyExc_SystemError, "null argument to internal routine"), -1) : \
+        (likely((obj)->ob_type->tp_as_mapping) ? (PySequence_DelSlice(obj, a, b)) : \
+            (PyErr_Format(PyExc_TypeError, "'%.200s' object doesn't support slice deletion", (obj)->ob_type->tp_name), -1)))
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define PyMethod_New(func, self, klass) ((self) ? PyMethod_New(func, self) : PyInstanceMethod_New(func))
+#endif
+#if PY_VERSION_HEX < 0x02050000
+  #define __Pyx_GetAttrString(o,n)   PyObject_GetAttrString((o),((char *)(n)))
+  #define __Pyx_SetAttrString(o,n,a) PyObject_SetAttrString((o),((char *)(n)),(a))
+  #define __Pyx_DelAttrString(o,n)   PyObject_DelAttrString((o),((char *)(n)))
+#else
+  #define __Pyx_GetAttrString(o,n)   PyObject_GetAttrString((o),(n))
+  #define __Pyx_SetAttrString(o,n,a) PyObject_SetAttrString((o),(n),(a))
+  #define __Pyx_DelAttrString(o,n)   PyObject_DelAttrString((o),(n))
+#endif
+#if PY_VERSION_HEX < 0x02050000
+  #define __Pyx_NAMESTR(n) ((char *)(n))
+  #define __Pyx_DOCSTR(n)  ((char *)(n))
+#else
+  #define __Pyx_NAMESTR(n) (n)
+  #define __Pyx_DOCSTR(n)  (n)
+#endif
+
+
+#if PY_MAJOR_VERSION >= 3
+  #define __Pyx_PyNumber_Divide(x,y)         PyNumber_TrueDivide(x,y)
+  #define __Pyx_PyNumber_InPlaceDivide(x,y)  PyNumber_InPlaceTrueDivide(x,y)
+#else
+  #define __Pyx_PyNumber_Divide(x,y)         PyNumber_Divide(x,y)
+  #define __Pyx_PyNumber_InPlaceDivide(x,y)  PyNumber_InPlaceDivide(x,y)
+#endif
+
+#ifndef __PYX_EXTERN_C
+  #ifdef __cplusplus
+    #define __PYX_EXTERN_C extern "C"
+  #else
+    #define __PYX_EXTERN_C extern
+  #endif
+#endif
+
+#if defined(WIN32) || defined(MS_WINDOWS)
+#define _USE_MATH_DEFINES
+#endif
+#include <math.h>
+#define __PYX_HAVE__bx__motif___pwm
+#define __PYX_HAVE_API__bx__motif___pwm
+#include "numpy/arrayobject.h"
+#ifdef _OPENMP
+#include <omp.h>
+#endif /* _OPENMP */
+
+#ifdef PYREX_WITHOUT_ASSERTIONS
+#define CYTHON_WITHOUT_ASSERTIONS
+#endif
+
+#ifndef CYTHON_INLINE
+  #if defined(__GNUC__)
+    #define CYTHON_INLINE __inline__
+  #elif defined(_MSC_VER)
+    #define CYTHON_INLINE __inline
+  #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+    #define CYTHON_INLINE inline
+  #else
+    #define CYTHON_INLINE
+  #endif
+#endif
+#ifndef CYTHON_UNUSED
+# if defined(__GNUC__)
+#   if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
+#     define CYTHON_UNUSED __attribute__ ((__unused__))
+#   else
+#     define CYTHON_UNUSED
+#   endif
+# elif defined(__ICC) || (defined(__INTEL_COMPILER) && !defined(_MSC_VER))
+#   define CYTHON_UNUSED __attribute__ ((__unused__))
+# else
+#   define CYTHON_UNUSED
+# endif
+#endif
+typedef struct {PyObject **p; char *s; const long n; const char* encoding; const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry; /*proto*/
+
+#define __Pyx_PyBytes_FromUString(s) PyBytes_FromString((char*)s)
+#define __Pyx_PyBytes_AsUString(s)   ((unsigned char*) PyBytes_AsString(s))
+#define __Pyx_Owned_Py_None(b) (Py_INCREF(Py_None), Py_None)
+#define __Pyx_PyBool_FromLong(b) ((b) ? (Py_INCREF(Py_True), Py_True) : (Py_INCREF(Py_False), Py_False))
+static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*);
+static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x);
+static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*);
+static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t);
+static CYTHON_INLINE size_t __Pyx_PyInt_AsSize_t(PyObject*);
+#if CYTHON_COMPILING_IN_CPYTHON
+#define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x))
+#else
+#define __pyx_PyFloat_AsDouble(x) PyFloat_AsDouble(x)
+#endif
+#define __pyx_PyFloat_AsFloat(x) ((float) __pyx_PyFloat_AsDouble(x))
+
+
+#ifdef __GNUC__
+  /* Test for GCC > 2.95 */
+  #if __GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))
+    #define likely(x)   __builtin_expect(!!(x), 1)
+    #define unlikely(x) __builtin_expect(!!(x), 0)
+  #else /* __GNUC__ > 2 ... */
+    #define likely(x)   (x)
+    #define unlikely(x) (x)
+  #endif /* __GNUC__ > 2 ... */
+#else /* __GNUC__ */
+  #define likely(x)   (x)
+  #define unlikely(x) (x)
+#endif /* __GNUC__ */
+    
+static PyObject *__pyx_m;
+static PyObject *__pyx_b;
+static PyObject *__pyx_empty_tuple;
+static PyObject *__pyx_empty_bytes;
+static int __pyx_lineno;
+static int __pyx_clineno = 0;
+static const char * __pyx_cfilenm= __FILE__;
+static const char *__pyx_filename;
+
+
+static const char *__pyx_f[] = {
+  "_pwm.pyx",
+};
+
+/*--- Type declarations ---*/
+#ifndef CYTHON_REFNANNY
+  #define CYTHON_REFNANNY 0
+#endif
+#if CYTHON_REFNANNY
+  typedef struct {
+    void (*INCREF)(void*, PyObject*, int);
+    void (*DECREF)(void*, PyObject*, int);
+    void (*GOTREF)(void*, PyObject*, int);
+    void (*GIVEREF)(void*, PyObject*, int);
+    void* (*SetupContext)(const char*, int, const char*);
+    void (*FinishContext)(void**);
+  } __Pyx_RefNannyAPIStruct;
+  static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL;
+  static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname); /*proto*/
+  #define __Pyx_RefNannyDeclarations void *__pyx_refnanny = NULL;
+#ifdef WITH_THREAD
+  #define __Pyx_RefNannySetupContext(name, acquire_gil) \
+          if (acquire_gil) { \
+              PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure(); \
+              __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__); \
+              PyGILState_Release(__pyx_gilstate_save); \
+          } else { \
+              __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__); \
+          }
+#else
+  #define __Pyx_RefNannySetupContext(name, acquire_gil) \
+          __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__)
+#endif
+  #define __Pyx_RefNannyFinishContext() \
+          __Pyx_RefNanny->FinishContext(&__pyx_refnanny)
+  #define __Pyx_INCREF(r)  __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_DECREF(r)  __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_GOTREF(r)  __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_XINCREF(r)  do { if((r) != NULL) {__Pyx_INCREF(r); }} while(0)
+  #define __Pyx_XDECREF(r)  do { if((r) != NULL) {__Pyx_DECREF(r); }} while(0)
+  #define __Pyx_XGOTREF(r)  do { if((r) != NULL) {__Pyx_GOTREF(r); }} while(0)
+  #define __Pyx_XGIVEREF(r) do { if((r) != NULL) {__Pyx_GIVEREF(r);}} while(0)
+#else
+  #define __Pyx_RefNannyDeclarations
+  #define __Pyx_RefNannySetupContext(name, acquire_gil)
+  #define __Pyx_RefNannyFinishContext()
+  #define __Pyx_INCREF(r) Py_INCREF(r)
+  #define __Pyx_DECREF(r) Py_DECREF(r)
+  #define __Pyx_GOTREF(r)
+  #define __Pyx_GIVEREF(r)
+  #define __Pyx_XINCREF(r) Py_XINCREF(r)
+  #define __Pyx_XDECREF(r) Py_XDECREF(r)
+  #define __Pyx_XGOTREF(r)
+  #define __Pyx_XGIVEREF(r)
+#endif /* CYTHON_REFNANNY */
+#define __Pyx_CLEAR(r)    do { PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);} while(0)
+#define __Pyx_XCLEAR(r)   do { if((r) != NULL) {PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);}} while(0)
+
+static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
+    Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/
+
+static void __Pyx_RaiseDoubleKeywordsError(const char* func_name, PyObject* kw_name); /*proto*/
+
+static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
+    PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
+    const char* function_name); /*proto*/
+
+static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
+    const char *name, int exact); /*proto*/
+
+static CYTHON_INLINE unsigned char __Pyx_PyInt_AsUnsignedChar(PyObject *);
+
+static CYTHON_INLINE unsigned short __Pyx_PyInt_AsUnsignedShort(PyObject *);
+
+static CYTHON_INLINE unsigned int __Pyx_PyInt_AsUnsignedInt(PyObject *);
+
+static CYTHON_INLINE char __Pyx_PyInt_AsChar(PyObject *);
+
+static CYTHON_INLINE short __Pyx_PyInt_AsShort(PyObject *);
+
+static CYTHON_INLINE int __Pyx_PyInt_AsInt(PyObject *);
+
+static CYTHON_INLINE signed char __Pyx_PyInt_AsSignedChar(PyObject *);
+
+static CYTHON_INLINE signed short __Pyx_PyInt_AsSignedShort(PyObject *);
+
+static CYTHON_INLINE signed int __Pyx_PyInt_AsSignedInt(PyObject *);
+
+static CYTHON_INLINE int __Pyx_PyInt_AsLongDouble(PyObject *);
+
+static CYTHON_INLINE unsigned long __Pyx_PyInt_AsUnsignedLong(PyObject *);
+
+static CYTHON_INLINE unsigned PY_LONG_LONG __Pyx_PyInt_AsUnsignedLongLong(PyObject *);
+
+static CYTHON_INLINE long __Pyx_PyInt_AsLong(PyObject *);
+
+static CYTHON_INLINE PY_LONG_LONG __Pyx_PyInt_AsLongLong(PyObject *);
+
+static CYTHON_INLINE signed long __Pyx_PyInt_AsSignedLong(PyObject *);
+
+static CYTHON_INLINE signed PY_LONG_LONG __Pyx_PyInt_AsSignedLongLong(PyObject *);
+
+static int __Pyx_check_binary_version(void);
+
+#if !defined(__Pyx_PyIdentifier_FromString)
+#if PY_MAJOR_VERSION < 3
+  #define __Pyx_PyIdentifier_FromString(s) PyString_FromString(s)
+#else
+  #define __Pyx_PyIdentifier_FromString(s) PyUnicode_FromString(s)
+#endif
+#endif
+
+static PyObject *__Pyx_ImportModule(const char *name); /*proto*/
+
+static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name, size_t size, int strict);  /*proto*/
+
+typedef struct {
+    int code_line;
+    PyCodeObject* code_object;
+} __Pyx_CodeObjectCacheEntry;
+struct __Pyx_CodeObjectCache {
+    int count;
+    int max_count;
+    __Pyx_CodeObjectCacheEntry* entries;
+};
+static struct __Pyx_CodeObjectCache __pyx_code_cache = {0,0,NULL};
+static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line);
+static PyCodeObject *__pyx_find_code_object(int code_line);
+static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object);
+
+static void __Pyx_AddTraceback(const char *funcname, int c_line,
+                               int py_line, const char *filename); /*proto*/
+
+static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
+
+
+/* Module declarations from 'numpy' */
+
+/* Module declarations from 'bx.motif._pwm' */
+static PyTypeObject *__pyx_ptype_2bx_5motif_4_pwm_ndarray = 0;
+#define __Pyx_MODULE_NAME "bx.motif._pwm"
+int __pyx_module_is_main_bx__motif___pwm = 0;
+
+/* Implementation of 'bx.motif._pwm' */
+static PyObject *__pyx_pf_2bx_5motif_4_pwm_score_string(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_matrix, PyArrayObject *__pyx_v_char_to_index, PyObject *__pyx_v_string, PyArrayObject *__pyx_v_rval); /* proto */
+static PyObject *__pyx_pf_2bx_5motif_4_pwm_2score_string_with_gaps(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_matrix, PyArrayObject *__pyx_v_char_to_index, PyObject *__pyx_v_string, PyArrayObject *__pyx_v_rval); /* proto */
+static char __pyx_k_1[] = "\nExtensions used by the `pwm` module.\n";
+static char __pyx_k_4[] = "/aut/proj/odenas/software/bx-python/lib/bx/motif/_pwm.pyx";
+static char __pyx_k_5[] = "bx.motif._pwm";
+static char __pyx_k_8[] = "score_string_with_gaps";
+static char __pyx_k__i[] = "i";
+static char __pyx_k__j[] = "j";
+static char __pyx_k__len[] = "len";
+static char __pyx_k__rval[] = "rval";
+static char __pyx_k__stop[] = "stop";
+static char __pyx_k__score[] = "score";
+static char __pyx_k__buffer[] = "buffer";
+static char __pyx_k__matrix[] = "matrix";
+static char __pyx_k__string[] = "string";
+static char __pyx_k____main__[] = "__main__";
+static char __pyx_k____test__[] = "__test__";
+static char __pyx_k__char_index[] = "char_index";
+static char __pyx_k__string_pos[] = "string_pos";
+static char __pyx_k__matrix_width[] = "matrix_width";
+static char __pyx_k__score_string[] = "score_string";
+static char __pyx_k__char_to_index[] = "char_to_index";
+static PyObject *__pyx_kp_s_4;
+static PyObject *__pyx_n_s_5;
+static PyObject *__pyx_n_s_8;
+static PyObject *__pyx_n_s____main__;
+static PyObject *__pyx_n_s____test__;
+static PyObject *__pyx_n_s__buffer;
+static PyObject *__pyx_n_s__char_index;
+static PyObject *__pyx_n_s__char_to_index;
+static PyObject *__pyx_n_s__i;
+static PyObject *__pyx_n_s__j;
+static PyObject *__pyx_n_s__len;
+static PyObject *__pyx_n_s__matrix;
+static PyObject *__pyx_n_s__matrix_width;
+static PyObject *__pyx_n_s__rval;
+static PyObject *__pyx_n_s__score;
+static PyObject *__pyx_n_s__score_string;
+static PyObject *__pyx_n_s__stop;
+static PyObject *__pyx_n_s__string;
+static PyObject *__pyx_n_s__string_pos;
+static PyObject *__pyx_k_tuple_2;
+static PyObject *__pyx_k_tuple_6;
+static PyObject *__pyx_k_codeobj_3;
+static PyObject *__pyx_k_codeobj_7;
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_5motif_4_pwm_1score_string(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_2bx_5motif_4_pwm_score_string[] = "\n    Score each position in string `string` using the scoring matrix `matrix`.\n    Characters in the string are mapped to columns in the matrix by `char_to_index`\n    and the score for each position is stored in `rval`.\n    \n    matrix *must* be a 2d array of type float32\n    char_to_index *must* be a 1d array of type int16\n    rval *must* be a 1d array of type float32 and the same length as string\n    ";
+static PyMethodDef __pyx_mdef_2bx_5motif_4_pwm_1score_string = {__Pyx_NAMESTR("score_string"), (PyCFunction)__pyx_pw_2bx_5motif_4_pwm_1score_string, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(__pyx_doc_2bx_5motif_4_pwm_score_string)};
+static PyObject *__pyx_pw_2bx_5motif_4_pwm_1score_string(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyArrayObject *__pyx_v_matrix = 0;
+  PyArrayObject *__pyx_v_char_to_index = 0;
+  PyObject *__pyx_v_string = 0;
+  PyArrayObject *__pyx_v_rval = 0;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("score_string (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__matrix,&__pyx_n_s__char_to_index,&__pyx_n_s__string,&__pyx_n_s__rval,0};
+    PyObject* values[4] = {0,0,0,0};
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__matrix)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__char_to_index)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("score_string", 1, 4, 4, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 20; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+        case  2:
+        if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__string)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("score_string", 1, 4, 4, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 20; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+        case  3:
+        if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__rval)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("score_string", 1, 4, 4, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 20; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "score_string") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 20; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else if (PyTuple_GET_SIZE(__pyx_args) != 4) {
+      goto __pyx_L5_argtuple_error;
+    } else {
+      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+      values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+      values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+    }
+    __pyx_v_matrix = ((PyArrayObject *)values[0]);
+    __pyx_v_char_to_index = ((PyArrayObject *)values[1]);
+    __pyx_v_string = values[2];
+    __pyx_v_rval = ((PyArrayObject *)values[3]);
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("score_string", 1, 4, 4, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 20; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.motif._pwm.score_string", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_matrix), __pyx_ptype_2bx_5motif_4_pwm_ndarray, 1, "matrix", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 20; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_char_to_index), __pyx_ptype_2bx_5motif_4_pwm_ndarray, 1, "char_to_index", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 20; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_rval), __pyx_ptype_2bx_5motif_4_pwm_ndarray, 1, "rval", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 20; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_r = __pyx_pf_2bx_5motif_4_pwm_score_string(__pyx_self, __pyx_v_matrix, __pyx_v_char_to_index, __pyx_v_string, __pyx_v_rval);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/motif/_pwm.pyx":20
+ *     ctypedef float npy_float32
+ * 
+ * def score_string( ndarray matrix, ndarray char_to_index, object string, ndarray rval ):             # <<<<<<<<<<<<<<
+ *     """
+ *     Score each position in string `string` using the scoring matrix `matrix`.
+ */
+
+static PyObject *__pyx_pf_2bx_5motif_4_pwm_score_string(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_matrix, PyArrayObject *__pyx_v_char_to_index, PyObject *__pyx_v_string, PyArrayObject *__pyx_v_rval) {
+  char *__pyx_v_buffer;
+  Py_ssize_t __pyx_v_len;
+  float __pyx_v_score;
+  int __pyx_v_i;
+  int __pyx_v_j;
+  int __pyx_v_matrix_width;
+  npy_int16 __pyx_v_char_index;
+  int __pyx_v_stop;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  int __pyx_t_2;
+  int __pyx_t_3;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("score_string", 0);
+
+  /* "bx/motif/_pwm.pyx":34
+ *     cdef float score
+ *     cdef int i, j
+ *     cdef int matrix_width = matrix.dimensions[0]             # <<<<<<<<<<<<<<
+ *     cdef npy_int16 char_index
+ *     # Get input string as character pointer
+ */
+  __pyx_v_matrix_width = (__pyx_v_matrix->dimensions[0]);
+
+  /* "bx/motif/_pwm.pyx":37
+ *     cdef npy_int16 char_index
+ *     # Get input string as character pointer
+ *     PyString_AsStringAndSize( string, &buffer, &len )             # <<<<<<<<<<<<<<
+ *     # Loop over each position in the string
+ *     cdef int stop = len - matrix.dimensions[0] + 1
+ */
+  __pyx_t_1 = PyString_AsStringAndSize(__pyx_v_string, (&__pyx_v_buffer), (&__pyx_v_len)); if (unlikely(__pyx_t_1 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 37; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "bx/motif/_pwm.pyx":39
+ *     PyString_AsStringAndSize( string, &buffer, &len )
+ *     # Loop over each position in the string
+ *     cdef int stop = len - matrix.dimensions[0] + 1             # <<<<<<<<<<<<<<
+ *     for i from 0 <= i < stop:
+ *         score = 0.0
+ */
+  __pyx_v_stop = ((__pyx_v_len - (__pyx_v_matrix->dimensions[0])) + 1);
+
+  /* "bx/motif/_pwm.pyx":40
+ *     # Loop over each position in the string
+ *     cdef int stop = len - matrix.dimensions[0] + 1
+ *     for i from 0 <= i < stop:             # <<<<<<<<<<<<<<
+ *         score = 0.0
+ *         for j from 0 <= j < matrix_width:
+ */
+  __pyx_t_1 = __pyx_v_stop;
+  for (__pyx_v_i = 0; __pyx_v_i < __pyx_t_1; __pyx_v_i++) {
+
+    /* "bx/motif/_pwm.pyx":41
+ *     cdef int stop = len - matrix.dimensions[0] + 1
+ *     for i from 0 <= i < stop:
+ *         score = 0.0             # <<<<<<<<<<<<<<
+ *         for j from 0 <= j < matrix_width:
+ *             char_index = ( <npy_int16 *> ( char_to_index.data + buffer[i+j] * char_to_index.strides[0] ) )[0]
+ */
+    __pyx_v_score = 0.0;
+
+    /* "bx/motif/_pwm.pyx":42
+ *     for i from 0 <= i < stop:
+ *         score = 0.0
+ *         for j from 0 <= j < matrix_width:             # <<<<<<<<<<<<<<
+ *             char_index = ( <npy_int16 *> ( char_to_index.data + buffer[i+j] * char_to_index.strides[0] ) )[0]
+ *             if char_index < 0:
+ */
+    __pyx_t_2 = __pyx_v_matrix_width;
+    for (__pyx_v_j = 0; __pyx_v_j < __pyx_t_2; __pyx_v_j++) {
+
+      /* "bx/motif/_pwm.pyx":43
+ *         score = 0.0
+ *         for j from 0 <= j < matrix_width:
+ *             char_index = ( <npy_int16 *> ( char_to_index.data + buffer[i+j] * char_to_index.strides[0] ) )[0]             # <<<<<<<<<<<<<<
+ *             if char_index < 0:
+ *                 break
+ */
+      __pyx_v_char_index = (((npy_int16 *)(__pyx_v_char_to_index->data + ((__pyx_v_buffer[(__pyx_v_i + __pyx_v_j)]) * (__pyx_v_char_to_index->strides[0]))))[0]);
+
+      /* "bx/motif/_pwm.pyx":44
+ *         for j from 0 <= j < matrix_width:
+ *             char_index = ( <npy_int16 *> ( char_to_index.data + buffer[i+j] * char_to_index.strides[0] ) )[0]
+ *             if char_index < 0:             # <<<<<<<<<<<<<<
+ *                 break
+ *             score += ( <npy_float32*> ( matrix.data + j * matrix.strides[0] + char_index * matrix.strides[1] ) )[0]
+ */
+      __pyx_t_3 = (__pyx_v_char_index < 0);
+      if (__pyx_t_3) {
+
+        /* "bx/motif/_pwm.pyx":45
+ *             char_index = ( <npy_int16 *> ( char_to_index.data + buffer[i+j] * char_to_index.strides[0] ) )[0]
+ *             if char_index < 0:
+ *                 break             # <<<<<<<<<<<<<<
+ *             score += ( <npy_float32*> ( matrix.data + j * matrix.strides[0] + char_index * matrix.strides[1] ) )[0]
+ *         else:
+ */
+        goto __pyx_L6_break;
+        goto __pyx_L7;
+      }
+      __pyx_L7:;
+
+      /* "bx/motif/_pwm.pyx":46
+ *             if char_index < 0:
+ *                 break
+ *             score += ( <npy_float32*> ( matrix.data + j * matrix.strides[0] + char_index * matrix.strides[1] ) )[0]             # <<<<<<<<<<<<<<
+ *         else:
+ *             ( <npy_float32*> ( rval.data + i * rval.strides[0] ) )[0] = score
+ */
+      __pyx_v_score = (__pyx_v_score + (((npy_float32 *)((__pyx_v_matrix->data + (__pyx_v_j * (__pyx_v_matrix->strides[0]))) + (__pyx_v_char_index * (__pyx_v_matrix->strides[1]))))[0]));
+    }
+    /*else*/ {
+
+      /* "bx/motif/_pwm.pyx":48
+ *             score += ( <npy_float32*> ( matrix.data + j * matrix.strides[0] + char_index * matrix.strides[1] ) )[0]
+ *         else:
+ *             ( <npy_float32*> ( rval.data + i * rval.strides[0] ) )[0] = score             # <<<<<<<<<<<<<<
+ * 
+ * def score_string_with_gaps( ndarray matrix, ndarray char_to_index, object string, ndarray rval ):
+ */
+      (((npy_float32 *)(__pyx_v_rval->data + (__pyx_v_i * (__pyx_v_rval->strides[0]))))[0]) = __pyx_v_score;
+    }
+    __pyx_L6_break:;
+  }
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_AddTraceback("bx.motif._pwm.score_string", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_5motif_4_pwm_3score_string_with_gaps(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_2bx_5motif_4_pwm_2score_string_with_gaps[] = "\n    Score each position in string `string` using the scoring matrix `matrix`.\n    Characters in the string are mapped to columns in the matrix by `char_to_index`\n    and the score for each position is stored in `rval`.\n\n    matrix *must* be a 2d array of type float32\n    char_to_index *must* be a 1d array of type int16\n    rval *must* be a 1d array of type float32 and the same length as string\n    ";
+static PyMethodDef __pyx_mdef_2bx_5motif_4_pwm_3score_string_with_gaps = {__Pyx_NAMESTR("score_string_with_gaps"), (PyCFunction)__pyx_pw_2bx_5motif_4_pwm_3score_string_with_gaps, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(__pyx_doc_2bx_5motif_4_pwm_2score_string_with_gaps)};
+static PyObject *__pyx_pw_2bx_5motif_4_pwm_3score_string_with_gaps(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyArrayObject *__pyx_v_matrix = 0;
+  PyArrayObject *__pyx_v_char_to_index = 0;
+  PyObject *__pyx_v_string = 0;
+  PyArrayObject *__pyx_v_rval = 0;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("score_string_with_gaps (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__matrix,&__pyx_n_s__char_to_index,&__pyx_n_s__string,&__pyx_n_s__rval,0};
+    PyObject* values[4] = {0,0,0,0};
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__matrix)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__char_to_index)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("score_string_with_gaps", 1, 4, 4, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 50; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+        case  2:
+        if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__string)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("score_string_with_gaps", 1, 4, 4, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 50; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+        case  3:
+        if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__rval)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("score_string_with_gaps", 1, 4, 4, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 50; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "score_string_with_gaps") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 50; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else if (PyTuple_GET_SIZE(__pyx_args) != 4) {
+      goto __pyx_L5_argtuple_error;
+    } else {
+      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+      values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+      values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+    }
+    __pyx_v_matrix = ((PyArrayObject *)values[0]);
+    __pyx_v_char_to_index = ((PyArrayObject *)values[1]);
+    __pyx_v_string = values[2];
+    __pyx_v_rval = ((PyArrayObject *)values[3]);
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("score_string_with_gaps", 1, 4, 4, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 50; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.motif._pwm.score_string_with_gaps", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_matrix), __pyx_ptype_2bx_5motif_4_pwm_ndarray, 1, "matrix", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 50; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_char_to_index), __pyx_ptype_2bx_5motif_4_pwm_ndarray, 1, "char_to_index", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 50; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_rval), __pyx_ptype_2bx_5motif_4_pwm_ndarray, 1, "rval", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 50; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_r = __pyx_pf_2bx_5motif_4_pwm_2score_string_with_gaps(__pyx_self, __pyx_v_matrix, __pyx_v_char_to_index, __pyx_v_string, __pyx_v_rval);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/motif/_pwm.pyx":50
+ *             ( <npy_float32*> ( rval.data + i * rval.strides[0] ) )[0] = score
+ * 
+ * def score_string_with_gaps( ndarray matrix, ndarray char_to_index, object string, ndarray rval ):             # <<<<<<<<<<<<<<
+ *     """
+ *     Score each position in string `string` using the scoring matrix `matrix`.
+ */
+
+static PyObject *__pyx_pf_2bx_5motif_4_pwm_2score_string_with_gaps(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_matrix, PyArrayObject *__pyx_v_char_to_index, PyObject *__pyx_v_string, PyArrayObject *__pyx_v_rval) {
+  char *__pyx_v_buffer;
+  Py_ssize_t __pyx_v_len;
+  float __pyx_v_score;
+  int __pyx_v_i;
+  int __pyx_v_j;
+  int __pyx_v_string_pos;
+  int __pyx_v_matrix_width;
+  npy_int16 __pyx_v_char_index;
+  int __pyx_v_stop;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  int __pyx_t_2;
+  int __pyx_t_3;
+  int __pyx_t_4;
+  int __pyx_t_5;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("score_string_with_gaps", 0);
+
+  /* "bx/motif/_pwm.pyx":64
+ *     cdef float score
+ *     cdef int i, j, string_pos
+ *     cdef int matrix_width = matrix.dimensions[0]             # <<<<<<<<<<<<<<
+ *     cdef npy_int16 char_index
+ *     # Get input string as character pointer
+ */
+  __pyx_v_matrix_width = (__pyx_v_matrix->dimensions[0]);
+
+  /* "bx/motif/_pwm.pyx":67
+ *     cdef npy_int16 char_index
+ *     # Get input string as character pointer
+ *     PyString_AsStringAndSize( string, &buffer, &len )             # <<<<<<<<<<<<<<
+ *     # Loop over each position in the string
+ *     cdef int stop = len - matrix.dimensions[0] + 1
+ */
+  __pyx_t_1 = PyString_AsStringAndSize(__pyx_v_string, (&__pyx_v_buffer), (&__pyx_v_len)); if (unlikely(__pyx_t_1 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 67; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "bx/motif/_pwm.pyx":69
+ *     PyString_AsStringAndSize( string, &buffer, &len )
+ *     # Loop over each position in the string
+ *     cdef int stop = len - matrix.dimensions[0] + 1             # <<<<<<<<<<<<<<
+ *     for i from 0 <= i < stop:
+ *         if buffer[i] == '-':
+ */
+  __pyx_v_stop = ((__pyx_v_len - (__pyx_v_matrix->dimensions[0])) + 1);
+
+  /* "bx/motif/_pwm.pyx":70
+ *     # Loop over each position in the string
+ *     cdef int stop = len - matrix.dimensions[0] + 1
+ *     for i from 0 <= i < stop:             # <<<<<<<<<<<<<<
+ *         if buffer[i] == '-':
+ *             # Never start scoring at a gap
+ */
+  __pyx_t_1 = __pyx_v_stop;
+  for (__pyx_v_i = 0; __pyx_v_i < __pyx_t_1; __pyx_v_i++) {
+
+    /* "bx/motif/_pwm.pyx":71
+ *     cdef int stop = len - matrix.dimensions[0] + 1
+ *     for i from 0 <= i < stop:
+ *         if buffer[i] == '-':             # <<<<<<<<<<<<<<
+ *             # Never start scoring at a gap
+ *             continue
+ */
+    __pyx_t_2 = ((__pyx_v_buffer[__pyx_v_i]) == '-');
+    if (__pyx_t_2) {
+
+      /* "bx/motif/_pwm.pyx":73
+ *         if buffer[i] == '-':
+ *             # Never start scoring at a gap
+ *             continue             # <<<<<<<<<<<<<<
+ *         score = 0.0
+ *         string_pos = i
+ */
+      goto __pyx_L3_continue;
+      goto __pyx_L5;
+    }
+    __pyx_L5:;
+
+    /* "bx/motif/_pwm.pyx":74
+ *             # Never start scoring at a gap
+ *             continue
+ *         score = 0.0             # <<<<<<<<<<<<<<
+ *         string_pos = i
+ *         for j from 0 <= j < matrix_width:
+ */
+    __pyx_v_score = 0.0;
+
+    /* "bx/motif/_pwm.pyx":75
+ *             continue
+ *         score = 0.0
+ *         string_pos = i             # <<<<<<<<<<<<<<
+ *         for j from 0 <= j < matrix_width:
+ *             # Advance to the next non-gap character
+ */
+    __pyx_v_string_pos = __pyx_v_i;
+
+    /* "bx/motif/_pwm.pyx":76
+ *         score = 0.0
+ *         string_pos = i
+ *         for j from 0 <= j < matrix_width:             # <<<<<<<<<<<<<<
+ *             # Advance to the next non-gap character
+ *             while buffer[string_pos] == '-' and string_pos < len:
+ */
+    __pyx_t_3 = __pyx_v_matrix_width;
+    for (__pyx_v_j = 0; __pyx_v_j < __pyx_t_3; __pyx_v_j++) {
+
+      /* "bx/motif/_pwm.pyx":78
+ *         for j from 0 <= j < matrix_width:
+ *             # Advance to the next non-gap character
+ *             while buffer[string_pos] == '-' and string_pos < len:             # <<<<<<<<<<<<<<
+ *                 string_pos += 1
+ *             # Ran out of non-gap characters, no more scoring is possible
+ */
+      while (1) {
+        __pyx_t_2 = ((__pyx_v_buffer[__pyx_v_string_pos]) == '-');
+        if (__pyx_t_2) {
+          __pyx_t_4 = (__pyx_v_string_pos < __pyx_v_len);
+          __pyx_t_5 = __pyx_t_4;
+        } else {
+          __pyx_t_5 = __pyx_t_2;
+        }
+        if (!__pyx_t_5) break;
+
+        /* "bx/motif/_pwm.pyx":79
+ *             # Advance to the next non-gap character
+ *             while buffer[string_pos] == '-' and string_pos < len:
+ *                 string_pos += 1             # <<<<<<<<<<<<<<
+ *             # Ran out of non-gap characters, no more scoring is possible
+ *             if string_pos == len:
+ */
+        __pyx_v_string_pos = (__pyx_v_string_pos + 1);
+      }
+
+      /* "bx/motif/_pwm.pyx":81
+ *                 string_pos += 1
+ *             # Ran out of non-gap characters, no more scoring is possible
+ *             if string_pos == len:             # <<<<<<<<<<<<<<
+ *                 return
+ *             # Find character for position and score
+ */
+      __pyx_t_5 = (__pyx_v_string_pos == __pyx_v_len);
+      if (__pyx_t_5) {
+
+        /* "bx/motif/_pwm.pyx":82
+ *             # Ran out of non-gap characters, no more scoring is possible
+ *             if string_pos == len:
+ *                 return             # <<<<<<<<<<<<<<
+ *             # Find character for position and score
+ *             char_index = ( <npy_int16 *> ( char_to_index.data + buffer[string_pos] * char_to_index.strides[0] ) )[0]
+ */
+        __Pyx_XDECREF(__pyx_r);
+        __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+        goto __pyx_L0;
+        goto __pyx_L10;
+      }
+      __pyx_L10:;
+
+      /* "bx/motif/_pwm.pyx":84
+ *                 return
+ *             # Find character for position and score
+ *             char_index = ( <npy_int16 *> ( char_to_index.data + buffer[string_pos] * char_to_index.strides[0] ) )[0]             # <<<<<<<<<<<<<<
+ *             if char_index < 0:
+ *                 break
+ */
+      __pyx_v_char_index = (((npy_int16 *)(__pyx_v_char_to_index->data + ((__pyx_v_buffer[__pyx_v_string_pos]) * (__pyx_v_char_to_index->strides[0]))))[0]);
+
+      /* "bx/motif/_pwm.pyx":85
+ *             # Find character for position and score
+ *             char_index = ( <npy_int16 *> ( char_to_index.data + buffer[string_pos] * char_to_index.strides[0] ) )[0]
+ *             if char_index < 0:             # <<<<<<<<<<<<<<
+ *                 break
+ *             score += ( <npy_float32*> ( matrix.data + j * matrix.strides[0] + char_index * matrix.strides[1] ) )[0]
+ */
+      __pyx_t_5 = (__pyx_v_char_index < 0);
+      if (__pyx_t_5) {
+
+        /* "bx/motif/_pwm.pyx":86
+ *             char_index = ( <npy_int16 *> ( char_to_index.data + buffer[string_pos] * char_to_index.strides[0] ) )[0]
+ *             if char_index < 0:
+ *                 break             # <<<<<<<<<<<<<<
+ *             score += ( <npy_float32*> ( matrix.data + j * matrix.strides[0] + char_index * matrix.strides[1] ) )[0]
+ *             # Matched a character, move forward
+ */
+        goto __pyx_L7_break;
+        goto __pyx_L11;
+      }
+      __pyx_L11:;
+
+      /* "bx/motif/_pwm.pyx":87
+ *             if char_index < 0:
+ *                 break
+ *             score += ( <npy_float32*> ( matrix.data + j * matrix.strides[0] + char_index * matrix.strides[1] ) )[0]             # <<<<<<<<<<<<<<
+ *             # Matched a character, move forward
+ *             string_pos += 1
+ */
+      __pyx_v_score = (__pyx_v_score + (((npy_float32 *)((__pyx_v_matrix->data + (__pyx_v_j * (__pyx_v_matrix->strides[0]))) + (__pyx_v_char_index * (__pyx_v_matrix->strides[1]))))[0]));
+
+      /* "bx/motif/_pwm.pyx":89
+ *             score += ( <npy_float32*> ( matrix.data + j * matrix.strides[0] + char_index * matrix.strides[1] ) )[0]
+ *             # Matched a character, move forward
+ *             string_pos += 1             # <<<<<<<<<<<<<<
+ *         else:
+ *             ( <npy_float32*> ( rval.data + i * rval.strides[0] ) )[0] = score
+ */
+      __pyx_v_string_pos = (__pyx_v_string_pos + 1);
+    }
+    /*else*/ {
+
+      /* "bx/motif/_pwm.pyx":91
+ *             string_pos += 1
+ *         else:
+ *             ( <npy_float32*> ( rval.data + i * rval.strides[0] ) )[0] = score             # <<<<<<<<<<<<<<
+ */
+      (((npy_float32 *)(__pyx_v_rval->data + (__pyx_v_i * (__pyx_v_rval->strides[0]))))[0]) = __pyx_v_score;
+    }
+    __pyx_L7_break:;
+    __pyx_L3_continue:;
+  }
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_AddTraceback("bx.motif._pwm.score_string_with_gaps", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyMethodDef __pyx_methods[] = {
+  {0, 0, 0, 0}
+};
+
+#if PY_MAJOR_VERSION >= 3
+static struct PyModuleDef __pyx_moduledef = {
+  #if PY_VERSION_HEX < 0x03020000
+    { PyObject_HEAD_INIT(NULL) NULL, 0, NULL },
+  #else
+    PyModuleDef_HEAD_INIT,
+  #endif
+    __Pyx_NAMESTR("_pwm"),
+    __Pyx_DOCSTR(__pyx_k_1), /* m_doc */
+    -1, /* m_size */
+    __pyx_methods /* m_methods */,
+    NULL, /* m_reload */
+    NULL, /* m_traverse */
+    NULL, /* m_clear */
+    NULL /* m_free */
+};
+#endif
+
+static __Pyx_StringTabEntry __pyx_string_tab[] = {
+  {&__pyx_kp_s_4, __pyx_k_4, sizeof(__pyx_k_4), 0, 0, 1, 0},
+  {&__pyx_n_s_5, __pyx_k_5, sizeof(__pyx_k_5), 0, 0, 1, 1},
+  {&__pyx_n_s_8, __pyx_k_8, sizeof(__pyx_k_8), 0, 0, 1, 1},
+  {&__pyx_n_s____main__, __pyx_k____main__, sizeof(__pyx_k____main__), 0, 0, 1, 1},
+  {&__pyx_n_s____test__, __pyx_k____test__, sizeof(__pyx_k____test__), 0, 0, 1, 1},
+  {&__pyx_n_s__buffer, __pyx_k__buffer, sizeof(__pyx_k__buffer), 0, 0, 1, 1},
+  {&__pyx_n_s__char_index, __pyx_k__char_index, sizeof(__pyx_k__char_index), 0, 0, 1, 1},
+  {&__pyx_n_s__char_to_index, __pyx_k__char_to_index, sizeof(__pyx_k__char_to_index), 0, 0, 1, 1},
+  {&__pyx_n_s__i, __pyx_k__i, sizeof(__pyx_k__i), 0, 0, 1, 1},
+  {&__pyx_n_s__j, __pyx_k__j, sizeof(__pyx_k__j), 0, 0, 1, 1},
+  {&__pyx_n_s__len, __pyx_k__len, sizeof(__pyx_k__len), 0, 0, 1, 1},
+  {&__pyx_n_s__matrix, __pyx_k__matrix, sizeof(__pyx_k__matrix), 0, 0, 1, 1},
+  {&__pyx_n_s__matrix_width, __pyx_k__matrix_width, sizeof(__pyx_k__matrix_width), 0, 0, 1, 1},
+  {&__pyx_n_s__rval, __pyx_k__rval, sizeof(__pyx_k__rval), 0, 0, 1, 1},
+  {&__pyx_n_s__score, __pyx_k__score, sizeof(__pyx_k__score), 0, 0, 1, 1},
+  {&__pyx_n_s__score_string, __pyx_k__score_string, sizeof(__pyx_k__score_string), 0, 0, 1, 1},
+  {&__pyx_n_s__stop, __pyx_k__stop, sizeof(__pyx_k__stop), 0, 0, 1, 1},
+  {&__pyx_n_s__string, __pyx_k__string, sizeof(__pyx_k__string), 0, 0, 1, 1},
+  {&__pyx_n_s__string_pos, __pyx_k__string_pos, sizeof(__pyx_k__string_pos), 0, 0, 1, 1},
+  {0, 0, 0, 0, 0, 0, 0}
+};
+static int __Pyx_InitCachedBuiltins(void) {
+  return 0;
+}
+
+static int __Pyx_InitCachedConstants(void) {
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0);
+
+  /* "bx/motif/_pwm.pyx":20
+ *     ctypedef float npy_float32
+ * 
+ * def score_string( ndarray matrix, ndarray char_to_index, object string, ndarray rval ):             # <<<<<<<<<<<<<<
+ *     """
+ *     Score each position in string `string` using the scoring matrix `matrix`.
+ */
+  __pyx_k_tuple_2 = PyTuple_Pack(12, ((PyObject *)__pyx_n_s__matrix), ((PyObject *)__pyx_n_s__char_to_index), ((PyObject *)__pyx_n_s__string), ((PyObject *)__pyx_n_s__rval), ((PyObject *)__pyx_n_s__buffer), ((PyObject *)__pyx_n_s__len), ((PyObject *)__pyx_n_s__score), ((PyObject *)__pyx_n_s__i), ((PyObject *)__pyx_n_s__j), ((PyObject *)__pyx_n_s__matrix_width), ((PyObject *)__pyx_n_s__char_index), ((PyObject *)__pyx_n_s__stop)); if (unlikely(!__pyx_k_tuple_2)) {__pyx_filename = __pyx_f[0 [...]
+  __Pyx_GOTREF(__pyx_k_tuple_2);
+  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_2));
+  __pyx_k_codeobj_3 = (PyObject*)__Pyx_PyCode_New(4, 0, 12, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_k_tuple_2, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_4, __pyx_n_s__score_string, 20, __pyx_empty_bytes); if (unlikely(!__pyx_k_codeobj_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 20; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "bx/motif/_pwm.pyx":50
+ *             ( <npy_float32*> ( rval.data + i * rval.strides[0] ) )[0] = score
+ * 
+ * def score_string_with_gaps( ndarray matrix, ndarray char_to_index, object string, ndarray rval ):             # <<<<<<<<<<<<<<
+ *     """
+ *     Score each position in string `string` using the scoring matrix `matrix`.
+ */
+  __pyx_k_tuple_6 = PyTuple_Pack(13, ((PyObject *)__pyx_n_s__matrix), ((PyObject *)__pyx_n_s__char_to_index), ((PyObject *)__pyx_n_s__string), ((PyObject *)__pyx_n_s__rval), ((PyObject *)__pyx_n_s__buffer), ((PyObject *)__pyx_n_s__len), ((PyObject *)__pyx_n_s__score), ((PyObject *)__pyx_n_s__i), ((PyObject *)__pyx_n_s__j), ((PyObject *)__pyx_n_s__string_pos), ((PyObject *)__pyx_n_s__matrix_width), ((PyObject *)__pyx_n_s__char_index), ((PyObject *)__pyx_n_s__stop)); if (unlikely(!__pyx_k_ [...]
+  __Pyx_GOTREF(__pyx_k_tuple_6);
+  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_6));
+  __pyx_k_codeobj_7 = (PyObject*)__Pyx_PyCode_New(4, 0, 13, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_k_tuple_6, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_4, __pyx_n_s_8, 50, __pyx_empty_bytes); if (unlikely(!__pyx_k_codeobj_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 50; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_RefNannyFinishContext();
+  return 0;
+  __pyx_L1_error:;
+  __Pyx_RefNannyFinishContext();
+  return -1;
+}
+
+static int __Pyx_InitGlobals(void) {
+  if (__Pyx_InitStrings(__pyx_string_tab) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  return 0;
+  __pyx_L1_error:;
+  return -1;
+}
+
+#if PY_MAJOR_VERSION < 3
+PyMODINIT_FUNC init_pwm(void); /*proto*/
+PyMODINIT_FUNC init_pwm(void)
+#else
+PyMODINIT_FUNC PyInit__pwm(void); /*proto*/
+PyMODINIT_FUNC PyInit__pwm(void)
+#endif
+{
+  PyObject *__pyx_t_1 = NULL;
+  __Pyx_RefNannyDeclarations
+  #if CYTHON_REFNANNY
+  __Pyx_RefNanny = __Pyx_RefNannyImportAPI("refnanny");
+  if (!__Pyx_RefNanny) {
+      PyErr_Clear();
+      __Pyx_RefNanny = __Pyx_RefNannyImportAPI("Cython.Runtime.refnanny");
+      if (!__Pyx_RefNanny)
+          Py_FatalError("failed to import 'refnanny' module");
+  }
+  #endif
+  __Pyx_RefNannySetupContext("PyMODINIT_FUNC PyInit__pwm(void)", 0);
+  if ( __Pyx_check_binary_version() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_bytes)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #ifdef __Pyx_CyFunction_USED
+  if (__Pyx_CyFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #endif
+  #ifdef __Pyx_FusedFunction_USED
+  if (__pyx_FusedFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #endif
+  #ifdef __Pyx_Generator_USED
+  if (__pyx_Generator_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #endif
+  /*--- Library function declarations ---*/
+  /*--- Threads initialization code ---*/
+  #if defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS
+  #ifdef WITH_THREAD /* Python build with threading support? */
+  PyEval_InitThreads();
+  #endif
+  #endif
+  /*--- Module creation code ---*/
+  #if PY_MAJOR_VERSION < 3
+  __pyx_m = Py_InitModule4(__Pyx_NAMESTR("_pwm"), __pyx_methods, __Pyx_DOCSTR(__pyx_k_1), 0, PYTHON_API_VERSION); Py_XINCREF(__pyx_m);
+  #else
+  __pyx_m = PyModule_Create(&__pyx_moduledef);
+  #endif
+  if (unlikely(!__pyx_m)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #if PY_MAJOR_VERSION >= 3
+  {
+    PyObject *modules = PyImport_GetModuleDict(); if (unlikely(!modules)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (!PyDict_GetItemString(modules, "bx.motif._pwm")) {
+      if (unlikely(PyDict_SetItemString(modules, "bx.motif._pwm", __pyx_m) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+  }
+  #endif
+  __pyx_b = PyImport_AddModule(__Pyx_NAMESTR(__Pyx_BUILTIN_MODULE_NAME)); if (unlikely(!__pyx_b)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #if CYTHON_COMPILING_IN_PYPY
+  Py_INCREF(__pyx_b);
+  #endif
+  if (__Pyx_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  /*--- Initialize various global constants etc. ---*/
+  if (unlikely(__Pyx_InitGlobals() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (__pyx_module_is_main_bx__motif___pwm) {
+    if (__Pyx_SetAttrString(__pyx_m, "__name__", __pyx_n_s____main__) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  }
+  /*--- Builtin init code ---*/
+  if (unlikely(__Pyx_InitCachedBuiltins() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  /*--- Constants init code ---*/
+  if (unlikely(__Pyx_InitCachedConstants() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  /*--- Global init code ---*/
+  /*--- Variable export code ---*/
+  /*--- Function export code ---*/
+  /*--- Type init code ---*/
+  __pyx_ptype_2bx_5motif_4_pwm_ndarray = __Pyx_ImportType("numpy", "ndarray", sizeof(PyArrayObject), 0); if (unlikely(!__pyx_ptype_2bx_5motif_4_pwm_ndarray)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 10; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  /*--- Type import code ---*/
+  /*--- Variable import code ---*/
+  /*--- Function import code ---*/
+  /*--- Execution code ---*/
+
+  /* "bx/motif/_pwm.pyx":20
+ *     ctypedef float npy_float32
+ * 
+ * def score_string( ndarray matrix, ndarray char_to_index, object string, ndarray rval ):             # <<<<<<<<<<<<<<
+ *     """
+ *     Score each position in string `string` using the scoring matrix `matrix`.
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_2bx_5motif_4_pwm_1score_string, NULL, __pyx_n_s_5); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 20; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s__score_string, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 20; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "bx/motif/_pwm.pyx":50
+ *             ( <npy_float32*> ( rval.data + i * rval.strides[0] ) )[0] = score
+ * 
+ * def score_string_with_gaps( ndarray matrix, ndarray char_to_index, object string, ndarray rval ):             # <<<<<<<<<<<<<<
+ *     """
+ *     Score each position in string `string` using the scoring matrix `matrix`.
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_2bx_5motif_4_pwm_3score_string_with_gaps, NULL, __pyx_n_s_5); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 50; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_8, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 50; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "bx/motif/_pwm.pyx":1
+ * """             # <<<<<<<<<<<<<<
+ * Extensions used by the `pwm` module.
+ * """
+ */
+  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(((PyObject *)__pyx_t_1));
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s____test__, ((PyObject *)__pyx_t_1)) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  if (__pyx_m) {
+    __Pyx_AddTraceback("init bx.motif._pwm", __pyx_clineno, __pyx_lineno, __pyx_filename);
+    Py_DECREF(__pyx_m); __pyx_m = 0;
+  } else if (!PyErr_Occurred()) {
+    PyErr_SetString(PyExc_ImportError, "init bx.motif._pwm");
+  }
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  #if PY_MAJOR_VERSION < 3
+  return;
+  #else
+  return __pyx_m;
+  #endif
+}
+
+/* Runtime support code */
+#if CYTHON_REFNANNY
+static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) {
+    PyObject *m = NULL, *p = NULL;
+    void *r = NULL;
+    m = PyImport_ImportModule((char *)modname);
+    if (!m) goto end;
+    p = PyObject_GetAttrString(m, (char *)"RefNannyAPI");
+    if (!p) goto end;
+    r = PyLong_AsVoidPtr(p);
+end:
+    Py_XDECREF(p);
+    Py_XDECREF(m);
+    return (__Pyx_RefNannyAPIStruct *)r;
+}
+#endif /* CYTHON_REFNANNY */
+
+static void __Pyx_RaiseArgtupleInvalid(
+    const char* func_name,
+    int exact,
+    Py_ssize_t num_min,
+    Py_ssize_t num_max,
+    Py_ssize_t num_found)
+{
+    Py_ssize_t num_expected;
+    const char *more_or_less;
+    if (num_found < num_min) {
+        num_expected = num_min;
+        more_or_less = "at least";
+    } else {
+        num_expected = num_max;
+        more_or_less = "at most";
+    }
+    if (exact) {
+        more_or_less = "exactly";
+    }
+    PyErr_Format(PyExc_TypeError,
+                 "%s() takes %s %" CYTHON_FORMAT_SSIZE_T "d positional argument%s (%" CYTHON_FORMAT_SSIZE_T "d given)",
+                 func_name, more_or_less, num_expected,
+                 (num_expected == 1) ? "" : "s", num_found);
+}
+
+static void __Pyx_RaiseDoubleKeywordsError(
+    const char* func_name,
+    PyObject* kw_name)
+{
+    PyErr_Format(PyExc_TypeError,
+        #if PY_MAJOR_VERSION >= 3
+        "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
+        #else
+        "%s() got multiple values for keyword argument '%s'", func_name,
+        PyString_AsString(kw_name));
+        #endif
+}
+
+static int __Pyx_ParseOptionalKeywords(
+    PyObject *kwds,
+    PyObject **argnames[],
+    PyObject *kwds2,
+    PyObject *values[],
+    Py_ssize_t num_pos_args,
+    const char* function_name)
+{
+    PyObject *key = 0, *value = 0;
+    Py_ssize_t pos = 0;
+    PyObject*** name;
+    PyObject*** first_kw_arg = argnames + num_pos_args;
+    while (PyDict_Next(kwds, &pos, &key, &value)) {
+        name = first_kw_arg;
+        while (*name && (**name != key)) name++;
+        if (*name) {
+            values[name-argnames] = value;
+            continue;
+        }
+        name = first_kw_arg;
+        #if PY_MAJOR_VERSION < 3
+        if (likely(PyString_CheckExact(key)) || likely(PyString_Check(key))) {
+            while (*name) {
+                if ((CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**name) == PyString_GET_SIZE(key))
+                        && _PyString_Eq(**name, key)) {
+                    values[name-argnames] = value;
+                    break;
+                }
+                name++;
+            }
+            if (*name) continue;
+            else {
+                PyObject*** argname = argnames;
+                while (argname != first_kw_arg) {
+                    if ((**argname == key) || (
+                            (CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**argname) == PyString_GET_SIZE(key))
+                             && _PyString_Eq(**argname, key))) {
+                        goto arg_passed_twice;
+                    }
+                    argname++;
+                }
+            }
+        } else
+        #endif
+        if (likely(PyUnicode_Check(key))) {
+            while (*name) {
+                int cmp = (**name == key) ? 0 :
+                #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3
+                    (PyUnicode_GET_SIZE(**name) != PyUnicode_GET_SIZE(key)) ? 1 :
+                #endif
+                    PyUnicode_Compare(**name, key);
+                if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad;
+                if (cmp == 0) {
+                    values[name-argnames] = value;
+                    break;
+                }
+                name++;
+            }
+            if (*name) continue;
+            else {
+                PyObject*** argname = argnames;
+                while (argname != first_kw_arg) {
+                    int cmp = (**argname == key) ? 0 :
+                    #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3
+                        (PyUnicode_GET_SIZE(**argname) != PyUnicode_GET_SIZE(key)) ? 1 :
+                    #endif
+                        PyUnicode_Compare(**argname, key);
+                    if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad;
+                    if (cmp == 0) goto arg_passed_twice;
+                    argname++;
+                }
+            }
+        } else
+            goto invalid_keyword_type;
+        if (kwds2) {
+            if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
+        } else {
+            goto invalid_keyword;
+        }
+    }
+    return 0;
+arg_passed_twice:
+    __Pyx_RaiseDoubleKeywordsError(function_name, key);
+    goto bad;
+invalid_keyword_type:
+    PyErr_Format(PyExc_TypeError,
+        "%s() keywords must be strings", function_name);
+    goto bad;
+invalid_keyword:
+    PyErr_Format(PyExc_TypeError,
+    #if PY_MAJOR_VERSION < 3
+        "%s() got an unexpected keyword argument '%s'",
+        function_name, PyString_AsString(key));
+    #else
+        "%s() got an unexpected keyword argument '%U'",
+        function_name, key);
+    #endif
+bad:
+    return -1;
+}
+
+static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
+    const char *name, int exact)
+{
+    if (!type) {
+        PyErr_Format(PyExc_SystemError, "Missing type object");
+        return 0;
+    }
+    if (none_allowed && obj == Py_None) return 1;
+    else if (exact) {
+        if (Py_TYPE(obj) == type) return 1;
+    }
+    else {
+        if (PyObject_TypeCheck(obj, type)) return 1;
+    }
+    PyErr_Format(PyExc_TypeError,
+        "Argument '%s' has incorrect type (expected %s, got %s)",
+        name, type->tp_name, Py_TYPE(obj)->tp_name);
+    return 0;
+}
+
+static CYTHON_INLINE unsigned char __Pyx_PyInt_AsUnsignedChar(PyObject* x) {
+    const unsigned char neg_one = (unsigned char)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(unsigned char) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(unsigned char)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to unsigned char" :
+                    "value too large to convert to unsigned char");
+            }
+            return (unsigned char)-1;
+        }
+        return (unsigned char)val;
+    }
+    return (unsigned char)__Pyx_PyInt_AsUnsignedLong(x);
+}
+
+static CYTHON_INLINE unsigned short __Pyx_PyInt_AsUnsignedShort(PyObject* x) {
+    const unsigned short neg_one = (unsigned short)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(unsigned short) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(unsigned short)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to unsigned short" :
+                    "value too large to convert to unsigned short");
+            }
+            return (unsigned short)-1;
+        }
+        return (unsigned short)val;
+    }
+    return (unsigned short)__Pyx_PyInt_AsUnsignedLong(x);
+}
+
+static CYTHON_INLINE unsigned int __Pyx_PyInt_AsUnsignedInt(PyObject* x) {
+    const unsigned int neg_one = (unsigned int)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(unsigned int) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(unsigned int)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to unsigned int" :
+                    "value too large to convert to unsigned int");
+            }
+            return (unsigned int)-1;
+        }
+        return (unsigned int)val;
+    }
+    return (unsigned int)__Pyx_PyInt_AsUnsignedLong(x);
+}
+
+static CYTHON_INLINE char __Pyx_PyInt_AsChar(PyObject* x) {
+    const char neg_one = (char)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(char) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(char)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to char" :
+                    "value too large to convert to char");
+            }
+            return (char)-1;
+        }
+        return (char)val;
+    }
+    return (char)__Pyx_PyInt_AsLong(x);
+}
+
+static CYTHON_INLINE short __Pyx_PyInt_AsShort(PyObject* x) {
+    const short neg_one = (short)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(short) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(short)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to short" :
+                    "value too large to convert to short");
+            }
+            return (short)-1;
+        }
+        return (short)val;
+    }
+    return (short)__Pyx_PyInt_AsLong(x);
+}
+
+static CYTHON_INLINE int __Pyx_PyInt_AsInt(PyObject* x) {
+    const int neg_one = (int)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(int) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(int)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to int" :
+                    "value too large to convert to int");
+            }
+            return (int)-1;
+        }
+        return (int)val;
+    }
+    return (int)__Pyx_PyInt_AsLong(x);
+}
+
+static CYTHON_INLINE signed char __Pyx_PyInt_AsSignedChar(PyObject* x) {
+    const signed char neg_one = (signed char)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(signed char) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(signed char)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to signed char" :
+                    "value too large to convert to signed char");
+            }
+            return (signed char)-1;
+        }
+        return (signed char)val;
+    }
+    return (signed char)__Pyx_PyInt_AsSignedLong(x);
+}
+
+static CYTHON_INLINE signed short __Pyx_PyInt_AsSignedShort(PyObject* x) {
+    const signed short neg_one = (signed short)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(signed short) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(signed short)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to signed short" :
+                    "value too large to convert to signed short");
+            }
+            return (signed short)-1;
+        }
+        return (signed short)val;
+    }
+    return (signed short)__Pyx_PyInt_AsSignedLong(x);
+}
+
+static CYTHON_INLINE signed int __Pyx_PyInt_AsSignedInt(PyObject* x) {
+    const signed int neg_one = (signed int)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(signed int) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(signed int)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to signed int" :
+                    "value too large to convert to signed int");
+            }
+            return (signed int)-1;
+        }
+        return (signed int)val;
+    }
+    return (signed int)__Pyx_PyInt_AsSignedLong(x);
+}
+
+static CYTHON_INLINE int __Pyx_PyInt_AsLongDouble(PyObject* x) {
+    const int neg_one = (int)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(int) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(int)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to int" :
+                    "value too large to convert to int");
+            }
+            return (int)-1;
+        }
+        return (int)val;
+    }
+    return (int)__Pyx_PyInt_AsLong(x);
+}
+
+static CYTHON_INLINE unsigned long __Pyx_PyInt_AsUnsignedLong(PyObject* x) {
+    const unsigned long neg_one = (unsigned long)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to unsigned long");
+            return (unsigned long)-1;
+        }
+        return (unsigned long)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to unsigned long");
+                return (unsigned long)-1;
+            }
+            return (unsigned long)PyLong_AsUnsignedLong(x);
+        } else {
+            return (unsigned long)PyLong_AsLong(x);
+        }
+    } else {
+        unsigned long val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (unsigned long)-1;
+        val = __Pyx_PyInt_AsUnsignedLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE unsigned PY_LONG_LONG __Pyx_PyInt_AsUnsignedLongLong(PyObject* x) {
+    const unsigned PY_LONG_LONG neg_one = (unsigned PY_LONG_LONG)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to unsigned PY_LONG_LONG");
+            return (unsigned PY_LONG_LONG)-1;
+        }
+        return (unsigned PY_LONG_LONG)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to unsigned PY_LONG_LONG");
+                return (unsigned PY_LONG_LONG)-1;
+            }
+            return (unsigned PY_LONG_LONG)PyLong_AsUnsignedLongLong(x);
+        } else {
+            return (unsigned PY_LONG_LONG)PyLong_AsLongLong(x);
+        }
+    } else {
+        unsigned PY_LONG_LONG val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (unsigned PY_LONG_LONG)-1;
+        val = __Pyx_PyInt_AsUnsignedLongLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE long __Pyx_PyInt_AsLong(PyObject* x) {
+    const long neg_one = (long)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to long");
+            return (long)-1;
+        }
+        return (long)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to long");
+                return (long)-1;
+            }
+            return (long)PyLong_AsUnsignedLong(x);
+        } else {
+            return (long)PyLong_AsLong(x);
+        }
+    } else {
+        long val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (long)-1;
+        val = __Pyx_PyInt_AsLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE PY_LONG_LONG __Pyx_PyInt_AsLongLong(PyObject* x) {
+    const PY_LONG_LONG neg_one = (PY_LONG_LONG)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to PY_LONG_LONG");
+            return (PY_LONG_LONG)-1;
+        }
+        return (PY_LONG_LONG)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to PY_LONG_LONG");
+                return (PY_LONG_LONG)-1;
+            }
+            return (PY_LONG_LONG)PyLong_AsUnsignedLongLong(x);
+        } else {
+            return (PY_LONG_LONG)PyLong_AsLongLong(x);
+        }
+    } else {
+        PY_LONG_LONG val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (PY_LONG_LONG)-1;
+        val = __Pyx_PyInt_AsLongLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE signed long __Pyx_PyInt_AsSignedLong(PyObject* x) {
+    const signed long neg_one = (signed long)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to signed long");
+            return (signed long)-1;
+        }
+        return (signed long)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to signed long");
+                return (signed long)-1;
+            }
+            return (signed long)PyLong_AsUnsignedLong(x);
+        } else {
+            return (signed long)PyLong_AsLong(x);
+        }
+    } else {
+        signed long val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (signed long)-1;
+        val = __Pyx_PyInt_AsSignedLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE signed PY_LONG_LONG __Pyx_PyInt_AsSignedLongLong(PyObject* x) {
+    const signed PY_LONG_LONG neg_one = (signed PY_LONG_LONG)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to signed PY_LONG_LONG");
+            return (signed PY_LONG_LONG)-1;
+        }
+        return (signed PY_LONG_LONG)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to signed PY_LONG_LONG");
+                return (signed PY_LONG_LONG)-1;
+            }
+            return (signed PY_LONG_LONG)PyLong_AsUnsignedLongLong(x);
+        } else {
+            return (signed PY_LONG_LONG)PyLong_AsLongLong(x);
+        }
+    } else {
+        signed PY_LONG_LONG val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (signed PY_LONG_LONG)-1;
+        val = __Pyx_PyInt_AsSignedLongLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static int __Pyx_check_binary_version(void) {
+    char ctversion[4], rtversion[4];
+    PyOS_snprintf(ctversion, 4, "%d.%d", PY_MAJOR_VERSION, PY_MINOR_VERSION);
+    PyOS_snprintf(rtversion, 4, "%s", Py_GetVersion());
+    if (ctversion[0] != rtversion[0] || ctversion[2] != rtversion[2]) {
+        char message[200];
+        PyOS_snprintf(message, sizeof(message),
+                      "compiletime version %s of module '%.100s' "
+                      "does not match runtime version %s",
+                      ctversion, __Pyx_MODULE_NAME, rtversion);
+        #if PY_VERSION_HEX < 0x02050000
+        return PyErr_Warn(NULL, message);
+        #else
+        return PyErr_WarnEx(NULL, message, 1);
+        #endif
+    }
+    return 0;
+}
+
+#ifndef __PYX_HAVE_RT_ImportModule
+#define __PYX_HAVE_RT_ImportModule
+static PyObject *__Pyx_ImportModule(const char *name) {
+    PyObject *py_name = 0;
+    PyObject *py_module = 0;
+    py_name = __Pyx_PyIdentifier_FromString(name);
+    if (!py_name)
+        goto bad;
+    py_module = PyImport_Import(py_name);
+    Py_DECREF(py_name);
+    return py_module;
+bad:
+    Py_XDECREF(py_name);
+    return 0;
+}
+#endif
+
+#ifndef __PYX_HAVE_RT_ImportType
+#define __PYX_HAVE_RT_ImportType
+static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name,
+    size_t size, int strict)
+{
+    PyObject *py_module = 0;
+    PyObject *result = 0;
+    PyObject *py_name = 0;
+    char warning[200];
+    Py_ssize_t basicsize;
+#ifdef Py_LIMITED_API
+    PyObject *py_basicsize;
+#endif
+    py_module = __Pyx_ImportModule(module_name);
+    if (!py_module)
+        goto bad;
+    py_name = __Pyx_PyIdentifier_FromString(class_name);
+    if (!py_name)
+        goto bad;
+    result = PyObject_GetAttr(py_module, py_name);
+    Py_DECREF(py_name);
+    py_name = 0;
+    Py_DECREF(py_module);
+    py_module = 0;
+    if (!result)
+        goto bad;
+    if (!PyType_Check(result)) {
+        PyErr_Format(PyExc_TypeError,
+            "%s.%s is not a type object",
+            module_name, class_name);
+        goto bad;
+    }
+#ifndef Py_LIMITED_API
+    basicsize = ((PyTypeObject *)result)->tp_basicsize;
+#else
+    py_basicsize = PyObject_GetAttrString(result, "__basicsize__");
+    if (!py_basicsize)
+        goto bad;
+    basicsize = PyLong_AsSsize_t(py_basicsize);
+    Py_DECREF(py_basicsize);
+    py_basicsize = 0;
+    if (basicsize == (Py_ssize_t)-1 && PyErr_Occurred())
+        goto bad;
+#endif
+    if (!strict && (size_t)basicsize > size) {
+        PyOS_snprintf(warning, sizeof(warning),
+            "%s.%s size changed, may indicate binary incompatibility",
+            module_name, class_name);
+        #if PY_VERSION_HEX < 0x02050000
+        if (PyErr_Warn(NULL, warning) < 0) goto bad;
+        #else
+        if (PyErr_WarnEx(NULL, warning, 0) < 0) goto bad;
+        #endif
+    }
+    else if ((size_t)basicsize != size) {
+        PyErr_Format(PyExc_ValueError,
+            "%s.%s has the wrong size, try recompiling",
+            module_name, class_name);
+        goto bad;
+    }
+    return (PyTypeObject *)result;
+bad:
+    Py_XDECREF(py_module);
+    Py_XDECREF(result);
+    return NULL;
+}
+#endif
+
+static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) {
+    int start = 0, mid = 0, end = count - 1;
+    if (end >= 0 && code_line > entries[end].code_line) {
+        return count;
+    }
+    while (start < end) {
+        mid = (start + end) / 2;
+        if (code_line < entries[mid].code_line) {
+            end = mid;
+        } else if (code_line > entries[mid].code_line) {
+             start = mid + 1;
+        } else {
+            return mid;
+        }
+    }
+    if (code_line <= entries[mid].code_line) {
+        return mid;
+    } else {
+        return mid + 1;
+    }
+}
+static PyCodeObject *__pyx_find_code_object(int code_line) {
+    PyCodeObject* code_object;
+    int pos;
+    if (unlikely(!code_line) || unlikely(!__pyx_code_cache.entries)) {
+        return NULL;
+    }
+    pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line);
+    if (unlikely(pos >= __pyx_code_cache.count) || unlikely(__pyx_code_cache.entries[pos].code_line != code_line)) {
+        return NULL;
+    }
+    code_object = __pyx_code_cache.entries[pos].code_object;
+    Py_INCREF(code_object);
+    return code_object;
+}
+static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) {
+    int pos, i;
+    __Pyx_CodeObjectCacheEntry* entries = __pyx_code_cache.entries;
+    if (unlikely(!code_line)) {
+        return;
+    }
+    if (unlikely(!entries)) {
+        entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Malloc(64*sizeof(__Pyx_CodeObjectCacheEntry));
+        if (likely(entries)) {
+            __pyx_code_cache.entries = entries;
+            __pyx_code_cache.max_count = 64;
+            __pyx_code_cache.count = 1;
+            entries[0].code_line = code_line;
+            entries[0].code_object = code_object;
+            Py_INCREF(code_object);
+        }
+        return;
+    }
+    pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line);
+    if ((pos < __pyx_code_cache.count) && unlikely(__pyx_code_cache.entries[pos].code_line == code_line)) {
+        PyCodeObject* tmp = entries[pos].code_object;
+        entries[pos].code_object = code_object;
+        Py_DECREF(tmp);
+        return;
+    }
+    if (__pyx_code_cache.count == __pyx_code_cache.max_count) {
+        int new_max = __pyx_code_cache.max_count + 64;
+        entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Realloc(
+            __pyx_code_cache.entries, new_max*sizeof(__Pyx_CodeObjectCacheEntry));
+        if (unlikely(!entries)) {
+            return;
+        }
+        __pyx_code_cache.entries = entries;
+        __pyx_code_cache.max_count = new_max;
+    }
+    for (i=__pyx_code_cache.count; i>pos; i--) {
+        entries[i] = entries[i-1];
+    }
+    entries[pos].code_line = code_line;
+    entries[pos].code_object = code_object;
+    __pyx_code_cache.count++;
+    Py_INCREF(code_object);
+}
+
+#include "compile.h"
+#include "frameobject.h"
+#include "traceback.h"
+static PyCodeObject* __Pyx_CreateCodeObjectForTraceback(
+            const char *funcname, int c_line,
+            int py_line, const char *filename) {
+    PyCodeObject *py_code = 0;
+    PyObject *py_srcfile = 0;
+    PyObject *py_funcname = 0;
+    #if PY_MAJOR_VERSION < 3
+    py_srcfile = PyString_FromString(filename);
+    #else
+    py_srcfile = PyUnicode_FromString(filename);
+    #endif
+    if (!py_srcfile) goto bad;
+    if (c_line) {
+        #if PY_MAJOR_VERSION < 3
+        py_funcname = PyString_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line);
+        #else
+        py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line);
+        #endif
+    }
+    else {
+        #if PY_MAJOR_VERSION < 3
+        py_funcname = PyString_FromString(funcname);
+        #else
+        py_funcname = PyUnicode_FromString(funcname);
+        #endif
+    }
+    if (!py_funcname) goto bad;
+    py_code = __Pyx_PyCode_New(
+        0,            /*int argcount,*/
+        0,            /*int kwonlyargcount,*/
+        0,            /*int nlocals,*/
+        0,            /*int stacksize,*/
+        0,            /*int flags,*/
+        __pyx_empty_bytes, /*PyObject *code,*/
+        __pyx_empty_tuple, /*PyObject *consts,*/
+        __pyx_empty_tuple, /*PyObject *names,*/
+        __pyx_empty_tuple, /*PyObject *varnames,*/
+        __pyx_empty_tuple, /*PyObject *freevars,*/
+        __pyx_empty_tuple, /*PyObject *cellvars,*/
+        py_srcfile,   /*PyObject *filename,*/
+        py_funcname,  /*PyObject *name,*/
+        py_line,      /*int firstlineno,*/
+        __pyx_empty_bytes  /*PyObject *lnotab*/
+    );
+    Py_DECREF(py_srcfile);
+    Py_DECREF(py_funcname);
+    return py_code;
+bad:
+    Py_XDECREF(py_srcfile);
+    Py_XDECREF(py_funcname);
+    return NULL;
+}
+static void __Pyx_AddTraceback(const char *funcname, int c_line,
+                               int py_line, const char *filename) {
+    PyCodeObject *py_code = 0;
+    PyObject *py_globals = 0;
+    PyFrameObject *py_frame = 0;
+    py_code = __pyx_find_code_object(c_line ? c_line : py_line);
+    if (!py_code) {
+        py_code = __Pyx_CreateCodeObjectForTraceback(
+            funcname, c_line, py_line, filename);
+        if (!py_code) goto bad;
+        __pyx_insert_code_object(c_line ? c_line : py_line, py_code);
+    }
+    py_globals = PyModule_GetDict(__pyx_m);
+    if (!py_globals) goto bad;
+    py_frame = PyFrame_New(
+        PyThreadState_GET(), /*PyThreadState *tstate,*/
+        py_code,             /*PyCodeObject *code,*/
+        py_globals,          /*PyObject *globals,*/
+        0                    /*PyObject *locals*/
+    );
+    if (!py_frame) goto bad;
+    py_frame->f_lineno = py_line;
+    PyTraceBack_Here(py_frame);
+bad:
+    Py_XDECREF(py_code);
+    Py_XDECREF(py_frame);
+}
+
+static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
+    while (t->p) {
+        #if PY_MAJOR_VERSION < 3
+        if (t->is_unicode) {
+            *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
+        } else if (t->intern) {
+            *t->p = PyString_InternFromString(t->s);
+        } else {
+            *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
+        }
+        #else  /* Python 3+ has unicode identifiers */
+        if (t->is_unicode | t->is_str) {
+            if (t->intern) {
+                *t->p = PyUnicode_InternFromString(t->s);
+            } else if (t->encoding) {
+                *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL);
+            } else {
+                *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
+            }
+        } else {
+            *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
+        }
+        #endif
+        if (!*t->p)
+            return -1;
+        ++t;
+    }
+    return 0;
+}
+
+static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) {
+   int is_true = x == Py_True;
+   if (is_true | (x == Py_False) | (x == Py_None)) return is_true;
+   else return PyObject_IsTrue(x);
+}
+static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x) {
+  PyNumberMethods *m;
+  const char *name = NULL;
+  PyObject *res = NULL;
+#if PY_VERSION_HEX < 0x03000000
+  if (PyInt_Check(x) || PyLong_Check(x))
+#else
+  if (PyLong_Check(x))
+#endif
+    return Py_INCREF(x), x;
+  m = Py_TYPE(x)->tp_as_number;
+#if PY_VERSION_HEX < 0x03000000
+  if (m && m->nb_int) {
+    name = "int";
+    res = PyNumber_Int(x);
+  }
+  else if (m && m->nb_long) {
+    name = "long";
+    res = PyNumber_Long(x);
+  }
+#else
+  if (m && m->nb_int) {
+    name = "int";
+    res = PyNumber_Long(x);
+  }
+#endif
+  if (res) {
+#if PY_VERSION_HEX < 0x03000000
+    if (!PyInt_Check(res) && !PyLong_Check(res)) {
+#else
+    if (!PyLong_Check(res)) {
+#endif
+      PyErr_Format(PyExc_TypeError,
+                   "__%s__ returned non-%s (type %.200s)",
+                   name, name, Py_TYPE(res)->tp_name);
+      Py_DECREF(res);
+      return NULL;
+    }
+  }
+  else if (!PyErr_Occurred()) {
+    PyErr_SetString(PyExc_TypeError,
+                    "an integer is required");
+  }
+  return res;
+}
+static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) {
+  Py_ssize_t ival;
+  PyObject* x = PyNumber_Index(b);
+  if (!x) return -1;
+  ival = PyInt_AsSsize_t(x);
+  Py_DECREF(x);
+  return ival;
+}
+static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) {
+#if PY_VERSION_HEX < 0x02050000
+   if (ival <= LONG_MAX)
+       return PyInt_FromLong((long)ival);
+   else {
+       unsigned char *bytes = (unsigned char *) &ival;
+       int one = 1; int little = (int)*(unsigned char*)&one;
+       return _PyLong_FromByteArray(bytes, sizeof(size_t), little, 0);
+   }
+#else
+   return PyInt_FromSize_t(ival);
+#endif
+}
+static CYTHON_INLINE size_t __Pyx_PyInt_AsSize_t(PyObject* x) {
+   unsigned PY_LONG_LONG val = __Pyx_PyInt_AsUnsignedLongLong(x);
+   if (unlikely(val == (unsigned PY_LONG_LONG)-1 && PyErr_Occurred())) {
+       return (size_t)-1;
+   } else if (unlikely(val != (unsigned PY_LONG_LONG)(size_t)val)) {
+       PyErr_SetString(PyExc_OverflowError,
+                       "value too large to convert to size_t");
+       return (size_t)-1;
+   }
+   return (size_t)val;
+}
+
+
+#endif /* Py_PYTHON_H */
diff --git a/lib/bx/motif/_pwm.pyx b/lib/bx/motif/_pwm.pyx
new file mode 100644
index 0000000..e062510
--- /dev/null
+++ b/lib/bx/motif/_pwm.pyx
@@ -0,0 +1,91 @@
+"""
+Extensions used by the `pwm` module.
+"""
+
+cdef extern from "Python.h":
+    int PyString_AsStringAndSize(object obj, char **buffer, Py_ssize_t* length) except -1
+
+cdef extern from "numpy/arrayobject.h":
+    ctypedef int intp
+    ctypedef extern class numpy.ndarray [object PyArrayObject]:
+        cdef char *data
+        cdef int nd
+        cdef intp *dimensions
+        cdef intp *strides
+        cdef int flags
+    # These might be other types in the actual header depending on platform 
+    ctypedef int npy_int16
+    ctypedef float npy_float32
+
+def score_string( ndarray matrix, ndarray char_to_index, object string, ndarray rval ):
+    """
+    Score each position in string `string` using the scoring matrix `matrix`.
+    Characters in the string are mapped to columns in the matrix by `char_to_index`
+    and the score for each position is stored in `rval`.
+    
+    matrix *must* be a 2d array of type float32
+    char_to_index *must* be a 1d array of type int16
+    rval *must* be a 1d array of type float32 and the same length as string
+    """
+    cdef char *buffer
+    cdef Py_ssize_t len
+    cdef float score
+    cdef int i, j
+    cdef int matrix_width = matrix.dimensions[0]
+    cdef npy_int16 char_index
+    # Get input string as character pointer
+    PyString_AsStringAndSize( string, &buffer, &len )
+    # Loop over each position in the string 
+    cdef int stop = len - matrix.dimensions[0] + 1
+    for i from 0 <= i < stop:
+        score = 0.0
+        for j from 0 <= j < matrix_width:
+            char_index = ( <npy_int16 *> ( char_to_index.data + buffer[i+j] * char_to_index.strides[0] ) )[0]
+            if char_index < 0: 
+                break
+            score += ( <npy_float32*> ( matrix.data + j * matrix.strides[0] + char_index * matrix.strides[1] ) )[0]
+        else:
+            ( <npy_float32*> ( rval.data + i * rval.strides[0] ) )[0] = score
+            
+def score_string_with_gaps( ndarray matrix, ndarray char_to_index, object string, ndarray rval ):
+    """
+    Score each position in string `string` using the scoring matrix `matrix`.
+    Characters in the string are mapped to columns in the matrix by `char_to_index`
+    and the score for each position is stored in `rval`.
+
+    matrix *must* be a 2d array of type float32
+    char_to_index *must* be a 1d array of type int16
+    rval *must* be a 1d array of type float32 and the same length as string
+    """
+    cdef char *buffer
+    cdef Py_ssize_t len
+    cdef float score
+    cdef int i, j, string_pos
+    cdef int matrix_width = matrix.dimensions[0]
+    cdef npy_int16 char_index
+    # Get input string as character pointer
+    PyString_AsStringAndSize( string, &buffer, &len )
+    # Loop over each position in the string 
+    cdef int stop = len - matrix.dimensions[0] + 1
+    for i from 0 <= i < stop:
+        if buffer[i] == '-':
+            # Never start scoring at a gap
+            continue
+        score = 0.0
+        string_pos = i
+        for j from 0 <= j < matrix_width:
+            # Advance to the next non-gap character
+            while buffer[string_pos] == '-' and string_pos < len:
+                string_pos += 1
+            # Ran out of non-gap characters, no more scoring is possible
+            if string_pos == len:
+                return
+            # Find character for position and score
+            char_index = ( <npy_int16 *> ( char_to_index.data + buffer[string_pos] * char_to_index.strides[0] ) )[0]
+            if char_index < 0: 
+                break
+            score += ( <npy_float32*> ( matrix.data + j * matrix.strides[0] + char_index * matrix.strides[1] ) )[0]
+            # Matched a character, move forward
+            string_pos += 1
+        else:
+            ( <npy_float32*> ( rval.data + i * rval.strides[0] ) )[0] = score
\ No newline at end of file
diff --git a/lib/bx/motif/io/__init__.py b/lib/bx/motif/io/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/lib/bx/motif/io/transfac.py b/lib/bx/motif/io/transfac.py
new file mode 100644
index 0000000..950e06d
--- /dev/null
+++ b/lib/bx/motif/io/transfac.py
@@ -0,0 +1,221 @@
+"""
+Classes for reading and writing motif data.
+"""
+
+from bx.motif.pwm import FrequencyMatrix
+
+class TransfacMotif( object ):
+    
+    def __init__( self ):
+        self.accession = None
+        self.id = None
+        self.dates = None
+        self.name = None
+        self.description = None
+        self.binding_factors = None
+        self.basis = None
+        self.comment = None
+        self.matrix = None
+        self.attributes = None
+        self.sites = None
+        
+transfac_actions = {
+    "AC": ( "store_single", "accession" ),
+    "ID": ( "store_single", "id" ),
+    "DT": ( "store_single_list", "dates" ),
+    "NA": ( "store_single", "name" ),
+    "DE": ( "store_block", "description" ),
+    "BF": ( "store_single_list", "binding_factors" ),
+    "BA": ( "store_block", "basis" ),
+    "CC": ( "store_block", "comment" ),
+    "P0": ( "store_matrix", "matrix" ),
+    # For CREAD format files
+    "TY": ( "store_single", "type" ),
+    "AT": ( "store_single_key_value", "attributes" ),
+    "BS": ( "store_single_list", "sites" )
+}
+        
+class TransfacReader( object ):
+    """
+    Reads motifs in TRANSFAC format.
+    """
+    
+    parse_actions = transfac_actions
+    
+    def __init__( self, input ):
+        self.input = iter( input )
+        self.input_exhausted = False
+    
+    def as_dict( self, key="id" ):
+        """
+        Return a dictionary containing all remaining motifs, using `key`
+        as the dictionary key.
+        """
+        rval = {}
+        for motif in self:
+            rval[ getattr( motif, key ) ] = motif
+        return rval
+    
+    def __iter__( self ):
+        return self
+    
+    def next( self ):
+        rval = self.next_motif()
+        while rval is None:
+            rval = self.next_motif()
+        return rval
+    
+    def next_motif( self ):
+        if self.input_exhausted:
+            raise StopIteration
+        # Accumulate lines until either the end of record indicator "//" is
+        # encounted or the input is exhausted.   
+        lines = []
+        while 1:
+            try:
+                line = self.input.next()
+            except StopIteration, e:
+                self.input_exhausted = True
+                break
+            if line.startswith( "//" ):
+                break
+            if not line.isspace():
+                lines.append( line )
+        if lines:
+            return self.parse_record( lines )
+    
+    def parse_record( self, lines ):
+        """
+        Parse a TRANSFAC record out of `lines` and return a motif.
+        """
+        # Break lines up
+        temp_lines = []
+        for line in lines:
+            fields = line.rstrip( "\r\n" ).split( None, 1 )
+            if len( fields ) == 1:
+                fields.append( "" )
+            temp_lines.append( fields )
+        lines = temp_lines
+        # Fill in motif from lines
+        motif = TransfacMotif()
+        current_line = 0
+        while 1:
+            # Done parsing if no more lines to consume
+            if current_line >= len( lines ):
+                break
+            # Remove prefix and first separator from line
+            prefix, rest = lines[ current_line ]
+            # No action for this prefix, just ignore the line
+            if prefix not in self.parse_actions:
+                current_line += 1
+                continue
+            # Get action for line
+            action = self.parse_actions[ prefix ]
+            # Store a single line value
+            if action[0] == "store_single":
+                key = action[1]
+                setattr( motif, key, rest )
+                current_line += 1
+            # Add a single line value to a list
+            if action[0] == "store_single_list":
+                key = action[1]
+                if not getattr( motif, key ):
+                    setattr( motif, key, [] )
+                getattr( motif, key ).append( rest )
+                current_line += 1
+            # Add a single line value to a dictionary
+            if action[0] == "store_single_key_value":
+                key = action[1]
+                k, v = rest.strip().split( '=', 1 )
+                if not getattr( motif, key ):
+                    setattr( motif, key, {} )
+                getattr( motif, key )[k] = v
+                current_line += 1
+            # Store a block of text
+            if action[0] == "store_block":
+                key = action[1]
+                value = []
+                while current_line < len( lines ) and lines[ current_line ][0] == prefix:
+                    value.append( lines[current_line][1] )
+                    current_line += 1
+                setattr( motif, key, str.join( "\n", value ) )
+            # Store a matrix
+            if action[0] == "store_matrix":
+                # First line is alphabet
+                alphabet = rest.split()
+                alphabet_size = len( alphabet )
+                rows = []
+                pattern = ""
+                current_line += 1
+                # Next lines are the rows of the matrix (we allow 0 rows)
+                while current_line < len( lines ):
+                    prefix, rest = lines[ current_line ]
+                    # Prefix should be a two digit 0 padded row number
+                    if not prefix.isdigit():
+                        break
+                    # The first `alphabet_size` fields are the row values
+                    values = rest.split()
+                    rows.append( map( float, values[:alphabet_size] ) )
+                    # TRANSFAC includes an extra column with the IUPAC code
+                    if len( values ) > alphabet_size:
+                        pattern += values[alphabet_size]
+                    current_line += 1
+                # Only store the pattern if it is the correct length (meaning
+                # that every row had an extra field)
+                if len( pattern ) != len( rows ):
+                    pattern = None
+                matrix = FrequencyMatrix.from_rows( alphabet, rows )
+                setattr( motif, action[1], matrix )
+        # Only return a motif if we saw at least ID or AC or NA
+        if motif.id or motif.accession or motif.name:
+            return motif
+            
+class TransfacWriter( object ):
+    """
+    Writes motifs in TRANSFAC format.
+    """
+
+    actions = transfac_actions
+
+    def __init__( self, output ):
+        self.output = output
+        
+    def write( self, motif ):
+        output = self.output
+        for prefix, actions in self.actions.iteritems():
+            action = actions[0]
+            if action == "store_single":
+                key = actions[1]
+                if getattr( motif, key ) is not None:
+                    print >> output, prefix, "  ", getattr( motif, key )
+                    print >> output, "XX"
+            elif action == "store_single_list":
+                key = actions[1]
+                if getattr( motif, key ) is not None:
+                    value = getattr( motif, key )
+                    for v in value:
+                        print >> output, prefix, "  ", v
+                    print >> output, "XX"
+            elif action == "store_single_key_value":
+                key = actions[1]
+                if getattr( motif, key ) is not None:
+                    value = getattr( motif, key )
+                    for k, v in value.iteritems():
+                        print >> output, prefix, "  ", "%s=%s" % ( k, v )
+                    print >> output, "XX"
+            elif action == "store_block":
+                key = actions[1]
+                if getattr( motif, key ) is not None:
+                    value = getattr( motif, key )
+                    for line in value.split( "\n" ):
+                        print >> output, prefix, "  ", line
+                    print >> output, "XX"
+            elif action == "store_matrix":
+                key = actions[1]
+                if getattr( motif, key ) is not None:
+                    matrix = getattr( motif, key )
+                    print >> output, prefix, "  ", " ".join( [ s.rjust(6) for s in matrix.alphabet ] )
+                    for i in range( matrix.width ):
+                        print >> output, "%02d" % ( i + 1 ), "  ", " ".join( [ str(matrix.values[i,matrix.char_to_index[ord(s)]]).rjust(6) for s in matrix.alphabet ] )
+                    print >> output, "XX"
+        print "//"
diff --git a/lib/bx/motif/io/transfac_tests.py b/lib/bx/motif/io/transfac_tests.py
new file mode 100644
index 0000000..6afc013
--- /dev/null
+++ b/lib/bx/motif/io/transfac_tests.py
@@ -0,0 +1,94 @@
+from StringIO import StringIO
+import transfac
+from numpy import allclose
+
+sample = """
+VV  TRANSFAC MATRIX TABLE, Rel.3.2 26-06-1997
+XX
+//
+AC  a
+XX
+ID  V$MYOD_01
+XX
+DT  19.10.92 (created); ewi.
+DT  16.10.95 (updated); ewi.
+XX
+NA  MyoD
+XX
+DE  myoblast determination gene product
+XX
+BF  T00526; MyoD; Species: mouse, Mus musculus.
+XX
+P0      A      C      G      T
+01     100     200     200     0     S
+02     200     100     200     0     R
+03     300     0     100     100     A
+04     0     500     0     0     C
+05     500     0     0     0     A
+06     0     0     400     100     G
+07     0     100     400     0     G
+08     0     0     0     500     T
+09     0     0     500     0     G
+10     0     100     200     200     K
+11     0     200     0     300     Y
+12     100     0     300     100     G
+XX
+BA  5 functional elements in 3 genes
+XX
+//
+AC  M00002
+XX
+ID  V$E47_01
+XX
+DT  19.10.92 (created); ewi.
+DT  16.10.95 (updated); ewi.
+XX
+NA  E47
+XX
+DE  E47
+XX
+BF  T00207; E47; Species: human, Homo sapiens.
+XX
+P0      A      C      G      T
+00     400     400     300     0     N
+02     200     500     400     0     S
+03     300     200     400     200     N
+04     200     0     900     0     G
+05     0     1100     0     0     C
+06     1100     0     0     0     A
+07     0     0     1100     0     G
+08     100     200     800     0     G
+09     0     0     0     1100     T
+10     0     0     1100     0     G
+11     0     0     400     700     K
+12     100     400     300     300     N
+13     100     600     200     200     C
+14     100     400     400     200     N
+15     100     400     200     300     N
+XX
+BA  11 selected strong binding sites for E47, E47-MyoD, E12+MyoD 
+BA  and (weak) for E12
+XX
+CC  Group I in [903]; 5 sites selected in vitro for binding to E12N 
+CC  (=N-terminally truncated E12); matrix corrected according to 
+CC  the published sequences
+XX
+RN  [1]
+RA  Sun X.-H., Baltimore D.
+RT  An inhibitory domain of E12 transcription factor prevents 
+RT  DNA binding in E12 homodimers but not in E12 heterodimers
+RL  Cell 64:459-470 (1991).
+XX
+"""
+
+def test_reader():
+    input = StringIO( sample )
+    motifs = list( transfac.TransfacReader( input ) )
+    assert len( motifs ) == 2
+    # Single value parse
+    assert motifs[1].accession == "M00002"
+    # Value list parse
+    assert motifs[1].dates == [ '19.10.92 (created); ewi.', '16.10.95 (updated); ewi.' ]
+    # Matrix parse
+    assert motifs[1].matrix.sorted_alphabet == ['A','C','G','T']
+    assert allclose( motifs[1].matrix.values[0], [400,400,300,0] )
\ No newline at end of file
diff --git a/lib/bx/motif/logo/__init__.py b/lib/bx/motif/logo/__init__.py
new file mode 100644
index 0000000..7a7ef04
--- /dev/null
+++ b/lib/bx/motif/logo/__init__.py
@@ -0,0 +1,71 @@
+import pkg_resources
+from StringIO import StringIO
+from string import Template
+from numpy import *
+
+PAD = 2
+
+# Colors from rgb.txt, 
+DNA_DEFAULT_COLORS = {
+    'A': "0.00 1.00 0.00", # green
+    'C': "0.00 0.00 1.00", # blue
+    'G': "1.00 0.65 0.00", # orange red
+    'T': "1.00 0.00 0.00"  # red
+}
+
+# Template is adapted from Jim Kent's lib/dnaMotif.pss to support aritrary
+# alphabets.
+TEMPLATE = "template.ps"
+
+def freqs_to_heights( matrix ):
+    """
+    Calculate logo height using the method of:
+    
+    Schneider TD, Stephens RM. "Sequence logos: a new way to display consensus 
+    sequences." Nucleic Acids Res. 1990 Oct 25;18(20):6097-100.
+    """
+    # Columns are sequence positions, rows are symbol counts/frequencies
+    f = matrix.values.transpose()
+    n, m = f.shape
+    # Ensure normalized
+    f = f / sum( f, axis=0 )
+    # Shannon entropy (the where replaces 0 with 1 so that '0 log 0 == 0')
+    H = - sum( f * log2( where( f, f, 1 ) ), axis=0 )
+    # Height
+    return transpose( f * ( log2( n ) - H ) )
+    
+def eps_logo( matrix, base_width, height, colors=DNA_DEFAULT_COLORS ):
+    """
+    Return an EPS document containing a sequence logo for matrix where each
+    bases is shown as a column of `base_width` points and the total logo
+    height is `height` points. If `colors` is provided it is a mapping from
+    characters to rgb color strings. 
+    """
+    alphabet = matrix.sorted_alphabet
+    rval = StringIO()
+    # Read header ans substitute in width / height
+    header = Template( pkg_resources.resource_string( __name__, "template.ps" ) )
+    rval.write( header.substitute( bounding_box_width = ceil( base_width * matrix.width ) + PAD,
+                                   bounding_box_height = ceil( height ) + PAD ) )
+    # Determine heights
+    heights = freqs_to_heights( matrix )
+    height_scale = height / log2( len( alphabet ) )
+    # Draw each "row" of the matrix
+    for i, row in enumerate( heights ):
+        x = ( i * base_width )
+        y = 0
+        for j, base_height in enumerate( row ):
+            char = alphabet[j]
+            page_height = height_scale * base_height
+            # print matrix.alphabet[j], base_height, height_scale, page_height
+            if page_height > 1:
+                # Draw letter
+                rval.write(  "%s setrgbcolor\n" % colors.get( char, '0 0 0' ) )
+                rval.write( "%3.2f " % x )
+                rval.write( "%3.2f " % y )
+                rval.write( "%3.2f " % ( x + base_width ) )
+                rval.write( "%3.2f " % ( y + page_height ) )
+                rval.write( "(%s) textInBox\n" % char )
+            y += page_height
+    rval.write( "showpage" )
+    return rval.getvalue()
\ No newline at end of file
diff --git a/lib/bx/motif/logo/template.ps b/lib/bx/motif/logo/template.ps
new file mode 100644
index 0000000..f1579ac
--- /dev/null
+++ b/lib/bx/motif/logo/template.ps
@@ -0,0 +1,62 @@
+%!PS-Adobe-3.1 EPSF-3.0
+%%BoundingBox: 0 0 ${bounding_box_width} ${bounding_box_height}
+
+/logoFont {
+/Helvetica-Bold findfont
+10 scalefont
+setfont
+} def
+
+/textBounds {
+% Figure out bounding box of string in current font.  Usage:
+% call: text letterSize 
+% sets: tbX1 tbY1 tbX2 tbY2 tbW tbH
+% The bounds are relative to the current position
+gsave
+newpath
+0 0 moveto
+true charpath
+flattenpath
+pathbbox
+grestore
+/tbY2 exch def
+/tbX2 exch def
+/tbY1 exch def
+/tbX1 exch def
+/tbW tbX2 tbX1 sub def
+/tbH tbY2 tbY1 sub def
+} def
+
+/textInBox {
+% Draw text so that it fits inside of box.  Usage:
+%   x1 y1 x2 y2 text textInBox
+
+% Copy parameters from variables to stack and save context
+/tibText exch def
+/tibY2 exch def
+/tibX2 exch def
+/tibY1 exch def
+/tibX1 exch def
+gsave
+
+% move to x1/y1 adjusted for text offset
+tibText textBounds
+tibX1 tbX1 sub tibY1 tbY1 sub moveto
+
+% Set scaling
+/tibW tibX2 tibX1 sub def
+/tibH tibY2 tibY1 sub def
+tibW tbW div tibH tbH div scale
+
+% draw and return
+tibText show
+grestore
+} def
+
+/aColor { 0 0.7 0 setrgbcolor } def
+/cColor { 0 0.5 0.7 setrgbcolor } def
+/gColor { 0.8 0.5 0 setrgbcolor } def
+/tColor { 0.9 0 0 setrgbcolor } def
+
+logoFont
+
diff --git a/lib/bx/motif/pwm.py b/lib/bx/motif/pwm.py
new file mode 100644
index 0000000..bad9daf
--- /dev/null
+++ b/lib/bx/motif/pwm.py
@@ -0,0 +1,149 @@
+"""
+Classes for working with position specific matrices.
+"""
+
+from numpy import *
+from copy import copy
+
+import _pwm
+
+class BaseMatrix( object ):
+    """
+    Base class for position specific matrices. 
+    """
+    def __init__( self, alphabet=None, sorted_alphabet=None, 
+                  char_to_index=None, values=None ):
+        self.alphabet = alphabet
+        self.sorted_alphabet = sorted_alphabet
+        self.char_to_index = char_to_index
+        self.values = values
+
+    @classmethod
+    def from_rows( Class, alphabet, rows ):
+        """
+        Create a new matrix for a sequence over alphabet `alphabet` taking 
+        values from `rows` which is a list whose length is the width of the
+        matrix, and whose elements are lists of values associated with each
+        character (in the order those characters appear in alphabet). 
+        """
+        # Sorted alphabet
+        sorted_alphabet = sorted( alphabet )
+        # Character to index mapping (initialized to -1)
+        char_to_index = zeros( (256), int16 ) - 1
+        for i, ch  in enumerate( sorted_alphabet ):
+            char_to_index[ ord(ch) ] = i
+        # Array
+        values = zeros( ( len( rows) , len( alphabet ) ), float32 )
+        for i, row in enumerate( rows ):
+            assert len( row ) == len( alphabet )
+            for ch, val in zip( alphabet, row ):
+                values[i, char_to_index[ord(ch)]] = val
+        # Matrix
+        matrix = Class()
+        matrix.alphabet = alphabet
+        matrix.sorted_alphabet = sorted_alphabet
+        matrix.char_to_index = char_to_index
+        matrix.values = values
+        return matrix
+      
+    @classmethod
+    def create_from_other( Class, other, values=None ):
+        """
+        Create a new Matrix with attributes taken from `other` but with the 
+        values taken from `values` if provided
+        """
+        m = Class()
+        m.alphabet = other.alphabet
+        m.sorted_alphabet = other.sorted_alphabet
+        m.char_to_index = other.char_to_index
+        if values is not None:
+            m.values = values
+        else:
+            m.values = other.values
+        return m
+            
+    @property
+    def width( self ):
+        """
+        Return the width (size along the sequence axis) of this matrix.
+        """
+        return self.values.shape[0]
+
+    def reverse_complement( self ):
+        """
+        Create the reverse complement of this matrix. The result probably
+        only makese sense if the alphabet is that of DNA ('A','C','G','T').
+        """
+        rval = copy( self )
+        # Conveniently enough, reversing rows and columns is exactly what we
+        # want, since this results in A swapping with T and C swapping with G.
+        rval.values = self.values[::-1,::-1].copy()
+        return rval
+
+class FrequencyMatrix( BaseMatrix ):
+    """
+    A position specific count/frequency matrix.
+    """
+        
+    DEFAULT_CORRECTION = 0.0000000001
+    """
+    Default value to use for correcting when dealing with counts of zero,
+    chosen to produce scoring matrices that are the same as produced by CREAD.
+    """
+        
+    def to_logodds_scoring_matrix( self, background=None, correction=DEFAULT_CORRECTION ):
+        """
+        Create a standard logodds scoring matrix.
+        """
+        alphabet_size = len( self.alphabet )
+        if background is None:
+            background = ones( alphabet_size, float32 ) / alphabet_size
+        # Row totals as a one column array
+        totals = sum( self.values, 1 )[:,newaxis]
+        values = log2( maximum( self.values, correction ) ) \
+               - log2( totals ) \
+               - log2( maximum( background, correction ) )
+        return ScoringMatrix.create_from_other( self, values.astype( float32 ) )
+
+    def to_stormo_scoring_matrix( self, background=None ):
+        """
+        Create a scoring matrix from this count matrix using the method from:
+
+        Hertz, G.Z. and G.D. Stormo (1999). Identifying DNA and protein patterns with statistically 
+        significant alignments of multiple sequences. Bioinformatics 15(7): 563-577.
+        """
+        alphabet_size = len( self.alphabet )
+        if background is None:
+            background = ones( alphabet_size, float32 ) / alphabet_size
+        # Row totals as a one column array
+        totals = sum( self.values, 1 )[:,newaxis]
+        values = log2( self.values + background ) \
+               - log2( totals + 1 ) - log2( background )
+        return ScoringMatrix.create_from_other( self, values.astype( float32 ) )
+        
+class ScoringMatrix( BaseMatrix ):
+    """
+    A position specific matrix containing values that are suitable for
+    scoring a sequence.
+    """
+        
+    def score_string( self, string ):
+        """
+        Score each valid position in `string` using this scoring matrix. 
+        Positions which were not scored are set to nan.
+        """
+        rval = zeros( len( string ), float32 )
+        rval[:] = nan
+        _pwm.score_string( self.values, self.char_to_index, string, rval )
+        return rval
+        
+    def score_string_with_gaps( self, string ):
+        """
+        Score each valid position in `string` using this scoring matrix. 
+        Positions which were not scored are set to nan. Gap characters are
+        ignored (matrices score across them).
+        """
+        rval = zeros( len( string ), float32 )
+        rval[:] = nan
+        _pwm.score_string_with_gaps( self.values, self.char_to_index, string, rval )
+        return rval
\ No newline at end of file
diff --git a/lib/bx/motif/pwm_tests.py b/lib/bx/motif/pwm_tests.py
new file mode 100644
index 0000000..bc6667e
--- /dev/null
+++ b/lib/bx/motif/pwm_tests.py
@@ -0,0 +1,81 @@
+import pwm
+from numpy import allclose, isnan
+
+def test_create():
+    m = pwm.FrequencyMatrix.from_rows( ['A','C','G','T'], get_ctcf_rows() )
+    # Alphabet sort
+    assert m.sorted_alphabet == [ 'A', 'C', 'G', 'T' ]
+    # Character to index mapping
+    assert m.char_to_index[ ord('A') ] == 0
+    assert m.char_to_index[ ord('C') ] == 1
+    assert m.char_to_index[ ord('G') ] == 2
+    assert m.char_to_index[ ord('T') ] == 3
+    assert m.char_to_index[ ord('Q') ] == -1
+    # Values
+    assert allclose( m.values[0],  [ 2620, 2052, 3013, 2314 ] )
+    assert allclose( m.values[19],  [ 3144, 3231, 3056, 567 ] )
+    
+def test_scoring():
+    m = pwm.FrequencyMatrix.from_rows( ['A','C','G','T'], get_ctcf_rows() )
+    # Stormo method
+    sm = m.to_stormo_scoring_matrix()
+    # Forward matches
+    assert allclose( sm.score_string( "AATCACCACCTCCTGGCAGG" )[0], -156.8261261 )
+    assert allclose( sm.score_string( "TGCCTGCCTCTGTAGGCTCC" )[0], -128.8106842 )
+    assert allclose( sm.score_string( "GTTGCCAGTTGGGGGAAGCA" )[0], 4.65049839 )
+    assert allclose( sm.score_string( "GCAGACACCAGGTGGTTCAG" )[0], 1.60168743 )
+    # Reverse matches
+    rc = sm.reverse_complement()
+    assert allclose( rc.score_string( "AATCACCACCTCCTGGCAGG" )[0], 0.014178276062 )
+    assert allclose( rc.score_string( "TGCCTGCCTCTGTAGGCTCC" )[0], 0.723828315735 )
+    assert allclose( rc.score_string( "GTTGCCAGTTGGGGGAAGCA" )[0], -126.99407196 )
+    assert allclose( rc.score_string( "GCAGACACCAGGTGGTTCAG" )[0], -86.9560623169 )
+    # Nothing valid
+    assert isnan( sm.score_string_with_gaps( "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" ) ).all()
+    # Too short
+    assert isnan( sm.score_string( "TTTT" ) ).all()
+
+def test_scoring_with_gaps():
+    m = pwm.FrequencyMatrix.from_rows( ['A','C','G','T'], get_ctcf_rows() )
+    # Stormo method
+    sm = m.to_stormo_scoring_matrix()
+    # Forward matches
+    assert allclose( sm.score_string_with_gaps( "GTTGCCAGT----TGGGGGAAGCATTT---AA" )[0], 4.65049839 )
+    assert allclose( sm.score_string_with_gaps( "GCAGA--CACCAGGTGG--TTCAG---" )[0], 1.60168743 )
+    assert allclose( sm.score_string_with_gaps( "----GTTGCCAGTTGGGGGAAGCA" )[4], 4.65049839 )
+    assert allclose( sm.score_string_with_gaps( "TTT--GTT--GCCA--GTTGGGG-G-A-A-G-C-A-" )[5], 4.65049839 )
+    assert isnan( sm.score_string_with_gaps( "TTT--GTT--GCCA--GTTGGGG-G-A-A-G-C-A-" )[4] )
+    # Nothing valid
+    assert isnan( sm.score_string_with_gaps( "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" ) ).all()
+    assert isnan( sm.score_string_with_gaps( "------------------------------------" ) ).all()
+    # Too short
+    assert isnan( sm.score_string_with_gaps( "TTTT" ) ).all()
+    assert isnan( sm.score_string_with_gaps( "TTTT----" ) ).all()
+
+
+def get_ctcf_rows():
+    """
+    The CTCF primary site motif
+    """
+    return [
+         [   2620 ,  2052  ,  3013  ,  2314   ],
+         [      0 ,  3580  ,  1746  ,  4672   ],
+         [   2008 ,  1790  ,  4497  ,  1703   ],
+         [   3362 ,     0  ,  6637  ,     0   ],
+         [      0 , 10000  ,     0  ,     0   ],
+         [      0 , 10000  ,     0  ,     0   ],
+         [   7467 ,     0  ,  1310  ,  1222   ],
+         [    786 ,  4890  ,  4323  ,     0   ],
+         [   1179 ,  6288  ,   829  ,  1703   ],
+         [  10000 ,     0  ,     0  ,     0   ],
+         [      0 ,     0  , 10000  ,     0   ],
+         [   4847 ,     0  ,  5152  ,     0   ],
+         [      0 ,     0  ,  6200  ,  3799   ],
+         [      0 ,     0  , 10000  ,     0   ],
+         [      0 ,     0  , 10000  ,     0   ],
+         [   1572 ,  7467  ,     0  ,   960   ],
+         [   3842 ,     0  ,  5545  ,   611   ],
+         [      0 ,  5895  ,  4104  ,     0   ],
+         [   1615 ,  4192  ,  1397  ,  2794   ],
+         [   3144 ,  3231  ,  3056  ,   567   ]
+    ]
\ No newline at end of file
diff --git a/lib/bx/phylo/__init__.py b/lib/bx/phylo/__init__.py
new file mode 100644
index 0000000..f3732ed
--- /dev/null
+++ b/lib/bx/phylo/__init__.py
@@ -0,0 +1,3 @@
+"""
+Phylogenetic file format support.
+"""
\ No newline at end of file
diff --git a/lib/bx/phylo/newick.py b/lib/bx/phylo/newick.py
new file mode 100644
index 0000000..5e1374f
--- /dev/null
+++ b/lib/bx/phylo/newick.py
@@ -0,0 +1,98 @@
+"""
+Support for parsing phylogenetic tree's in newick format.
+
+TODO: Tree/Edge should be a generic data structure, not newick specific.
+"""
+from functools import total_ordering
+
+from bx_extras.pyparsing import *
+
+__all__ = [ "Tree", "Edge", "NewickParser", "newick_parser" ]
+
+def indent( s ):
+    return "\n".join( "    " + line for line in s.split( "\n" ) )
+
+def print_( p, s ):
+    print p, type(s), s
+    return s
+
+ at total_ordering
+class Tree( object ):
+    def __init__( self, label, edges=None ):
+        self.label = label
+        self.edges = edges
+    def pretty( self ):
+        if self.edges:
+            return "Tree( '%s',\n%s\n)" % ( self.label, indent( "\n".join( repr( edge ) for edge in self.edges ) ) )
+        else:
+            return "Tree( '%s' )" % self.label
+    def __lt__(self, other):
+        return self.__dict__ < other.__dict__
+    def __eq__(self, other):
+        return self.__dict__ == other.__dict__
+    def __repr__( self ):
+        return "Tree( %s, %s )" % ( repr( self.label ), repr( self.edges ) )
+
+ at total_ordering
+class Edge( object ):
+    def __init__( self, length, tip ):
+        self.length = length
+        self.tip = tip
+    def pretty( self ):
+        return "Edge( %s, \n%s\n)" % ( repr( self.length ), indent( repr( self.tip ) ) )
+    def __lt__(self, other):
+        return self.__dict__ < other.__dict__
+    def __eq__(self, other):
+        return self.__dict__ == other.__dict__
+    def __repr__( self ):
+        return "Edge( %s, %s )" % ( repr( self.length ), repr( self.tip ) )
+
+def create_parser():
+    """
+    Create a 'pyparsing' parser for newick format trees roughly based on the
+    grammar here:
+        http://evolution.genetics.washington.edu/phylip/newick_doc.html
+
+    Problems:
+        - Is a single leaf a valid tree?
+        - Branch length on root? Doesn't make sense to me, and forces the root
+          to be an edge.
+    """
+    # Basic tokens
+    real = Combine( Word( "+-" + nums, nums ) +
+                    Optional( "." + Optional( Word( nums ) ) ) +
+                    Optional( CaselessLiteral( "E" ) + Word( "+-" + nums, nums ) ) )
+    lpar = Suppress( "(" )
+    rpar = Suppress( ")" )
+    colon = Suppress( ":" )
+    semi = Suppress( ";" )
+    quot = Suppress( "'" )
+    # Labels are either unquoted or single quoted, if unquoted underscores will be replaced with spaces
+    quoted_label = QuotedString( "'", None, "''" ).setParseAction( lambda s, l, t: t[0] )
+    simple_label = Word( alphas + nums + "_." ).setParseAction( lambda s, l, t: t[0].replace( "_", " " ) )
+    label = quoted_label | simple_label
+    # Branch length is a real number (note though that exponents are not in the spec!)
+    branch_length = real.setParseAction( lambda s, l, t: float( t[0] ) )
+    # Need to forward declare this due to circularity
+    node_list = Forward()
+    # A node might have an list of edges (for a subtree), a label, and/or a branch length
+    node = ( Optional( node_list, None ) + Optional( label, "" ) + Optional( colon + branch_length, None ) ) \
+        .setParseAction( lambda s, l, t: Edge( t[2], Tree( t[1] or None, t[0] ) ) )
+    node_list << ( lpar + delimitedList( node ) + rpar ) \
+        .setParseAction( lambda s, l, t: [ t.asList() ] )
+    # The root cannot have a branch length
+    tree = ( node_list + Optional( label, "" ) + semi )\
+        .setParseAction( lambda s, l, t: Tree( t[1] or None, t[0] ) )
+    # Return the outermost element
+    return tree
+
+class NewickParser( object ):
+    """
+    Class wrapping a parser for building Trees from newick format strings
+    """
+    def __init__( self ):
+        self.parser = create_parser()
+    def parse_string( self, s ):
+        return self.parser.parseString( s )[0]
+
+newick_parser = NewickParser()
diff --git a/lib/bx/phylo/newick_tests.py b/lib/bx/phylo/newick_tests.py
new file mode 100644
index 0000000..3fca8da
--- /dev/null
+++ b/lib/bx/phylo/newick_tests.py
@@ -0,0 +1,33 @@
+"""
+Tests for `bx.phylo.newick`.
+"""
+
+from bx.phylo.newick import *
+import unittest
+
+trees = [ r"(B:6.0,(A:5.0,C:3.0,'Foo ''bar':4.0)Q_X:5.0,D:11.0)label;",
+          "((raccoon:19.19959,bear:6.80041):0.84600,((sea_lion:11.99700, seal:12.00300):7.52973,(( monkey:100.85930,cat:47.14069):20.59201, weasel:18.87953):2.09460):3.87382,dog:25.46154);",
+          "(Bovine:0.69395,(Gibbon:0.36079,(Orang:0.33636,(Gorilla:0.17147,(Chimp:0.19268, Human:0.11927):0.08386):0.06124):0.15057):0.54939,Mouse:1.21460);",
+          "(Bovine:0.69395,(Hylobates:0.36079,(Pongo:0.33636,(G._Gorilla:0.17147, (P._paniscus:0.19268,H._sapiens:0.11927):0.08386):0.06124):0.15057):0.54939, Rodent:1.21460);",
+          "(B,(A,C,E),D);",
+          "(,(,,),);",
+          "(A,(B,C),D);",
+          "((A,D),(C,B));"
+]
+
+results = [ ( Tree( 'label', [Edge( 6.0, Tree( 'B', None ) ), Edge( 5.0, Tree( 'Q X', [Edge( 5.0, Tree( 'A', None ) ), Edge( 3.0, Tree( 'C', None ) ), Edge( 4.0, Tree( "Foo 'bar", None ) )] ) ), Edge( 11.0, Tree( 'D', None ) )] ) ),
+            ( Tree( None, [Edge( 0.84599999999999997, Tree( None, [Edge( 19.199590000000001, Tree( 'raccoon', None ) ), Edge( 6.8004100000000003, Tree( 'bear', None ) )] ) ), Edge( 3.8738199999999998, Tree( None, [Edge( 7.5297299999999998, Tree( None, [Edge( 11.997, Tree( 'sea lion', None ) ), Edge( 12.003, Tree( 'seal', None ) )] ) ), Edge( 2.0945999999999998, Tree( None, [Edge( 20.592009999999998, Tree( None, [Edge( 100.8593, Tree( 'monkey', None ) ), Edge( 47.140689999999999, Tree( 'c [...]
+            ( Tree( None, [Edge( 0.69394999999999996, Tree( 'Bovine', None ) ), Edge( 0.54939000000000004, Tree( None, [Edge( 0.36079, Tree( 'Gibbon', None ) ), Edge( 0.15057000000000001, Tree( None, [Edge( 0.33635999999999999, Tree( 'Orang', None ) ), Edge( 0.061240000000000003, Tree( None, [Edge( 0.17147000000000001, Tree( 'Gorilla', None ) ), Edge( 0.083860000000000004, Tree( None, [Edge( 0.19267999999999999, Tree( 'Chimp', None ) ), Edge( 0.11927, Tree( 'Human', None ) )] ) )] ) )] ) [...]
+            ( Tree( None, [Edge( 0.69394999999999996, Tree( 'Bovine', None ) ), Edge( 0.54939000000000004, Tree( None, [Edge( 0.36079, Tree( 'Hylobates', None ) ), Edge( 0.15057000000000001, Tree( None, [Edge( 0.33635999999999999, Tree( 'Pongo', None ) ), Edge( 0.061240000000000003, Tree( None, [Edge( 0.17147000000000001, Tree( 'G. Gorilla', None ) ), Edge( 0.083860000000000004, Tree( None, [Edge( 0.19267999999999999, Tree( 'P. paniscus', None ) ), Edge( 0.11927, Tree( 'H. sapiens', None [...]
+            ( Tree( None, [Edge( None, Tree( 'B', None ) ), Edge( None, Tree( None, [Edge( None, Tree( 'A', None ) ), Edge( None, Tree( 'C', None ) ), Edge( None, Tree( 'E', None ) )] ) ), Edge( None, Tree( 'D', None ) )] ) ),
+            ( Tree( None, [Edge( None, Tree( None, None ) ), Edge( None, Tree( None, [Edge( None, Tree( None, None ) ), Edge( None, Tree( None, None ) ), Edge( None, Tree( None, None ) )] ) ), Edge( None, Tree( None, None ) )] ) ),
+            ( Tree( None, [Edge( None, Tree( 'A', None ) ), Edge( None, Tree( None, [Edge( None, Tree( 'B', None ) ), Edge( None, Tree( 'C', None ) )] ) ), Edge( None, Tree( 'D', None ) )] ) ),
+            ( Tree( None, [Edge( None, Tree( None, [Edge( None, Tree( 'A', None ) ), Edge( None, Tree( 'D', None ) )] ) ), Edge( None, Tree( None, [Edge( None, Tree( 'C', None ) ), Edge( None, Tree( 'B', None ) )] ) )] ) ),
+            ]
+
+def tests(): 
+    for i in range(len(trees)):
+        def _( s, r ):
+            assert newick_parser.parse_string( s ) == r
+        _.description = "check tree parsing " + str(i)
+        yield _, trees[i], results[i] 
diff --git a/lib/bx/phylo/phast.py b/lib/bx/phylo/phast.py
new file mode 100644
index 0000000..4ba3a0c
--- /dev/null
+++ b/lib/bx/phylo/phast.py
@@ -0,0 +1,42 @@
+"""
+Rudimentary support for PHAST's tree model file format (a simple format for
+storing trees and rate matrices).
+"""
+
+from numpy import *
+
+class TreeModel:
+    def __init__( self ):
+        self.alphabet = None
+        self.radix = 0
+        self.order = 0
+        self.subst_mod = None
+        self.background = None
+        self.tree = None
+        self.matrix = None
+    ## TODO: Need scipy for this method
+    ## def matrix_for_time( self, t ):
+    ##     return expm( self.matrix * t )
+    ## matrix_for_time = cachedmethod( matrix_for_time )
+    @staticmethod
+    def from_file( f ):
+        input = iter( f )
+        tm = TreeModel()
+        for line in input:
+            if line.startswith( "ALPHABET:" ):
+                tm.alphabet = tuple( line.split()[1:] )    
+                tm.radix = len( tm.alphabet )
+            if line.startswith( "ORDER:" ):
+                tm.order = int( line.split()[1] )
+            if line.startswith( "SUBST_MOD:" ):
+                tm.subst_mod = line[11:].rstrip()                   
+            if line.startswith( "BACKGROUND:" ):
+                tm.background = tuple( map( float, line.split()[1:] ) )
+            if line.startswith( "TREE:" ):
+                tm.tree = line[6:].strip() 
+            if line.startswith( "RATE_MAT:" ):
+                matrix = zeros( (tm.radix,tm.radix), float )
+                for i in range( len( tm.alphabet ) ):
+                    matrix[i] = map( float, input.next().split() )
+                tm.matrix = matrix
+        return tm
diff --git a/lib/bx/phylo/phast_tests.py b/lib/bx/phylo/phast_tests.py
new file mode 100644
index 0000000..2e60976
--- /dev/null
+++ b/lib/bx/phylo/phast_tests.py
@@ -0,0 +1,36 @@
+"""
+Tests for `bx.phylo.phast`.
+"""
+
+import unittest
+from StringIO import StringIO
+from bx.phylo.phast import TreeModel
+from numpy import *
+
+test_data = """ALPHABET: A C G T - 
+ORDER: 0
+SUBST_MOD: HKY85+Gap
+TRAINING_LNL: -178667772.836697
+BACKGROUND: 0.227006 0.169993 0.169307 0.227262 0.206432 
+RATE_MAT:
+  -0.971735    0.122443    0.465361    0.163692    0.220238 
+   0.163508   -1.130351    0.121949    0.624656    0.220238 
+   0.623952    0.122443   -1.130326    0.163692    0.220238 
+   0.163508    0.467247    0.121949   -0.972942    0.220238 
+   0.242187    0.181362    0.180630    0.242461   -0.846640 
+TREE: ((((((hg16:0.007738,panTro1:0.008356):0.027141,(baboon:0.009853,rheMac1:0.010187):0.035049):0.103138,galago:0.174770):0.019102,((rn3:0.092633,mm6:0.089667):0.273942,rabbit:0.230839):0.021927):0.023762,(canFam1:0.204637,(elephant:0.123777,tenrec:0.278910):0.085977):0.009439):0.306466,monDom1:0.401151)mammals;
+"""
+
+def test_parser():
+    tm = TreeModel.from_file( StringIO( test_data ) )
+    assert tm.alphabet == ( 'A', 'C', 'G', 'T', '-' )
+    assert tm.order == 0
+    assert tm.subst_mod == "HKY85+Gap"
+    assert allclose( tm.background, [ 0.227006, 0.169993, 0.169307, 0.227262, 0.206432 ] )
+    assert allclose( tm.matrix, array( 
+        [ [ -0.971735,  0.122443,   0.465361,   0.163692,   0.220238 ],
+          [ 0.163508,  -1.130351,   0.121949,   0.624656,   0.220238 ],
+          [ 0.623952,   0.122443,  -1.130326,   0.163692,   0.220238 ],
+          [ 0.163508,   0.467247,   0.121949,  -0.972942,   0.220238 ],
+          [ 0.242187,   0.181362,   0.180630,   0.242461,  -0.846640 ] ] ) )
+    assert tm.tree == "((((((hg16:0.007738,panTro1:0.008356):0.027141,(baboon:0.009853,rheMac1:0.010187):0.035049):0.103138,galago:0.174770):0.019102,((rn3:0.092633,mm6:0.089667):0.273942,rabbit:0.230839):0.021927):0.023762,(canFam1:0.204637,(elephant:0.123777,tenrec:0.278910):0.085977):0.009439):0.306466,monDom1:0.401151)mammals;"
diff --git a/lib/bx/pwm/__init__.py b/lib/bx/pwm/__init__.py
new file mode 100644
index 0000000..de97217
--- /dev/null
+++ b/lib/bx/pwm/__init__.py
@@ -0,0 +1,7 @@
+"""
+Data structures and tools for working with Position Weight Matrices (PWMs).
+
+TODO: Some of the packages in this directory are actually command line
+programs that provide no library functions and should be moved to the
+scripts directory.
+"""
\ No newline at end of file
diff --git a/lib/bx/pwm/_position_weight_matrix.c b/lib/bx/pwm/_position_weight_matrix.c
new file mode 100644
index 0000000..083b726
--- /dev/null
+++ b/lib/bx/pwm/_position_weight_matrix.c
@@ -0,0 +1,1620 @@
+/* Generated by Cython 0.18 on Mon Jul 15 13:25:44 2013 */
+
+#define PY_SSIZE_T_CLEAN
+#include "Python.h"
+#ifndef Py_PYTHON_H
+    #error Python headers needed to compile C extensions, please install development version of Python.
+#elif PY_VERSION_HEX < 0x02040000
+    #error Cython requires Python 2.4+.
+#else
+#include <stddef.h> /* For offsetof */
+#ifndef offsetof
+#define offsetof(type, member) ( (size_t) & ((type*)0) -> member )
+#endif
+#if !defined(WIN32) && !defined(MS_WINDOWS)
+  #ifndef __stdcall
+    #define __stdcall
+  #endif
+  #ifndef __cdecl
+    #define __cdecl
+  #endif
+  #ifndef __fastcall
+    #define __fastcall
+  #endif
+#endif
+#ifndef DL_IMPORT
+  #define DL_IMPORT(t) t
+#endif
+#ifndef DL_EXPORT
+  #define DL_EXPORT(t) t
+#endif
+#ifndef PY_LONG_LONG
+  #define PY_LONG_LONG LONG_LONG
+#endif
+#ifndef Py_HUGE_VAL
+  #define Py_HUGE_VAL HUGE_VAL
+#endif
+#ifdef PYPY_VERSION
+#define CYTHON_COMPILING_IN_PYPY 1
+#define CYTHON_COMPILING_IN_CPYTHON 0
+#else
+#define CYTHON_COMPILING_IN_PYPY 0
+#define CYTHON_COMPILING_IN_CPYTHON 1
+#endif
+#if PY_VERSION_HEX < 0x02050000
+  typedef int Py_ssize_t;
+  #define PY_SSIZE_T_MAX INT_MAX
+  #define PY_SSIZE_T_MIN INT_MIN
+  #define PY_FORMAT_SIZE_T ""
+  #define CYTHON_FORMAT_SSIZE_T ""
+  #define PyInt_FromSsize_t(z) PyInt_FromLong(z)
+  #define PyInt_AsSsize_t(o)   __Pyx_PyInt_AsInt(o)
+  #define PyNumber_Index(o)    ((PyNumber_Check(o) && !PyFloat_Check(o)) ? PyNumber_Int(o) : \
+                                (PyErr_Format(PyExc_TypeError, \
+                                              "expected index value, got %.200s", Py_TYPE(o)->tp_name), \
+                                 (PyObject*)0))
+  #define __Pyx_PyIndex_Check(o) (PyNumber_Check(o) && !PyFloat_Check(o) && \
+                                  !PyComplex_Check(o))
+  #define PyIndex_Check __Pyx_PyIndex_Check
+  #define PyErr_WarnEx(category, message, stacklevel) PyErr_Warn(category, message)
+  #define __PYX_BUILD_PY_SSIZE_T "i"
+#else
+  #define __PYX_BUILD_PY_SSIZE_T "n"
+  #define CYTHON_FORMAT_SSIZE_T "z"
+  #define __Pyx_PyIndex_Check PyIndex_Check
+#endif
+#if PY_VERSION_HEX < 0x02060000
+  #define Py_REFCNT(ob) (((PyObject*)(ob))->ob_refcnt)
+  #define Py_TYPE(ob)   (((PyObject*)(ob))->ob_type)
+  #define Py_SIZE(ob)   (((PyVarObject*)(ob))->ob_size)
+  #define PyVarObject_HEAD_INIT(type, size) \
+          PyObject_HEAD_INIT(type) size,
+  #define PyType_Modified(t)
+  typedef struct {
+     void *buf;
+     PyObject *obj;
+     Py_ssize_t len;
+     Py_ssize_t itemsize;
+     int readonly;
+     int ndim;
+     char *format;
+     Py_ssize_t *shape;
+     Py_ssize_t *strides;
+     Py_ssize_t *suboffsets;
+     void *internal;
+  } Py_buffer;
+  #define PyBUF_SIMPLE 0
+  #define PyBUF_WRITABLE 0x0001
+  #define PyBUF_FORMAT 0x0004
+  #define PyBUF_ND 0x0008
+  #define PyBUF_STRIDES (0x0010 | PyBUF_ND)
+  #define PyBUF_C_CONTIGUOUS (0x0020 | PyBUF_STRIDES)
+  #define PyBUF_F_CONTIGUOUS (0x0040 | PyBUF_STRIDES)
+  #define PyBUF_ANY_CONTIGUOUS (0x0080 | PyBUF_STRIDES)
+  #define PyBUF_INDIRECT (0x0100 | PyBUF_STRIDES)
+  #define PyBUF_RECORDS (PyBUF_STRIDES | PyBUF_FORMAT | PyBUF_WRITABLE)
+  #define PyBUF_FULL (PyBUF_INDIRECT | PyBUF_FORMAT | PyBUF_WRITABLE)
+  typedef int (*getbufferproc)(PyObject *, Py_buffer *, int);
+  typedef void (*releasebufferproc)(PyObject *, Py_buffer *);
+#endif
+#if PY_MAJOR_VERSION < 3
+  #define __Pyx_BUILTIN_MODULE_NAME "__builtin__"
+  #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \
+          PyCode_New(a, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
+#else
+  #define __Pyx_BUILTIN_MODULE_NAME "builtins"
+  #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \
+          PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
+#endif
+#if PY_MAJOR_VERSION < 3 && PY_MINOR_VERSION < 6
+  #define PyUnicode_FromString(s) PyUnicode_Decode(s, strlen(s), "UTF-8", "strict")
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define Py_TPFLAGS_CHECKTYPES 0
+  #define Py_TPFLAGS_HAVE_INDEX 0
+#endif
+#if (PY_VERSION_HEX < 0x02060000) || (PY_MAJOR_VERSION >= 3)
+  #define Py_TPFLAGS_HAVE_NEWBUFFER 0
+#endif
+#if PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND)
+  #define CYTHON_PEP393_ENABLED 1
+  #define __Pyx_PyUnicode_READY(op)       (likely(PyUnicode_IS_READY(op)) ? \
+                                              0 : _PyUnicode_Ready((PyObject *)(op)))
+  #define __Pyx_PyUnicode_GET_LENGTH(u)   PyUnicode_GET_LENGTH(u)
+  #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_READ_CHAR(u, i)
+  #define __Pyx_PyUnicode_READ(k, d, i)   PyUnicode_READ(k, d, i)
+#else
+  #define CYTHON_PEP393_ENABLED 0
+  #define __Pyx_PyUnicode_READY(op)       (0)
+  #define __Pyx_PyUnicode_GET_LENGTH(u)   PyUnicode_GET_SIZE(u)
+  #define __Pyx_PyUnicode_READ_CHAR(u, i) ((Py_UCS4)(PyUnicode_AS_UNICODE(u)[i]))
+  #define __Pyx_PyUnicode_READ(k, d, i)   ((k=k), (Py_UCS4)(((Py_UNICODE*)d)[i]))
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define PyBaseString_Type            PyUnicode_Type
+  #define PyStringObject               PyUnicodeObject
+  #define PyString_Type                PyUnicode_Type
+  #define PyString_Check               PyUnicode_Check
+  #define PyString_CheckExact          PyUnicode_CheckExact
+#endif
+#if PY_VERSION_HEX < 0x02060000
+  #define PyBytesObject                PyStringObject
+  #define PyBytes_Type                 PyString_Type
+  #define PyBytes_Check                PyString_Check
+  #define PyBytes_CheckExact           PyString_CheckExact
+  #define PyBytes_FromString           PyString_FromString
+  #define PyBytes_FromStringAndSize    PyString_FromStringAndSize
+  #define PyBytes_FromFormat           PyString_FromFormat
+  #define PyBytes_DecodeEscape         PyString_DecodeEscape
+  #define PyBytes_AsString             PyString_AsString
+  #define PyBytes_AsStringAndSize      PyString_AsStringAndSize
+  #define PyBytes_Size                 PyString_Size
+  #define PyBytes_AS_STRING            PyString_AS_STRING
+  #define PyBytes_GET_SIZE             PyString_GET_SIZE
+  #define PyBytes_Repr                 PyString_Repr
+  #define PyBytes_Concat               PyString_Concat
+  #define PyBytes_ConcatAndDel         PyString_ConcatAndDel
+#endif
+#if PY_VERSION_HEX < 0x02060000
+  #define PySet_Check(obj)             PyObject_TypeCheck(obj, &PySet_Type)
+  #define PyFrozenSet_Check(obj)       PyObject_TypeCheck(obj, &PyFrozenSet_Type)
+#endif
+#ifndef PySet_CheckExact
+  #define PySet_CheckExact(obj)        (Py_TYPE(obj) == &PySet_Type)
+#endif
+#define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type)
+#if PY_MAJOR_VERSION >= 3
+  #define PyIntObject                  PyLongObject
+  #define PyInt_Type                   PyLong_Type
+  #define PyInt_Check(op)              PyLong_Check(op)
+  #define PyInt_CheckExact(op)         PyLong_CheckExact(op)
+  #define PyInt_FromString             PyLong_FromString
+  #define PyInt_FromUnicode            PyLong_FromUnicode
+  #define PyInt_FromLong               PyLong_FromLong
+  #define PyInt_FromSize_t             PyLong_FromSize_t
+  #define PyInt_FromSsize_t            PyLong_FromSsize_t
+  #define PyInt_AsLong                 PyLong_AsLong
+  #define PyInt_AS_LONG                PyLong_AS_LONG
+  #define PyInt_AsSsize_t              PyLong_AsSsize_t
+  #define PyInt_AsUnsignedLongMask     PyLong_AsUnsignedLongMask
+  #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define PyBoolObject                 PyLongObject
+#endif
+#if PY_VERSION_HEX < 0x03020000
+  typedef long Py_hash_t;
+  #define __Pyx_PyInt_FromHash_t PyInt_FromLong
+  #define __Pyx_PyInt_AsHash_t   PyInt_AsLong
+#else
+  #define __Pyx_PyInt_FromHash_t PyInt_FromSsize_t
+  #define __Pyx_PyInt_AsHash_t   PyInt_AsSsize_t
+#endif
+#if (PY_MAJOR_VERSION < 3) || (PY_VERSION_HEX >= 0x03010300)
+  #define __Pyx_PySequence_GetSlice(obj, a, b) PySequence_GetSlice(obj, a, b)
+  #define __Pyx_PySequence_SetSlice(obj, a, b, value) PySequence_SetSlice(obj, a, b, value)
+  #define __Pyx_PySequence_DelSlice(obj, a, b) PySequence_DelSlice(obj, a, b)
+#else
+  #define __Pyx_PySequence_GetSlice(obj, a, b) (unlikely(!(obj)) ? \
+        (PyErr_SetString(PyExc_SystemError, "null argument to internal routine"), (PyObject*)0) : \
+        (likely((obj)->ob_type->tp_as_mapping) ? (PySequence_GetSlice(obj, a, b)) : \
+            (PyErr_Format(PyExc_TypeError, "'%.200s' object is unsliceable", (obj)->ob_type->tp_name), (PyObject*)0)))
+  #define __Pyx_PySequence_SetSlice(obj, a, b, value) (unlikely(!(obj)) ? \
+        (PyErr_SetString(PyExc_SystemError, "null argument to internal routine"), -1) : \
+        (likely((obj)->ob_type->tp_as_mapping) ? (PySequence_SetSlice(obj, a, b, value)) : \
+            (PyErr_Format(PyExc_TypeError, "'%.200s' object doesn't support slice assignment", (obj)->ob_type->tp_name), -1)))
+  #define __Pyx_PySequence_DelSlice(obj, a, b) (unlikely(!(obj)) ? \
+        (PyErr_SetString(PyExc_SystemError, "null argument to internal routine"), -1) : \
+        (likely((obj)->ob_type->tp_as_mapping) ? (PySequence_DelSlice(obj, a, b)) : \
+            (PyErr_Format(PyExc_TypeError, "'%.200s' object doesn't support slice deletion", (obj)->ob_type->tp_name), -1)))
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define PyMethod_New(func, self, klass) ((self) ? PyMethod_New(func, self) : PyInstanceMethod_New(func))
+#endif
+#if PY_VERSION_HEX < 0x02050000
+  #define __Pyx_GetAttrString(o,n)   PyObject_GetAttrString((o),((char *)(n)))
+  #define __Pyx_SetAttrString(o,n,a) PyObject_SetAttrString((o),((char *)(n)),(a))
+  #define __Pyx_DelAttrString(o,n)   PyObject_DelAttrString((o),((char *)(n)))
+#else
+  #define __Pyx_GetAttrString(o,n)   PyObject_GetAttrString((o),(n))
+  #define __Pyx_SetAttrString(o,n,a) PyObject_SetAttrString((o),(n),(a))
+  #define __Pyx_DelAttrString(o,n)   PyObject_DelAttrString((o),(n))
+#endif
+#if PY_VERSION_HEX < 0x02050000
+  #define __Pyx_NAMESTR(n) ((char *)(n))
+  #define __Pyx_DOCSTR(n)  ((char *)(n))
+#else
+  #define __Pyx_NAMESTR(n) (n)
+  #define __Pyx_DOCSTR(n)  (n)
+#endif
+
+
+#if PY_MAJOR_VERSION >= 3
+  #define __Pyx_PyNumber_Divide(x,y)         PyNumber_TrueDivide(x,y)
+  #define __Pyx_PyNumber_InPlaceDivide(x,y)  PyNumber_InPlaceTrueDivide(x,y)
+#else
+  #define __Pyx_PyNumber_Divide(x,y)         PyNumber_Divide(x,y)
+  #define __Pyx_PyNumber_InPlaceDivide(x,y)  PyNumber_InPlaceDivide(x,y)
+#endif
+
+#ifndef __PYX_EXTERN_C
+  #ifdef __cplusplus
+    #define __PYX_EXTERN_C extern "C"
+  #else
+    #define __PYX_EXTERN_C extern
+  #endif
+#endif
+
+#if defined(WIN32) || defined(MS_WINDOWS)
+#define _USE_MATH_DEFINES
+#endif
+#include <math.h>
+#define __PYX_HAVE__bx__pwm___position_weight_matrix
+#define __PYX_HAVE_API__bx__pwm___position_weight_matrix
+#include "pwm_utils.h"
+#ifdef _OPENMP
+#include <omp.h>
+#endif /* _OPENMP */
+
+#ifdef PYREX_WITHOUT_ASSERTIONS
+#define CYTHON_WITHOUT_ASSERTIONS
+#endif
+
+#ifndef CYTHON_INLINE
+  #if defined(__GNUC__)
+    #define CYTHON_INLINE __inline__
+  #elif defined(_MSC_VER)
+    #define CYTHON_INLINE __inline
+  #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+    #define CYTHON_INLINE inline
+  #else
+    #define CYTHON_INLINE
+  #endif
+#endif
+#ifndef CYTHON_UNUSED
+# if defined(__GNUC__)
+#   if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
+#     define CYTHON_UNUSED __attribute__ ((__unused__))
+#   else
+#     define CYTHON_UNUSED
+#   endif
+# elif defined(__ICC) || (defined(__INTEL_COMPILER) && !defined(_MSC_VER))
+#   define CYTHON_UNUSED __attribute__ ((__unused__))
+# else
+#   define CYTHON_UNUSED
+# endif
+#endif
+typedef struct {PyObject **p; char *s; const long n; const char* encoding; const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry; /*proto*/
+
+#define __Pyx_PyBytes_FromUString(s) PyBytes_FromString((char*)s)
+#define __Pyx_PyBytes_AsUString(s)   ((unsigned char*) PyBytes_AsString(s))
+#define __Pyx_Owned_Py_None(b) (Py_INCREF(Py_None), Py_None)
+#define __Pyx_PyBool_FromLong(b) ((b) ? (Py_INCREF(Py_True), Py_True) : (Py_INCREF(Py_False), Py_False))
+static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*);
+static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x);
+static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*);
+static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t);
+static CYTHON_INLINE size_t __Pyx_PyInt_AsSize_t(PyObject*);
+#if CYTHON_COMPILING_IN_CPYTHON
+#define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x))
+#else
+#define __pyx_PyFloat_AsDouble(x) PyFloat_AsDouble(x)
+#endif
+#define __pyx_PyFloat_AsFloat(x) ((float) __pyx_PyFloat_AsDouble(x))
+
+
+#ifdef __GNUC__
+  /* Test for GCC > 2.95 */
+  #if __GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))
+    #define likely(x)   __builtin_expect(!!(x), 1)
+    #define unlikely(x) __builtin_expect(!!(x), 0)
+  #else /* __GNUC__ > 2 ... */
+    #define likely(x)   (x)
+    #define unlikely(x) (x)
+  #endif /* __GNUC__ > 2 ... */
+#else /* __GNUC__ */
+  #define likely(x)   (x)
+  #define unlikely(x) (x)
+#endif /* __GNUC__ */
+    
+static PyObject *__pyx_m;
+static PyObject *__pyx_b;
+static PyObject *__pyx_empty_tuple;
+static PyObject *__pyx_empty_bytes;
+static int __pyx_lineno;
+static int __pyx_clineno = 0;
+static const char * __pyx_cfilenm= __FILE__;
+static const char *__pyx_filename;
+
+
+static const char *__pyx_f[] = {
+  "_position_weight_matrix.pyx",
+};
+
+/*--- Type declarations ---*/
+#ifndef CYTHON_REFNANNY
+  #define CYTHON_REFNANNY 0
+#endif
+#if CYTHON_REFNANNY
+  typedef struct {
+    void (*INCREF)(void*, PyObject*, int);
+    void (*DECREF)(void*, PyObject*, int);
+    void (*GOTREF)(void*, PyObject*, int);
+    void (*GIVEREF)(void*, PyObject*, int);
+    void* (*SetupContext)(const char*, int, const char*);
+    void (*FinishContext)(void**);
+  } __Pyx_RefNannyAPIStruct;
+  static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL;
+  static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname); /*proto*/
+  #define __Pyx_RefNannyDeclarations void *__pyx_refnanny = NULL;
+#ifdef WITH_THREAD
+  #define __Pyx_RefNannySetupContext(name, acquire_gil) \
+          if (acquire_gil) { \
+              PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure(); \
+              __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__); \
+              PyGILState_Release(__pyx_gilstate_save); \
+          } else { \
+              __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__); \
+          }
+#else
+  #define __Pyx_RefNannySetupContext(name, acquire_gil) \
+          __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__)
+#endif
+  #define __Pyx_RefNannyFinishContext() \
+          __Pyx_RefNanny->FinishContext(&__pyx_refnanny)
+  #define __Pyx_INCREF(r)  __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_DECREF(r)  __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_GOTREF(r)  __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_XINCREF(r)  do { if((r) != NULL) {__Pyx_INCREF(r); }} while(0)
+  #define __Pyx_XDECREF(r)  do { if((r) != NULL) {__Pyx_DECREF(r); }} while(0)
+  #define __Pyx_XGOTREF(r)  do { if((r) != NULL) {__Pyx_GOTREF(r); }} while(0)
+  #define __Pyx_XGIVEREF(r) do { if((r) != NULL) {__Pyx_GIVEREF(r);}} while(0)
+#else
+  #define __Pyx_RefNannyDeclarations
+  #define __Pyx_RefNannySetupContext(name, acquire_gil)
+  #define __Pyx_RefNannyFinishContext()
+  #define __Pyx_INCREF(r) Py_INCREF(r)
+  #define __Pyx_DECREF(r) Py_DECREF(r)
+  #define __Pyx_GOTREF(r)
+  #define __Pyx_GIVEREF(r)
+  #define __Pyx_XINCREF(r) Py_XINCREF(r)
+  #define __Pyx_XDECREF(r) Py_XDECREF(r)
+  #define __Pyx_XGOTREF(r)
+  #define __Pyx_XGIVEREF(r)
+#endif /* CYTHON_REFNANNY */
+#define __Pyx_CLEAR(r)    do { PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);} while(0)
+#define __Pyx_XCLEAR(r)   do { if((r) != NULL) {PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);}} while(0)
+
+static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
+    Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/
+
+static void __Pyx_RaiseDoubleKeywordsError(const char* func_name, PyObject* kw_name); /*proto*/
+
+static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
+    PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
+    const char* function_name); /*proto*/
+
+static CYTHON_INLINE unsigned char __Pyx_PyInt_AsUnsignedChar(PyObject *);
+
+static CYTHON_INLINE unsigned short __Pyx_PyInt_AsUnsignedShort(PyObject *);
+
+static CYTHON_INLINE unsigned int __Pyx_PyInt_AsUnsignedInt(PyObject *);
+
+static CYTHON_INLINE char __Pyx_PyInt_AsChar(PyObject *);
+
+static CYTHON_INLINE short __Pyx_PyInt_AsShort(PyObject *);
+
+static CYTHON_INLINE int __Pyx_PyInt_AsInt(PyObject *);
+
+static CYTHON_INLINE signed char __Pyx_PyInt_AsSignedChar(PyObject *);
+
+static CYTHON_INLINE signed short __Pyx_PyInt_AsSignedShort(PyObject *);
+
+static CYTHON_INLINE signed int __Pyx_PyInt_AsSignedInt(PyObject *);
+
+static CYTHON_INLINE int __Pyx_PyInt_AsLongDouble(PyObject *);
+
+static CYTHON_INLINE unsigned long __Pyx_PyInt_AsUnsignedLong(PyObject *);
+
+static CYTHON_INLINE unsigned PY_LONG_LONG __Pyx_PyInt_AsUnsignedLongLong(PyObject *);
+
+static CYTHON_INLINE long __Pyx_PyInt_AsLong(PyObject *);
+
+static CYTHON_INLINE PY_LONG_LONG __Pyx_PyInt_AsLongLong(PyObject *);
+
+static CYTHON_INLINE signed long __Pyx_PyInt_AsSignedLong(PyObject *);
+
+static CYTHON_INLINE signed PY_LONG_LONG __Pyx_PyInt_AsSignedLongLong(PyObject *);
+
+static int __Pyx_check_binary_version(void);
+
+typedef struct {
+    int code_line;
+    PyCodeObject* code_object;
+} __Pyx_CodeObjectCacheEntry;
+struct __Pyx_CodeObjectCache {
+    int count;
+    int max_count;
+    __Pyx_CodeObjectCacheEntry* entries;
+};
+static struct __Pyx_CodeObjectCache __pyx_code_cache = {0,0,NULL};
+static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line);
+static PyCodeObject *__pyx_find_code_object(int code_line);
+static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object);
+
+static void __Pyx_AddTraceback(const char *funcname, int c_line,
+                               int py_line, const char *filename); /*proto*/
+
+static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
+
+
+/* Module declarations from 'bx.pwm._position_weight_matrix' */
+#define __Pyx_MODULE_NAME "bx.pwm._position_weight_matrix"
+int __pyx_module_is_main_bx__pwm___position_weight_matrix = 0;
+
+/* Implementation of 'bx.pwm._position_weight_matrix' */
+static PyObject *__pyx_pf_2bx_3pwm_23_position_weight_matrix_c_match_consensus(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_sequence, PyObject *__pyx_v_pattern, PyObject *__pyx_v_size); /* proto */
+static char __pyx_k_3[] = "/aut/proj/odenas/software/bx-python/lib/bx/pwm/_position_weight_matrix.pyx";
+static char __pyx_k_4[] = "bx.pwm._position_weight_matrix";
+static char __pyx_k__size[] = "size";
+static char __pyx_k__pattern[] = "pattern";
+static char __pyx_k____main__[] = "__main__";
+static char __pyx_k____test__[] = "__test__";
+static char __pyx_k__sequence[] = "sequence";
+static char __pyx_k__c_match_consensus[] = "c_match_consensus";
+static PyObject *__pyx_kp_s_3;
+static PyObject *__pyx_n_s_4;
+static PyObject *__pyx_n_s____main__;
+static PyObject *__pyx_n_s____test__;
+static PyObject *__pyx_n_s__c_match_consensus;
+static PyObject *__pyx_n_s__pattern;
+static PyObject *__pyx_n_s__sequence;
+static PyObject *__pyx_n_s__size;
+static PyObject *__pyx_k_tuple_1;
+static PyObject *__pyx_k_codeobj_2;
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_3pwm_23_position_weight_matrix_1c_match_consensus(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_mdef_2bx_3pwm_23_position_weight_matrix_1c_match_consensus = {__Pyx_NAMESTR("c_match_consensus"), (PyCFunction)__pyx_pw_2bx_3pwm_23_position_weight_matrix_1c_match_consensus, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(0)};
+static PyObject *__pyx_pw_2bx_3pwm_23_position_weight_matrix_1c_match_consensus(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_sequence = 0;
+  PyObject *__pyx_v_pattern = 0;
+  PyObject *__pyx_v_size = 0;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("c_match_consensus (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__sequence,&__pyx_n_s__pattern,&__pyx_n_s__size,0};
+    PyObject* values[3] = {0,0,0};
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__sequence)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__pattern)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("c_match_consensus", 1, 3, 3, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 4; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+        case  2:
+        if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__size)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("c_match_consensus", 1, 3, 3, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 4; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "c_match_consensus") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 4; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else if (PyTuple_GET_SIZE(__pyx_args) != 3) {
+      goto __pyx_L5_argtuple_error;
+    } else {
+      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+      values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+    }
+    __pyx_v_sequence = values[0];
+    __pyx_v_pattern = values[1];
+    __pyx_v_size = values[2];
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("c_match_consensus", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 4; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.pwm._position_weight_matrix.c_match_consensus", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_3pwm_23_position_weight_matrix_c_match_consensus(__pyx_self, __pyx_v_sequence, __pyx_v_pattern, __pyx_v_size);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/pwm/_position_weight_matrix.pyx":4
+ *     int pattern_match( char* string, char* pattern, int n)
+ * 
+ * def c_match_consensus( sequence, pattern, size ):             # <<<<<<<<<<<<<<
+ *     return pattern_match( sequence, pattern, size )
+ */
+
+static PyObject *__pyx_pf_2bx_3pwm_23_position_weight_matrix_c_match_consensus(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_sequence, PyObject *__pyx_v_pattern, PyObject *__pyx_v_size) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  char *__pyx_t_1;
+  char *__pyx_t_2;
+  int __pyx_t_3;
+  PyObject *__pyx_t_4 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("c_match_consensus", 0);
+
+  /* "bx/pwm/_position_weight_matrix.pyx":5
+ * 
+ * def c_match_consensus( sequence, pattern, size ):
+ *     return pattern_match( sequence, pattern, size )             # <<<<<<<<<<<<<<
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = PyBytes_AsString(__pyx_v_sequence); if (unlikely((!__pyx_t_1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 5; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyBytes_AsString(__pyx_v_pattern); if (unlikely((!__pyx_t_2) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 5; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = __Pyx_PyInt_AsInt(__pyx_v_size); if (unlikely((__pyx_t_3 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 5; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_4 = PyInt_FromLong(pattern_match(__pyx_t_1, __pyx_t_2, __pyx_t_3)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 5; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __pyx_r = __pyx_t_4;
+  __pyx_t_4 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_AddTraceback("bx.pwm._position_weight_matrix.c_match_consensus", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyMethodDef __pyx_methods[] = {
+  {0, 0, 0, 0}
+};
+
+#if PY_MAJOR_VERSION >= 3
+static struct PyModuleDef __pyx_moduledef = {
+  #if PY_VERSION_HEX < 0x03020000
+    { PyObject_HEAD_INIT(NULL) NULL, 0, NULL },
+  #else
+    PyModuleDef_HEAD_INIT,
+  #endif
+    __Pyx_NAMESTR("_position_weight_matrix"),
+    0, /* m_doc */
+    -1, /* m_size */
+    __pyx_methods /* m_methods */,
+    NULL, /* m_reload */
+    NULL, /* m_traverse */
+    NULL, /* m_clear */
+    NULL /* m_free */
+};
+#endif
+
+static __Pyx_StringTabEntry __pyx_string_tab[] = {
+  {&__pyx_kp_s_3, __pyx_k_3, sizeof(__pyx_k_3), 0, 0, 1, 0},
+  {&__pyx_n_s_4, __pyx_k_4, sizeof(__pyx_k_4), 0, 0, 1, 1},
+  {&__pyx_n_s____main__, __pyx_k____main__, sizeof(__pyx_k____main__), 0, 0, 1, 1},
+  {&__pyx_n_s____test__, __pyx_k____test__, sizeof(__pyx_k____test__), 0, 0, 1, 1},
+  {&__pyx_n_s__c_match_consensus, __pyx_k__c_match_consensus, sizeof(__pyx_k__c_match_consensus), 0, 0, 1, 1},
+  {&__pyx_n_s__pattern, __pyx_k__pattern, sizeof(__pyx_k__pattern), 0, 0, 1, 1},
+  {&__pyx_n_s__sequence, __pyx_k__sequence, sizeof(__pyx_k__sequence), 0, 0, 1, 1},
+  {&__pyx_n_s__size, __pyx_k__size, sizeof(__pyx_k__size), 0, 0, 1, 1},
+  {0, 0, 0, 0, 0, 0, 0}
+};
+static int __Pyx_InitCachedBuiltins(void) {
+  return 0;
+}
+
+static int __Pyx_InitCachedConstants(void) {
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0);
+
+  /* "bx/pwm/_position_weight_matrix.pyx":4
+ *     int pattern_match( char* string, char* pattern, int n)
+ * 
+ * def c_match_consensus( sequence, pattern, size ):             # <<<<<<<<<<<<<<
+ *     return pattern_match( sequence, pattern, size )
+ */
+  __pyx_k_tuple_1 = PyTuple_Pack(3, ((PyObject *)__pyx_n_s__sequence), ((PyObject *)__pyx_n_s__pattern), ((PyObject *)__pyx_n_s__size)); if (unlikely(!__pyx_k_tuple_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 4; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_k_tuple_1);
+  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_1));
+  __pyx_k_codeobj_2 = (PyObject*)__Pyx_PyCode_New(3, 0, 3, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_k_tuple_1, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_3, __pyx_n_s__c_match_consensus, 4, __pyx_empty_bytes); if (unlikely(!__pyx_k_codeobj_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 4; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_RefNannyFinishContext();
+  return 0;
+  __pyx_L1_error:;
+  __Pyx_RefNannyFinishContext();
+  return -1;
+}
+
+static int __Pyx_InitGlobals(void) {
+  if (__Pyx_InitStrings(__pyx_string_tab) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  return 0;
+  __pyx_L1_error:;
+  return -1;
+}
+
+#if PY_MAJOR_VERSION < 3
+PyMODINIT_FUNC init_position_weight_matrix(void); /*proto*/
+PyMODINIT_FUNC init_position_weight_matrix(void)
+#else
+PyMODINIT_FUNC PyInit__position_weight_matrix(void); /*proto*/
+PyMODINIT_FUNC PyInit__position_weight_matrix(void)
+#endif
+{
+  PyObject *__pyx_t_1 = NULL;
+  __Pyx_RefNannyDeclarations
+  #if CYTHON_REFNANNY
+  __Pyx_RefNanny = __Pyx_RefNannyImportAPI("refnanny");
+  if (!__Pyx_RefNanny) {
+      PyErr_Clear();
+      __Pyx_RefNanny = __Pyx_RefNannyImportAPI("Cython.Runtime.refnanny");
+      if (!__Pyx_RefNanny)
+          Py_FatalError("failed to import 'refnanny' module");
+  }
+  #endif
+  __Pyx_RefNannySetupContext("PyMODINIT_FUNC PyInit__position_weight_matrix(void)", 0);
+  if ( __Pyx_check_binary_version() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_bytes)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #ifdef __Pyx_CyFunction_USED
+  if (__Pyx_CyFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #endif
+  #ifdef __Pyx_FusedFunction_USED
+  if (__pyx_FusedFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #endif
+  #ifdef __Pyx_Generator_USED
+  if (__pyx_Generator_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #endif
+  /*--- Library function declarations ---*/
+  /*--- Threads initialization code ---*/
+  #if defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS
+  #ifdef WITH_THREAD /* Python build with threading support? */
+  PyEval_InitThreads();
+  #endif
+  #endif
+  /*--- Module creation code ---*/
+  #if PY_MAJOR_VERSION < 3
+  __pyx_m = Py_InitModule4(__Pyx_NAMESTR("_position_weight_matrix"), __pyx_methods, 0, 0, PYTHON_API_VERSION); Py_XINCREF(__pyx_m);
+  #else
+  __pyx_m = PyModule_Create(&__pyx_moduledef);
+  #endif
+  if (unlikely(!__pyx_m)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #if PY_MAJOR_VERSION >= 3
+  {
+    PyObject *modules = PyImport_GetModuleDict(); if (unlikely(!modules)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (!PyDict_GetItemString(modules, "bx.pwm._position_weight_matrix")) {
+      if (unlikely(PyDict_SetItemString(modules, "bx.pwm._position_weight_matrix", __pyx_m) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+  }
+  #endif
+  __pyx_b = PyImport_AddModule(__Pyx_NAMESTR(__Pyx_BUILTIN_MODULE_NAME)); if (unlikely(!__pyx_b)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #if CYTHON_COMPILING_IN_PYPY
+  Py_INCREF(__pyx_b);
+  #endif
+  if (__Pyx_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  /*--- Initialize various global constants etc. ---*/
+  if (unlikely(__Pyx_InitGlobals() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (__pyx_module_is_main_bx__pwm___position_weight_matrix) {
+    if (__Pyx_SetAttrString(__pyx_m, "__name__", __pyx_n_s____main__) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  }
+  /*--- Builtin init code ---*/
+  if (unlikely(__Pyx_InitCachedBuiltins() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  /*--- Constants init code ---*/
+  if (unlikely(__Pyx_InitCachedConstants() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  /*--- Global init code ---*/
+  /*--- Variable export code ---*/
+  /*--- Function export code ---*/
+  /*--- Type init code ---*/
+  /*--- Type import code ---*/
+  /*--- Variable import code ---*/
+  /*--- Function import code ---*/
+  /*--- Execution code ---*/
+
+  /* "bx/pwm/_position_weight_matrix.pyx":4
+ *     int pattern_match( char* string, char* pattern, int n)
+ * 
+ * def c_match_consensus( sequence, pattern, size ):             # <<<<<<<<<<<<<<
+ *     return pattern_match( sequence, pattern, size )
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_2bx_3pwm_23_position_weight_matrix_1c_match_consensus, NULL, __pyx_n_s_4); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 4; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s__c_match_consensus, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 4; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "bx/pwm/_position_weight_matrix.pyx":1
+ * cdef extern from "pwm_utils.h":             # <<<<<<<<<<<<<<
+ *     int pattern_match( char* string, char* pattern, int n)
+ * 
+ */
+  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(((PyObject *)__pyx_t_1));
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s____test__, ((PyObject *)__pyx_t_1)) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  if (__pyx_m) {
+    __Pyx_AddTraceback("init bx.pwm._position_weight_matrix", __pyx_clineno, __pyx_lineno, __pyx_filename);
+    Py_DECREF(__pyx_m); __pyx_m = 0;
+  } else if (!PyErr_Occurred()) {
+    PyErr_SetString(PyExc_ImportError, "init bx.pwm._position_weight_matrix");
+  }
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  #if PY_MAJOR_VERSION < 3
+  return;
+  #else
+  return __pyx_m;
+  #endif
+}
+
+/* Runtime support code */
+#if CYTHON_REFNANNY
+static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) {
+    PyObject *m = NULL, *p = NULL;
+    void *r = NULL;
+    m = PyImport_ImportModule((char *)modname);
+    if (!m) goto end;
+    p = PyObject_GetAttrString(m, (char *)"RefNannyAPI");
+    if (!p) goto end;
+    r = PyLong_AsVoidPtr(p);
+end:
+    Py_XDECREF(p);
+    Py_XDECREF(m);
+    return (__Pyx_RefNannyAPIStruct *)r;
+}
+#endif /* CYTHON_REFNANNY */
+
+static void __Pyx_RaiseArgtupleInvalid(
+    const char* func_name,
+    int exact,
+    Py_ssize_t num_min,
+    Py_ssize_t num_max,
+    Py_ssize_t num_found)
+{
+    Py_ssize_t num_expected;
+    const char *more_or_less;
+    if (num_found < num_min) {
+        num_expected = num_min;
+        more_or_less = "at least";
+    } else {
+        num_expected = num_max;
+        more_or_less = "at most";
+    }
+    if (exact) {
+        more_or_less = "exactly";
+    }
+    PyErr_Format(PyExc_TypeError,
+                 "%s() takes %s %" CYTHON_FORMAT_SSIZE_T "d positional argument%s (%" CYTHON_FORMAT_SSIZE_T "d given)",
+                 func_name, more_or_less, num_expected,
+                 (num_expected == 1) ? "" : "s", num_found);
+}
+
+static void __Pyx_RaiseDoubleKeywordsError(
+    const char* func_name,
+    PyObject* kw_name)
+{
+    PyErr_Format(PyExc_TypeError,
+        #if PY_MAJOR_VERSION >= 3
+        "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
+        #else
+        "%s() got multiple values for keyword argument '%s'", func_name,
+        PyString_AsString(kw_name));
+        #endif
+}
+
+static int __Pyx_ParseOptionalKeywords(
+    PyObject *kwds,
+    PyObject **argnames[],
+    PyObject *kwds2,
+    PyObject *values[],
+    Py_ssize_t num_pos_args,
+    const char* function_name)
+{
+    PyObject *key = 0, *value = 0;
+    Py_ssize_t pos = 0;
+    PyObject*** name;
+    PyObject*** first_kw_arg = argnames + num_pos_args;
+    while (PyDict_Next(kwds, &pos, &key, &value)) {
+        name = first_kw_arg;
+        while (*name && (**name != key)) name++;
+        if (*name) {
+            values[name-argnames] = value;
+            continue;
+        }
+        name = first_kw_arg;
+        #if PY_MAJOR_VERSION < 3
+        if (likely(PyString_CheckExact(key)) || likely(PyString_Check(key))) {
+            while (*name) {
+                if ((CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**name) == PyString_GET_SIZE(key))
+                        && _PyString_Eq(**name, key)) {
+                    values[name-argnames] = value;
+                    break;
+                }
+                name++;
+            }
+            if (*name) continue;
+            else {
+                PyObject*** argname = argnames;
+                while (argname != first_kw_arg) {
+                    if ((**argname == key) || (
+                            (CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**argname) == PyString_GET_SIZE(key))
+                             && _PyString_Eq(**argname, key))) {
+                        goto arg_passed_twice;
+                    }
+                    argname++;
+                }
+            }
+        } else
+        #endif
+        if (likely(PyUnicode_Check(key))) {
+            while (*name) {
+                int cmp = (**name == key) ? 0 :
+                #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3
+                    (PyUnicode_GET_SIZE(**name) != PyUnicode_GET_SIZE(key)) ? 1 :
+                #endif
+                    PyUnicode_Compare(**name, key);
+                if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad;
+                if (cmp == 0) {
+                    values[name-argnames] = value;
+                    break;
+                }
+                name++;
+            }
+            if (*name) continue;
+            else {
+                PyObject*** argname = argnames;
+                while (argname != first_kw_arg) {
+                    int cmp = (**argname == key) ? 0 :
+                    #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3
+                        (PyUnicode_GET_SIZE(**argname) != PyUnicode_GET_SIZE(key)) ? 1 :
+                    #endif
+                        PyUnicode_Compare(**argname, key);
+                    if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad;
+                    if (cmp == 0) goto arg_passed_twice;
+                    argname++;
+                }
+            }
+        } else
+            goto invalid_keyword_type;
+        if (kwds2) {
+            if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
+        } else {
+            goto invalid_keyword;
+        }
+    }
+    return 0;
+arg_passed_twice:
+    __Pyx_RaiseDoubleKeywordsError(function_name, key);
+    goto bad;
+invalid_keyword_type:
+    PyErr_Format(PyExc_TypeError,
+        "%s() keywords must be strings", function_name);
+    goto bad;
+invalid_keyword:
+    PyErr_Format(PyExc_TypeError,
+    #if PY_MAJOR_VERSION < 3
+        "%s() got an unexpected keyword argument '%s'",
+        function_name, PyString_AsString(key));
+    #else
+        "%s() got an unexpected keyword argument '%U'",
+        function_name, key);
+    #endif
+bad:
+    return -1;
+}
+
+static CYTHON_INLINE unsigned char __Pyx_PyInt_AsUnsignedChar(PyObject* x) {
+    const unsigned char neg_one = (unsigned char)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(unsigned char) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(unsigned char)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to unsigned char" :
+                    "value too large to convert to unsigned char");
+            }
+            return (unsigned char)-1;
+        }
+        return (unsigned char)val;
+    }
+    return (unsigned char)__Pyx_PyInt_AsUnsignedLong(x);
+}
+
+static CYTHON_INLINE unsigned short __Pyx_PyInt_AsUnsignedShort(PyObject* x) {
+    const unsigned short neg_one = (unsigned short)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(unsigned short) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(unsigned short)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to unsigned short" :
+                    "value too large to convert to unsigned short");
+            }
+            return (unsigned short)-1;
+        }
+        return (unsigned short)val;
+    }
+    return (unsigned short)__Pyx_PyInt_AsUnsignedLong(x);
+}
+
+static CYTHON_INLINE unsigned int __Pyx_PyInt_AsUnsignedInt(PyObject* x) {
+    const unsigned int neg_one = (unsigned int)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(unsigned int) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(unsigned int)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to unsigned int" :
+                    "value too large to convert to unsigned int");
+            }
+            return (unsigned int)-1;
+        }
+        return (unsigned int)val;
+    }
+    return (unsigned int)__Pyx_PyInt_AsUnsignedLong(x);
+}
+
+static CYTHON_INLINE char __Pyx_PyInt_AsChar(PyObject* x) {
+    const char neg_one = (char)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(char) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(char)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to char" :
+                    "value too large to convert to char");
+            }
+            return (char)-1;
+        }
+        return (char)val;
+    }
+    return (char)__Pyx_PyInt_AsLong(x);
+}
+
+static CYTHON_INLINE short __Pyx_PyInt_AsShort(PyObject* x) {
+    const short neg_one = (short)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(short) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(short)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to short" :
+                    "value too large to convert to short");
+            }
+            return (short)-1;
+        }
+        return (short)val;
+    }
+    return (short)__Pyx_PyInt_AsLong(x);
+}
+
+static CYTHON_INLINE int __Pyx_PyInt_AsInt(PyObject* x) {
+    const int neg_one = (int)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(int) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(int)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to int" :
+                    "value too large to convert to int");
+            }
+            return (int)-1;
+        }
+        return (int)val;
+    }
+    return (int)__Pyx_PyInt_AsLong(x);
+}
+
+static CYTHON_INLINE signed char __Pyx_PyInt_AsSignedChar(PyObject* x) {
+    const signed char neg_one = (signed char)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(signed char) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(signed char)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to signed char" :
+                    "value too large to convert to signed char");
+            }
+            return (signed char)-1;
+        }
+        return (signed char)val;
+    }
+    return (signed char)__Pyx_PyInt_AsSignedLong(x);
+}
+
+static CYTHON_INLINE signed short __Pyx_PyInt_AsSignedShort(PyObject* x) {
+    const signed short neg_one = (signed short)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(signed short) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(signed short)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to signed short" :
+                    "value too large to convert to signed short");
+            }
+            return (signed short)-1;
+        }
+        return (signed short)val;
+    }
+    return (signed short)__Pyx_PyInt_AsSignedLong(x);
+}
+
+static CYTHON_INLINE signed int __Pyx_PyInt_AsSignedInt(PyObject* x) {
+    const signed int neg_one = (signed int)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(signed int) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(signed int)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to signed int" :
+                    "value too large to convert to signed int");
+            }
+            return (signed int)-1;
+        }
+        return (signed int)val;
+    }
+    return (signed int)__Pyx_PyInt_AsSignedLong(x);
+}
+
+static CYTHON_INLINE int __Pyx_PyInt_AsLongDouble(PyObject* x) {
+    const int neg_one = (int)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(int) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(int)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to int" :
+                    "value too large to convert to int");
+            }
+            return (int)-1;
+        }
+        return (int)val;
+    }
+    return (int)__Pyx_PyInt_AsLong(x);
+}
+
+static CYTHON_INLINE unsigned long __Pyx_PyInt_AsUnsignedLong(PyObject* x) {
+    const unsigned long neg_one = (unsigned long)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to unsigned long");
+            return (unsigned long)-1;
+        }
+        return (unsigned long)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to unsigned long");
+                return (unsigned long)-1;
+            }
+            return (unsigned long)PyLong_AsUnsignedLong(x);
+        } else {
+            return (unsigned long)PyLong_AsLong(x);
+        }
+    } else {
+        unsigned long val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (unsigned long)-1;
+        val = __Pyx_PyInt_AsUnsignedLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE unsigned PY_LONG_LONG __Pyx_PyInt_AsUnsignedLongLong(PyObject* x) {
+    const unsigned PY_LONG_LONG neg_one = (unsigned PY_LONG_LONG)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to unsigned PY_LONG_LONG");
+            return (unsigned PY_LONG_LONG)-1;
+        }
+        return (unsigned PY_LONG_LONG)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to unsigned PY_LONG_LONG");
+                return (unsigned PY_LONG_LONG)-1;
+            }
+            return (unsigned PY_LONG_LONG)PyLong_AsUnsignedLongLong(x);
+        } else {
+            return (unsigned PY_LONG_LONG)PyLong_AsLongLong(x);
+        }
+    } else {
+        unsigned PY_LONG_LONG val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (unsigned PY_LONG_LONG)-1;
+        val = __Pyx_PyInt_AsUnsignedLongLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE long __Pyx_PyInt_AsLong(PyObject* x) {
+    const long neg_one = (long)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to long");
+            return (long)-1;
+        }
+        return (long)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to long");
+                return (long)-1;
+            }
+            return (long)PyLong_AsUnsignedLong(x);
+        } else {
+            return (long)PyLong_AsLong(x);
+        }
+    } else {
+        long val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (long)-1;
+        val = __Pyx_PyInt_AsLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE PY_LONG_LONG __Pyx_PyInt_AsLongLong(PyObject* x) {
+    const PY_LONG_LONG neg_one = (PY_LONG_LONG)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to PY_LONG_LONG");
+            return (PY_LONG_LONG)-1;
+        }
+        return (PY_LONG_LONG)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to PY_LONG_LONG");
+                return (PY_LONG_LONG)-1;
+            }
+            return (PY_LONG_LONG)PyLong_AsUnsignedLongLong(x);
+        } else {
+            return (PY_LONG_LONG)PyLong_AsLongLong(x);
+        }
+    } else {
+        PY_LONG_LONG val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (PY_LONG_LONG)-1;
+        val = __Pyx_PyInt_AsLongLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE signed long __Pyx_PyInt_AsSignedLong(PyObject* x) {
+    const signed long neg_one = (signed long)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to signed long");
+            return (signed long)-1;
+        }
+        return (signed long)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to signed long");
+                return (signed long)-1;
+            }
+            return (signed long)PyLong_AsUnsignedLong(x);
+        } else {
+            return (signed long)PyLong_AsLong(x);
+        }
+    } else {
+        signed long val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (signed long)-1;
+        val = __Pyx_PyInt_AsSignedLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE signed PY_LONG_LONG __Pyx_PyInt_AsSignedLongLong(PyObject* x) {
+    const signed PY_LONG_LONG neg_one = (signed PY_LONG_LONG)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to signed PY_LONG_LONG");
+            return (signed PY_LONG_LONG)-1;
+        }
+        return (signed PY_LONG_LONG)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to signed PY_LONG_LONG");
+                return (signed PY_LONG_LONG)-1;
+            }
+            return (signed PY_LONG_LONG)PyLong_AsUnsignedLongLong(x);
+        } else {
+            return (signed PY_LONG_LONG)PyLong_AsLongLong(x);
+        }
+    } else {
+        signed PY_LONG_LONG val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (signed PY_LONG_LONG)-1;
+        val = __Pyx_PyInt_AsSignedLongLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static int __Pyx_check_binary_version(void) {
+    char ctversion[4], rtversion[4];
+    PyOS_snprintf(ctversion, 4, "%d.%d", PY_MAJOR_VERSION, PY_MINOR_VERSION);
+    PyOS_snprintf(rtversion, 4, "%s", Py_GetVersion());
+    if (ctversion[0] != rtversion[0] || ctversion[2] != rtversion[2]) {
+        char message[200];
+        PyOS_snprintf(message, sizeof(message),
+                      "compiletime version %s of module '%.100s' "
+                      "does not match runtime version %s",
+                      ctversion, __Pyx_MODULE_NAME, rtversion);
+        #if PY_VERSION_HEX < 0x02050000
+        return PyErr_Warn(NULL, message);
+        #else
+        return PyErr_WarnEx(NULL, message, 1);
+        #endif
+    }
+    return 0;
+}
+
+static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) {
+    int start = 0, mid = 0, end = count - 1;
+    if (end >= 0 && code_line > entries[end].code_line) {
+        return count;
+    }
+    while (start < end) {
+        mid = (start + end) / 2;
+        if (code_line < entries[mid].code_line) {
+            end = mid;
+        } else if (code_line > entries[mid].code_line) {
+             start = mid + 1;
+        } else {
+            return mid;
+        }
+    }
+    if (code_line <= entries[mid].code_line) {
+        return mid;
+    } else {
+        return mid + 1;
+    }
+}
+static PyCodeObject *__pyx_find_code_object(int code_line) {
+    PyCodeObject* code_object;
+    int pos;
+    if (unlikely(!code_line) || unlikely(!__pyx_code_cache.entries)) {
+        return NULL;
+    }
+    pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line);
+    if (unlikely(pos >= __pyx_code_cache.count) || unlikely(__pyx_code_cache.entries[pos].code_line != code_line)) {
+        return NULL;
+    }
+    code_object = __pyx_code_cache.entries[pos].code_object;
+    Py_INCREF(code_object);
+    return code_object;
+}
+static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) {
+    int pos, i;
+    __Pyx_CodeObjectCacheEntry* entries = __pyx_code_cache.entries;
+    if (unlikely(!code_line)) {
+        return;
+    }
+    if (unlikely(!entries)) {
+        entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Malloc(64*sizeof(__Pyx_CodeObjectCacheEntry));
+        if (likely(entries)) {
+            __pyx_code_cache.entries = entries;
+            __pyx_code_cache.max_count = 64;
+            __pyx_code_cache.count = 1;
+            entries[0].code_line = code_line;
+            entries[0].code_object = code_object;
+            Py_INCREF(code_object);
+        }
+        return;
+    }
+    pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line);
+    if ((pos < __pyx_code_cache.count) && unlikely(__pyx_code_cache.entries[pos].code_line == code_line)) {
+        PyCodeObject* tmp = entries[pos].code_object;
+        entries[pos].code_object = code_object;
+        Py_DECREF(tmp);
+        return;
+    }
+    if (__pyx_code_cache.count == __pyx_code_cache.max_count) {
+        int new_max = __pyx_code_cache.max_count + 64;
+        entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Realloc(
+            __pyx_code_cache.entries, new_max*sizeof(__Pyx_CodeObjectCacheEntry));
+        if (unlikely(!entries)) {
+            return;
+        }
+        __pyx_code_cache.entries = entries;
+        __pyx_code_cache.max_count = new_max;
+    }
+    for (i=__pyx_code_cache.count; i>pos; i--) {
+        entries[i] = entries[i-1];
+    }
+    entries[pos].code_line = code_line;
+    entries[pos].code_object = code_object;
+    __pyx_code_cache.count++;
+    Py_INCREF(code_object);
+}
+
+#include "compile.h"
+#include "frameobject.h"
+#include "traceback.h"
+static PyCodeObject* __Pyx_CreateCodeObjectForTraceback(
+            const char *funcname, int c_line,
+            int py_line, const char *filename) {
+    PyCodeObject *py_code = 0;
+    PyObject *py_srcfile = 0;
+    PyObject *py_funcname = 0;
+    #if PY_MAJOR_VERSION < 3
+    py_srcfile = PyString_FromString(filename);
+    #else
+    py_srcfile = PyUnicode_FromString(filename);
+    #endif
+    if (!py_srcfile) goto bad;
+    if (c_line) {
+        #if PY_MAJOR_VERSION < 3
+        py_funcname = PyString_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line);
+        #else
+        py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line);
+        #endif
+    }
+    else {
+        #if PY_MAJOR_VERSION < 3
+        py_funcname = PyString_FromString(funcname);
+        #else
+        py_funcname = PyUnicode_FromString(funcname);
+        #endif
+    }
+    if (!py_funcname) goto bad;
+    py_code = __Pyx_PyCode_New(
+        0,            /*int argcount,*/
+        0,            /*int kwonlyargcount,*/
+        0,            /*int nlocals,*/
+        0,            /*int stacksize,*/
+        0,            /*int flags,*/
+        __pyx_empty_bytes, /*PyObject *code,*/
+        __pyx_empty_tuple, /*PyObject *consts,*/
+        __pyx_empty_tuple, /*PyObject *names,*/
+        __pyx_empty_tuple, /*PyObject *varnames,*/
+        __pyx_empty_tuple, /*PyObject *freevars,*/
+        __pyx_empty_tuple, /*PyObject *cellvars,*/
+        py_srcfile,   /*PyObject *filename,*/
+        py_funcname,  /*PyObject *name,*/
+        py_line,      /*int firstlineno,*/
+        __pyx_empty_bytes  /*PyObject *lnotab*/
+    );
+    Py_DECREF(py_srcfile);
+    Py_DECREF(py_funcname);
+    return py_code;
+bad:
+    Py_XDECREF(py_srcfile);
+    Py_XDECREF(py_funcname);
+    return NULL;
+}
+static void __Pyx_AddTraceback(const char *funcname, int c_line,
+                               int py_line, const char *filename) {
+    PyCodeObject *py_code = 0;
+    PyObject *py_globals = 0;
+    PyFrameObject *py_frame = 0;
+    py_code = __pyx_find_code_object(c_line ? c_line : py_line);
+    if (!py_code) {
+        py_code = __Pyx_CreateCodeObjectForTraceback(
+            funcname, c_line, py_line, filename);
+        if (!py_code) goto bad;
+        __pyx_insert_code_object(c_line ? c_line : py_line, py_code);
+    }
+    py_globals = PyModule_GetDict(__pyx_m);
+    if (!py_globals) goto bad;
+    py_frame = PyFrame_New(
+        PyThreadState_GET(), /*PyThreadState *tstate,*/
+        py_code,             /*PyCodeObject *code,*/
+        py_globals,          /*PyObject *globals,*/
+        0                    /*PyObject *locals*/
+    );
+    if (!py_frame) goto bad;
+    py_frame->f_lineno = py_line;
+    PyTraceBack_Here(py_frame);
+bad:
+    Py_XDECREF(py_code);
+    Py_XDECREF(py_frame);
+}
+
+static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
+    while (t->p) {
+        #if PY_MAJOR_VERSION < 3
+        if (t->is_unicode) {
+            *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
+        } else if (t->intern) {
+            *t->p = PyString_InternFromString(t->s);
+        } else {
+            *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
+        }
+        #else  /* Python 3+ has unicode identifiers */
+        if (t->is_unicode | t->is_str) {
+            if (t->intern) {
+                *t->p = PyUnicode_InternFromString(t->s);
+            } else if (t->encoding) {
+                *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL);
+            } else {
+                *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
+            }
+        } else {
+            *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
+        }
+        #endif
+        if (!*t->p)
+            return -1;
+        ++t;
+    }
+    return 0;
+}
+
+static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) {
+   int is_true = x == Py_True;
+   if (is_true | (x == Py_False) | (x == Py_None)) return is_true;
+   else return PyObject_IsTrue(x);
+}
+static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x) {
+  PyNumberMethods *m;
+  const char *name = NULL;
+  PyObject *res = NULL;
+#if PY_VERSION_HEX < 0x03000000
+  if (PyInt_Check(x) || PyLong_Check(x))
+#else
+  if (PyLong_Check(x))
+#endif
+    return Py_INCREF(x), x;
+  m = Py_TYPE(x)->tp_as_number;
+#if PY_VERSION_HEX < 0x03000000
+  if (m && m->nb_int) {
+    name = "int";
+    res = PyNumber_Int(x);
+  }
+  else if (m && m->nb_long) {
+    name = "long";
+    res = PyNumber_Long(x);
+  }
+#else
+  if (m && m->nb_int) {
+    name = "int";
+    res = PyNumber_Long(x);
+  }
+#endif
+  if (res) {
+#if PY_VERSION_HEX < 0x03000000
+    if (!PyInt_Check(res) && !PyLong_Check(res)) {
+#else
+    if (!PyLong_Check(res)) {
+#endif
+      PyErr_Format(PyExc_TypeError,
+                   "__%s__ returned non-%s (type %.200s)",
+                   name, name, Py_TYPE(res)->tp_name);
+      Py_DECREF(res);
+      return NULL;
+    }
+  }
+  else if (!PyErr_Occurred()) {
+    PyErr_SetString(PyExc_TypeError,
+                    "an integer is required");
+  }
+  return res;
+}
+static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) {
+  Py_ssize_t ival;
+  PyObject* x = PyNumber_Index(b);
+  if (!x) return -1;
+  ival = PyInt_AsSsize_t(x);
+  Py_DECREF(x);
+  return ival;
+}
+static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) {
+#if PY_VERSION_HEX < 0x02050000
+   if (ival <= LONG_MAX)
+       return PyInt_FromLong((long)ival);
+   else {
+       unsigned char *bytes = (unsigned char *) &ival;
+       int one = 1; int little = (int)*(unsigned char*)&one;
+       return _PyLong_FromByteArray(bytes, sizeof(size_t), little, 0);
+   }
+#else
+   return PyInt_FromSize_t(ival);
+#endif
+}
+static CYTHON_INLINE size_t __Pyx_PyInt_AsSize_t(PyObject* x) {
+   unsigned PY_LONG_LONG val = __Pyx_PyInt_AsUnsignedLongLong(x);
+   if (unlikely(val == (unsigned PY_LONG_LONG)-1 && PyErr_Occurred())) {
+       return (size_t)-1;
+   } else if (unlikely(val != (unsigned PY_LONG_LONG)(size_t)val)) {
+       PyErr_SetString(PyExc_OverflowError,
+                       "value too large to convert to size_t");
+       return (size_t)-1;
+   }
+   return (size_t)val;
+}
+
+
+#endif /* Py_PYTHON_H */
diff --git a/lib/bx/pwm/_position_weight_matrix.pyx b/lib/bx/pwm/_position_weight_matrix.pyx
new file mode 100644
index 0000000..f743165
--- /dev/null
+++ b/lib/bx/pwm/_position_weight_matrix.pyx
@@ -0,0 +1,5 @@
+cdef extern from "pwm_utils.h":
+    int pattern_match( char* string, char* pattern, int n)
+
+def c_match_consensus( sequence, pattern, size ):
+    return pattern_match( sequence, pattern, size )
diff --git a/lib/bx/pwm/bed_score_aligned_pwm.py b/lib/bx/pwm/bed_score_aligned_pwm.py
new file mode 100755
index 0000000..bdfe895
--- /dev/null
+++ b/lib/bx/pwm/bed_score_aligned_pwm.py
@@ -0,0 +1,87 @@
+#!/usr/bin/env python2.4
+"""
+Returns all positions of a maf with any pwm score > threshold
+The positions are projected onto human coordinates
+"""
+
+import psyco_full
+from bx.align import maf as align_maf
+import position_weight_matrix as pwmx
+from bx.pwm.pwm_score_maf import MafBlockScorer
+import sys
+from bx import intervals
+import Numeric
+
+def isnan(x):
+    return not x==x
+
+def main():
+
+    if len(sys.argv) < 5:
+        print >>sys.stderr, "%s bedfile inmaf spec1,spec2,... motif_file " % sys.argv[0]
+        sys.exit(0)
+
+    # read in intervals
+    regions = {}
+    for line in open( sys.argv[1] ):
+        if line.startswith('#'): continue
+        fields = line.strip().split()
+        chrom, start, end = fields[0], int( fields[1] ), int( fields[2] )
+        try:
+            name = fields[3]
+        except:
+            name = None
+        if chrom not in regions: regions[chrom] = intervals.Intersecter()
+        regions[chrom].add( start, end, name )
+
+    pwm = {}
+    for wm in pwmx.Reader(open( sys.argv[4] )):
+        pwm[ wm.id] = wm
+        print >>sys.stderr, wm.id, len(wm)
+
+    inmaf = open(sys.argv[2])
+    threshold = 0.5
+
+    species = []
+
+    for sp in sys.argv[3].split(','):
+        species.append( sp )
+
+    for maf in align_maf.Reader(inmaf):
+        mafchrom = maf.components[0].src.split('.')[1]
+        mafstart = maf.components[0].start
+        mafend = maf.components[0].end
+        reftext = maf.components[0].text
+
+        # maf block scores for each matrix
+        for scoremax,width,headers in MafBlockScorer(pwm,species, maf):
+            #print >>sys.stderr,headers
+            blocklength = width
+            mafsrc,mafstart,mafend = headers[0]
+            mafchrom = mafsrc.split('.')[1]
+
+            # lists of scores for each position in scoremax
+            for mx_name,mx in scoremax.items():
+                #print >>sys.stderr, mx_name, len(pwm[mx_name])
+
+                for offset in range(blocklength):
+    
+                    # scan all species with threshold
+                    for i in range(len(species)):
+                        if mx[i][offset] > threshold:
+                            refstart = mafstart + offset - reftext.count('-',0,offset)
+                            refend = refstart + len(pwm[mx_name])
+
+                            data = " ".join([ "%.2f" % mx[x][offset] for x in range(len(species))])
+                            # quote the motif
+                            r = regions[mafchrom].find( refstart, refend )
+                            if mafchrom in regions and len( r ) > 0:
+                                region_label = r[0].value
+                            else:
+                                #region_label = 0
+                                continue
+                            v_name = mx_name.replace(' ','_')
+                            print mafchrom,refstart,refend,region_label,v_name,data
+                            break
+
+if __name__ == '__main__': main()
diff --git a/lib/bx/pwm/bed_score_aligned_string.py b/lib/bx/pwm/bed_score_aligned_string.py
new file mode 100755
index 0000000..ef68a5c
--- /dev/null
+++ b/lib/bx/pwm/bed_score_aligned_string.py
@@ -0,0 +1,86 @@
+#!/usr/bin/env python2.4
+"""
+Returns all positions of a maf with any pwm score > threshold
+The positions are projected onto human coordinates
+"""
+
+import psyco_full
+from bx.align import maf as align_maf
+import position_weight_matrix as pwmx
+from bx.pwm.pwm_score_maf import MafMotifScorer
+import sys
+from bx import intervals
+import Numeric
+
+def isnan(x):
+    return not x==x
+
+def main():
+
+    if len(sys.argv) < 5:
+        print >>sys.stderr, "%s bedfile inmaf spec1,spec2,... string [string2,...]" % sys.argv[0]
+        sys.exit(0)
+
+    # read in intervals
+    regions = {}
+    for line in open( sys.argv[1] ):
+        if line.startswith('#'): continue
+        fields = line.strip().split()
+        chrom, start, end = fields[0], int( fields[1] ), int( fields[2] )
+        try:
+            name = fields[3]
+        except:
+            name = None
+        if chrom not in regions: regions[chrom] = intervals.Intersecter()
+        regions[chrom].add( start, end, name )
+
+    motif_strings = sys.argv[4:]
+    if not isinstance(motif_strings, list): motif_strings = [motif_strings]
+    inmaf = open(sys.argv[2])
+    threshold = 0.5
+
+    species = []
+
+    for sp in sys.argv[3].split(','):
+        species.append( sp )
+
+    for maf in align_maf.Reader(inmaf):
+        mafchrom = maf.components[0].src.split('.')[1]
+        mafstart = maf.components[0].start
+        mafend = maf.components[0].end
+        reftext = maf.components[0].text
+        r = regions[mafchrom].find( mafstart, mafend )
+        if mafchrom not in regions or len( r ) == 0: continue
+
+        # maf block scores for each matrix
+        for scoremax,width,headers in MafMotifScorer(species, maf, motif_strings):
+            #print >>sys.stderr,headers
+            blocklength = width
+            mafsrc,mafstart,mafend = headers[0]
+            mafchrom = mafsrc.split('.')[1]
+
+            # lists of scores for each position in scoremax
+            for mx_name,mx in scoremax.items():
+                #print >>sys.stderr, mx_name, len(pwm[mx_name])
+
+                for offset in range(blocklength):
+    
+                    # scan all species with threshold
+                    for i in range(len(species)):
+                        if mx[i][offset] > threshold:
+                            refstart = mafstart + offset - reftext.count('-',0,offset)
+                            refend = refstart + len(mx_name)
+
+                            data = " ".join([ "%.2f" % mx[x][offset] for x in range(len(species))])
+                            # quote the motif
+                            r = regions[mafchrom].find( refstart, refend )
+                            if mafchrom in regions and len( r ) > 0:
+                                region_label = r[0].value
+                            else:
+                                #region_label = 0
+                                continue
+                            v_name = mx_name.replace(' ','_')
+                            print mafchrom,refstart,refend,region_label,v_name,data
+                            break
+
+if __name__ == '__main__': main()
diff --git a/lib/bx/pwm/maf_select_motifs.py b/lib/bx/pwm/maf_select_motifs.py
new file mode 100755
index 0000000..d45b53b
--- /dev/null
+++ b/lib/bx/pwm/maf_select_motifs.py
@@ -0,0 +1,69 @@
+#!/usr/bin/env python2.4
+"""
+Returns all positions of a maf with any pwm score > threshold
+The positions are projected onto human coordinates
+"""
+
+import psyco_full
+from bx.align import maf as align_maf
+import bx.pwm.position_weight_matrix as pwmx
+from bx.pwm.pwm_score_maf import MafMotifSelect
+import sys
+from bx import intervals
+
+def isnan(x):
+    return not x==x
+
+def main():
+
+    if len(sys.argv) < 5:
+        print >>sys.stderr, "%s transfac|basic pwmfile inmaf threshold [motif]" % sys.argv[0]
+        sys.exit(2)
+
+    r = pwmx.Reader(open(sys.argv[2]),format=sys.argv[1])
+    pwm = iter(r).next()
+    inmaf = open(sys.argv[3])
+    threshold = float(sys.argv[4])
+    if len(sys.argv) > 5: motif = sys.argv[5]
+    else: motif = None
+
+    for maf in align_maf.Reader(inmaf):
+        for mafmotif,pwm_score,motif_score in MafMotifSelect(maf, pwm, motif, threshold):
+            #mafwrite( mafmotif,pwm_score,motif_score)
+            print mafmotif, pwm_score, motif_score
+            print 'zzzzzzzzzzzzzzzzzzzzzzzzzzzzz'
+
+def mafwrite(alignment,kvec=None,jvec=None,file=sys.stdout):
+    file.write( "a score=" + str( alignment.score ) )
+    for key in alignment.attributes:
+        file.write( " %s=%s" % ( key, alignment.attributes[key] ) )
+    file.write( "\n" )
+    rows = []
+    if not kvec: kvec = [0 for c in alignment.components]
+    if not jvec: jvec = [0 for c in alignment.components]
+    for c,x,y in zip(alignment.components,kvec,jvec):
+    #for c in alignment.components:
+        rows.append( ( "s", c.src, str( c.start ), str( c.size ), c.strand, str( c.src_size ), c.text, "%.2f" % x, str(y) ) )
+        #rows.append( ( "s", c.src, str( c.start ), str( c.size ), c.strand, str( c.src_size ), c.text ) )
+        file.write( format_tabular( rows, "llrrrrrrr" ) )
+
+def format_tabular( rows, align=None ):
+    if len( rows ) == 0: return ""
+    lengths = [ len( col ) for col in rows[ 0 ] ]
+    for row in rows[1:]:
+        for i in range( 0, len( row ) ):
+            lengths[ i ] = max( lengths[ i ], len( row[ i ] ) )
+    rval = ""
+    for row in rows:
+        for i in range( 0, len( row ) ):
+            if align and align[ i ] == "l":
+                rval += row[ i ].ljust( lengths[ i ] )
+            else:
+                rval += row[ i ].rjust( lengths[ i ] )
+            rval += " "
+        rval += "\n"
+    return rval
+
+    
+
+if __name__ == '__main__': main()
diff --git a/lib/bx/pwm/position_weight_matrix.py b/lib/bx/pwm/position_weight_matrix.py
new file mode 100755
index 0000000..8c4089c
--- /dev/null
+++ b/lib/bx/pwm/position_weight_matrix.py
@@ -0,0 +1,849 @@
+#!/usr/bin/env python
+
+import sys
+import math
+import string
+from numpy import *
+from sets import *
+
+# This is the average of all species in the alignment outside of exons
+#        > mean(r)
+#        A         T         C         G
+#        0.2863776 0.2878264 0.2129560 0.2128400
+#        > sd(r)
+#        A          T          C          G
+#        0.01316192 0.01371148 0.01293836 0.01386655
+
+ENCODE_NONCODING_BACKGROUND = { 'A':0.2863776,'T':0.2878264,'G':0.2128400,'C':0.2129560}
+
+class Align(object):
+    def __init__ (self, seqrows, headers=None):
+        self.rows = seqrows
+        self.nrows = len(seqrows)
+        ncol = None
+        for rownum,row in enumerate(self.rows):
+            try:
+                if ncol == None: ncol = len(row)
+                elif ncol != len(row):
+                    raise ValueError("Align: __init__:alignment block:row %d does not have %d columns, it has %d" % (rownum,ncol,len(row)))
+            except:
+                print row
+                raise Exception('')
+        self.ncols = ncol
+        self.dims = (self.nrows,self.ncols)
+        self.headers = headers
+    def __str__ (self):
+        return "\n".join(self.rows)
+
+class AlignScoreMatrix (object):
+    def __init__(self,align):
+        nan = float('nan')
+
+        matrix = zeros((align.nrows,align.ncols),float32)
+
+        # set to nans
+        for ir in range( len(matrix) ):
+            for ic in range(len( matrix[ir] )):
+                matrix[ir][ic] = nan
+        self.matrix = matrix
+
+    def __len__(self):
+        return shape(self.matrix)[1]
+
+    def __str__(self):
+        print self.matrix
+
+def score_align_motif (align,motif,gapmask=None,byPosition=True):
+
+    #dbg
+    #print >>sys.stderr, align.headers
+    chr,chr_start,chr_stop = align.headers[0]
+
+    # a blank score matrix
+    nrows,ncols = align.dims
+    ascoremax = AlignScoreMatrix( align )
+    scoremax = ascoremax.matrix
+
+    minSeqLen = len( motif )
+    for ir in range(nrows):
+        pass
+
+        # row is missing data
+        if isnan(align.rows[ir][0]): continue
+
+        for start in range(ncols):
+
+            if align.rows[ir][start] == '-': continue
+            elif align.rows[ir][start] == 'n': continue
+            elif align.rows[ir][start] == 'N': continue
+
+            # get enough sequence for the weight matrix
+            subseq = ""
+            end = 0
+            ic = start
+            while len(subseq) < minSeqLen:
+            #for ic in range(start,ncols):
+
+                if ic >= len(align.rows[ir]): break
+                char = align.rows[ir][ic].upper()
+                ic += 1
+                if char == '-' or char == 'N': continue
+                else: subseq += char
+
+            if len(subseq) == minSeqLen:
+                end = ic+1
+                for_score = int( match_consensus(subseq,motif) )
+                revseq = reverse_complement( subseq )
+                rev_score = int( match_consensus(revseq,motif) )
+
+                score = max(for_score, rev_score)
+                #dbg
+                #if ir == 0: print >>sys.stderr, int(chr_start) + start - align.rows[ir].count('-',0,start), subseq, score
+
+                # replace the alignment positions with the result
+                if byPosition:
+                    scoremax[ir][start] = score
+                else:
+                # replace positions matching the width of the pwm
+                    for i in range(start,end):
+                        if isnan(scoremax[ir][i]): scoremax[ir][i] = score
+                        elif score > scoremax[ir][i]: scoremax[ir][i] = score
+                #break
+    # mask gap characters
+    if gapmask == None:
+        gapmask = score_align_gaps(align)
+    putmask( scoremax, gapmask, float('nan') )
+    return scoremax
+
+#-----------
+#
+# WeightMatrix--
+#    A position weight matrix (PWM) representation of a motif.
+#
+#----------
+# construction arguments:
+#   id:         id (name) of the motif
+#   rows:       the matrix;  each row is a hash from symbol to weight, with
+#               .. the weight in string form
+#   alphabet:   symbols allowed
+#   background: hash from symbol to background probability of that symbol;  if
+#               .. not specified, ENCODE_NONCODING_BACKGROUND is used
+# internal fields:
+#   rows:       the matrix;  each row is a hash from symbol to log-odds score
+#               .. of that symbol for that row of the weight matrix
+#   counts:     the matrix;  count[row][sym] is the weight, as an integer
+#   probs:      the matrix;  probs[row][sym] is the weight, as an probability
+#----------
+
+class PositionWeightMatrix (object):
+
+    complementMap = string.maketrans("ACGTacgt","TGCAtgca")
+
+    # IUPAC-IUB
+    symbols = {
+        'A':Set(['A']),
+        'C':Set(['C']),
+        'G':Set(['G']),
+        'T':Set(['T']),
+        'R':Set(['A','G']),
+        'Y':Set(['C','T']),
+        'M':Set(['A','C']),
+        'K':Set(['G','T']),
+        'S':Set(['G','C']),
+        'W':Set(['A','T']),
+        'H':Set(['A','C','T']),
+        'B':Set(['G','T','C']),
+        'V':Set(['G','C','A']),
+        'D':Set(['G','T','A'])}
+
+    def __init__ (self, id, rows, alphabet, background=None, score_correction=True):
+
+        self.id       = id
+        self.alphabet = alphabet
+        nsymbols = len(self.alphabet)
+        for i in range(len(self.alphabet)):
+            self.alphabet[ i ] = self.alphabet[ i ].upper()
+        if background != None:
+            self.background = background
+        else:
+            self.background = {}
+            sorted_alphabet = []
+            sorted_alphabet[:] = self.alphabet[:]
+            sorted_alphabet.sort()
+            if ['A','C','G','T'] == sorted_alphabet:
+                self.background = ENCODE_NONCODING_BACKGROUND
+            else:
+                for x in self.alphabet: self.background[ x ] = float(1)/len(self.alphabet)
+
+        if (score_correction == True):
+            self.score_correction = self.corrected_probability_score
+        else:
+            self.score_correction = self.simple_probability
+
+        # partition counts from consensus symbol
+        # in order to properly handle scaling in the presense of non-integers,
+        # we prescan the matrix to figure out the largest scale factor, then go
+        # back through and scale 'em all (some rows may be integer counts,
+        # others may be probabilities)
+
+        self.consensus = []
+        scale = 1
+
+        for i in range(len(rows)):
+
+            #try:
+            fields,consensus = rows[i][:nsymbols],rows[i][-1]
+            for x,count in enumerate(fields):
+                try:
+                    (w,s) = self.parse_weight(count)
+                except ValueError:
+                    raise ValueError("pwm row %s has bad weight %s" % (" ".join(fields),t))
+
+                # replace row counts with (values,scale)
+                rows[i][x] = (w,s)
+                scale = max(s,scale)
+
+            #except:
+                #print >>sys.stderr,rows
+                #raise ValueError
+                #raise ValueError, "pwm row %s has wrong field count" % " ".join(fields)
+
+            self.consensus.append(consensus)
+
+
+        hashRows = []
+        self.matrix_base_counts = {} # for pseudocounts
+        self.counts = [] # for scaled counts
+        self.probs = [] # for probabilities
+
+        # scale counts to integers
+        for i in range(len(rows)):
+            hashRows.append(dict())
+            for x,sym in enumerate(alphabet):
+                (w,s) = rows[i][x]
+                hashRows[i][sym] = w * scale/s
+                assert hashRows[i][sym] >= 0
+                if sym not in self.matrix_base_counts: self.matrix_base_counts[sym] = 0
+                self.matrix_base_counts[sym] += hashRows[i][sym]
+            self.counts.append( hashRows[i].copy() )
+            self.probs.append( hashRows[i].copy() )
+            totalWeight = float(sum(self.probs[i].values()))
+            for sym in self.probs[i]:
+                self.probs[i][sym] /= totalWeight
+        self.sites = sum ( hashRows[0].values() )
+
+        # scan pwm to pre-compute logs of probabilities and min and max log-odds
+        # scores (over the whole PWM) for scaling;  note that the same min and max
+        # applies for scaling long-odds scores for quantum comparisions
+        self.information_content = []
+        minSum = 0
+        maxSum = 0
+
+        for i in range( len( hashRows )):
+            self.information_content.append( self.information_content_calculation( i, hashRows ) )
+            newHashRow = {}
+            for base in self.alphabet:
+                newHashRow[base] = self.pwm_score(base, i, hashRows)
+            hashRows[i] = newHashRow
+
+            minSum += min(hashRows[i].values())
+            maxSum += max(hashRows[i].values())
+
+        self.minSum = minSum
+        self.maxSum = maxSum
+        self.rows = hashRows
+
+    # Reference 1: Wasserman and Sandelin: Nat Rev Genet. 2004 Apr;5(4):276-87.
+    # Reference 2: Gertz et al.: Genome Res. 2005 Aug;15(8):1145-52.
+    def information_content_calculation(self, i, counts):
+        # Reference 1)
+        return 2 + sum( [ self.information_base_content(base,i,counts) for base in self.alphabet ] )
+
+        # Reference 2)
+        #return sum( [ self.information_base_content(base,i,counts) for base in self.alphabet ] )
+
+    def information_base_content(self, base, i, counts):
+
+        # Reference 1)
+        #return self.score_correction(counts,base,i) * math.log ( self.score_correction(counts,base,i), 2)
+
+        # Reference 2)
+        return self.score_correction(counts,base,i) * self.pwm_score(base, i, counts)
+
+    def __call__ (self,seq):
+        return self.score_seq(seq)
+
+    def __add__ (self,other):
+
+        assert self.alphabet == other.alphabet
+        r,(p,q) = self.max_correlation(other)
+
+        if p == q == 0: width = max( len(self),len(other) )
+        elif p > 0: width = max( len(other)+p, len(self) )
+        elif q > 0: width = max( len(self)+q, len(other) )
+
+        sumx = zeros( (width,len(self.alphabet)),dtype='int')
+        selfx = self.to_count_matrix()
+        otherx = other.to_count_matrix()
+
+        if p == q == 0:
+            sumx[:len(self)] += selfx
+            sumx[:len(other)] += otherx
+        elif p > 0:
+            sumx[p:p+len(other)] += otherx
+            sumx[:len(self)] += selfx
+        else:
+            sumx[:len(other)] += otherx
+            sumx[q:q+len(self)] += selfx
+
+        newRows = []
+        for i,x in enumerate(sumx):
+            y = list(x)
+            y.append( consensus_symbol(y) )
+            y = [ str(yi) for yi in y]
+            newRows.append( y )
+        return PositionWeightMatrix(self.id+other.id,newRows,self.alphabet,self.background)
+
+    def __old_add__ (self,other,maxp=None):
+
+        assert self.alphabet == other.alphabet
+        bigN = max(len(self),len(other))
+        smallN = min(len(self),len(other))
+        if not maxp:
+            prsq = self.correlation(other)
+            maxp = prsq.index( max(prsq) )
+
+        leftpad = ' ' * maxp
+        rightsize = bigN - smallN
+        rightpad = ' ' * rightsize
+        leftStrings = []
+        rightStrings = []
+
+        if len(self) > len(other):
+            larger = self
+            smaller = other
+            leftStrings = self.consensus
+            rightStrings = list(leftpad) + other.consensus + list(rightpad)
+        else:
+            smaller = self
+            larger = other
+            leftStrings = list(leftpad) + self.consensus + list(rightpad)
+            rightStrings = other.consensus
+
+        sumx = zeros([bigN,len(self.alphabet)])
+        sumx += larger.to_count_matrix()
+        sumx[maxp:maxp+smallN] += smaller.to_count_matrix()
+
+        newRows = []
+        for i,x in enumerate(sumx):
+            y = list(x)
+            y.append( leftStrings[i] + rightStrings[i] )
+            y = [ str(yi) for yi in y]
+            newRows.append( y )
+
+        #return PositionWeightMatrix(self.id+other.id,newRows[maxp:maxp+smallN],self.alphabet,self.background)
+        return PositionWeightMatrix(self.id+other.id,newRows,self.alphabet,self.background)
+
+    def to_matrix(self):
+        m = zeros([len(self),len(self.alphabet)])
+        for i in range(len(self)):
+            for j,a in enumerate(self.alphabet):
+                m[i][j] = self[i][a]
+        return m
+
+    def to_count_matrix(self):
+        m = zeros([len(self),len(self.alphabet)],dtype='int')
+        for i in range(len(self)):
+            for j,a in enumerate(self.alphabet):
+                m[i][j] = self.counts[i][a]
+        return m
+
+    def max_correlation(self, otherwmx):
+        rsq,ixtuple = self.slide_correlation(otherwmx)
+        max_rsq = max(rsq)
+        maxp,maxq = ixtuple[rsq.index(max_rsq)]
+        return max_rsq,(maxp,maxq)
+
+    def slide_correlation(self, other):
+        assert self.alphabet == other.alphabet
+        selfx = self.to_count_matrix()
+        otherx = other.to_count_matrix()
+        rsq = []
+        ixtuple = []
+        # self staggered over other, scan self backwards until flush
+        for q in range(len(other)-1,-1,-1):
+            r = 0
+            n = 0
+            for p in range(len(self)):
+                if q+p < len(other):
+                    r += rsquared( list(selfx[p]), list(otherx[q+p]) )
+                    n += 1
+                else:
+                    n += 1
+            rsq.append( r/n )
+            ixtuple.append( (0,q) )
+        # other staggered below self , scan other forward
+        for p in range(1,len(self)):
+            r = 0
+            n = 0
+            for q in range(len(other)):
+                if p+q < len(self):
+                    r += rsquared( list(selfx[p+q]), list(otherx[q]) )
+                    n += 1
+                else:
+                    n += 1
+            rsq.append( r/n )
+            ixtuple.append( (p,0) )
+        return rsq,ixtuple
+
+    def correlation(self, otherwmx):
+        assert self.alphabet == otherwmx.alphabet
+        width = len(self.alphabet)
+        if len(self) > len(otherwmx):
+            larger = self.to_count_matrix()
+            smaller = otherwmx.to_count_matrix()
+        else:
+            smaller = self.to_count_matrix()
+            larger = otherwmx.to_count_matrix()
+        bigN = len(larger)
+        smallN = len(smaller)
+        position_rsq = []
+
+        # slide small over large, for ave rsq
+        for p in range(bigN):
+            if p+smallN <= bigN:
+                r = 0
+                for q in range(smallN):
+                    r += rsquared(list(smaller[q]),list(larger[p+q]))
+                position_rsq.append( r / smallN )
+        return position_rsq
+
+    def score_align (self,align,gapmask=None,byPosition=True):
+
+        # a blank score matrix
+        nrows,ncols = align.dims
+        ascoremax = AlignScoreMatrix( align )
+        scoremax = ascoremax.matrix
+
+        minSeqLen = len( self )
+        for ir in range(nrows):
+
+            # row is missing data
+            if isnan(align.rows[ir][0]): continue
+
+            for start in range(ncols):
+                if align.rows[ir][start] == '-': continue
+                elif align.rows[ir][start] == 'n': continue
+                elif align.rows[ir][start] == 'N': continue
+
+                # get enough sequence for the weight matrix
+                subseq = ""
+                end = 0
+                for ic in range(start,ncols):
+
+                    char = align.rows[ir][ic]
+                    if char == '-' or char == 'N': continue
+                    else: subseq += char
+
+                    if len(subseq) == minSeqLen:
+                        end = ic+1
+
+                        #forward
+                        scores = self.score_seq( subseq )
+                        raw,forward_score = scores[0]
+                        #reverse
+                        scores = self.score_reverse_seq( subseq )
+                        raw,reverse_score = scores[0]
+
+                        score = max(forward_score, reverse_score)
+
+                        # replace the alignment positions with the result
+                        if byPosition:
+                            scoremax[ir][start] = score
+                        else:
+                        # replace positions matching the width of the pwm
+                            for i in range(start,end):
+                                if isnan(scoremax[ir][i]): scoremax[ir][i] = score
+                                elif score > scoremax[ir][i]: scoremax[ir][i] = score
+        # mask gap characters
+        if gapmask == None:
+            gapmask = score_align_gaps(align)
+        putmask( scoremax, gapmask, float('nan') )
+        return scoremax
+
+    # seq can be a string, a list of characters, or a quantum sequence (a list
+    # of hashes from symbols to probability)
+
+    def score_seq(self,seq):
+        if (type(seq[0]) == dict):
+            return self.score_quantum_seq(seq)
+
+        scores = []
+        for start in range( len(seq)):
+            if start + len(self) > len(seq): break
+            subseq = seq[ start:start+len(self) ]
+            raw = 0
+            try:
+                for i,nt in enumerate(subseq): raw += self.rows[i][nt.upper()]
+                scaled = self.scaled( raw )
+            except KeyError:
+                raw,scaled = float('nan'),float('nan')
+            scores.append( (raw, scaled) )
+        return scores
+
+    def score_quantum_seq(self,seq):
+        scores = []
+        for start in range(len(seq)):
+            if (start + len(self) > len(seq)): break
+            subseq = seq[start:start+len(self)]
+            raw = 0
+            try:
+                for i,nt in enumerate(subseq):
+                    numer = sum([subseq[i][nt] * self.probs[i][nt]   for nt in subseq[i]])
+                    denom = sum([subseq[i][nt] * self.background[nt] for nt in subseq[i]])
+                    raw += math.log(numer/denom,2)
+                scaled = self.scaled(raw)
+            except KeyError:
+                raw,scaled = float('nan'),float('nan')
+            except OverflowError,e:
+                raw,scaled = float('nan'),float('nan')
+            except ValueError,e:
+                raw,scaled = float('nan'),float('nan')
+            scores.append((raw,scaled))
+        return scores
+
+    def score_reverse_seq(self,seq):
+        revSeq = reverse_complement( seq )
+        scores = self.score_seq( revSeq )
+        scores.reverse()
+        return scores
+
+    def scaled(self,val):
+        return ( val - self.minSum ) / (self.maxSum - self.minSum)
+
+    def pseudocount(self, base=None):
+        f = lambda count: math.sqrt( count + 1 )
+        if base in self.alphabet:
+            return f( self.matrix_base_counts[base] )
+        elif base == None:
+            return f ( self.sites )
+        else:
+            return float("nan")
+
+    def simple_probability (self,freq, base, i):
+        # p(base,i) = f(base,i)
+        #             ----------------------
+        #             sum(f(base,{A,C,G,T}))
+
+        return float( freq[i][base] ) / sum([freq[i][nt] for nt in self.alphabet])
+
+    def corrected_probability_score (self,freq, base, i):
+        # p(base,i) = f(base,i) + s(base)
+        #             --------------------
+        #              N + sum(s(A,C,T,G))
+
+        f = float( freq[i][base] )
+        s = self.pseudocount(base)
+        N = self.sites
+        #print >>sys.stderr, "f:%.3f + s:%.3f = %.3f" % (f,s,f + s)
+        #print >>sys.stderr, "-------------------------"
+        #print >>sys.stderr, "N:%d + %d = %d" % (N,self.pseudocount(), N + self.pseudocount())
+        #print >>sys.stderr, "\t\t %.3f\n" % ((f + s) / (N + self.pseudocount()))
+
+        assert (f + s) > 0
+        return (f + s) / (N + self.pseudocount())
+
+    def pwm_score (self,base,i,freq,background=None):
+        if background == None: background = self.background
+        p = self.score_correction(freq,base,i)
+        #print >>sys.stderr, p
+        #print >>sys.stderr, "k %d %c" % (i,base),freq[i][base]
+        b = background[ base ]
+        try:
+            return math.log( p/b, 2)
+        except OverflowError,e:
+            ## print >>sys.stderr,"base=%c, math.log(%.3f / %.3f)" % (base,p,b)
+            ## print >>sys.stderr,self.id
+            return float('nan')
+        except ValueError,e:
+            ## print >>sys.stderr,"base=%c, math.log(%.3f / %.3f)" % (base,p,b)
+            ## print >>sys.stderr,self.id
+            return float('nan')
+
+    def parse_weight (self, weightString):
+
+        fields = weightString.split(".")
+        if (len(fields) > 2): raise ValueError
+
+        w = int(fields[0])
+        s = 1
+
+        if (len(fields) == 2):
+            for cnt in range(0,len(fields[1])): s *= 10
+            w = s*w + int(fields[1])
+
+        return (w,s)    # w = the weight
+                        # s = the scale used (a power of 10)
+
+    def __str__ (self):
+        lines = [self.id]
+        headers = ["%s" % nt for nt in self.alphabet]
+        lines.append("P0\t" + "\t".join(headers))
+        for ix in range(0,len(self.rows)):
+            weights = ["%d" % self.counts[ix][nt] for nt in self.alphabet]
+            #lines.append(("%02d\t" % ix) + "\t".join(weights) + "\t" + self.consensus[ix])
+            lines.append(("%02d\t" % ix) + "\t".join(weights) + "\t" + str(sum(self.counts[ix].values())) + "\t" + self.consensus[ix])
+
+        return "\n".join(lines)
+
+    def __getitem__ (self,key):
+        return self.rows[key]
+
+    def __setitem__ (self,key,value):
+        self.rows[key] = value
+
+    def __len__ (self):
+        return len( self.rows )
+
+def score_align_gaps (align):
+    # a blank score matrix
+    nrows,ncols = align.dims
+    scoremax = AlignScoreMatrix( align ).matrix
+    for ir in range(nrows):
+        # row is missing data
+        if isnan(align.rows[ir][0]): continue
+        # scan for gaps
+        for pos in range(ncols):
+            if align.rows[ir][pos] == '-': scoremax[ir][pos] = 1
+            else: scoremax[ir][pos] = 0
+    return scoremax
+
+#-----------
+#
+# WeightMatrix Reader--
+#    Read position weight matrices (PWM) from a file.
+#
+#-----------
+
+class Reader (object):
+    """Iterate over all interesting weight matrices in a file"""
+
+    def __init__ (self,file,tfIds=None,name=None,format='basic',background=None,score_correction=True):
+        self.tfIds      = tfIds
+        self.file       = file
+        self.name       = name
+        self.lineNumber = 0
+        self.format     = format
+        self.background = background
+        self.score_correction = score_correction
+
+
+    def close (self):
+        self.file.close()
+
+
+    def where (self):
+        if (self.name == None):
+            return "line %d" % self.lineNumber
+        else:
+            return "line %d in %s" % (self.lineNumber,self.name)
+
+
+    def __iter__ (self):
+        if self.format == 'basic':
+            return self.read_as_basic()
+        elif self.format == 'transfac':
+            return self.read_as_transfac()
+        else:
+            raise ValueError("unknown weight matrix file format: '%s'" % self.format)
+
+    def read_as_basic(self):
+        tfId    = None
+        pwmRows = None
+
+        alphabet = ['A','C','G','T']
+        while (True):
+            line = self.file.readline()
+            if (not line): break
+            line = line.strip()
+            self.lineNumber += 1
+            if line.startswith(">"):
+                if pwmRows != None:
+                    yield PositionWeightMatrix(tfId,pwmRows,alphabet,background=self.background)
+                    #try:
+                        #yield PositionWeightMatrix(tfId,pwmRows,alphabet)
+                    #except:
+                        #print >>sys.stderr, "Failed to read", tfId
+                tfId = line.strip()[1:]
+                pwmRows = []
+            elif line[0].isdigit():
+                tokens = line.strip().split()
+                tokens.append( consensus_symbol(line) )
+                vals = [float(v) for v in tokens[:-1]]
+                #print >>sys.stderr,[ "%.2f" % (float(v)/sum(vals)) for v in vals], tokens[-1]
+                pwmRows.append( tokens )
+        if pwmRows != None: # we've finished collecting a desired matrix
+            yield PositionWeightMatrix(tfId,pwmRows,alphabet,background=self.background,score_correction=self.score_correction)
+
+    def read_as_transfac(self):
+        self.tfToPwm = {}
+        tfId    = None
+        pwmRows = None
+
+        while (True):
+            line = self.file.readline()
+            if (not line): break
+            line = line.strip()
+            self.lineNumber += 1
+            # handle an ID line
+            if line.startswith("ID"):
+                if pwmRows != None: # we've finished collecting a desired matrix
+                    try:
+                        yield PositionWeightMatrix(tfId,pwmRows,alphabet,background=self.background,score_correction=self.score_correction)
+                    except:
+                        print >>sys.stderr, "Failed to read", tfId
+                    tfId    = None
+                    pwmRows = None
+
+                tokens = line.split (None, 2)
+                if len(tokens) != 2:
+                    raise ValueError, "bad line, need two fields (%s)" % self.where()
+                tfId = tokens[1]
+                if self.tfIds != None and (not tfId in self.tfIds):
+                    continue          # ignore it, this isn't a desired matrix
+                if tfId in self.tfToPwm:
+                    raise ValueError, "transcription factor %s appears twice (%s)" \
+                        % (tfId,self.where())
+                pwmRows = []          # start collecting a desired matrix
+                continue
+
+            # if we're not collecting, skip this line
+            if pwmRows == None: continue
+            if len(line) < 1:   continue
+
+            # name, if present, added to ID
+            if line.startswith('NA'):
+                words = line.strip().split()
+                tfId =  tfId + "\t" + " ".join(words[1:])
+
+            # handle a P0 line
+            if line.startswith("P0"):
+                alphabet = line.split()[1:]
+                if len(alphabet) < 2:
+                    raise ValueError, "bad line, need more dna (%s)" % self.where()
+                continue
+
+            # handle a 01,02,etc. line
+            if line[0].isdigit():
+                tokens = line.split ()
+                try:
+                    index = int(tokens[0])
+                    if index != len(pwmRows)+1: raise ValueError
+                except:
+                    raise ValueError,"bad line, bad index (%s)" % self.where()
+                pwmRows.append(tokens[1:])
+                continue
+            # skip low quality entries
+            if line.startswith("CC  TRANSFAC Sites of quality"):
+                print >>sys.stderr, line.strip(), tfId
+                pwmRows = None
+                continue
+        if pwmRows != None: # we've finished collecting a desired matrix
+            yield PositionWeightMatrix(tfId,pwmRows,alphabet,background=self.background,score_correction=self.score_correction)
+        # clean up
+        self.tfToPwm = None
+
+def isnan(x):
+    #return ieeespecial.isnan(x)
+    if x==x: return False
+    return True
+
+def reverse_complement (nukes):
+    return nukes[::-1].translate(PositionWeightMatrix.complementMap)
+
+def rsquared( x, y ):
+    try:
+        return sum_of_squares(x,y)**2 / (sum_of_squares(x) * sum_of_squares(y))
+    except ZeroDivisionError:
+        #return float('nan')
+        return 0
+
+def sum_of_squares( x,y=None ):
+    if not y: y = x
+    xmean = float(sum( x )) / len( x )
+    ymean = float(sum( y )) / len( y )
+    assert len(x) == len(y)
+    return sum([ float(xi)*float(yi) for xi,yi in zip(x,y)]) - len(x)*xmean*ymean
+
+def match_consensus(sequence,pattern):
+
+    return c_match_consensus( sequence, pattern, len(sequence))
+
+    #for s,p in zip(sequence,pattern):
+        #if p == 'N': continue
+        #if not s in PositionWeightMatrix.symbols[p]: return False
+
+    #return True
+
+def consensus_symbol( pattern ):
+
+    if type(pattern)==type(""):
+        try:
+            pattern = [int(x) for x in pattern.split()]
+        except ValueError,e:
+            print >>sys.stderr, pattern
+            raise ValueError,e
+
+    # IUPAC-IUB nomenclature for wobblers
+    wobblers = {
+        'R':Set(['A','G']),
+        'Y':Set(['C','T']),
+        'M':Set(['A','C']),
+        'K':Set(['G','T']),
+        'S':Set(['G','C']),
+        'W':Set(['A','T']),
+        'H':Set(['A','C','T']),
+        'B':Set(['G','T','C']),
+        'V':Set(['G','C','A']),
+        'D':Set(['G','T','A'])}
+
+    symbols = ['A','C','G','T']
+
+    if type(pattern)==type({}):
+        pattern = [pattern[u] for u in symbols]
+
+    total = sum(pattern)
+    f = [ (space/1e5)+(float(x)/total) for space,x in enumerate(pattern) ]
+    copy = []
+    copy[:] = f[:]
+    copy.sort()
+
+    # http://www.genomatix.de/online_help/help_matinspector/matrix_help.html --
+    # url says consensus must be greater than 50%, and at least twice the freq
+    # of the second-most frequent.  A double-degenerate symbol can be used
+    # if the top two account for 75% or more of the nt, if each is less than 50%
+    # Otherwise, N is used in the consensus.
+    tops = copy[-2:]
+    if tops[1] > 0.5 and tops[1] >= 2 * tops[0]: return symbols[f.index(tops[1])]
+    elif tops[0] < 0.5 and sum(tops) >= 0.75:
+        degen = Set([ symbols[f.index(v)] for v in tops ])
+        for degenSymbol,wobbles in wobblers.items():
+            #print >>sys.stderr,wobbles
+            if degen == wobbles:
+                return degenSymbol
+    else: return 'N'
+    print >>sys.stderr,pattern
+    raise Exception('?')
+
+# import C extensions
+try:
+    from _position_weight_matrix import c_match_consensus
+    ## print >>sys.stderr, "C match_consensus used"
+except:
+    ## print >>sys.stderr, "python match_consensus used"
+    def match_consensus(sequence, pattern, size):
+        for s,p in zip(sequence,pattern):
+            if p == 'N': continue
+            if not s in PositionWeightMatrix.symbols[p]: return False
+
+        return True
diff --git a/lib/bx/pwm/pwm_score_maf.py b/lib/bx/pwm/pwm_score_maf.py
new file mode 100755
index 0000000..6ed91f1
--- /dev/null
+++ b/lib/bx/pwm/pwm_score_maf.py
@@ -0,0 +1,218 @@
+#!/usr/bin/python2.4
+import sys,os
+from bx.align import maf as align_maf
+import bx.pwm.position_weight_matrix as pwmx
+
+def isnan(x):
+    #return ieeespecial.isnan(x)
+    if x==x: return False
+    return True
+
+NaN = float('nan')
+#NaN = ieeespecial.nan
+#Inf = ieeespecial.plus_inf
+#NInf = ieeespecial.minus_inf
+
+def main():
+
+    pwm_file = sys.argv[1]
+    splist = sys.argv[2]
+    if len(sys.argv) ==4: 
+        inmaf = open(sys.argv[3])
+    else:
+        inmaf = sys.stdin
+
+    # read alignment species
+    species = []
+    for sp in splist.split(','):
+        species.append( sp )
+
+    # read weight matrices
+    pwm = {}
+    for wm in pwmx.Reader(open( pwm_file ), format='basic'):
+        pwm[ wm.id ] = wm
+
+    fbunch = {}
+    for scoremax,index,headers in MafScorer(pwm, species, inmaf):
+        #print >>sys.stderr, index
+        for k,matrix in scoremax.items():
+            fname = k + '.mx'
+            if fname not in fbunch:
+                fbunch[fname] = open(fname,'w')
+                print >>sys.stderr,"Writing",fname
+
+            for i in range( len(matrix)):
+                for j in range( len(matrix[i])):
+                    print >>fbunch[fname], "%.2f" % matrix[i][j],
+                print >>fbunch[fname]
+
+    for file in fbunch.values():
+        file.close()
+
+def MafScorer(pwm,species,inmaf):
+
+    index = 0
+    scoremax,width = None,None
+    for maf in align_maf.Reader( inmaf ):
+        #try:
+        if True:
+            val = MafBlockScorer(pwm,species,maf)
+            for scoremax,width,headers in val: yield scoremax,index,headers
+            #scoremax,width,headers = MafBlockScorer(pwm,species,maf)
+        try: pass
+        except:
+            print >>sys.stderr, "Failed on:"
+            syserr = align_maf.Writer( sys.stderr )
+            syserr.write( maf )
+            #print >>sys.stderr,headers
+            if width: print >>sys.stderr,width
+            if scoremax: print >>sys.stderr,len(scoremax)
+            syserr.close()
+            sys.exit(1)
+        index += width
+        yield scoremax,index,headers
+
+def MafMotifSelect(mafblock,pwm,motif=None,threshold=0):
+
+    if motif != None and len(motif) != len(pwm): 
+        raise Exception("pwm and motif must be the same length")
+    # generic alignment
+    alignlist = [ c.text for c in mafblock.components ]
+    align = pwmx.Align( alignlist )
+    nrows,ncols = align.dims
+    #chr,chr_start,chr_stop = align.headers[0]
+    # required sequence length
+    minSeqLen = len( motif )
+    # record the text sizes from the alignment rows
+    align_match_lens = []
+
+    for start in range(ncols - minSeqLen):
+        if align.rows[0][start] == '-': continue
+        subseq = ""
+        pwm_score_vec = []
+        motif_score_vec = []
+        max_cols = 0
+        for ir in range(nrows):
+            expanded = align.rows[ir].count( '-', start, minSeqLen)
+            subtext = align.rows[ir][ start : minSeqLen+expanded ]
+            max_cols = max( len(subtext), max_cols )
+            subseq = subtext.replace('-','')
+            revseq = pwmx.reverse_complement(subseq)
+            # pwm score
+            nill,f_score = pwm.score_seq( subseq )[0]
+            r_score, nill = pwm.score_seq( revseq )[0]
+            pwm_score_vec.append( max(f_score, r_score) )
+            # consensus score
+            if motif is not None:
+                for_score = int( pwmx.match_consensus(subseq,motif) )
+                rev_score = int( pwmx.match_consensus(revseq,motif) )
+                motif_score_vec.append( max(for_score, rev_score) )
+        #check threshold
+        try:
+            assert not isnan(max(pwm_score_vec) )
+            assert not isnan(max(motif_score_vec) )
+        except:
+            print >>sys.stderr, pwm_score_vec, motif_score_vec
+            print >>sys.stderr, len(subseq), len(pwm)
+        if max(pwm_score_vec) < threshold: continue
+        if max(motif_score_vec) < threshold: continue
+        # chop block
+        col_start = start
+        col_end = max_cols + 1
+        motifmaf = mafblock.slice( col_start, col_end )
+        yield motifmaf, pwm_score_vec, motif_score_vec
+                
+    """
+    for ir in range(nrows):
+        # scan alignment row for motif subsequences
+        for start in range(ncols):
+            if align.rows[ir][start] == '-': continue
+            elif align.rows[ir][start] == 'n': continue
+            elif align.rows[ir][start] == 'N': continue
+            # gather enough subseq for motif
+            for ic in range(start,ncols):
+                char = align.rows[ir][ic].upper()
+                if char == '-' or char == 'N': continue
+                else: subseq += char
+                if len(subseq) == minSeqLen: 
+                    revseq = pwmx.reverse_complement( subseq )
+                    align_match_lens.append( ic )
+                    # pwm score
+                    nill,f_score = pwm.score_seq( subseq )[0]
+                    r_score, nill = pwm.score_seq( revseq )[0]
+                    pwm_score_vec.append( max(f_score, r_score) )
+                    # consensus score
+                    if motif is not None:
+                        for_score = int( pwmx.match_consensus(subseq,motif) )
+                        rev_score = int( pwmx.match_consensus(revseq,motif) )
+                        motif_score_vec.append( max(for_score, rev_score) )
+                    #check threshold
+                    try:
+                        assert not isnan(max(pwm_score_vec) )
+                        assert not isnan(max(motif_score_vec) )
+                    except:
+                        print >>sys.stderr, pwm_score_vec, motif_score_vec
+                        print >>sys.stderr, len(subseq), len(pwm)
+                    if max(pwm_score_vec) < threshold: continue
+                    if max(motif_score_vec) < threshold: continue
+                    # chop block
+                    col_start = start
+                    col_end = max( align_match_lens ) + 1
+                    motifmaf = mafblock.slice( col_start, col_end )
+
+                    print subseq,revseq,ic
+                    print align_match_lens
+                    yield motifmaf, pwm_score_vec, motif_score_vec
+        """
+
+def MafBlockScorer(pwm,species,maf):
+    width = len(maf.components[0].text)
+    headers = [ (c.src,c.start,c.end) for c in maf.components]
+
+    # expand block rows to full
+    mafBlockSpecies = [specName.src.split('.')[0] for specName in maf.components]
+    alignlist = []
+    for sp in species:
+        try:
+            i = mafBlockSpecies.index( sp )
+            alignlist.append( maf.components[i].text )
+        except ValueError:
+            alignlist.append( [ NaN for n in range( width ) ] )
+    alignrows = pwmx.Align( alignlist )
+    scoremax = {}
+    # record gap positions
+    filter = pwmx.score_align_gaps( alignrows )
+    # score pwm models
+    for model in pwm.keys():
+        #print >>sys.stderr,"%s_%d_%d" % headers[0],width,model
+        scoremax[model] = pwm[model].score_align( alignrows, filter )
+    yield scoremax,width,headers
+
+def MafMotifScorer(species,maf,motifs):
+    width = len(maf.components[0].text)
+    headers = [ (c.src,c.start,c.end) for c in maf.components]
+
+    # expand block rows to full
+    mafBlockSpecies = [specName.src.split('.')[0] for specName in maf.components]
+    alignlist = []
+    for sp in species:
+        try:
+            i = mafBlockSpecies.index( sp )
+            alignlist.append( maf.components[i].text )
+        except ValueError:
+            alignlist.append( [ NaN for n in range( width ) ] )
+
+    alignrows = pwmx.Align( alignlist, headers )
+    # record gap positions
+    filter = pwmx.score_align_gaps( alignrows )
+    # score motif
+    #print >>sys.stderr, headers
+    if isinstance( motifs, list):
+        scoremax = {}
+        for string in motifs:
+            scoremax[string] = pwmx.score_align_motif( alignrows, string, filter )
+    else:
+        scoremax = pwmx.score_align_motif( alignrows, motif, filter )
+    yield scoremax,width,headers
+
+if __name__ == '__main__': main()
diff --git a/lib/bx/pwm/pwm_score_motifs.py b/lib/bx/pwm/pwm_score_motifs.py
new file mode 100755
index 0000000..f88de4d
--- /dev/null
+++ b/lib/bx/pwm/pwm_score_motifs.py
@@ -0,0 +1,59 @@
+#!/usr/bin/env python2.4
+"""
+Returns all positions of a maf with any pwm score > threshold
+The positions are projected onto human coordinates
+"""
+
+import psyco_full
+from bx.align import maf as align_maf
+import position_weight_matrix as pwmx
+from bx.pwm.pwm_score_maf import MafMotifScorer
+import sys
+from bx import intervals
+
+def isnan(x):
+    return not x==x
+
+def main():
+
+    if len(sys.argv) < 4:
+        print >>sys.stderr, "%s motif inmaf spec1,spec2,... " % sys.argv[0]
+        sys.exit(0)
+
+    targmotif = sys.argv[1]
+    inmaf = open(sys.argv[2])
+    threshold = 0
+
+    species = []
+
+    for sp in sys.argv[3].split(','):
+        species.append( sp )
+
+    for maf in align_maf.Reader(inmaf):
+        mafchrom = maf.components[0].src.split('.')[1]
+        mafstart = maf.components[0].start
+        mafend = maf.components[0].end
+        reftext = maf.components[0].text
+
+        # maf block scores for each matrix
+        for scoremax,width,headers in MafMotifScorer(species, maf,targmotif):
+            #print >>sys.stderr,headers
+            blocklength = width
+            mafsrc,mafstart,mafend = headers[0]
+            mafchrom = mafsrc.split('.')[1]
+
+            # lists of scores for each position in scoremax
+            mx = scoremax
+            for offset in range(blocklength):
+
+                # scan all species with threshold
+                for i in range(len(species)):
+                    if mx[i][offset] > threshold:
+                        refstart = mafstart + offset - reftext.count('-',0,offset)
+                        refend = refstart + len( targmotif )
+                        data = " ".join([ "%.2f" % mx[x][offset] for x in range(len(species))])
+                        # quote the motif
+                        print mafchrom,refstart,refend,"'"+targmotif+"'",data
+                        break
+
+if __name__ == '__main__': main()
diff --git a/lib/bx/pwm/pwm_score_positions.py b/lib/bx/pwm/pwm_score_positions.py
new file mode 100755
index 0000000..c2a796e
--- /dev/null
+++ b/lib/bx/pwm/pwm_score_positions.py
@@ -0,0 +1,63 @@
+#!/usr/bin/env python2.4
+"""
+Returns all positions of a maf with any pwm score > threshold
+The positions are projected onto human coordinates
+"""
+
+import psyco_full
+from bx.align import maf as align_maf
+import bx.pwm.position_weight_matrix as pwmx
+from bx.pwm.pwm_score_maf import MafBlockScorer
+import sys
+from bx import intervals
+
+def isnan(x):
+    return not x==x
+
+def main():
+
+    if len(sys.argv) < 6:
+        print >>sys.stderr, "%s transfac|basic pwmfile inmaf threshold spec1,spec2,... " % sys.argv[0]
+        sys.exit(0)
+
+    pwm = {}
+    format = sys.argv[1]
+    for wm in pwmx.Reader(open(sys.argv[2]),format=format):
+        pwm[ wm.id ] = wm
+
+    
+    inmaf = open(sys.argv[3])
+    threshold = float(sys.argv[4])
+
+    species = []
+
+    for sp in sys.argv[5].split(','):
+        species.append( sp )
+
+    for maf in align_maf.Reader(inmaf):
+        mafchrom = maf.components[0].src.split('.')[1]
+        mafstart = maf.components[0].start
+        mafend = maf.components[0].end
+        reftext = maf.components[0].text
+
+        # maf block scores for each matrix
+        for scoremax,width,headers in MafBlockScorer(pwm, species, maf):
+            blocklength = width
+            mafsrc,mafstart,mafend = headers[0]
+            mafchrom = mafsrc.split('.')[1]
+
+            # lists of scores for each position in scoremax
+            for id,mx in scoremax.items():
+                for offset in range(blocklength):
+
+                    # scan all species with threshold
+                    for i in range(len(species)):
+                        if mx[i][offset] > threshold:
+                            refstart = mafstart + offset - reftext.count('-',0,offset)
+                            refend = refstart + len(pwm[id])
+                            data = " ".join([ "%.2f" % mx[x][offset] for x in range(len(species))])
+                            # underscore spaces in the name
+                            print mafchrom,refstart,refend,id.replace(' ','_'),data
+                            break
+
+if __name__ == '__main__': main()
diff --git a/lib/bx/pwm/pwm_tests.py b/lib/bx/pwm/pwm_tests.py
new file mode 100644
index 0000000..5adf338
--- /dev/null
+++ b/lib/bx/pwm/pwm_tests.py
@@ -0,0 +1,97 @@
+import unittest
+import sys
+import bx.pwm.position_weight_matrix as pwm
+from StringIO import StringIO
+
+basicPwm = \
+""">MA0101 c-REL REL
+0   5   8   4
+0   1   15  1
+1   0   15  1
+5   1   9   2
+6   5   3   3
+5   1   1   10
+1   0   0   16
+2   0   0   15
+0   15  0   2
+1   16  0   0
+"""
+
+transfacPwm = \
+"""ID  TATA
+XX
+P0    A    C    G    T
+01   33   73   78   16      S
+02   10   24   11  155      T
+03  176    3    2   19      A
+04    2    7    3  188      T
+05  178    2    3   17      A
+06  133    2    2   63      A
+07  183    3   10    4      A
+08  112    2   24   62      W
+09   78   26   80   16      R
+10   29   72   75   24      N
+11   42   74   68   16      N
+12   42   65   66   27      N
+13   41   60   67   32      N
+14   35   54   72   39      N
+15   40   51   73   36      N
+XX
+"""
+
+background = { 'A':.28,'C':.21, 'G':.24, 'T':.27 }
+
+dSeq = "ACCGAGTTAGCGTAAA"
+dScoresExpected = "-15.3697 0.4240 -16.5309 0.4027"
+
+qSeq = [{'A':0.27,'C':0.34,'G':0.07,'T':0.32},
+        {'A':0.24,'C':0.32,'G':0.09,'T':0.35},
+        {'A':0.80,'C':0.11,'G':0.03,'T':0.06},
+        {'A':0.07,'C':0.22,'G':0.37,'T':0.34},
+        {'A':0.07,'C':0.44,'G':0.03,'T':0.46},
+        {'A':0.43,'C':0.04,'G':0.18,'T':0.35},
+        {'A':0.84,'C':0.14,'G':0.01,'T':0.01},
+        {'A':0.31,'C':0.52,'G':0.13,'T':0.04},
+        {'A':0.22,'C':0.22,'G':0.45,'T':0.11},
+        {'A':0.36,'C':0.15,'G':0.42,'T':0.07},
+        {'A':0.11,'C':0.78,'G':0.07,'T':0.04},
+        {'A':0.07,'C':0.16,'G':0.64,'T':0.13},
+        {'A':0.34,'C':0.59,'G':0.03,'T':0.04},
+        {'A':0.32,'C':0.15,'G':0.07,'T':0.46},
+        {'A':0.07,'C':0.03,'G':0.59,'T':0.31}]
+
+qScoresExpected = "4.1106 0.7810"
+
+class PWMTestCase (unittest.TestCase):
+
+    def testReader(self):
+
+        # test basic format: i.e. for jaspar
+        wms = [wm for wm in pwm.Reader(StringIO(basicPwm),format="basic", \
+                          background=background,score_correction=False)]
+        assert len(wms) == 1
+
+        # test transfac format
+        wms = [wm for wm in pwm.Reader(StringIO(transfacPwm),format="transfac", \
+                          background=background,score_correction=False)]
+        assert len(wms) == 1
+
+        wm = wms[0]
+        dScores = wm.score_seq(dSeq)
+        assert len(dScores) == 2
+        assert "%.4f %.4f %.4f %.4f" % (dScores[0][0],dScores[0][1],dScores[1][0],dScores[1][1]) == dScoresExpected
+
+        qdSeq = []
+        for (ix,nt) in enumerate(dSeq):
+            qdSeq.append(dict())
+            qdSeq[ix][nt] = 1.0
+        qScores = wm.score_seq(qdSeq)
+        assert len(qScores) == 2
+        assert "%.4f %.4f %.4f %.4f" % (qScores[0][0],qScores[0][1],qScores[1][0],qScores[1][1]) == dScoresExpected
+
+        qScores = wm.score_seq(qSeq)
+        assert len(qScores) == 1
+        assert "%.4f %.4f" % (qScores[0][0],qScores[0][1]) == qScoresExpected
+
+test_classes = [PWMTestCase]
+suite = unittest.TestSuite ([unittest.makeSuite (c) for c in test_classes])
diff --git a/lib/bx/seq/__init__.py b/lib/bx/seq/__init__.py
new file mode 100644
index 0000000..4eb406d
--- /dev/null
+++ b/lib/bx/seq/__init__.py
@@ -0,0 +1,7 @@
+"""
+Classes for dealing with biological sequences. See `core` for the abstract
+sequence classes and `nib` and `qdna` for specifics of various
+formats.
+"""
+
+from bx.seq.core import *
diff --git a/lib/bx/seq/_nib.c b/lib/bx/seq/_nib.c
new file mode 100644
index 0000000..155b683
--- /dev/null
+++ b/lib/bx/seq/_nib.c
@@ -0,0 +1,1922 @@
+/* Generated by Cython 0.18 on Mon Jul 15 13:25:44 2013 */
+
+#define PY_SSIZE_T_CLEAN
+#include "Python.h"
+#ifndef Py_PYTHON_H
+    #error Python headers needed to compile C extensions, please install development version of Python.
+#elif PY_VERSION_HEX < 0x02040000
+    #error Cython requires Python 2.4+.
+#else
+#include <stddef.h> /* For offsetof */
+#ifndef offsetof
+#define offsetof(type, member) ( (size_t) & ((type*)0) -> member )
+#endif
+#if !defined(WIN32) && !defined(MS_WINDOWS)
+  #ifndef __stdcall
+    #define __stdcall
+  #endif
+  #ifndef __cdecl
+    #define __cdecl
+  #endif
+  #ifndef __fastcall
+    #define __fastcall
+  #endif
+#endif
+#ifndef DL_IMPORT
+  #define DL_IMPORT(t) t
+#endif
+#ifndef DL_EXPORT
+  #define DL_EXPORT(t) t
+#endif
+#ifndef PY_LONG_LONG
+  #define PY_LONG_LONG LONG_LONG
+#endif
+#ifndef Py_HUGE_VAL
+  #define Py_HUGE_VAL HUGE_VAL
+#endif
+#ifdef PYPY_VERSION
+#define CYTHON_COMPILING_IN_PYPY 1
+#define CYTHON_COMPILING_IN_CPYTHON 0
+#else
+#define CYTHON_COMPILING_IN_PYPY 0
+#define CYTHON_COMPILING_IN_CPYTHON 1
+#endif
+#if PY_VERSION_HEX < 0x02050000
+  typedef int Py_ssize_t;
+  #define PY_SSIZE_T_MAX INT_MAX
+  #define PY_SSIZE_T_MIN INT_MIN
+  #define PY_FORMAT_SIZE_T ""
+  #define CYTHON_FORMAT_SSIZE_T ""
+  #define PyInt_FromSsize_t(z) PyInt_FromLong(z)
+  #define PyInt_AsSsize_t(o)   __Pyx_PyInt_AsInt(o)
+  #define PyNumber_Index(o)    ((PyNumber_Check(o) && !PyFloat_Check(o)) ? PyNumber_Int(o) : \
+                                (PyErr_Format(PyExc_TypeError, \
+                                              "expected index value, got %.200s", Py_TYPE(o)->tp_name), \
+                                 (PyObject*)0))
+  #define __Pyx_PyIndex_Check(o) (PyNumber_Check(o) && !PyFloat_Check(o) && \
+                                  !PyComplex_Check(o))
+  #define PyIndex_Check __Pyx_PyIndex_Check
+  #define PyErr_WarnEx(category, message, stacklevel) PyErr_Warn(category, message)
+  #define __PYX_BUILD_PY_SSIZE_T "i"
+#else
+  #define __PYX_BUILD_PY_SSIZE_T "n"
+  #define CYTHON_FORMAT_SSIZE_T "z"
+  #define __Pyx_PyIndex_Check PyIndex_Check
+#endif
+#if PY_VERSION_HEX < 0x02060000
+  #define Py_REFCNT(ob) (((PyObject*)(ob))->ob_refcnt)
+  #define Py_TYPE(ob)   (((PyObject*)(ob))->ob_type)
+  #define Py_SIZE(ob)   (((PyVarObject*)(ob))->ob_size)
+  #define PyVarObject_HEAD_INIT(type, size) \
+          PyObject_HEAD_INIT(type) size,
+  #define PyType_Modified(t)
+  typedef struct {
+     void *buf;
+     PyObject *obj;
+     Py_ssize_t len;
+     Py_ssize_t itemsize;
+     int readonly;
+     int ndim;
+     char *format;
+     Py_ssize_t *shape;
+     Py_ssize_t *strides;
+     Py_ssize_t *suboffsets;
+     void *internal;
+  } Py_buffer;
+  #define PyBUF_SIMPLE 0
+  #define PyBUF_WRITABLE 0x0001
+  #define PyBUF_FORMAT 0x0004
+  #define PyBUF_ND 0x0008
+  #define PyBUF_STRIDES (0x0010 | PyBUF_ND)
+  #define PyBUF_C_CONTIGUOUS (0x0020 | PyBUF_STRIDES)
+  #define PyBUF_F_CONTIGUOUS (0x0040 | PyBUF_STRIDES)
+  #define PyBUF_ANY_CONTIGUOUS (0x0080 | PyBUF_STRIDES)
+  #define PyBUF_INDIRECT (0x0100 | PyBUF_STRIDES)
+  #define PyBUF_RECORDS (PyBUF_STRIDES | PyBUF_FORMAT | PyBUF_WRITABLE)
+  #define PyBUF_FULL (PyBUF_INDIRECT | PyBUF_FORMAT | PyBUF_WRITABLE)
+  typedef int (*getbufferproc)(PyObject *, Py_buffer *, int);
+  typedef void (*releasebufferproc)(PyObject *, Py_buffer *);
+#endif
+#if PY_MAJOR_VERSION < 3
+  #define __Pyx_BUILTIN_MODULE_NAME "__builtin__"
+  #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \
+          PyCode_New(a, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
+#else
+  #define __Pyx_BUILTIN_MODULE_NAME "builtins"
+  #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \
+          PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
+#endif
+#if PY_MAJOR_VERSION < 3 && PY_MINOR_VERSION < 6
+  #define PyUnicode_FromString(s) PyUnicode_Decode(s, strlen(s), "UTF-8", "strict")
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define Py_TPFLAGS_CHECKTYPES 0
+  #define Py_TPFLAGS_HAVE_INDEX 0
+#endif
+#if (PY_VERSION_HEX < 0x02060000) || (PY_MAJOR_VERSION >= 3)
+  #define Py_TPFLAGS_HAVE_NEWBUFFER 0
+#endif
+#if PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND)
+  #define CYTHON_PEP393_ENABLED 1
+  #define __Pyx_PyUnicode_READY(op)       (likely(PyUnicode_IS_READY(op)) ? \
+                                              0 : _PyUnicode_Ready((PyObject *)(op)))
+  #define __Pyx_PyUnicode_GET_LENGTH(u)   PyUnicode_GET_LENGTH(u)
+  #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_READ_CHAR(u, i)
+  #define __Pyx_PyUnicode_READ(k, d, i)   PyUnicode_READ(k, d, i)
+#else
+  #define CYTHON_PEP393_ENABLED 0
+  #define __Pyx_PyUnicode_READY(op)       (0)
+  #define __Pyx_PyUnicode_GET_LENGTH(u)   PyUnicode_GET_SIZE(u)
+  #define __Pyx_PyUnicode_READ_CHAR(u, i) ((Py_UCS4)(PyUnicode_AS_UNICODE(u)[i]))
+  #define __Pyx_PyUnicode_READ(k, d, i)   ((k=k), (Py_UCS4)(((Py_UNICODE*)d)[i]))
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define PyBaseString_Type            PyUnicode_Type
+  #define PyStringObject               PyUnicodeObject
+  #define PyString_Type                PyUnicode_Type
+  #define PyString_Check               PyUnicode_Check
+  #define PyString_CheckExact          PyUnicode_CheckExact
+#endif
+#if PY_VERSION_HEX < 0x02060000
+  #define PyBytesObject                PyStringObject
+  #define PyBytes_Type                 PyString_Type
+  #define PyBytes_Check                PyString_Check
+  #define PyBytes_CheckExact           PyString_CheckExact
+  #define PyBytes_FromString           PyString_FromString
+  #define PyBytes_FromStringAndSize    PyString_FromStringAndSize
+  #define PyBytes_FromFormat           PyString_FromFormat
+  #define PyBytes_DecodeEscape         PyString_DecodeEscape
+  #define PyBytes_AsString             PyString_AsString
+  #define PyBytes_AsStringAndSize      PyString_AsStringAndSize
+  #define PyBytes_Size                 PyString_Size
+  #define PyBytes_AS_STRING            PyString_AS_STRING
+  #define PyBytes_GET_SIZE             PyString_GET_SIZE
+  #define PyBytes_Repr                 PyString_Repr
+  #define PyBytes_Concat               PyString_Concat
+  #define PyBytes_ConcatAndDel         PyString_ConcatAndDel
+#endif
+#if PY_VERSION_HEX < 0x02060000
+  #define PySet_Check(obj)             PyObject_TypeCheck(obj, &PySet_Type)
+  #define PyFrozenSet_Check(obj)       PyObject_TypeCheck(obj, &PyFrozenSet_Type)
+#endif
+#ifndef PySet_CheckExact
+  #define PySet_CheckExact(obj)        (Py_TYPE(obj) == &PySet_Type)
+#endif
+#define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type)
+#if PY_MAJOR_VERSION >= 3
+  #define PyIntObject                  PyLongObject
+  #define PyInt_Type                   PyLong_Type
+  #define PyInt_Check(op)              PyLong_Check(op)
+  #define PyInt_CheckExact(op)         PyLong_CheckExact(op)
+  #define PyInt_FromString             PyLong_FromString
+  #define PyInt_FromUnicode            PyLong_FromUnicode
+  #define PyInt_FromLong               PyLong_FromLong
+  #define PyInt_FromSize_t             PyLong_FromSize_t
+  #define PyInt_FromSsize_t            PyLong_FromSsize_t
+  #define PyInt_AsLong                 PyLong_AsLong
+  #define PyInt_AS_LONG                PyLong_AS_LONG
+  #define PyInt_AsSsize_t              PyLong_AsSsize_t
+  #define PyInt_AsUnsignedLongMask     PyLong_AsUnsignedLongMask
+  #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define PyBoolObject                 PyLongObject
+#endif
+#if PY_VERSION_HEX < 0x03020000
+  typedef long Py_hash_t;
+  #define __Pyx_PyInt_FromHash_t PyInt_FromLong
+  #define __Pyx_PyInt_AsHash_t   PyInt_AsLong
+#else
+  #define __Pyx_PyInt_FromHash_t PyInt_FromSsize_t
+  #define __Pyx_PyInt_AsHash_t   PyInt_AsSsize_t
+#endif
+#if (PY_MAJOR_VERSION < 3) || (PY_VERSION_HEX >= 0x03010300)
+  #define __Pyx_PySequence_GetSlice(obj, a, b) PySequence_GetSlice(obj, a, b)
+  #define __Pyx_PySequence_SetSlice(obj, a, b, value) PySequence_SetSlice(obj, a, b, value)
+  #define __Pyx_PySequence_DelSlice(obj, a, b) PySequence_DelSlice(obj, a, b)
+#else
+  #define __Pyx_PySequence_GetSlice(obj, a, b) (unlikely(!(obj)) ? \
+        (PyErr_SetString(PyExc_SystemError, "null argument to internal routine"), (PyObject*)0) : \
+        (likely((obj)->ob_type->tp_as_mapping) ? (PySequence_GetSlice(obj, a, b)) : \
+            (PyErr_Format(PyExc_TypeError, "'%.200s' object is unsliceable", (obj)->ob_type->tp_name), (PyObject*)0)))
+  #define __Pyx_PySequence_SetSlice(obj, a, b, value) (unlikely(!(obj)) ? \
+        (PyErr_SetString(PyExc_SystemError, "null argument to internal routine"), -1) : \
+        (likely((obj)->ob_type->tp_as_mapping) ? (PySequence_SetSlice(obj, a, b, value)) : \
+            (PyErr_Format(PyExc_TypeError, "'%.200s' object doesn't support slice assignment", (obj)->ob_type->tp_name), -1)))
+  #define __Pyx_PySequence_DelSlice(obj, a, b) (unlikely(!(obj)) ? \
+        (PyErr_SetString(PyExc_SystemError, "null argument to internal routine"), -1) : \
+        (likely((obj)->ob_type->tp_as_mapping) ? (PySequence_DelSlice(obj, a, b)) : \
+            (PyErr_Format(PyExc_TypeError, "'%.200s' object doesn't support slice deletion", (obj)->ob_type->tp_name), -1)))
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define PyMethod_New(func, self, klass) ((self) ? PyMethod_New(func, self) : PyInstanceMethod_New(func))
+#endif
+#if PY_VERSION_HEX < 0x02050000
+  #define __Pyx_GetAttrString(o,n)   PyObject_GetAttrString((o),((char *)(n)))
+  #define __Pyx_SetAttrString(o,n,a) PyObject_SetAttrString((o),((char *)(n)),(a))
+  #define __Pyx_DelAttrString(o,n)   PyObject_DelAttrString((o),((char *)(n)))
+#else
+  #define __Pyx_GetAttrString(o,n)   PyObject_GetAttrString((o),(n))
+  #define __Pyx_SetAttrString(o,n,a) PyObject_SetAttrString((o),(n),(a))
+  #define __Pyx_DelAttrString(o,n)   PyObject_DelAttrString((o),(n))
+#endif
+#if PY_VERSION_HEX < 0x02050000
+  #define __Pyx_NAMESTR(n) ((char *)(n))
+  #define __Pyx_DOCSTR(n)  ((char *)(n))
+#else
+  #define __Pyx_NAMESTR(n) (n)
+  #define __Pyx_DOCSTR(n)  (n)
+#endif
+
+
+#if PY_MAJOR_VERSION >= 3
+  #define __Pyx_PyNumber_Divide(x,y)         PyNumber_TrueDivide(x,y)
+  #define __Pyx_PyNumber_InPlaceDivide(x,y)  PyNumber_InPlaceTrueDivide(x,y)
+#else
+  #define __Pyx_PyNumber_Divide(x,y)         PyNumber_Divide(x,y)
+  #define __Pyx_PyNumber_InPlaceDivide(x,y)  PyNumber_InPlaceDivide(x,y)
+#endif
+
+#ifndef __PYX_EXTERN_C
+  #ifdef __cplusplus
+    #define __PYX_EXTERN_C extern "C"
+  #else
+    #define __PYX_EXTERN_C extern
+  #endif
+#endif
+
+#if defined(WIN32) || defined(MS_WINDOWS)
+#define _USE_MATH_DEFINES
+#endif
+#include <math.h>
+#define __PYX_HAVE__bx__seq___nib
+#define __PYX_HAVE_API__bx__seq___nib
+#ifdef _OPENMP
+#include <omp.h>
+#endif /* _OPENMP */
+
+#ifdef PYREX_WITHOUT_ASSERTIONS
+#define CYTHON_WITHOUT_ASSERTIONS
+#endif
+
+#ifndef CYTHON_INLINE
+  #if defined(__GNUC__)
+    #define CYTHON_INLINE __inline__
+  #elif defined(_MSC_VER)
+    #define CYTHON_INLINE __inline
+  #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+    #define CYTHON_INLINE inline
+  #else
+    #define CYTHON_INLINE
+  #endif
+#endif
+#ifndef CYTHON_UNUSED
+# if defined(__GNUC__)
+#   if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
+#     define CYTHON_UNUSED __attribute__ ((__unused__))
+#   else
+#     define CYTHON_UNUSED
+#   endif
+# elif defined(__ICC) || (defined(__INTEL_COMPILER) && !defined(_MSC_VER))
+#   define CYTHON_UNUSED __attribute__ ((__unused__))
+# else
+#   define CYTHON_UNUSED
+# endif
+#endif
+typedef struct {PyObject **p; char *s; const long n; const char* encoding; const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry; /*proto*/
+
+#define __Pyx_PyBytes_FromUString(s) PyBytes_FromString((char*)s)
+#define __Pyx_PyBytes_AsUString(s)   ((unsigned char*) PyBytes_AsString(s))
+#define __Pyx_Owned_Py_None(b) (Py_INCREF(Py_None), Py_None)
+#define __Pyx_PyBool_FromLong(b) ((b) ? (Py_INCREF(Py_True), Py_True) : (Py_INCREF(Py_False), Py_False))
+static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*);
+static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x);
+static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*);
+static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t);
+static CYTHON_INLINE size_t __Pyx_PyInt_AsSize_t(PyObject*);
+#if CYTHON_COMPILING_IN_CPYTHON
+#define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x))
+#else
+#define __pyx_PyFloat_AsDouble(x) PyFloat_AsDouble(x)
+#endif
+#define __pyx_PyFloat_AsFloat(x) ((float) __pyx_PyFloat_AsDouble(x))
+
+
+#ifdef __GNUC__
+  /* Test for GCC > 2.95 */
+  #if __GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))
+    #define likely(x)   __builtin_expect(!!(x), 1)
+    #define unlikely(x) __builtin_expect(!!(x), 0)
+  #else /* __GNUC__ > 2 ... */
+    #define likely(x)   (x)
+    #define unlikely(x) (x)
+  #endif /* __GNUC__ > 2 ... */
+#else /* __GNUC__ */
+  #define likely(x)   (x)
+  #define unlikely(x) (x)
+#endif /* __GNUC__ */
+    
+static PyObject *__pyx_m;
+static PyObject *__pyx_b;
+static PyObject *__pyx_empty_tuple;
+static PyObject *__pyx_empty_bytes;
+static int __pyx_lineno;
+static int __pyx_clineno = 0;
+static const char * __pyx_cfilenm= __FILE__;
+static const char *__pyx_filename;
+
+
+static const char *__pyx_f[] = {
+  "_nib.pyx",
+};
+
+/*--- Type declarations ---*/
+#ifndef CYTHON_REFNANNY
+  #define CYTHON_REFNANNY 0
+#endif
+#if CYTHON_REFNANNY
+  typedef struct {
+    void (*INCREF)(void*, PyObject*, int);
+    void (*DECREF)(void*, PyObject*, int);
+    void (*GOTREF)(void*, PyObject*, int);
+    void (*GIVEREF)(void*, PyObject*, int);
+    void* (*SetupContext)(const char*, int, const char*);
+    void (*FinishContext)(void**);
+  } __Pyx_RefNannyAPIStruct;
+  static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL;
+  static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname); /*proto*/
+  #define __Pyx_RefNannyDeclarations void *__pyx_refnanny = NULL;
+#ifdef WITH_THREAD
+  #define __Pyx_RefNannySetupContext(name, acquire_gil) \
+          if (acquire_gil) { \
+              PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure(); \
+              __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__); \
+              PyGILState_Release(__pyx_gilstate_save); \
+          } else { \
+              __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__); \
+          }
+#else
+  #define __Pyx_RefNannySetupContext(name, acquire_gil) \
+          __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__)
+#endif
+  #define __Pyx_RefNannyFinishContext() \
+          __Pyx_RefNanny->FinishContext(&__pyx_refnanny)
+  #define __Pyx_INCREF(r)  __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_DECREF(r)  __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_GOTREF(r)  __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_XINCREF(r)  do { if((r) != NULL) {__Pyx_INCREF(r); }} while(0)
+  #define __Pyx_XDECREF(r)  do { if((r) != NULL) {__Pyx_DECREF(r); }} while(0)
+  #define __Pyx_XGOTREF(r)  do { if((r) != NULL) {__Pyx_GOTREF(r); }} while(0)
+  #define __Pyx_XGIVEREF(r) do { if((r) != NULL) {__Pyx_GIVEREF(r);}} while(0)
+#else
+  #define __Pyx_RefNannyDeclarations
+  #define __Pyx_RefNannySetupContext(name, acquire_gil)
+  #define __Pyx_RefNannyFinishContext()
+  #define __Pyx_INCREF(r) Py_INCREF(r)
+  #define __Pyx_DECREF(r) Py_DECREF(r)
+  #define __Pyx_GOTREF(r)
+  #define __Pyx_GIVEREF(r)
+  #define __Pyx_XINCREF(r) Py_XINCREF(r)
+  #define __Pyx_XDECREF(r) Py_XDECREF(r)
+  #define __Pyx_XGOTREF(r)
+  #define __Pyx_XGIVEREF(r)
+#endif /* CYTHON_REFNANNY */
+#define __Pyx_CLEAR(r)    do { PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);} while(0)
+#define __Pyx_XCLEAR(r)   do { if((r) != NULL) {PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);}} while(0)
+
+static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
+    Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/
+
+static void __Pyx_RaiseDoubleKeywordsError(const char* func_name, PyObject* kw_name); /*proto*/
+
+static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
+    PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
+    const char* function_name); /*proto*/
+
+static CYTHON_INLINE long __Pyx_div_long(long, long); /* proto */
+
+static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level); /*proto*/
+
+static CYTHON_INLINE unsigned char __Pyx_PyInt_AsUnsignedChar(PyObject *);
+
+static CYTHON_INLINE unsigned short __Pyx_PyInt_AsUnsignedShort(PyObject *);
+
+static CYTHON_INLINE unsigned int __Pyx_PyInt_AsUnsignedInt(PyObject *);
+
+static CYTHON_INLINE char __Pyx_PyInt_AsChar(PyObject *);
+
+static CYTHON_INLINE short __Pyx_PyInt_AsShort(PyObject *);
+
+static CYTHON_INLINE int __Pyx_PyInt_AsInt(PyObject *);
+
+static CYTHON_INLINE signed char __Pyx_PyInt_AsSignedChar(PyObject *);
+
+static CYTHON_INLINE signed short __Pyx_PyInt_AsSignedShort(PyObject *);
+
+static CYTHON_INLINE signed int __Pyx_PyInt_AsSignedInt(PyObject *);
+
+static CYTHON_INLINE int __Pyx_PyInt_AsLongDouble(PyObject *);
+
+static CYTHON_INLINE unsigned long __Pyx_PyInt_AsUnsignedLong(PyObject *);
+
+static CYTHON_INLINE unsigned PY_LONG_LONG __Pyx_PyInt_AsUnsignedLongLong(PyObject *);
+
+static CYTHON_INLINE long __Pyx_PyInt_AsLong(PyObject *);
+
+static CYTHON_INLINE PY_LONG_LONG __Pyx_PyInt_AsLongLong(PyObject *);
+
+static CYTHON_INLINE signed long __Pyx_PyInt_AsSignedLong(PyObject *);
+
+static CYTHON_INLINE signed PY_LONG_LONG __Pyx_PyInt_AsSignedLongLong(PyObject *);
+
+static int __Pyx_check_binary_version(void);
+
+typedef struct {
+    int code_line;
+    PyCodeObject* code_object;
+} __Pyx_CodeObjectCacheEntry;
+struct __Pyx_CodeObjectCache {
+    int count;
+    int max_count;
+    __Pyx_CodeObjectCacheEntry* entries;
+};
+static struct __Pyx_CodeObjectCache __pyx_code_cache = {0,0,NULL};
+static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line);
+static PyCodeObject *__pyx_find_code_object(int code_line);
+static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object);
+
+static void __Pyx_AddTraceback(const char *funcname, int c_line,
+                               int py_line, const char *filename); /*proto*/
+
+static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
+
+
+/* Module declarations from 'bx.seq._nib' */
+static char *__pyx_v_2bx_3seq_4_nib_NIB_I2C_TABLE_FIRST;
+static char *__pyx_v_2bx_3seq_4_nib_NIB_I2C_TABLE_SECOND;
+#define __Pyx_MODULE_NAME "bx.seq._nib"
+int __pyx_module_is_main_bx__seq___nib = 0;
+
+/* Implementation of 'bx.seq._nib' */
+static PyObject *__pyx_pf_2bx_3seq_4_nib_translate_raw_data(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_data, int __pyx_v_start, int __pyx_v_length); /* proto */
+static char __pyx_k_1[] = "TTTTTTTTTTTTTTTTCCCCCCCCCCCCCCCCAAAAAAAAAAAAAAAAGGGGGGGGGGGGGGGGNNNNNNNNNNNNNNNNXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXttttttttttttttttccccccccccccccccaaaaaaaaaaaaaaaaggggggggggggggggnnnnnnnnnnnnnnnnxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
+static char __pyx_k_2[] = "TCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxx";
+static char __pyx_k_5[] = "/aut/proj/odenas/software/bx-python/lib/bx/seq/_nib.pyx";
+static char __pyx_k_6[] = "bx.seq._nib";
+static char __pyx_k__i[] = "i";
+static char __pyx_k__j[] = "j";
+static char __pyx_k__sys[] = "sys";
+static char __pyx_k__data[] = "data";
+static char __pyx_k__rval[] = "rval";
+static char __pyx_k__start[] = "start";
+static char __pyx_k__length[] = "length";
+static char __pyx_k__p_data[] = "p_data";
+static char __pyx_k__p_rval[] = "p_rval";
+static char __pyx_k__struct[] = "struct";
+static char __pyx_k____main__[] = "__main__";
+static char __pyx_k____test__[] = "__test__";
+static char __pyx_k__translate_raw_data[] = "translate_raw_data";
+static PyObject *__pyx_kp_s_5;
+static PyObject *__pyx_n_s_6;
+static PyObject *__pyx_n_s____main__;
+static PyObject *__pyx_n_s____test__;
+static PyObject *__pyx_n_s__data;
+static PyObject *__pyx_n_s__i;
+static PyObject *__pyx_n_s__j;
+static PyObject *__pyx_n_s__length;
+static PyObject *__pyx_n_s__p_data;
+static PyObject *__pyx_n_s__p_rval;
+static PyObject *__pyx_n_s__rval;
+static PyObject *__pyx_n_s__start;
+static PyObject *__pyx_n_s__struct;
+static PyObject *__pyx_n_s__sys;
+static PyObject *__pyx_n_s__translate_raw_data;
+static PyObject *__pyx_k_tuple_3;
+static PyObject *__pyx_k_codeobj_4;
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_3seq_4_nib_1translate_raw_data(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_2bx_3seq_4_nib_translate_raw_data[] = "\n    Data is a block read from the file that needs to be unpacked, dealing\n    with end conditions based on start/length.\n    ";
+static PyMethodDef __pyx_mdef_2bx_3seq_4_nib_1translate_raw_data = {__Pyx_NAMESTR("translate_raw_data"), (PyCFunction)__pyx_pw_2bx_3seq_4_nib_1translate_raw_data, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(__pyx_doc_2bx_3seq_4_nib_translate_raw_data)};
+static PyObject *__pyx_pw_2bx_3seq_4_nib_1translate_raw_data(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_data = 0;
+  int __pyx_v_start;
+  int __pyx_v_length;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("translate_raw_data (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__data,&__pyx_n_s__start,&__pyx_n_s__length,0};
+    PyObject* values[3] = {0,0,0};
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__data)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__start)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("translate_raw_data", 1, 3, 3, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 15; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+        case  2:
+        if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__length)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("translate_raw_data", 1, 3, 3, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 15; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "translate_raw_data") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 15; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else if (PyTuple_GET_SIZE(__pyx_args) != 3) {
+      goto __pyx_L5_argtuple_error;
+    } else {
+      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+      values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+    }
+    __pyx_v_data = values[0];
+    __pyx_v_start = __Pyx_PyInt_AsInt(values[1]); if (unlikely((__pyx_v_start == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 15; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_length = __Pyx_PyInt_AsInt(values[2]); if (unlikely((__pyx_v_length == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 15; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("translate_raw_data", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 15; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.seq._nib.translate_raw_data", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_3seq_4_nib_translate_raw_data(__pyx_self, __pyx_v_data, __pyx_v_start, __pyx_v_length);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/seq/_nib.pyx":15
+ * NIB_I2C_TABLE_SECOND = "TCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxx"
+ * 
+ * def translate_raw_data( data, int start, int length ):             # <<<<<<<<<<<<<<
+ *     """
+ *     Data is a block read from the file that needs to be unpacked, dealing
+ */
+
+static PyObject *__pyx_pf_2bx_3seq_4_nib_translate_raw_data(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_data, int __pyx_v_start, int __pyx_v_length) {
+  int __pyx_v_i;
+  CYTHON_UNUSED int __pyx_v_j;
+  char *__pyx_v_p_rval;
+  unsigned char *__pyx_v_p_data;
+  PyObject *__pyx_v_rval = NULL;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  long __pyx_t_2;
+  int __pyx_t_3;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("translate_raw_data", 0);
+
+  /* "bx/seq/_nib.pyx":24
+ *     cdef unsigned char * p_data
+ *     # Allocate string to write into
+ *     rval = PyString_FromStringAndSize( NULL, length )             # <<<<<<<<<<<<<<
+ *     # Get char pointer access to strings
+ *     p_rval = PyString_AsString( rval )
+ */
+  __pyx_t_1 = PyString_FromStringAndSize(NULL, __pyx_v_length); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 24; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_v_rval = __pyx_t_1;
+  __pyx_t_1 = 0;
+
+  /* "bx/seq/_nib.pyx":26
+ *     rval = PyString_FromStringAndSize( NULL, length )
+ *     # Get char pointer access to strings
+ *     p_rval = PyString_AsString( rval )             # <<<<<<<<<<<<<<
+ *     p_data = <unsigned char *> PyString_AsString( data )
+ *     i = 0
+ */
+  __pyx_v_p_rval = PyString_AsString(__pyx_v_rval);
+
+  /* "bx/seq/_nib.pyx":27
+ *     # Get char pointer access to strings
+ *     p_rval = PyString_AsString( rval )
+ *     p_data = <unsigned char *> PyString_AsString( data )             # <<<<<<<<<<<<<<
+ *     i = 0
+ *     # Odd start
+ */
+  __pyx_v_p_data = ((unsigned char *)PyString_AsString(__pyx_v_data));
+
+  /* "bx/seq/_nib.pyx":28
+ *     p_rval = PyString_AsString( rval )
+ *     p_data = <unsigned char *> PyString_AsString( data )
+ *     i = 0             # <<<<<<<<<<<<<<
+ *     # Odd start
+ *     if start & 1:
+ */
+  __pyx_v_i = 0;
+
+  /* "bx/seq/_nib.pyx":30
+ *     i = 0
+ *     # Odd start
+ *     if start & 1:             # <<<<<<<<<<<<<<
+ *         #p_rval[i] = NIB_I2C_TABLE[ p_data[0] & 0xF ]
+ *         p_rval[i] = NIB_I2C_TABLE_SECOND[ p_data[0] ]
+ */
+  __pyx_t_2 = (__pyx_v_start & 1);
+  if (__pyx_t_2) {
+
+    /* "bx/seq/_nib.pyx":32
+ *     if start & 1:
+ *         #p_rval[i] = NIB_I2C_TABLE[ p_data[0] & 0xF ]
+ *         p_rval[i] = NIB_I2C_TABLE_SECOND[ p_data[0] ]             # <<<<<<<<<<<<<<
+ *         p_data = p_data + 1
+ *         i = 1
+ */
+    (__pyx_v_p_rval[__pyx_v_i]) = (__pyx_v_2bx_3seq_4_nib_NIB_I2C_TABLE_SECOND[(__pyx_v_p_data[0])]);
+
+    /* "bx/seq/_nib.pyx":33
+ *         #p_rval[i] = NIB_I2C_TABLE[ p_data[0] & 0xF ]
+ *         p_rval[i] = NIB_I2C_TABLE_SECOND[ p_data[0] ]
+ *         p_data = p_data + 1             # <<<<<<<<<<<<<<
+ *         i = 1
+ *     # Two output values for each input value
+ */
+    __pyx_v_p_data = (__pyx_v_p_data + 1);
+
+    /* "bx/seq/_nib.pyx":34
+ *         p_rval[i] = NIB_I2C_TABLE_SECOND[ p_data[0] ]
+ *         p_data = p_data + 1
+ *         i = 1             # <<<<<<<<<<<<<<
+ *     # Two output values for each input value
+ *     for j from 0 <= j < (length-i)/2:
+ */
+    __pyx_v_i = 1;
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  /* "bx/seq/_nib.pyx":36
+ *         i = 1
+ *     # Two output values for each input value
+ *     for j from 0 <= j < (length-i)/2:             # <<<<<<<<<<<<<<
+ *         #p_rval[i]   = NIB_I2C_TABLE[ ( p_data[0] >> 4 ) & 0xF ];
+ *         #p_rval[i+1] = NIB_I2C_TABLE[ ( p_data[0] >> 0 ) & 0xF ];
+ */
+  __pyx_t_2 = __Pyx_div_long((__pyx_v_length - __pyx_v_i), 2);
+  for (__pyx_v_j = 0; __pyx_v_j < __pyx_t_2; __pyx_v_j++) {
+
+    /* "bx/seq/_nib.pyx":39
+ *         #p_rval[i]   = NIB_I2C_TABLE[ ( p_data[0] >> 4 ) & 0xF ];
+ *         #p_rval[i+1] = NIB_I2C_TABLE[ ( p_data[0] >> 0 ) & 0xF ];
+ *         p_rval[i]   = NIB_I2C_TABLE_FIRST [ p_data[0] ]             # <<<<<<<<<<<<<<
+ *         p_rval[i+1] = NIB_I2C_TABLE_SECOND[ p_data[0] ]
+ *         i = i + 2
+ */
+    (__pyx_v_p_rval[__pyx_v_i]) = (__pyx_v_2bx_3seq_4_nib_NIB_I2C_TABLE_FIRST[(__pyx_v_p_data[0])]);
+
+    /* "bx/seq/_nib.pyx":40
+ *         #p_rval[i+1] = NIB_I2C_TABLE[ ( p_data[0] >> 0 ) & 0xF ];
+ *         p_rval[i]   = NIB_I2C_TABLE_FIRST [ p_data[0] ]
+ *         p_rval[i+1] = NIB_I2C_TABLE_SECOND[ p_data[0] ]             # <<<<<<<<<<<<<<
+ *         i = i + 2
+ *         p_data = p_data + 1
+ */
+    (__pyx_v_p_rval[(__pyx_v_i + 1)]) = (__pyx_v_2bx_3seq_4_nib_NIB_I2C_TABLE_SECOND[(__pyx_v_p_data[0])]);
+
+    /* "bx/seq/_nib.pyx":41
+ *         p_rval[i]   = NIB_I2C_TABLE_FIRST [ p_data[0] ]
+ *         p_rval[i+1] = NIB_I2C_TABLE_SECOND[ p_data[0] ]
+ *         i = i + 2             # <<<<<<<<<<<<<<
+ *         p_data = p_data + 1
+ *     # Odd end
+ */
+    __pyx_v_i = (__pyx_v_i + 2);
+
+    /* "bx/seq/_nib.pyx":42
+ *         p_rval[i+1] = NIB_I2C_TABLE_SECOND[ p_data[0] ]
+ *         i = i + 2
+ *         p_data = p_data + 1             # <<<<<<<<<<<<<<
+ *     # Odd end
+ *     if i < length:
+ */
+    __pyx_v_p_data = (__pyx_v_p_data + 1);
+  }
+
+  /* "bx/seq/_nib.pyx":44
+ *         p_data = p_data + 1
+ *     # Odd end
+ *     if i < length:             # <<<<<<<<<<<<<<
+ *         p_rval[i] = NIB_I2C_TABLE_FIRST[ p_data[0] ]
+ *     return rval
+ */
+  __pyx_t_3 = (__pyx_v_i < __pyx_v_length);
+  if (__pyx_t_3) {
+
+    /* "bx/seq/_nib.pyx":45
+ *     # Odd end
+ *     if i < length:
+ *         p_rval[i] = NIB_I2C_TABLE_FIRST[ p_data[0] ]             # <<<<<<<<<<<<<<
+ *     return rval
+ */
+    (__pyx_v_p_rval[__pyx_v_i]) = (__pyx_v_2bx_3seq_4_nib_NIB_I2C_TABLE_FIRST[(__pyx_v_p_data[0])]);
+    goto __pyx_L6;
+  }
+  __pyx_L6:;
+
+  /* "bx/seq/_nib.pyx":46
+ *     if i < length:
+ *         p_rval[i] = NIB_I2C_TABLE_FIRST[ p_data[0] ]
+ *     return rval             # <<<<<<<<<<<<<<
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __Pyx_INCREF(__pyx_v_rval);
+  __pyx_r = __pyx_v_rval;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("bx.seq._nib.translate_raw_data", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_rval);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyMethodDef __pyx_methods[] = {
+  {0, 0, 0, 0}
+};
+
+#if PY_MAJOR_VERSION >= 3
+static struct PyModuleDef __pyx_moduledef = {
+  #if PY_VERSION_HEX < 0x03020000
+    { PyObject_HEAD_INIT(NULL) NULL, 0, NULL },
+  #else
+    PyModuleDef_HEAD_INIT,
+  #endif
+    __Pyx_NAMESTR("_nib"),
+    0, /* m_doc */
+    -1, /* m_size */
+    __pyx_methods /* m_methods */,
+    NULL, /* m_reload */
+    NULL, /* m_traverse */
+    NULL, /* m_clear */
+    NULL /* m_free */
+};
+#endif
+
+static __Pyx_StringTabEntry __pyx_string_tab[] = {
+  {&__pyx_kp_s_5, __pyx_k_5, sizeof(__pyx_k_5), 0, 0, 1, 0},
+  {&__pyx_n_s_6, __pyx_k_6, sizeof(__pyx_k_6), 0, 0, 1, 1},
+  {&__pyx_n_s____main__, __pyx_k____main__, sizeof(__pyx_k____main__), 0, 0, 1, 1},
+  {&__pyx_n_s____test__, __pyx_k____test__, sizeof(__pyx_k____test__), 0, 0, 1, 1},
+  {&__pyx_n_s__data, __pyx_k__data, sizeof(__pyx_k__data), 0, 0, 1, 1},
+  {&__pyx_n_s__i, __pyx_k__i, sizeof(__pyx_k__i), 0, 0, 1, 1},
+  {&__pyx_n_s__j, __pyx_k__j, sizeof(__pyx_k__j), 0, 0, 1, 1},
+  {&__pyx_n_s__length, __pyx_k__length, sizeof(__pyx_k__length), 0, 0, 1, 1},
+  {&__pyx_n_s__p_data, __pyx_k__p_data, sizeof(__pyx_k__p_data), 0, 0, 1, 1},
+  {&__pyx_n_s__p_rval, __pyx_k__p_rval, sizeof(__pyx_k__p_rval), 0, 0, 1, 1},
+  {&__pyx_n_s__rval, __pyx_k__rval, sizeof(__pyx_k__rval), 0, 0, 1, 1},
+  {&__pyx_n_s__start, __pyx_k__start, sizeof(__pyx_k__start), 0, 0, 1, 1},
+  {&__pyx_n_s__struct, __pyx_k__struct, sizeof(__pyx_k__struct), 0, 0, 1, 1},
+  {&__pyx_n_s__sys, __pyx_k__sys, sizeof(__pyx_k__sys), 0, 0, 1, 1},
+  {&__pyx_n_s__translate_raw_data, __pyx_k__translate_raw_data, sizeof(__pyx_k__translate_raw_data), 0, 0, 1, 1},
+  {0, 0, 0, 0, 0, 0, 0}
+};
+static int __Pyx_InitCachedBuiltins(void) {
+  return 0;
+}
+
+static int __Pyx_InitCachedConstants(void) {
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0);
+
+  /* "bx/seq/_nib.pyx":15
+ * NIB_I2C_TABLE_SECOND = "TCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxx"
+ * 
+ * def translate_raw_data( data, int start, int length ):             # <<<<<<<<<<<<<<
+ *     """
+ *     Data is a block read from the file that needs to be unpacked, dealing
+ */
+  __pyx_k_tuple_3 = PyTuple_Pack(8, ((PyObject *)__pyx_n_s__data), ((PyObject *)__pyx_n_s__start), ((PyObject *)__pyx_n_s__length), ((PyObject *)__pyx_n_s__i), ((PyObject *)__pyx_n_s__j), ((PyObject *)__pyx_n_s__p_rval), ((PyObject *)__pyx_n_s__p_data), ((PyObject *)__pyx_n_s__rval)); if (unlikely(!__pyx_k_tuple_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 15; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_k_tuple_3);
+  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_3));
+  __pyx_k_codeobj_4 = (PyObject*)__Pyx_PyCode_New(3, 0, 8, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_k_tuple_3, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_5, __pyx_n_s__translate_raw_data, 15, __pyx_empty_bytes); if (unlikely(!__pyx_k_codeobj_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 15; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_RefNannyFinishContext();
+  return 0;
+  __pyx_L1_error:;
+  __Pyx_RefNannyFinishContext();
+  return -1;
+}
+
+static int __Pyx_InitGlobals(void) {
+  if (__Pyx_InitStrings(__pyx_string_tab) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  return 0;
+  __pyx_L1_error:;
+  return -1;
+}
+
+#if PY_MAJOR_VERSION < 3
+PyMODINIT_FUNC init_nib(void); /*proto*/
+PyMODINIT_FUNC init_nib(void)
+#else
+PyMODINIT_FUNC PyInit__nib(void); /*proto*/
+PyMODINIT_FUNC PyInit__nib(void)
+#endif
+{
+  PyObject *__pyx_t_1 = NULL;
+  __Pyx_RefNannyDeclarations
+  #if CYTHON_REFNANNY
+  __Pyx_RefNanny = __Pyx_RefNannyImportAPI("refnanny");
+  if (!__Pyx_RefNanny) {
+      PyErr_Clear();
+      __Pyx_RefNanny = __Pyx_RefNannyImportAPI("Cython.Runtime.refnanny");
+      if (!__Pyx_RefNanny)
+          Py_FatalError("failed to import 'refnanny' module");
+  }
+  #endif
+  __Pyx_RefNannySetupContext("PyMODINIT_FUNC PyInit__nib(void)", 0);
+  if ( __Pyx_check_binary_version() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_bytes)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #ifdef __Pyx_CyFunction_USED
+  if (__Pyx_CyFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #endif
+  #ifdef __Pyx_FusedFunction_USED
+  if (__pyx_FusedFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #endif
+  #ifdef __Pyx_Generator_USED
+  if (__pyx_Generator_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #endif
+  /*--- Library function declarations ---*/
+  /*--- Threads initialization code ---*/
+  #if defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS
+  #ifdef WITH_THREAD /* Python build with threading support? */
+  PyEval_InitThreads();
+  #endif
+  #endif
+  /*--- Module creation code ---*/
+  #if PY_MAJOR_VERSION < 3
+  __pyx_m = Py_InitModule4(__Pyx_NAMESTR("_nib"), __pyx_methods, 0, 0, PYTHON_API_VERSION); Py_XINCREF(__pyx_m);
+  #else
+  __pyx_m = PyModule_Create(&__pyx_moduledef);
+  #endif
+  if (unlikely(!__pyx_m)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #if PY_MAJOR_VERSION >= 3
+  {
+    PyObject *modules = PyImport_GetModuleDict(); if (unlikely(!modules)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (!PyDict_GetItemString(modules, "bx.seq._nib")) {
+      if (unlikely(PyDict_SetItemString(modules, "bx.seq._nib", __pyx_m) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+  }
+  #endif
+  __pyx_b = PyImport_AddModule(__Pyx_NAMESTR(__Pyx_BUILTIN_MODULE_NAME)); if (unlikely(!__pyx_b)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #if CYTHON_COMPILING_IN_PYPY
+  Py_INCREF(__pyx_b);
+  #endif
+  if (__Pyx_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  /*--- Initialize various global constants etc. ---*/
+  if (unlikely(__Pyx_InitGlobals() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (__pyx_module_is_main_bx__seq___nib) {
+    if (__Pyx_SetAttrString(__pyx_m, "__name__", __pyx_n_s____main__) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  }
+  /*--- Builtin init code ---*/
+  if (unlikely(__Pyx_InitCachedBuiltins() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  /*--- Constants init code ---*/
+  if (unlikely(__Pyx_InitCachedConstants() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  /*--- Global init code ---*/
+  /*--- Variable export code ---*/
+  /*--- Function export code ---*/
+  /*--- Type init code ---*/
+  /*--- Type import code ---*/
+  /*--- Variable import code ---*/
+  /*--- Function import code ---*/
+  /*--- Execution code ---*/
+
+  /* "bx/seq/_nib.pyx":6
+ *     int _PyString_Resize( object, int ) except -1
+ * 
+ * import struct, sys             # <<<<<<<<<<<<<<
+ * 
+ * cdef char * NIB_I2C_TABLE
+ */
+  __pyx_t_1 = __Pyx_Import(((PyObject *)__pyx_n_s__struct), 0, -1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 6; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s__struct, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 6; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_1 = __Pyx_Import(((PyObject *)__pyx_n_s__sys), 0, -1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 6; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s__sys, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 6; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "bx/seq/_nib.pyx":12
+ * cdef char * NIB_I2C_TABLE_SECOND
+ * #NIB_I2C_TABLE        = "TCAGNXXXtcagnxxx"
+ * NIB_I2C_TABLE_FIRST  = "TTTTTTTTTTTTTTTTCCCCCCCCCCCCCCCCAAAAAAAAAAAAAAAAGGGGGGGGGGGGGGGGNNNNNNNNNNNNNNNNXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXttttttttttttttttccccccccccccccccaaaaaaaaaaaaaaaaggggggggggggggggnnnnnnnnnnnnnnnnxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"             # <<<<<<<<<<<<<<
+ * NIB_I2C_TABLE_SECOND = "TCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxx"
+ * 
+ */
+  __pyx_v_2bx_3seq_4_nib_NIB_I2C_TABLE_FIRST = __pyx_k_1;
+
+  /* "bx/seq/_nib.pyx":13
+ * #NIB_I2C_TABLE        = "TCAGNXXXtcagnxxx"
+ * NIB_I2C_TABLE_FIRST  = "TTTTTTTTTTTTTTTTCCCCCCCCCCCCCCCCAAAAAAAAAAAAAAAAGGGGGGGGGGGGGGGGNNNNNNNNNNNNNNNNXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXttttttttttttttttccccccccccccccccaaaaaaaaaaaaaaaaggggggggggggggggnnnnnnnnnnnnnnnnxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ * NIB_I2C_TABLE_SECOND = "TCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxx"             # <<<<<<<<<<<<<<
+ * 
+ * def translate_raw_data( data, int start, int length ):
+ */
+  __pyx_v_2bx_3seq_4_nib_NIB_I2C_TABLE_SECOND = __pyx_k_2;
+
+  /* "bx/seq/_nib.pyx":15
+ * NIB_I2C_TABLE_SECOND = "TCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxx"
+ * 
+ * def translate_raw_data( data, int start, int length ):             # <<<<<<<<<<<<<<
+ *     """
+ *     Data is a block read from the file that needs to be unpacked, dealing
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_2bx_3seq_4_nib_1translate_raw_data, NULL, __pyx_n_s_6); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 15; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s__translate_raw_data, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 15; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "bx/seq/_nib.pyx":1
+ * cdef extern from "Python.h":             # <<<<<<<<<<<<<<
+ *     char * PyString_AsString( object )
+ *     object PyString_FromStringAndSize( char *, int )
+ */
+  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(((PyObject *)__pyx_t_1));
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s____test__, ((PyObject *)__pyx_t_1)) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  if (__pyx_m) {
+    __Pyx_AddTraceback("init bx.seq._nib", __pyx_clineno, __pyx_lineno, __pyx_filename);
+    Py_DECREF(__pyx_m); __pyx_m = 0;
+  } else if (!PyErr_Occurred()) {
+    PyErr_SetString(PyExc_ImportError, "init bx.seq._nib");
+  }
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  #if PY_MAJOR_VERSION < 3
+  return;
+  #else
+  return __pyx_m;
+  #endif
+}
+
+/* Runtime support code */
+#if CYTHON_REFNANNY
+static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) {
+    PyObject *m = NULL, *p = NULL;
+    void *r = NULL;
+    m = PyImport_ImportModule((char *)modname);
+    if (!m) goto end;
+    p = PyObject_GetAttrString(m, (char *)"RefNannyAPI");
+    if (!p) goto end;
+    r = PyLong_AsVoidPtr(p);
+end:
+    Py_XDECREF(p);
+    Py_XDECREF(m);
+    return (__Pyx_RefNannyAPIStruct *)r;
+}
+#endif /* CYTHON_REFNANNY */
+
+static void __Pyx_RaiseArgtupleInvalid(
+    const char* func_name,
+    int exact,
+    Py_ssize_t num_min,
+    Py_ssize_t num_max,
+    Py_ssize_t num_found)
+{
+    Py_ssize_t num_expected;
+    const char *more_or_less;
+    if (num_found < num_min) {
+        num_expected = num_min;
+        more_or_less = "at least";
+    } else {
+        num_expected = num_max;
+        more_or_less = "at most";
+    }
+    if (exact) {
+        more_or_less = "exactly";
+    }
+    PyErr_Format(PyExc_TypeError,
+                 "%s() takes %s %" CYTHON_FORMAT_SSIZE_T "d positional argument%s (%" CYTHON_FORMAT_SSIZE_T "d given)",
+                 func_name, more_or_less, num_expected,
+                 (num_expected == 1) ? "" : "s", num_found);
+}
+
+static void __Pyx_RaiseDoubleKeywordsError(
+    const char* func_name,
+    PyObject* kw_name)
+{
+    PyErr_Format(PyExc_TypeError,
+        #if PY_MAJOR_VERSION >= 3
+        "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
+        #else
+        "%s() got multiple values for keyword argument '%s'", func_name,
+        PyString_AsString(kw_name));
+        #endif
+}
+
+static int __Pyx_ParseOptionalKeywords(
+    PyObject *kwds,
+    PyObject **argnames[],
+    PyObject *kwds2,
+    PyObject *values[],
+    Py_ssize_t num_pos_args,
+    const char* function_name)
+{
+    PyObject *key = 0, *value = 0;
+    Py_ssize_t pos = 0;
+    PyObject*** name;
+    PyObject*** first_kw_arg = argnames + num_pos_args;
+    while (PyDict_Next(kwds, &pos, &key, &value)) {
+        name = first_kw_arg;
+        while (*name && (**name != key)) name++;
+        if (*name) {
+            values[name-argnames] = value;
+            continue;
+        }
+        name = first_kw_arg;
+        #if PY_MAJOR_VERSION < 3
+        if (likely(PyString_CheckExact(key)) || likely(PyString_Check(key))) {
+            while (*name) {
+                if ((CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**name) == PyString_GET_SIZE(key))
+                        && _PyString_Eq(**name, key)) {
+                    values[name-argnames] = value;
+                    break;
+                }
+                name++;
+            }
+            if (*name) continue;
+            else {
+                PyObject*** argname = argnames;
+                while (argname != first_kw_arg) {
+                    if ((**argname == key) || (
+                            (CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**argname) == PyString_GET_SIZE(key))
+                             && _PyString_Eq(**argname, key))) {
+                        goto arg_passed_twice;
+                    }
+                    argname++;
+                }
+            }
+        } else
+        #endif
+        if (likely(PyUnicode_Check(key))) {
+            while (*name) {
+                int cmp = (**name == key) ? 0 :
+                #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3
+                    (PyUnicode_GET_SIZE(**name) != PyUnicode_GET_SIZE(key)) ? 1 :
+                #endif
+                    PyUnicode_Compare(**name, key);
+                if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad;
+                if (cmp == 0) {
+                    values[name-argnames] = value;
+                    break;
+                }
+                name++;
+            }
+            if (*name) continue;
+            else {
+                PyObject*** argname = argnames;
+                while (argname != first_kw_arg) {
+                    int cmp = (**argname == key) ? 0 :
+                    #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3
+                        (PyUnicode_GET_SIZE(**argname) != PyUnicode_GET_SIZE(key)) ? 1 :
+                    #endif
+                        PyUnicode_Compare(**argname, key);
+                    if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad;
+                    if (cmp == 0) goto arg_passed_twice;
+                    argname++;
+                }
+            }
+        } else
+            goto invalid_keyword_type;
+        if (kwds2) {
+            if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
+        } else {
+            goto invalid_keyword;
+        }
+    }
+    return 0;
+arg_passed_twice:
+    __Pyx_RaiseDoubleKeywordsError(function_name, key);
+    goto bad;
+invalid_keyword_type:
+    PyErr_Format(PyExc_TypeError,
+        "%s() keywords must be strings", function_name);
+    goto bad;
+invalid_keyword:
+    PyErr_Format(PyExc_TypeError,
+    #if PY_MAJOR_VERSION < 3
+        "%s() got an unexpected keyword argument '%s'",
+        function_name, PyString_AsString(key));
+    #else
+        "%s() got an unexpected keyword argument '%U'",
+        function_name, key);
+    #endif
+bad:
+    return -1;
+}
+
+static CYTHON_INLINE long __Pyx_div_long(long a, long b) {
+    long q = a / b;
+    long r = a - q*b;
+    q -= ((r != 0) & ((r ^ b) < 0));
+    return q;
+}
+
+static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level) {
+    PyObject *empty_list = 0;
+    PyObject *module = 0;
+    PyObject *global_dict = 0;
+    PyObject *empty_dict = 0;
+    PyObject *list;
+    #if PY_VERSION_HEX < 0x03030000
+    PyObject *py_import = 0;
+    py_import = __Pyx_GetAttrString(__pyx_b, "__import__");
+    if (!py_import)
+        goto bad;
+    #endif
+    if (from_list)
+        list = from_list;
+    else {
+        empty_list = PyList_New(0);
+        if (!empty_list)
+            goto bad;
+        list = empty_list;
+    }
+    global_dict = PyModule_GetDict(__pyx_m);
+    if (!global_dict)
+        goto bad;
+    empty_dict = PyDict_New();
+    if (!empty_dict)
+        goto bad;
+    #if PY_VERSION_HEX >= 0x02050000
+    {
+        #if PY_MAJOR_VERSION >= 3
+        if (level == -1) {
+            if (strchr(__Pyx_MODULE_NAME, '.')) {
+                #if PY_VERSION_HEX < 0x03030000
+                PyObject *py_level = PyInt_FromLong(1);
+                if (!py_level)
+                    goto bad;
+                module = PyObject_CallFunctionObjArgs(py_import,
+                    name, global_dict, empty_dict, list, py_level, NULL);
+                Py_DECREF(py_level);
+                #else
+                module = PyImport_ImportModuleLevelObject(
+                    name, global_dict, empty_dict, list, 1);
+                #endif
+                if (!module) {
+                    if (!PyErr_ExceptionMatches(PyExc_ImportError))
+                        goto bad;
+                    PyErr_Clear();
+                }
+            }
+            level = 0; /* try absolute import on failure */
+        }
+        #endif
+        if (!module) {
+            #if PY_VERSION_HEX < 0x03030000
+            PyObject *py_level = PyInt_FromLong(level);
+            if (!py_level)
+                goto bad;
+            module = PyObject_CallFunctionObjArgs(py_import,
+                name, global_dict, empty_dict, list, py_level, NULL);
+            Py_DECREF(py_level);
+            #else
+            module = PyImport_ImportModuleLevelObject(
+                name, global_dict, empty_dict, list, level);
+            #endif
+        }
+    }
+    #else
+    if (level>0) {
+        PyErr_SetString(PyExc_RuntimeError, "Relative import is not supported for Python <=2.4.");
+        goto bad;
+    }
+    module = PyObject_CallFunctionObjArgs(py_import,
+        name, global_dict, empty_dict, list, NULL);
+    #endif
+bad:
+    #if PY_VERSION_HEX < 0x03030000
+    Py_XDECREF(py_import);
+    #endif
+    Py_XDECREF(empty_list);
+    Py_XDECREF(empty_dict);
+    return module;
+}
+
+static CYTHON_INLINE unsigned char __Pyx_PyInt_AsUnsignedChar(PyObject* x) {
+    const unsigned char neg_one = (unsigned char)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(unsigned char) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(unsigned char)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to unsigned char" :
+                    "value too large to convert to unsigned char");
+            }
+            return (unsigned char)-1;
+        }
+        return (unsigned char)val;
+    }
+    return (unsigned char)__Pyx_PyInt_AsUnsignedLong(x);
+}
+
+static CYTHON_INLINE unsigned short __Pyx_PyInt_AsUnsignedShort(PyObject* x) {
+    const unsigned short neg_one = (unsigned short)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(unsigned short) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(unsigned short)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to unsigned short" :
+                    "value too large to convert to unsigned short");
+            }
+            return (unsigned short)-1;
+        }
+        return (unsigned short)val;
+    }
+    return (unsigned short)__Pyx_PyInt_AsUnsignedLong(x);
+}
+
+static CYTHON_INLINE unsigned int __Pyx_PyInt_AsUnsignedInt(PyObject* x) {
+    const unsigned int neg_one = (unsigned int)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(unsigned int) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(unsigned int)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to unsigned int" :
+                    "value too large to convert to unsigned int");
+            }
+            return (unsigned int)-1;
+        }
+        return (unsigned int)val;
+    }
+    return (unsigned int)__Pyx_PyInt_AsUnsignedLong(x);
+}
+
+static CYTHON_INLINE char __Pyx_PyInt_AsChar(PyObject* x) {
+    const char neg_one = (char)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(char) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(char)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to char" :
+                    "value too large to convert to char");
+            }
+            return (char)-1;
+        }
+        return (char)val;
+    }
+    return (char)__Pyx_PyInt_AsLong(x);
+}
+
+static CYTHON_INLINE short __Pyx_PyInt_AsShort(PyObject* x) {
+    const short neg_one = (short)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(short) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(short)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to short" :
+                    "value too large to convert to short");
+            }
+            return (short)-1;
+        }
+        return (short)val;
+    }
+    return (short)__Pyx_PyInt_AsLong(x);
+}
+
+static CYTHON_INLINE int __Pyx_PyInt_AsInt(PyObject* x) {
+    const int neg_one = (int)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(int) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(int)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to int" :
+                    "value too large to convert to int");
+            }
+            return (int)-1;
+        }
+        return (int)val;
+    }
+    return (int)__Pyx_PyInt_AsLong(x);
+}
+
+static CYTHON_INLINE signed char __Pyx_PyInt_AsSignedChar(PyObject* x) {
+    const signed char neg_one = (signed char)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(signed char) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(signed char)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to signed char" :
+                    "value too large to convert to signed char");
+            }
+            return (signed char)-1;
+        }
+        return (signed char)val;
+    }
+    return (signed char)__Pyx_PyInt_AsSignedLong(x);
+}
+
+static CYTHON_INLINE signed short __Pyx_PyInt_AsSignedShort(PyObject* x) {
+    const signed short neg_one = (signed short)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(signed short) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(signed short)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to signed short" :
+                    "value too large to convert to signed short");
+            }
+            return (signed short)-1;
+        }
+        return (signed short)val;
+    }
+    return (signed short)__Pyx_PyInt_AsSignedLong(x);
+}
+
+static CYTHON_INLINE signed int __Pyx_PyInt_AsSignedInt(PyObject* x) {
+    const signed int neg_one = (signed int)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(signed int) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(signed int)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to signed int" :
+                    "value too large to convert to signed int");
+            }
+            return (signed int)-1;
+        }
+        return (signed int)val;
+    }
+    return (signed int)__Pyx_PyInt_AsSignedLong(x);
+}
+
+static CYTHON_INLINE int __Pyx_PyInt_AsLongDouble(PyObject* x) {
+    const int neg_one = (int)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(int) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(int)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to int" :
+                    "value too large to convert to int");
+            }
+            return (int)-1;
+        }
+        return (int)val;
+    }
+    return (int)__Pyx_PyInt_AsLong(x);
+}
+
+static CYTHON_INLINE unsigned long __Pyx_PyInt_AsUnsignedLong(PyObject* x) {
+    const unsigned long neg_one = (unsigned long)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to unsigned long");
+            return (unsigned long)-1;
+        }
+        return (unsigned long)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to unsigned long");
+                return (unsigned long)-1;
+            }
+            return (unsigned long)PyLong_AsUnsignedLong(x);
+        } else {
+            return (unsigned long)PyLong_AsLong(x);
+        }
+    } else {
+        unsigned long val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (unsigned long)-1;
+        val = __Pyx_PyInt_AsUnsignedLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE unsigned PY_LONG_LONG __Pyx_PyInt_AsUnsignedLongLong(PyObject* x) {
+    const unsigned PY_LONG_LONG neg_one = (unsigned PY_LONG_LONG)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to unsigned PY_LONG_LONG");
+            return (unsigned PY_LONG_LONG)-1;
+        }
+        return (unsigned PY_LONG_LONG)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to unsigned PY_LONG_LONG");
+                return (unsigned PY_LONG_LONG)-1;
+            }
+            return (unsigned PY_LONG_LONG)PyLong_AsUnsignedLongLong(x);
+        } else {
+            return (unsigned PY_LONG_LONG)PyLong_AsLongLong(x);
+        }
+    } else {
+        unsigned PY_LONG_LONG val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (unsigned PY_LONG_LONG)-1;
+        val = __Pyx_PyInt_AsUnsignedLongLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE long __Pyx_PyInt_AsLong(PyObject* x) {
+    const long neg_one = (long)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to long");
+            return (long)-1;
+        }
+        return (long)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to long");
+                return (long)-1;
+            }
+            return (long)PyLong_AsUnsignedLong(x);
+        } else {
+            return (long)PyLong_AsLong(x);
+        }
+    } else {
+        long val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (long)-1;
+        val = __Pyx_PyInt_AsLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE PY_LONG_LONG __Pyx_PyInt_AsLongLong(PyObject* x) {
+    const PY_LONG_LONG neg_one = (PY_LONG_LONG)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to PY_LONG_LONG");
+            return (PY_LONG_LONG)-1;
+        }
+        return (PY_LONG_LONG)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to PY_LONG_LONG");
+                return (PY_LONG_LONG)-1;
+            }
+            return (PY_LONG_LONG)PyLong_AsUnsignedLongLong(x);
+        } else {
+            return (PY_LONG_LONG)PyLong_AsLongLong(x);
+        }
+    } else {
+        PY_LONG_LONG val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (PY_LONG_LONG)-1;
+        val = __Pyx_PyInt_AsLongLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE signed long __Pyx_PyInt_AsSignedLong(PyObject* x) {
+    const signed long neg_one = (signed long)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to signed long");
+            return (signed long)-1;
+        }
+        return (signed long)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to signed long");
+                return (signed long)-1;
+            }
+            return (signed long)PyLong_AsUnsignedLong(x);
+        } else {
+            return (signed long)PyLong_AsLong(x);
+        }
+    } else {
+        signed long val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (signed long)-1;
+        val = __Pyx_PyInt_AsSignedLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE signed PY_LONG_LONG __Pyx_PyInt_AsSignedLongLong(PyObject* x) {
+    const signed PY_LONG_LONG neg_one = (signed PY_LONG_LONG)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to signed PY_LONG_LONG");
+            return (signed PY_LONG_LONG)-1;
+        }
+        return (signed PY_LONG_LONG)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to signed PY_LONG_LONG");
+                return (signed PY_LONG_LONG)-1;
+            }
+            return (signed PY_LONG_LONG)PyLong_AsUnsignedLongLong(x);
+        } else {
+            return (signed PY_LONG_LONG)PyLong_AsLongLong(x);
+        }
+    } else {
+        signed PY_LONG_LONG val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (signed PY_LONG_LONG)-1;
+        val = __Pyx_PyInt_AsSignedLongLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static int __Pyx_check_binary_version(void) {
+    char ctversion[4], rtversion[4];
+    PyOS_snprintf(ctversion, 4, "%d.%d", PY_MAJOR_VERSION, PY_MINOR_VERSION);
+    PyOS_snprintf(rtversion, 4, "%s", Py_GetVersion());
+    if (ctversion[0] != rtversion[0] || ctversion[2] != rtversion[2]) {
+        char message[200];
+        PyOS_snprintf(message, sizeof(message),
+                      "compiletime version %s of module '%.100s' "
+                      "does not match runtime version %s",
+                      ctversion, __Pyx_MODULE_NAME, rtversion);
+        #if PY_VERSION_HEX < 0x02050000
+        return PyErr_Warn(NULL, message);
+        #else
+        return PyErr_WarnEx(NULL, message, 1);
+        #endif
+    }
+    return 0;
+}
+
+static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) {
+    int start = 0, mid = 0, end = count - 1;
+    if (end >= 0 && code_line > entries[end].code_line) {
+        return count;
+    }
+    while (start < end) {
+        mid = (start + end) / 2;
+        if (code_line < entries[mid].code_line) {
+            end = mid;
+        } else if (code_line > entries[mid].code_line) {
+             start = mid + 1;
+        } else {
+            return mid;
+        }
+    }
+    if (code_line <= entries[mid].code_line) {
+        return mid;
+    } else {
+        return mid + 1;
+    }
+}
+static PyCodeObject *__pyx_find_code_object(int code_line) {
+    PyCodeObject* code_object;
+    int pos;
+    if (unlikely(!code_line) || unlikely(!__pyx_code_cache.entries)) {
+        return NULL;
+    }
+    pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line);
+    if (unlikely(pos >= __pyx_code_cache.count) || unlikely(__pyx_code_cache.entries[pos].code_line != code_line)) {
+        return NULL;
+    }
+    code_object = __pyx_code_cache.entries[pos].code_object;
+    Py_INCREF(code_object);
+    return code_object;
+}
+static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) {
+    int pos, i;
+    __Pyx_CodeObjectCacheEntry* entries = __pyx_code_cache.entries;
+    if (unlikely(!code_line)) {
+        return;
+    }
+    if (unlikely(!entries)) {
+        entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Malloc(64*sizeof(__Pyx_CodeObjectCacheEntry));
+        if (likely(entries)) {
+            __pyx_code_cache.entries = entries;
+            __pyx_code_cache.max_count = 64;
+            __pyx_code_cache.count = 1;
+            entries[0].code_line = code_line;
+            entries[0].code_object = code_object;
+            Py_INCREF(code_object);
+        }
+        return;
+    }
+    pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line);
+    if ((pos < __pyx_code_cache.count) && unlikely(__pyx_code_cache.entries[pos].code_line == code_line)) {
+        PyCodeObject* tmp = entries[pos].code_object;
+        entries[pos].code_object = code_object;
+        Py_DECREF(tmp);
+        return;
+    }
+    if (__pyx_code_cache.count == __pyx_code_cache.max_count) {
+        int new_max = __pyx_code_cache.max_count + 64;
+        entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Realloc(
+            __pyx_code_cache.entries, new_max*sizeof(__Pyx_CodeObjectCacheEntry));
+        if (unlikely(!entries)) {
+            return;
+        }
+        __pyx_code_cache.entries = entries;
+        __pyx_code_cache.max_count = new_max;
+    }
+    for (i=__pyx_code_cache.count; i>pos; i--) {
+        entries[i] = entries[i-1];
+    }
+    entries[pos].code_line = code_line;
+    entries[pos].code_object = code_object;
+    __pyx_code_cache.count++;
+    Py_INCREF(code_object);
+}
+
+#include "compile.h"
+#include "frameobject.h"
+#include "traceback.h"
+static PyCodeObject* __Pyx_CreateCodeObjectForTraceback(
+            const char *funcname, int c_line,
+            int py_line, const char *filename) {
+    PyCodeObject *py_code = 0;
+    PyObject *py_srcfile = 0;
+    PyObject *py_funcname = 0;
+    #if PY_MAJOR_VERSION < 3
+    py_srcfile = PyString_FromString(filename);
+    #else
+    py_srcfile = PyUnicode_FromString(filename);
+    #endif
+    if (!py_srcfile) goto bad;
+    if (c_line) {
+        #if PY_MAJOR_VERSION < 3
+        py_funcname = PyString_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line);
+        #else
+        py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line);
+        #endif
+    }
+    else {
+        #if PY_MAJOR_VERSION < 3
+        py_funcname = PyString_FromString(funcname);
+        #else
+        py_funcname = PyUnicode_FromString(funcname);
+        #endif
+    }
+    if (!py_funcname) goto bad;
+    py_code = __Pyx_PyCode_New(
+        0,            /*int argcount,*/
+        0,            /*int kwonlyargcount,*/
+        0,            /*int nlocals,*/
+        0,            /*int stacksize,*/
+        0,            /*int flags,*/
+        __pyx_empty_bytes, /*PyObject *code,*/
+        __pyx_empty_tuple, /*PyObject *consts,*/
+        __pyx_empty_tuple, /*PyObject *names,*/
+        __pyx_empty_tuple, /*PyObject *varnames,*/
+        __pyx_empty_tuple, /*PyObject *freevars,*/
+        __pyx_empty_tuple, /*PyObject *cellvars,*/
+        py_srcfile,   /*PyObject *filename,*/
+        py_funcname,  /*PyObject *name,*/
+        py_line,      /*int firstlineno,*/
+        __pyx_empty_bytes  /*PyObject *lnotab*/
+    );
+    Py_DECREF(py_srcfile);
+    Py_DECREF(py_funcname);
+    return py_code;
+bad:
+    Py_XDECREF(py_srcfile);
+    Py_XDECREF(py_funcname);
+    return NULL;
+}
+static void __Pyx_AddTraceback(const char *funcname, int c_line,
+                               int py_line, const char *filename) {
+    PyCodeObject *py_code = 0;
+    PyObject *py_globals = 0;
+    PyFrameObject *py_frame = 0;
+    py_code = __pyx_find_code_object(c_line ? c_line : py_line);
+    if (!py_code) {
+        py_code = __Pyx_CreateCodeObjectForTraceback(
+            funcname, c_line, py_line, filename);
+        if (!py_code) goto bad;
+        __pyx_insert_code_object(c_line ? c_line : py_line, py_code);
+    }
+    py_globals = PyModule_GetDict(__pyx_m);
+    if (!py_globals) goto bad;
+    py_frame = PyFrame_New(
+        PyThreadState_GET(), /*PyThreadState *tstate,*/
+        py_code,             /*PyCodeObject *code,*/
+        py_globals,          /*PyObject *globals,*/
+        0                    /*PyObject *locals*/
+    );
+    if (!py_frame) goto bad;
+    py_frame->f_lineno = py_line;
+    PyTraceBack_Here(py_frame);
+bad:
+    Py_XDECREF(py_code);
+    Py_XDECREF(py_frame);
+}
+
+static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
+    while (t->p) {
+        #if PY_MAJOR_VERSION < 3
+        if (t->is_unicode) {
+            *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
+        } else if (t->intern) {
+            *t->p = PyString_InternFromString(t->s);
+        } else {
+            *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
+        }
+        #else  /* Python 3+ has unicode identifiers */
+        if (t->is_unicode | t->is_str) {
+            if (t->intern) {
+                *t->p = PyUnicode_InternFromString(t->s);
+            } else if (t->encoding) {
+                *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL);
+            } else {
+                *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
+            }
+        } else {
+            *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
+        }
+        #endif
+        if (!*t->p)
+            return -1;
+        ++t;
+    }
+    return 0;
+}
+
+static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) {
+   int is_true = x == Py_True;
+   if (is_true | (x == Py_False) | (x == Py_None)) return is_true;
+   else return PyObject_IsTrue(x);
+}
+static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x) {
+  PyNumberMethods *m;
+  const char *name = NULL;
+  PyObject *res = NULL;
+#if PY_VERSION_HEX < 0x03000000
+  if (PyInt_Check(x) || PyLong_Check(x))
+#else
+  if (PyLong_Check(x))
+#endif
+    return Py_INCREF(x), x;
+  m = Py_TYPE(x)->tp_as_number;
+#if PY_VERSION_HEX < 0x03000000
+  if (m && m->nb_int) {
+    name = "int";
+    res = PyNumber_Int(x);
+  }
+  else if (m && m->nb_long) {
+    name = "long";
+    res = PyNumber_Long(x);
+  }
+#else
+  if (m && m->nb_int) {
+    name = "int";
+    res = PyNumber_Long(x);
+  }
+#endif
+  if (res) {
+#if PY_VERSION_HEX < 0x03000000
+    if (!PyInt_Check(res) && !PyLong_Check(res)) {
+#else
+    if (!PyLong_Check(res)) {
+#endif
+      PyErr_Format(PyExc_TypeError,
+                   "__%s__ returned non-%s (type %.200s)",
+                   name, name, Py_TYPE(res)->tp_name);
+      Py_DECREF(res);
+      return NULL;
+    }
+  }
+  else if (!PyErr_Occurred()) {
+    PyErr_SetString(PyExc_TypeError,
+                    "an integer is required");
+  }
+  return res;
+}
+static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) {
+  Py_ssize_t ival;
+  PyObject* x = PyNumber_Index(b);
+  if (!x) return -1;
+  ival = PyInt_AsSsize_t(x);
+  Py_DECREF(x);
+  return ival;
+}
+static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) {
+#if PY_VERSION_HEX < 0x02050000
+   if (ival <= LONG_MAX)
+       return PyInt_FromLong((long)ival);
+   else {
+       unsigned char *bytes = (unsigned char *) &ival;
+       int one = 1; int little = (int)*(unsigned char*)&one;
+       return _PyLong_FromByteArray(bytes, sizeof(size_t), little, 0);
+   }
+#else
+   return PyInt_FromSize_t(ival);
+#endif
+}
+static CYTHON_INLINE size_t __Pyx_PyInt_AsSize_t(PyObject* x) {
+   unsigned PY_LONG_LONG val = __Pyx_PyInt_AsUnsignedLongLong(x);
+   if (unlikely(val == (unsigned PY_LONG_LONG)-1 && PyErr_Occurred())) {
+       return (size_t)-1;
+   } else if (unlikely(val != (unsigned PY_LONG_LONG)(size_t)val)) {
+       PyErr_SetString(PyExc_OverflowError,
+                       "value too large to convert to size_t");
+       return (size_t)-1;
+   }
+   return (size_t)val;
+}
+
+
+#endif /* Py_PYTHON_H */
diff --git a/lib/bx/seq/_nib.pyx b/lib/bx/seq/_nib.pyx
new file mode 100644
index 0000000..166b0b8
--- /dev/null
+++ b/lib/bx/seq/_nib.pyx
@@ -0,0 +1,46 @@
+cdef extern from "Python.h":
+    char * PyString_AsString( object )
+    object PyString_FromStringAndSize( char *, int )
+    int _PyString_Resize( object, int ) except -1
+
+import struct, sys
+
+cdef char * NIB_I2C_TABLE 
+cdef char * NIB_I2C_TABLE_FIRST 
+cdef char * NIB_I2C_TABLE_SECOND
+#NIB_I2C_TABLE        = "TCAGNXXXtcagnxxx"
+NIB_I2C_TABLE_FIRST  = "TTTTTTTTTTTTTTTTCCCCCCCCCCCCCCCCAAAAAAAAAAAAAAAAGGGGGGGGGGGGGGGGNNNNNNNNNNNNNNNNXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXttttttttttttttttccccccccccccccccaaaaaaaaaaaaaaaaggggggggggggggggnnnnnnnnnnnnnnnnxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+NIB_I2C_TABLE_SECOND = "TCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxxTCAGNXXXtcagnxxx"
+
+def translate_raw_data( data, int start, int length ):
+    """
+    Data is a block read from the file that needs to be unpacked, dealing
+    with end conditions based on start/length.
+    """
+    cdef int i, j
+    cdef char * p_rval
+    cdef unsigned char * p_data
+    # Allocate string to write into
+    rval = PyString_FromStringAndSize( NULL, length ) 
+    # Get char pointer access to strings
+    p_rval = PyString_AsString( rval )
+    p_data = <unsigned char *> PyString_AsString( data )
+    i = 0
+    # Odd start
+    if start & 1: 
+        #p_rval[i] = NIB_I2C_TABLE[ p_data[0] & 0xF ]
+        p_rval[i] = NIB_I2C_TABLE_SECOND[ p_data[0] ]
+        p_data = p_data + 1
+        i = 1
+    # Two output values for each input value
+    for j from 0 <= j < (length-i)/2:
+        #p_rval[i]   = NIB_I2C_TABLE[ ( p_data[0] >> 4 ) & 0xF ];
+        #p_rval[i+1] = NIB_I2C_TABLE[ ( p_data[0] >> 0 ) & 0xF ];
+        p_rval[i]   = NIB_I2C_TABLE_FIRST [ p_data[0] ]
+        p_rval[i+1] = NIB_I2C_TABLE_SECOND[ p_data[0] ]
+        i = i + 2
+        p_data = p_data + 1
+    # Odd end
+    if i < length: 
+        p_rval[i] = NIB_I2C_TABLE_FIRST[ p_data[0] ]
+    return rval
diff --git a/lib/bx/seq/_twobit.c b/lib/bx/seq/_twobit.c
new file mode 100644
index 0000000..204373d
--- /dev/null
+++ b/lib/bx/seq/_twobit.c
@@ -0,0 +1,3010 @@
+/* Generated by Cython 0.18 on Mon Jul 15 13:25:44 2013 */
+
+#define PY_SSIZE_T_CLEAN
+#include "Python.h"
+#ifndef Py_PYTHON_H
+    #error Python headers needed to compile C extensions, please install development version of Python.
+#elif PY_VERSION_HEX < 0x02040000
+    #error Cython requires Python 2.4+.
+#else
+#include <stddef.h> /* For offsetof */
+#ifndef offsetof
+#define offsetof(type, member) ( (size_t) & ((type*)0) -> member )
+#endif
+#if !defined(WIN32) && !defined(MS_WINDOWS)
+  #ifndef __stdcall
+    #define __stdcall
+  #endif
+  #ifndef __cdecl
+    #define __cdecl
+  #endif
+  #ifndef __fastcall
+    #define __fastcall
+  #endif
+#endif
+#ifndef DL_IMPORT
+  #define DL_IMPORT(t) t
+#endif
+#ifndef DL_EXPORT
+  #define DL_EXPORT(t) t
+#endif
+#ifndef PY_LONG_LONG
+  #define PY_LONG_LONG LONG_LONG
+#endif
+#ifndef Py_HUGE_VAL
+  #define Py_HUGE_VAL HUGE_VAL
+#endif
+#ifdef PYPY_VERSION
+#define CYTHON_COMPILING_IN_PYPY 1
+#define CYTHON_COMPILING_IN_CPYTHON 0
+#else
+#define CYTHON_COMPILING_IN_PYPY 0
+#define CYTHON_COMPILING_IN_CPYTHON 1
+#endif
+#if PY_VERSION_HEX < 0x02050000
+  typedef int Py_ssize_t;
+  #define PY_SSIZE_T_MAX INT_MAX
+  #define PY_SSIZE_T_MIN INT_MIN
+  #define PY_FORMAT_SIZE_T ""
+  #define CYTHON_FORMAT_SSIZE_T ""
+  #define PyInt_FromSsize_t(z) PyInt_FromLong(z)
+  #define PyInt_AsSsize_t(o)   __Pyx_PyInt_AsInt(o)
+  #define PyNumber_Index(o)    ((PyNumber_Check(o) && !PyFloat_Check(o)) ? PyNumber_Int(o) : \
+                                (PyErr_Format(PyExc_TypeError, \
+                                              "expected index value, got %.200s", Py_TYPE(o)->tp_name), \
+                                 (PyObject*)0))
+  #define __Pyx_PyIndex_Check(o) (PyNumber_Check(o) && !PyFloat_Check(o) && \
+                                  !PyComplex_Check(o))
+  #define PyIndex_Check __Pyx_PyIndex_Check
+  #define PyErr_WarnEx(category, message, stacklevel) PyErr_Warn(category, message)
+  #define __PYX_BUILD_PY_SSIZE_T "i"
+#else
+  #define __PYX_BUILD_PY_SSIZE_T "n"
+  #define CYTHON_FORMAT_SSIZE_T "z"
+  #define __Pyx_PyIndex_Check PyIndex_Check
+#endif
+#if PY_VERSION_HEX < 0x02060000
+  #define Py_REFCNT(ob) (((PyObject*)(ob))->ob_refcnt)
+  #define Py_TYPE(ob)   (((PyObject*)(ob))->ob_type)
+  #define Py_SIZE(ob)   (((PyVarObject*)(ob))->ob_size)
+  #define PyVarObject_HEAD_INIT(type, size) \
+          PyObject_HEAD_INIT(type) size,
+  #define PyType_Modified(t)
+  typedef struct {
+     void *buf;
+     PyObject *obj;
+     Py_ssize_t len;
+     Py_ssize_t itemsize;
+     int readonly;
+     int ndim;
+     char *format;
+     Py_ssize_t *shape;
+     Py_ssize_t *strides;
+     Py_ssize_t *suboffsets;
+     void *internal;
+  } Py_buffer;
+  #define PyBUF_SIMPLE 0
+  #define PyBUF_WRITABLE 0x0001
+  #define PyBUF_FORMAT 0x0004
+  #define PyBUF_ND 0x0008
+  #define PyBUF_STRIDES (0x0010 | PyBUF_ND)
+  #define PyBUF_C_CONTIGUOUS (0x0020 | PyBUF_STRIDES)
+  #define PyBUF_F_CONTIGUOUS (0x0040 | PyBUF_STRIDES)
+  #define PyBUF_ANY_CONTIGUOUS (0x0080 | PyBUF_STRIDES)
+  #define PyBUF_INDIRECT (0x0100 | PyBUF_STRIDES)
+  #define PyBUF_RECORDS (PyBUF_STRIDES | PyBUF_FORMAT | PyBUF_WRITABLE)
+  #define PyBUF_FULL (PyBUF_INDIRECT | PyBUF_FORMAT | PyBUF_WRITABLE)
+  typedef int (*getbufferproc)(PyObject *, Py_buffer *, int);
+  typedef void (*releasebufferproc)(PyObject *, Py_buffer *);
+#endif
+#if PY_MAJOR_VERSION < 3
+  #define __Pyx_BUILTIN_MODULE_NAME "__builtin__"
+  #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \
+          PyCode_New(a, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
+#else
+  #define __Pyx_BUILTIN_MODULE_NAME "builtins"
+  #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \
+          PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
+#endif
+#if PY_MAJOR_VERSION < 3 && PY_MINOR_VERSION < 6
+  #define PyUnicode_FromString(s) PyUnicode_Decode(s, strlen(s), "UTF-8", "strict")
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define Py_TPFLAGS_CHECKTYPES 0
+  #define Py_TPFLAGS_HAVE_INDEX 0
+#endif
+#if (PY_VERSION_HEX < 0x02060000) || (PY_MAJOR_VERSION >= 3)
+  #define Py_TPFLAGS_HAVE_NEWBUFFER 0
+#endif
+#if PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND)
+  #define CYTHON_PEP393_ENABLED 1
+  #define __Pyx_PyUnicode_READY(op)       (likely(PyUnicode_IS_READY(op)) ? \
+                                              0 : _PyUnicode_Ready((PyObject *)(op)))
+  #define __Pyx_PyUnicode_GET_LENGTH(u)   PyUnicode_GET_LENGTH(u)
+  #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_READ_CHAR(u, i)
+  #define __Pyx_PyUnicode_READ(k, d, i)   PyUnicode_READ(k, d, i)
+#else
+  #define CYTHON_PEP393_ENABLED 0
+  #define __Pyx_PyUnicode_READY(op)       (0)
+  #define __Pyx_PyUnicode_GET_LENGTH(u)   PyUnicode_GET_SIZE(u)
+  #define __Pyx_PyUnicode_READ_CHAR(u, i) ((Py_UCS4)(PyUnicode_AS_UNICODE(u)[i]))
+  #define __Pyx_PyUnicode_READ(k, d, i)   ((k=k), (Py_UCS4)(((Py_UNICODE*)d)[i]))
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define PyBaseString_Type            PyUnicode_Type
+  #define PyStringObject               PyUnicodeObject
+  #define PyString_Type                PyUnicode_Type
+  #define PyString_Check               PyUnicode_Check
+  #define PyString_CheckExact          PyUnicode_CheckExact
+#endif
+#if PY_VERSION_HEX < 0x02060000
+  #define PyBytesObject                PyStringObject
+  #define PyBytes_Type                 PyString_Type
+  #define PyBytes_Check                PyString_Check
+  #define PyBytes_CheckExact           PyString_CheckExact
+  #define PyBytes_FromString           PyString_FromString
+  #define PyBytes_FromStringAndSize    PyString_FromStringAndSize
+  #define PyBytes_FromFormat           PyString_FromFormat
+  #define PyBytes_DecodeEscape         PyString_DecodeEscape
+  #define PyBytes_AsString             PyString_AsString
+  #define PyBytes_AsStringAndSize      PyString_AsStringAndSize
+  #define PyBytes_Size                 PyString_Size
+  #define PyBytes_AS_STRING            PyString_AS_STRING
+  #define PyBytes_GET_SIZE             PyString_GET_SIZE
+  #define PyBytes_Repr                 PyString_Repr
+  #define PyBytes_Concat               PyString_Concat
+  #define PyBytes_ConcatAndDel         PyString_ConcatAndDel
+#endif
+#if PY_VERSION_HEX < 0x02060000
+  #define PySet_Check(obj)             PyObject_TypeCheck(obj, &PySet_Type)
+  #define PyFrozenSet_Check(obj)       PyObject_TypeCheck(obj, &PyFrozenSet_Type)
+#endif
+#ifndef PySet_CheckExact
+  #define PySet_CheckExact(obj)        (Py_TYPE(obj) == &PySet_Type)
+#endif
+#define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type)
+#if PY_MAJOR_VERSION >= 3
+  #define PyIntObject                  PyLongObject
+  #define PyInt_Type                   PyLong_Type
+  #define PyInt_Check(op)              PyLong_Check(op)
+  #define PyInt_CheckExact(op)         PyLong_CheckExact(op)
+  #define PyInt_FromString             PyLong_FromString
+  #define PyInt_FromUnicode            PyLong_FromUnicode
+  #define PyInt_FromLong               PyLong_FromLong
+  #define PyInt_FromSize_t             PyLong_FromSize_t
+  #define PyInt_FromSsize_t            PyLong_FromSsize_t
+  #define PyInt_AsLong                 PyLong_AsLong
+  #define PyInt_AS_LONG                PyLong_AS_LONG
+  #define PyInt_AsSsize_t              PyLong_AsSsize_t
+  #define PyInt_AsUnsignedLongMask     PyLong_AsUnsignedLongMask
+  #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define PyBoolObject                 PyLongObject
+#endif
+#if PY_VERSION_HEX < 0x03020000
+  typedef long Py_hash_t;
+  #define __Pyx_PyInt_FromHash_t PyInt_FromLong
+  #define __Pyx_PyInt_AsHash_t   PyInt_AsLong
+#else
+  #define __Pyx_PyInt_FromHash_t PyInt_FromSsize_t
+  #define __Pyx_PyInt_AsHash_t   PyInt_AsSsize_t
+#endif
+#if (PY_MAJOR_VERSION < 3) || (PY_VERSION_HEX >= 0x03010300)
+  #define __Pyx_PySequence_GetSlice(obj, a, b) PySequence_GetSlice(obj, a, b)
+  #define __Pyx_PySequence_SetSlice(obj, a, b, value) PySequence_SetSlice(obj, a, b, value)
+  #define __Pyx_PySequence_DelSlice(obj, a, b) PySequence_DelSlice(obj, a, b)
+#else
+  #define __Pyx_PySequence_GetSlice(obj, a, b) (unlikely(!(obj)) ? \
+        (PyErr_SetString(PyExc_SystemError, "null argument to internal routine"), (PyObject*)0) : \
+        (likely((obj)->ob_type->tp_as_mapping) ? (PySequence_GetSlice(obj, a, b)) : \
+            (PyErr_Format(PyExc_TypeError, "'%.200s' object is unsliceable", (obj)->ob_type->tp_name), (PyObject*)0)))
+  #define __Pyx_PySequence_SetSlice(obj, a, b, value) (unlikely(!(obj)) ? \
+        (PyErr_SetString(PyExc_SystemError, "null argument to internal routine"), -1) : \
+        (likely((obj)->ob_type->tp_as_mapping) ? (PySequence_SetSlice(obj, a, b, value)) : \
+            (PyErr_Format(PyExc_TypeError, "'%.200s' object doesn't support slice assignment", (obj)->ob_type->tp_name), -1)))
+  #define __Pyx_PySequence_DelSlice(obj, a, b) (unlikely(!(obj)) ? \
+        (PyErr_SetString(PyExc_SystemError, "null argument to internal routine"), -1) : \
+        (likely((obj)->ob_type->tp_as_mapping) ? (PySequence_DelSlice(obj, a, b)) : \
+            (PyErr_Format(PyExc_TypeError, "'%.200s' object doesn't support slice deletion", (obj)->ob_type->tp_name), -1)))
+#endif
+#if PY_MAJOR_VERSION >= 3
+  #define PyMethod_New(func, self, klass) ((self) ? PyMethod_New(func, self) : PyInstanceMethod_New(func))
+#endif
+#if PY_VERSION_HEX < 0x02050000
+  #define __Pyx_GetAttrString(o,n)   PyObject_GetAttrString((o),((char *)(n)))
+  #define __Pyx_SetAttrString(o,n,a) PyObject_SetAttrString((o),((char *)(n)),(a))
+  #define __Pyx_DelAttrString(o,n)   PyObject_DelAttrString((o),((char *)(n)))
+#else
+  #define __Pyx_GetAttrString(o,n)   PyObject_GetAttrString((o),(n))
+  #define __Pyx_SetAttrString(o,n,a) PyObject_SetAttrString((o),(n),(a))
+  #define __Pyx_DelAttrString(o,n)   PyObject_DelAttrString((o),(n))
+#endif
+#if PY_VERSION_HEX < 0x02050000
+  #define __Pyx_NAMESTR(n) ((char *)(n))
+  #define __Pyx_DOCSTR(n)  ((char *)(n))
+#else
+  #define __Pyx_NAMESTR(n) (n)
+  #define __Pyx_DOCSTR(n)  (n)
+#endif
+
+
+#if PY_MAJOR_VERSION >= 3
+  #define __Pyx_PyNumber_Divide(x,y)         PyNumber_TrueDivide(x,y)
+  #define __Pyx_PyNumber_InPlaceDivide(x,y)  PyNumber_InPlaceTrueDivide(x,y)
+#else
+  #define __Pyx_PyNumber_Divide(x,y)         PyNumber_Divide(x,y)
+  #define __Pyx_PyNumber_InPlaceDivide(x,y)  PyNumber_InPlaceDivide(x,y)
+#endif
+
+#ifndef __PYX_EXTERN_C
+  #ifdef __cplusplus
+    #define __PYX_EXTERN_C extern "C"
+  #else
+    #define __PYX_EXTERN_C extern
+  #endif
+#endif
+
+#if defined(WIN32) || defined(MS_WINDOWS)
+#define _USE_MATH_DEFINES
+#endif
+#include <math.h>
+#define __PYX_HAVE__bx__seq___twobit
+#define __PYX_HAVE_API__bx__seq___twobit
+#include "ctype.h"
+#include "string.h"
+#ifdef _OPENMP
+#include <omp.h>
+#endif /* _OPENMP */
+
+#ifdef PYREX_WITHOUT_ASSERTIONS
+#define CYTHON_WITHOUT_ASSERTIONS
+#endif
+
+#ifndef CYTHON_INLINE
+  #if defined(__GNUC__)
+    #define CYTHON_INLINE __inline__
+  #elif defined(_MSC_VER)
+    #define CYTHON_INLINE __inline
+  #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+    #define CYTHON_INLINE inline
+  #else
+    #define CYTHON_INLINE
+  #endif
+#endif
+#ifndef CYTHON_UNUSED
+# if defined(__GNUC__)
+#   if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
+#     define CYTHON_UNUSED __attribute__ ((__unused__))
+#   else
+#     define CYTHON_UNUSED
+#   endif
+# elif defined(__ICC) || (defined(__INTEL_COMPILER) && !defined(_MSC_VER))
+#   define CYTHON_UNUSED __attribute__ ((__unused__))
+# else
+#   define CYTHON_UNUSED
+# endif
+#endif
+typedef struct {PyObject **p; char *s; const long n; const char* encoding; const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry; /*proto*/
+
+#define __Pyx_PyBytes_FromUString(s) PyBytes_FromString((char*)s)
+#define __Pyx_PyBytes_AsUString(s)   ((unsigned char*) PyBytes_AsString(s))
+#define __Pyx_Owned_Py_None(b) (Py_INCREF(Py_None), Py_None)
+#define __Pyx_PyBool_FromLong(b) ((b) ? (Py_INCREF(Py_True), Py_True) : (Py_INCREF(Py_False), Py_False))
+static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*);
+static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x);
+static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*);
+static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t);
+static CYTHON_INLINE size_t __Pyx_PyInt_AsSize_t(PyObject*);
+#if CYTHON_COMPILING_IN_CPYTHON
+#define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x))
+#else
+#define __pyx_PyFloat_AsDouble(x) PyFloat_AsDouble(x)
+#endif
+#define __pyx_PyFloat_AsFloat(x) ((float) __pyx_PyFloat_AsDouble(x))
+
+
+#ifdef __GNUC__
+  /* Test for GCC > 2.95 */
+  #if __GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))
+    #define likely(x)   __builtin_expect(!!(x), 1)
+    #define unlikely(x) __builtin_expect(!!(x), 0)
+  #else /* __GNUC__ > 2 ... */
+    #define likely(x)   (x)
+    #define unlikely(x) (x)
+  #endif /* __GNUC__ > 2 ... */
+#else /* __GNUC__ */
+  #define likely(x)   (x)
+  #define unlikely(x) (x)
+#endif /* __GNUC__ */
+    
+static PyObject *__pyx_m;
+static PyObject *__pyx_b;
+static PyObject *__pyx_empty_tuple;
+static PyObject *__pyx_empty_bytes;
+static int __pyx_lineno;
+static int __pyx_clineno = 0;
+static const char * __pyx_cfilenm= __FILE__;
+static const char *__pyx_filename;
+
+
+static const char *__pyx_f[] = {
+  "_twobit.pyx",
+};
+
+/*--- Type declarations ---*/
+#ifndef CYTHON_REFNANNY
+  #define CYTHON_REFNANNY 0
+#endif
+#if CYTHON_REFNANNY
+  typedef struct {
+    void (*INCREF)(void*, PyObject*, int);
+    void (*DECREF)(void*, PyObject*, int);
+    void (*GOTREF)(void*, PyObject*, int);
+    void (*GIVEREF)(void*, PyObject*, int);
+    void* (*SetupContext)(const char*, int, const char*);
+    void (*FinishContext)(void**);
+  } __Pyx_RefNannyAPIStruct;
+  static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL;
+  static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname); /*proto*/
+  #define __Pyx_RefNannyDeclarations void *__pyx_refnanny = NULL;
+#ifdef WITH_THREAD
+  #define __Pyx_RefNannySetupContext(name, acquire_gil) \
+          if (acquire_gil) { \
+              PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure(); \
+              __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__); \
+              PyGILState_Release(__pyx_gilstate_save); \
+          } else { \
+              __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__); \
+          }
+#else
+  #define __Pyx_RefNannySetupContext(name, acquire_gil) \
+          __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__)
+#endif
+  #define __Pyx_RefNannyFinishContext() \
+          __Pyx_RefNanny->FinishContext(&__pyx_refnanny)
+  #define __Pyx_INCREF(r)  __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_DECREF(r)  __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_GOTREF(r)  __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_XINCREF(r)  do { if((r) != NULL) {__Pyx_INCREF(r); }} while(0)
+  #define __Pyx_XDECREF(r)  do { if((r) != NULL) {__Pyx_DECREF(r); }} while(0)
+  #define __Pyx_XGOTREF(r)  do { if((r) != NULL) {__Pyx_GOTREF(r); }} while(0)
+  #define __Pyx_XGIVEREF(r) do { if((r) != NULL) {__Pyx_GIVEREF(r);}} while(0)
+#else
+  #define __Pyx_RefNannyDeclarations
+  #define __Pyx_RefNannySetupContext(name, acquire_gil)
+  #define __Pyx_RefNannyFinishContext()
+  #define __Pyx_INCREF(r) Py_INCREF(r)
+  #define __Pyx_DECREF(r) Py_DECREF(r)
+  #define __Pyx_GOTREF(r)
+  #define __Pyx_GIVEREF(r)
+  #define __Pyx_XINCREF(r) Py_XINCREF(r)
+  #define __Pyx_XDECREF(r) Py_XDECREF(r)
+  #define __Pyx_XGOTREF(r)
+  #define __Pyx_XGIVEREF(r)
+#endif /* CYTHON_REFNANNY */
+#define __Pyx_CLEAR(r)    do { PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);} while(0)
+#define __Pyx_XCLEAR(r)   do { if((r) != NULL) {PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);}} while(0)
+
+static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
+    Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/
+
+static void __Pyx_RaiseDoubleKeywordsError(const char* func_name, PyObject* kw_name); /*proto*/
+
+static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
+    PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
+    const char* function_name); /*proto*/
+
+static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/
+
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j) {
+    PyObject *r;
+    if (!j) return NULL;
+    r = PyObject_GetItem(o, j);
+    Py_DECREF(j);
+    return r;
+}
+#define __Pyx_GetItemInt_List(o, i, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \
+                                                    __Pyx_GetItemInt_List_Fast(o, i) : \
+                                                    __Pyx_GetItemInt_Generic(o, to_py_func(i)))
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    if (likely((0 <= i) & (i < PyList_GET_SIZE(o)))) {
+        PyObject *r = PyList_GET_ITEM(o, i);
+        Py_INCREF(r);
+        return r;
+    }
+    else if ((-PyList_GET_SIZE(o) <= i) & (i < 0)) {
+        PyObject *r = PyList_GET_ITEM(o, PyList_GET_SIZE(o) + i);
+        Py_INCREF(r);
+        return r;
+    }
+    return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
+#else
+    return PySequence_GetItem(o, i);
+#endif
+}
+#define __Pyx_GetItemInt_Tuple(o, i, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \
+                                                    __Pyx_GetItemInt_Tuple_Fast(o, i) : \
+                                                    __Pyx_GetItemInt_Generic(o, to_py_func(i)))
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    if (likely((0 <= i) & (i < PyTuple_GET_SIZE(o)))) {
+        PyObject *r = PyTuple_GET_ITEM(o, i);
+        Py_INCREF(r);
+        return r;
+    }
+    else if ((-PyTuple_GET_SIZE(o) <= i) & (i < 0)) {
+        PyObject *r = PyTuple_GET_ITEM(o, PyTuple_GET_SIZE(o) + i);
+        Py_INCREF(r);
+        return r;
+    }
+    return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
+#else
+    return PySequence_GetItem(o, i);
+#endif
+}
+#define __Pyx_GetItemInt(o, i, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \
+                                                    __Pyx_GetItemInt_Fast(o, i) : \
+                                                    __Pyx_GetItemInt_Generic(o, to_py_func(i)))
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    if (PyList_CheckExact(o)) {
+        Py_ssize_t n = (likely(i >= 0)) ? i : i + PyList_GET_SIZE(o);
+        if (likely((n >= 0) & (n < PyList_GET_SIZE(o)))) {
+            PyObject *r = PyList_GET_ITEM(o, n);
+            Py_INCREF(r);
+            return r;
+        }
+    }
+    else if (PyTuple_CheckExact(o)) {
+        Py_ssize_t n = (likely(i >= 0)) ? i : i + PyTuple_GET_SIZE(o);
+        if (likely((n >= 0) & (n < PyTuple_GET_SIZE(o)))) {
+            PyObject *r = PyTuple_GET_ITEM(o, n);
+            Py_INCREF(r);
+            return r;
+        }
+    } else {  /* inlined PySequence_GetItem() */
+        PySequenceMethods *m = Py_TYPE(o)->tp_as_sequence;
+        if (likely(m && m->sq_item)) {
+            if (unlikely(i < 0) && likely(m->sq_length)) {
+                Py_ssize_t l = m->sq_length(o);
+                if (unlikely(l < 0)) return NULL;
+                i += l;
+            }
+            return m->sq_item(o, i);
+        }
+    }
+#else
+    if (PySequence_Check(o)) {
+        return PySequence_GetItem(o, i);
+    }
+#endif
+    return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
+}
+
+static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level); /*proto*/
+
+static CYTHON_INLINE void __Pyx_RaiseImportError(PyObject *name);
+
+static CYTHON_INLINE unsigned char __Pyx_PyInt_AsUnsignedChar(PyObject *);
+
+static CYTHON_INLINE unsigned short __Pyx_PyInt_AsUnsignedShort(PyObject *);
+
+static CYTHON_INLINE unsigned int __Pyx_PyInt_AsUnsignedInt(PyObject *);
+
+static CYTHON_INLINE char __Pyx_PyInt_AsChar(PyObject *);
+
+static CYTHON_INLINE short __Pyx_PyInt_AsShort(PyObject *);
+
+static CYTHON_INLINE int __Pyx_PyInt_AsInt(PyObject *);
+
+static CYTHON_INLINE signed char __Pyx_PyInt_AsSignedChar(PyObject *);
+
+static CYTHON_INLINE signed short __Pyx_PyInt_AsSignedShort(PyObject *);
+
+static CYTHON_INLINE signed int __Pyx_PyInt_AsSignedInt(PyObject *);
+
+static CYTHON_INLINE int __Pyx_PyInt_AsLongDouble(PyObject *);
+
+static CYTHON_INLINE unsigned long __Pyx_PyInt_AsUnsignedLong(PyObject *);
+
+static CYTHON_INLINE unsigned PY_LONG_LONG __Pyx_PyInt_AsUnsignedLongLong(PyObject *);
+
+static CYTHON_INLINE long __Pyx_PyInt_AsLong(PyObject *);
+
+static CYTHON_INLINE PY_LONG_LONG __Pyx_PyInt_AsLongLong(PyObject *);
+
+static CYTHON_INLINE signed long __Pyx_PyInt_AsSignedLong(PyObject *);
+
+static CYTHON_INLINE signed PY_LONG_LONG __Pyx_PyInt_AsSignedLongLong(PyObject *);
+
+static int __Pyx_check_binary_version(void);
+
+typedef struct {
+    int code_line;
+    PyCodeObject* code_object;
+} __Pyx_CodeObjectCacheEntry;
+struct __Pyx_CodeObjectCache {
+    int count;
+    int max_count;
+    __Pyx_CodeObjectCacheEntry* entries;
+};
+static struct __Pyx_CodeObjectCache __pyx_code_cache = {0,0,NULL};
+static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line);
+static PyCodeObject *__pyx_find_code_object(int code_line);
+static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object);
+
+static void __Pyx_AddTraceback(const char *funcname, int c_line,
+                               int py_line, const char *filename); /*proto*/
+
+static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
+
+
+/* Module declarations from 'bx.seq._twobit' */
+static char *__pyx_v_2bx_3seq_7_twobit_valToNt;
+#define __Pyx_MODULE_NAME "bx.seq._twobit"
+int __pyx_module_is_main_bx__seq___twobit = 0;
+
+/* Implementation of 'bx.seq._twobit' */
+static PyObject *__pyx_pf_2bx_3seq_7_twobit_read(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_file, PyObject *__pyx_v_seq, int __pyx_v_fragStart, int __pyx_v_fragEnd, int __pyx_v_do_mask); /* proto */
+static char __pyx_k_3[] = "/aut/proj/odenas/software/bx-python/lib/bx/seq/_twobit.pyx";
+static char __pyx_k_4[] = "bx.seq._twobit";
+static char __pyx_k__e[] = "e";
+static char __pyx_k__i[] = "i";
+static char __pyx_k__j[] = "j";
+static char __pyx_k__s[] = "s";
+static char __pyx_k__dna[] = "dna";
+static char __pyx_k__seq[] = "seq";
+static char __pyx_k__sys[] = "sys";
+static char __pyx_k__TCAG[] = "TCAG";
+static char __pyx_k__file[] = "file";
+static char __pyx_k__pEnd[] = "pEnd";
+static char __pyx_k__pOff[] = "pOff";
+static char __pyx_k__read[] = "read";
+static char __pyx_k__seek[] = "seek";
+static char __pyx_k__bisect[] = "bisect";
+static char __pyx_k__dna_py[] = "dna_py";
+static char __pyx_k__midEnd[] = "midEnd";
+static char __pyx_k__pStart[] = "pStart";
+static char __pyx_k__packed[] = "packed";
+static char __pyx_k__struct[] = "struct";
+static char __pyx_k__do_mask[] = "do_mask";
+static char __pyx_k__fragEnd[] = "fragEnd";
+static char __pyx_k__partial[] = "partial";
+static char __pyx_k____main__[] = "__main__";
+static char __pyx_k____test__[] = "__test__";
+static char __pyx_k__dna_orig[] = "dna_orig";
+static char __pyx_k__midStart[] = "midStart";
+static char __pyx_k__start_ix[] = "start_ix";
+static char __pyx_k__fragStart[] = "fragStart";
+static char __pyx_k__packedEnd[] = "packedEnd";
+static char __pyx_k__packed_py[] = "packed_py";
+static char __pyx_k__partCount[] = "partCount";
+static char __pyx_k__remainder[] = "remainder";
+static char __pyx_k__packedStart[] = "packedStart";
+static char __pyx_k__m_block_count[] = "m_block_count";
+static char __pyx_k__n_block_count[] = "n_block_count";
+static char __pyx_k__n_block_sizes[] = "n_block_sizes";
+static char __pyx_k__packByteCount[] = "packByteCount";
+static char __pyx_k__n_block_starts[] = "n_block_starts";
+static char __pyx_k__sequence_offset[] = "sequence_offset";
+static char __pyx_k__masked_block_sizes[] = "masked_block_sizes";
+static char __pyx_k__masked_block_starts[] = "masked_block_starts";
+static PyObject *__pyx_kp_s_3;
+static PyObject *__pyx_n_s_4;
+static PyObject *__pyx_n_s____main__;
+static PyObject *__pyx_n_s____test__;
+static PyObject *__pyx_n_s__bisect;
+static PyObject *__pyx_n_s__dna;
+static PyObject *__pyx_n_s__dna_orig;
+static PyObject *__pyx_n_s__dna_py;
+static PyObject *__pyx_n_s__do_mask;
+static PyObject *__pyx_n_s__e;
+static PyObject *__pyx_n_s__file;
+static PyObject *__pyx_n_s__fragEnd;
+static PyObject *__pyx_n_s__fragStart;
+static PyObject *__pyx_n_s__i;
+static PyObject *__pyx_n_s__j;
+static PyObject *__pyx_n_s__m_block_count;
+static PyObject *__pyx_n_s__masked_block_sizes;
+static PyObject *__pyx_n_s__masked_block_starts;
+static PyObject *__pyx_n_s__midEnd;
+static PyObject *__pyx_n_s__midStart;
+static PyObject *__pyx_n_s__n_block_count;
+static PyObject *__pyx_n_s__n_block_sizes;
+static PyObject *__pyx_n_s__n_block_starts;
+static PyObject *__pyx_n_s__pEnd;
+static PyObject *__pyx_n_s__pOff;
+static PyObject *__pyx_n_s__pStart;
+static PyObject *__pyx_n_s__packByteCount;
+static PyObject *__pyx_n_s__packed;
+static PyObject *__pyx_n_s__packedEnd;
+static PyObject *__pyx_n_s__packedStart;
+static PyObject *__pyx_n_s__packed_py;
+static PyObject *__pyx_n_s__partCount;
+static PyObject *__pyx_n_s__partial;
+static PyObject *__pyx_n_s__read;
+static PyObject *__pyx_n_s__remainder;
+static PyObject *__pyx_n_s__s;
+static PyObject *__pyx_n_s__seek;
+static PyObject *__pyx_n_s__seq;
+static PyObject *__pyx_n_s__sequence_offset;
+static PyObject *__pyx_n_s__start_ix;
+static PyObject *__pyx_n_s__struct;
+static PyObject *__pyx_n_s__sys;
+static PyObject *__pyx_int_0;
+static PyObject *__pyx_int_1;
+static PyObject *__pyx_k_tuple_1;
+static PyObject *__pyx_k_codeobj_2;
+
+/* Python wrapper */
+static PyObject *__pyx_pw_2bx_3seq_7_twobit_1read(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_2bx_3seq_7_twobit_read[] = "\n    Stolen directly from Jim Kent's twoBit.c\n    ";
+static PyMethodDef __pyx_mdef_2bx_3seq_7_twobit_1read = {__Pyx_NAMESTR("read"), (PyCFunction)__pyx_pw_2bx_3seq_7_twobit_1read, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(__pyx_doc_2bx_3seq_7_twobit_read)};
+static PyObject *__pyx_pw_2bx_3seq_7_twobit_1read(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_file = 0;
+  PyObject *__pyx_v_seq = 0;
+  int __pyx_v_fragStart;
+  int __pyx_v_fragEnd;
+  int __pyx_v_do_mask;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("read (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__file,&__pyx_n_s__seq,&__pyx_n_s__fragStart,&__pyx_n_s__fragEnd,&__pyx_n_s__do_mask,0};
+    PyObject* values[5] = {0,0,0,0,0};
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+        case  4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__file)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__seq)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("read", 1, 5, 5, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 19; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+        case  2:
+        if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__fragStart)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("read", 1, 5, 5, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 19; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+        case  3:
+        if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__fragEnd)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("read", 1, 5, 5, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 19; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+        case  4:
+        if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__do_mask)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("read", 1, 5, 5, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 19; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "read") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 19; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else if (PyTuple_GET_SIZE(__pyx_args) != 5) {
+      goto __pyx_L5_argtuple_error;
+    } else {
+      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+      values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+      values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+      values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+    }
+    __pyx_v_file = values[0];
+    __pyx_v_seq = values[1];
+    __pyx_v_fragStart = __Pyx_PyInt_AsInt(values[2]); if (unlikely((__pyx_v_fragStart == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 19; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_fragEnd = __Pyx_PyInt_AsInt(values[3]); if (unlikely((__pyx_v_fragEnd == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 19; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_do_mask = __Pyx_PyObject_IsTrue(values[4]); if (unlikely((__pyx_v_do_mask == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 19; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("read", 1, 5, 5, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 19; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.seq._twobit.read", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_2bx_3seq_7_twobit_read(__pyx_self, __pyx_v_file, __pyx_v_seq, __pyx_v_fragStart, __pyx_v_fragEnd, __pyx_v_do_mask);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "bx/seq/_twobit.pyx":19
+ * valToNt = "TCAG"
+ * 
+ * def read( file, seq, int fragStart, int fragEnd, bint do_mask ):             # <<<<<<<<<<<<<<
+ *     """
+ *     Stolen directly from Jim Kent's twoBit.c
+ */
+
+static PyObject *__pyx_pf_2bx_3seq_7_twobit_read(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_file, PyObject *__pyx_v_seq, int __pyx_v_fragStart, int __pyx_v_fragEnd, int __pyx_v_do_mask) {
+  int __pyx_v_packedStart;
+  int __pyx_v_packedEnd;
+  int __pyx_v_packByteCount;
+  int __pyx_v_pOff;
+  int __pyx_v_pStart;
+  int __pyx_v_pEnd;
+  int __pyx_v_midStart;
+  int __pyx_v_remainder;
+  int __pyx_v_partCount;
+  int __pyx_v_i;
+  int __pyx_v_j;
+  int __pyx_v_s;
+  int __pyx_v_e;
+  char *__pyx_v_packed;
+  char *__pyx_v_dna;
+  char __pyx_v_partial;
+  PyObject *__pyx_v_dna_py = NULL;
+  PyObject *__pyx_v_packed_py = NULL;
+  int __pyx_v_midEnd;
+  PyObject *__pyx_v_n_block_count = NULL;
+  PyObject *__pyx_v_start_ix = NULL;
+  PyObject *__pyx_v_m_block_count = NULL;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  int __pyx_t_5;
+  int __pyx_t_6;
+  Py_ssize_t __pyx_t_7;
+  int __pyx_t_8;
+  int __pyx_t_9;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("read", 0);
+
+  /* "bx/seq/_twobit.pyx":29
+ *     cdef char * packed, * dna, *dna_orig
+ *     cdef char partial
+ *     packedStart = (fragStart>>2);             # <<<<<<<<<<<<<<
+ *     packedEnd = ((fragEnd+3)>>2);
+ *     packByteCount = packedEnd - packedStart;
+ */
+  __pyx_v_packedStart = (__pyx_v_fragStart >> 2);
+
+  /* "bx/seq/_twobit.pyx":30
+ *     cdef char partial
+ *     packedStart = (fragStart>>2);
+ *     packedEnd = ((fragEnd+3)>>2);             # <<<<<<<<<<<<<<
+ *     packByteCount = packedEnd - packedStart;
+ *     # Empty string in which to write unpacked DNA
+ */
+  __pyx_v_packedEnd = ((__pyx_v_fragEnd + 3) >> 2);
+
+  /* "bx/seq/_twobit.pyx":31
+ *     packedStart = (fragStart>>2);
+ *     packedEnd = ((fragEnd+3)>>2);
+ *     packByteCount = packedEnd - packedStart;             # <<<<<<<<<<<<<<
+ *     # Empty string in which to write unpacked DNA
+ *     dna_py = PyString_FromStringAndSize( NULL, fragEnd - fragStart )
+ */
+  __pyx_v_packByteCount = (__pyx_v_packedEnd - __pyx_v_packedStart);
+
+  /* "bx/seq/_twobit.pyx":33
+ *     packByteCount = packedEnd - packedStart;
+ *     # Empty string in which to write unpacked DNA
+ *     dna_py = PyString_FromStringAndSize( NULL, fragEnd - fragStart )             # <<<<<<<<<<<<<<
+ *     dna = PyString_AsString( dna_py )
+ *     # Read it
+ */
+  __pyx_t_1 = PyString_FromStringAndSize(NULL, (__pyx_v_fragEnd - __pyx_v_fragStart)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 33; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_v_dna_py = __pyx_t_1;
+  __pyx_t_1 = 0;
+
+  /* "bx/seq/_twobit.pyx":34
+ *     # Empty string in which to write unpacked DNA
+ *     dna_py = PyString_FromStringAndSize( NULL, fragEnd - fragStart )
+ *     dna = PyString_AsString( dna_py )             # <<<<<<<<<<<<<<
+ *     # Read it
+ *     file.seek( seq.sequence_offset + packedStart )
+ */
+  __pyx_v_dna = PyString_AsString(__pyx_v_dna_py);
+
+  /* "bx/seq/_twobit.pyx":36
+ *     dna = PyString_AsString( dna_py )
+ *     # Read it
+ *     file.seek( seq.sequence_offset + packedStart )             # <<<<<<<<<<<<<<
+ *     packed_py = file.read( packByteCount )
+ *     packed = PyString_AsString( packed_py )
+ */
+  __pyx_t_1 = PyObject_GetAttr(__pyx_v_file, __pyx_n_s__seek); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 36; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = PyObject_GetAttr(__pyx_v_seq, __pyx_n_s__sequence_offset); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 36; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = PyInt_FromLong(__pyx_v_packedStart); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 36; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_4 = PyNumber_Add(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 36; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 36; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_4);
+  __Pyx_GIVEREF(__pyx_t_4);
+  __pyx_t_4 = 0;
+  __pyx_t_4 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 36; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+
+  /* "bx/seq/_twobit.pyx":37
+ *     # Read it
+ *     file.seek( seq.sequence_offset + packedStart )
+ *     packed_py = file.read( packByteCount )             # <<<<<<<<<<<<<<
+ *     packed = PyString_AsString( packed_py )
+ *     # Handle case where everything is in one packed byte
+ */
+  __pyx_t_4 = PyObject_GetAttr(__pyx_v_file, __pyx_n_s__read); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 37; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __pyx_t_3 = PyInt_FromLong(__pyx_v_packByteCount); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 37; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 37; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_3);
+  __Pyx_GIVEREF(__pyx_t_3);
+  __pyx_t_3 = 0;
+  __pyx_t_3 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 37; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+  __pyx_v_packed_py = __pyx_t_3;
+  __pyx_t_3 = 0;
+
+  /* "bx/seq/_twobit.pyx":38
+ *     file.seek( seq.sequence_offset + packedStart )
+ *     packed_py = file.read( packByteCount )
+ *     packed = PyString_AsString( packed_py )             # <<<<<<<<<<<<<<
+ *     # Handle case where everything is in one packed byte
+ *     if packByteCount == 1:
+ */
+  __pyx_v_packed = PyString_AsString(__pyx_v_packed_py);
+
+  /* "bx/seq/_twobit.pyx":40
+ *     packed = PyString_AsString( packed_py )
+ *     # Handle case where everything is in one packed byte
+ *     if packByteCount == 1:             # <<<<<<<<<<<<<<
+ *         pOff = (packedStart<<2)
+ *         pStart = fragStart - pOff
+ */
+  __pyx_t_5 = (__pyx_v_packByteCount == 1);
+  if (__pyx_t_5) {
+
+    /* "bx/seq/_twobit.pyx":41
+ *     # Handle case where everything is in one packed byte
+ *     if packByteCount == 1:
+ *         pOff = (packedStart<<2)             # <<<<<<<<<<<<<<
+ *         pStart = fragStart - pOff
+ *         pEnd = fragEnd - pOff
+ */
+    __pyx_v_pOff = (__pyx_v_packedStart << 2);
+
+    /* "bx/seq/_twobit.pyx":42
+ *     if packByteCount == 1:
+ *         pOff = (packedStart<<2)
+ *         pStart = fragStart - pOff             # <<<<<<<<<<<<<<
+ *         pEnd = fragEnd - pOff
+ *         partial = packed[0]
+ */
+    __pyx_v_pStart = (__pyx_v_fragStart - __pyx_v_pOff);
+
+    /* "bx/seq/_twobit.pyx":43
+ *         pOff = (packedStart<<2)
+ *         pStart = fragStart - pOff
+ *         pEnd = fragEnd - pOff             # <<<<<<<<<<<<<<
+ *         partial = packed[0]
+ *         assert pEnd <= 4
+ */
+    __pyx_v_pEnd = (__pyx_v_fragEnd - __pyx_v_pOff);
+
+    /* "bx/seq/_twobit.pyx":44
+ *         pStart = fragStart - pOff
+ *         pEnd = fragEnd - pOff
+ *         partial = packed[0]             # <<<<<<<<<<<<<<
+ *         assert pEnd <= 4
+ *         assert pStart >= 0
+ */
+    __pyx_v_partial = (__pyx_v_packed[0]);
+
+    /* "bx/seq/_twobit.pyx":45
+ *         pEnd = fragEnd - pOff
+ *         partial = packed[0]
+ *         assert pEnd <= 4             # <<<<<<<<<<<<<<
+ *         assert pStart >= 0
+ *         for i from pStart <= i < pEnd:
+ */
+    #ifndef CYTHON_WITHOUT_ASSERTIONS
+    if (unlikely(!(__pyx_v_pEnd <= 4))) {
+      PyErr_SetNone(PyExc_AssertionError);
+      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 45; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+    #endif
+
+    /* "bx/seq/_twobit.pyx":46
+ *         partial = packed[0]
+ *         assert pEnd <= 4
+ *         assert pStart >= 0             # <<<<<<<<<<<<<<
+ *         for i from pStart <= i < pEnd:
+ *             dna[0] = valToNt[(partial >> (6-i-i)) & 3]
+ */
+    #ifndef CYTHON_WITHOUT_ASSERTIONS
+    if (unlikely(!(__pyx_v_pStart >= 0))) {
+      PyErr_SetNone(PyExc_AssertionError);
+      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 46; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+    #endif
+
+    /* "bx/seq/_twobit.pyx":47
+ *         assert pEnd <= 4
+ *         assert pStart >= 0
+ *         for i from pStart <= i < pEnd:             # <<<<<<<<<<<<<<
+ *             dna[0] = valToNt[(partial >> (6-i-i)) & 3]
+ *             dna = dna + 1
+ */
+    __pyx_t_6 = __pyx_v_pEnd;
+    for (__pyx_v_i = __pyx_v_pStart; __pyx_v_i < __pyx_t_6; __pyx_v_i++) {
+
+      /* "bx/seq/_twobit.pyx":48
+ *         assert pStart >= 0
+ *         for i from pStart <= i < pEnd:
+ *             dna[0] = valToNt[(partial >> (6-i-i)) & 3]             # <<<<<<<<<<<<<<
+ *             dna = dna + 1
+ *     else:
+ */
+      (__pyx_v_dna[0]) = (__pyx_v_2bx_3seq_7_twobit_valToNt[((__pyx_v_partial >> ((6 - __pyx_v_i) - __pyx_v_i)) & 3)]);
+
+      /* "bx/seq/_twobit.pyx":49
+ *         for i from pStart <= i < pEnd:
+ *             dna[0] = valToNt[(partial >> (6-i-i)) & 3]
+ *             dna = dna + 1             # <<<<<<<<<<<<<<
+ *     else:
+ *         # Handle partial first packed byte.
+ */
+      __pyx_v_dna = (__pyx_v_dna + 1);
+    }
+    goto __pyx_L3;
+  }
+  /*else*/ {
+
+    /* "bx/seq/_twobit.pyx":52
+ *     else:
+ *         # Handle partial first packed byte.
+ *         midStart = fragStart;             # <<<<<<<<<<<<<<
+ *         remainder = ( fragStart&3 )
+ *         if remainder > 0:
+ */
+    __pyx_v_midStart = __pyx_v_fragStart;
+
+    /* "bx/seq/_twobit.pyx":53
+ *         # Handle partial first packed byte.
+ *         midStart = fragStart;
+ *         remainder = ( fragStart&3 )             # <<<<<<<<<<<<<<
+ *         if remainder > 0:
+ *             partial = packed[0]; packed = packed + 1
+ */
+    __pyx_v_remainder = (__pyx_v_fragStart & 3);
+
+    /* "bx/seq/_twobit.pyx":54
+ *         midStart = fragStart;
+ *         remainder = ( fragStart&3 )
+ *         if remainder > 0:             # <<<<<<<<<<<<<<
+ *             partial = packed[0]; packed = packed + 1
+ *             partCount = 4 - remainder;
+ */
+    __pyx_t_5 = (__pyx_v_remainder > 0);
+    if (__pyx_t_5) {
+
+      /* "bx/seq/_twobit.pyx":55
+ *         remainder = ( fragStart&3 )
+ *         if remainder > 0:
+ *             partial = packed[0]; packed = packed + 1             # <<<<<<<<<<<<<<
+ *             partCount = 4 - remainder;
+ *             for i from partCount - 1 >= i >= 0:
+ */
+      __pyx_v_partial = (__pyx_v_packed[0]);
+      __pyx_v_packed = (__pyx_v_packed + 1);
+
+      /* "bx/seq/_twobit.pyx":56
+ *         if remainder > 0:
+ *             partial = packed[0]; packed = packed + 1
+ *             partCount = 4 - remainder;             # <<<<<<<<<<<<<<
+ *             for i from partCount - 1 >= i >= 0:
+ *                 dna[i] = valToNt[ partial & 3 ]
+ */
+      __pyx_v_partCount = (4 - __pyx_v_remainder);
+
+      /* "bx/seq/_twobit.pyx":57
+ *             partial = packed[0]; packed = packed + 1
+ *             partCount = 4 - remainder;
+ *             for i from partCount - 1 >= i >= 0:             # <<<<<<<<<<<<<<
+ *                 dna[i] = valToNt[ partial & 3 ]
+ *                 partial = partial >> 2
+ */
+      for (__pyx_v_i = (__pyx_v_partCount - 1); __pyx_v_i >= 0; __pyx_v_i--) {
+
+        /* "bx/seq/_twobit.pyx":58
+ *             partCount = 4 - remainder;
+ *             for i from partCount - 1 >= i >= 0:
+ *                 dna[i] = valToNt[ partial & 3 ]             # <<<<<<<<<<<<<<
+ *                 partial = partial >> 2
+ *             midStart = midStart + partCount
+ */
+        (__pyx_v_dna[__pyx_v_i]) = (__pyx_v_2bx_3seq_7_twobit_valToNt[(__pyx_v_partial & 3)]);
+
+        /* "bx/seq/_twobit.pyx":59
+ *             for i from partCount - 1 >= i >= 0:
+ *                 dna[i] = valToNt[ partial & 3 ]
+ *                 partial = partial >> 2             # <<<<<<<<<<<<<<
+ *             midStart = midStart + partCount
+ *             dna = dna + partCount
+ */
+        __pyx_v_partial = (__pyx_v_partial >> 2);
+      }
+
+      /* "bx/seq/_twobit.pyx":60
+ *                 dna[i] = valToNt[ partial & 3 ]
+ *                 partial = partial >> 2
+ *             midStart = midStart + partCount             # <<<<<<<<<<<<<<
+ *             dna = dna + partCount
+ *         # Handle middle bytes.
+ */
+      __pyx_v_midStart = (__pyx_v_midStart + __pyx_v_partCount);
+
+      /* "bx/seq/_twobit.pyx":61
+ *                 partial = partial >> 2
+ *             midStart = midStart + partCount
+ *             dna = dna + partCount             # <<<<<<<<<<<<<<
+ *         # Handle middle bytes.
+ *         remainder = fragEnd&3
+ */
+      __pyx_v_dna = (__pyx_v_dna + __pyx_v_partCount);
+      goto __pyx_L6;
+    }
+    __pyx_L6:;
+
+    /* "bx/seq/_twobit.pyx":63
+ *             dna = dna + partCount
+ *         # Handle middle bytes.
+ *         remainder = fragEnd&3             # <<<<<<<<<<<<<<
+ *         midEnd = fragEnd - remainder
+ *         i = midStart
+ */
+    __pyx_v_remainder = (__pyx_v_fragEnd & 3);
+
+    /* "bx/seq/_twobit.pyx":64
+ *         # Handle middle bytes.
+ *         remainder = fragEnd&3
+ *         midEnd = fragEnd - remainder             # <<<<<<<<<<<<<<
+ *         i = midStart
+ *         while i < midEnd:
+ */
+    __pyx_v_midEnd = (__pyx_v_fragEnd - __pyx_v_remainder);
+
+    /* "bx/seq/_twobit.pyx":65
+ *         remainder = fragEnd&3
+ *         midEnd = fragEnd - remainder
+ *         i = midStart             # <<<<<<<<<<<<<<
+ *         while i < midEnd:
+ *             partial = packed[0]
+ */
+    __pyx_v_i = __pyx_v_midStart;
+
+    /* "bx/seq/_twobit.pyx":66
+ *         midEnd = fragEnd - remainder
+ *         i = midStart
+ *         while i < midEnd:             # <<<<<<<<<<<<<<
+ *             partial = packed[0]
+ *             packed = packed + 1;
+ */
+    while (1) {
+      __pyx_t_5 = (__pyx_v_i < __pyx_v_midEnd);
+      if (!__pyx_t_5) break;
+
+      /* "bx/seq/_twobit.pyx":67
+ *         i = midStart
+ *         while i < midEnd:
+ *             partial = packed[0]             # <<<<<<<<<<<<<<
+ *             packed = packed + 1;
+ *             dna[3] = valToNt[partial&3];
+ */
+      __pyx_v_partial = (__pyx_v_packed[0]);
+
+      /* "bx/seq/_twobit.pyx":68
+ *         while i < midEnd:
+ *             partial = packed[0]
+ *             packed = packed + 1;             # <<<<<<<<<<<<<<
+ *             dna[3] = valToNt[partial&3];
+ *             partial = partial >> 2
+ */
+      __pyx_v_packed = (__pyx_v_packed + 1);
+
+      /* "bx/seq/_twobit.pyx":69
+ *             partial = packed[0]
+ *             packed = packed + 1;
+ *             dna[3] = valToNt[partial&3];             # <<<<<<<<<<<<<<
+ *             partial = partial >> 2
+ *             dna[2] = valToNt[partial&3];
+ */
+      (__pyx_v_dna[3]) = (__pyx_v_2bx_3seq_7_twobit_valToNt[(__pyx_v_partial & 3)]);
+
+      /* "bx/seq/_twobit.pyx":70
+ *             packed = packed + 1;
+ *             dna[3] = valToNt[partial&3];
+ *             partial = partial >> 2             # <<<<<<<<<<<<<<
+ *             dna[2] = valToNt[partial&3];
+ *             partial = partial >> 2
+ */
+      __pyx_v_partial = (__pyx_v_partial >> 2);
+
+      /* "bx/seq/_twobit.pyx":71
+ *             dna[3] = valToNt[partial&3];
+ *             partial = partial >> 2
+ *             dna[2] = valToNt[partial&3];             # <<<<<<<<<<<<<<
+ *             partial = partial >> 2
+ *             dna[1] = valToNt[partial&3];
+ */
+      (__pyx_v_dna[2]) = (__pyx_v_2bx_3seq_7_twobit_valToNt[(__pyx_v_partial & 3)]);
+
+      /* "bx/seq/_twobit.pyx":72
+ *             partial = partial >> 2
+ *             dna[2] = valToNt[partial&3];
+ *             partial = partial >> 2             # <<<<<<<<<<<<<<
+ *             dna[1] = valToNt[partial&3];
+ *             partial = partial >> 2
+ */
+      __pyx_v_partial = (__pyx_v_partial >> 2);
+
+      /* "bx/seq/_twobit.pyx":73
+ *             dna[2] = valToNt[partial&3];
+ *             partial = partial >> 2
+ *             dna[1] = valToNt[partial&3];             # <<<<<<<<<<<<<<
+ *             partial = partial >> 2
+ *             dna[0] = valToNt[partial&3];
+ */
+      (__pyx_v_dna[1]) = (__pyx_v_2bx_3seq_7_twobit_valToNt[(__pyx_v_partial & 3)]);
+
+      /* "bx/seq/_twobit.pyx":74
+ *             partial = partial >> 2
+ *             dna[1] = valToNt[partial&3];
+ *             partial = partial >> 2             # <<<<<<<<<<<<<<
+ *             dna[0] = valToNt[partial&3];
+ *             dna = dna + 4;
+ */
+      __pyx_v_partial = (__pyx_v_partial >> 2);
+
+      /* "bx/seq/_twobit.pyx":75
+ *             dna[1] = valToNt[partial&3];
+ *             partial = partial >> 2
+ *             dna[0] = valToNt[partial&3];             # <<<<<<<<<<<<<<
+ *             dna = dna + 4;
+ *             # Increment
+ */
+      (__pyx_v_dna[0]) = (__pyx_v_2bx_3seq_7_twobit_valToNt[(__pyx_v_partial & 3)]);
+
+      /* "bx/seq/_twobit.pyx":76
+ *             partial = partial >> 2
+ *             dna[0] = valToNt[partial&3];
+ *             dna = dna + 4;             # <<<<<<<<<<<<<<
+ *             # Increment
+ *             i = i + 4
+ */
+      __pyx_v_dna = (__pyx_v_dna + 4);
+
+      /* "bx/seq/_twobit.pyx":78
+ *             dna = dna + 4;
+ *             # Increment
+ *             i = i + 4             # <<<<<<<<<<<<<<
+ *             ## sys.stderr.write( "!!!< " + dna_py + " >!!!\n" ); sys.stderr.flush()
+ *         # End
+ */
+      __pyx_v_i = (__pyx_v_i + 4);
+    }
+
+    /* "bx/seq/_twobit.pyx":81
+ *             ## sys.stderr.write( "!!!< " + dna_py + " >!!!\n" ); sys.stderr.flush()
+ *         # End
+ *         if remainder > 0:             # <<<<<<<<<<<<<<
+ *             partial = packed[0];
+ *             partial = partial >> (8-remainder-remainder)
+ */
+    __pyx_t_5 = (__pyx_v_remainder > 0);
+    if (__pyx_t_5) {
+
+      /* "bx/seq/_twobit.pyx":82
+ *         # End
+ *         if remainder > 0:
+ *             partial = packed[0];             # <<<<<<<<<<<<<<
+ *             partial = partial >> (8-remainder-remainder)
+ *             for i from remainder - 1 >= i >= 0:
+ */
+      __pyx_v_partial = (__pyx_v_packed[0]);
+
+      /* "bx/seq/_twobit.pyx":83
+ *         if remainder > 0:
+ *             partial = packed[0];
+ *             partial = partial >> (8-remainder-remainder)             # <<<<<<<<<<<<<<
+ *             for i from remainder - 1 >= i >= 0:
+ *                 dna[i] = valToNt[partial&3]
+ */
+      __pyx_v_partial = (__pyx_v_partial >> ((8 - __pyx_v_remainder) - __pyx_v_remainder));
+
+      /* "bx/seq/_twobit.pyx":84
+ *             partial = packed[0];
+ *             partial = partial >> (8-remainder-remainder)
+ *             for i from remainder - 1 >= i >= 0:             # <<<<<<<<<<<<<<
+ *                 dna[i] = valToNt[partial&3]
+ *                 partial = partial >> 2
+ */
+      for (__pyx_v_i = (__pyx_v_remainder - 1); __pyx_v_i >= 0; __pyx_v_i--) {
+
+        /* "bx/seq/_twobit.pyx":85
+ *             partial = partial >> (8-remainder-remainder)
+ *             for i from remainder - 1 >= i >= 0:
+ *                 dna[i] = valToNt[partial&3]             # <<<<<<<<<<<<<<
+ *                 partial = partial >> 2
+ *     # Restore DNA pointer
+ */
+        (__pyx_v_dna[__pyx_v_i]) = (__pyx_v_2bx_3seq_7_twobit_valToNt[(__pyx_v_partial & 3)]);
+
+        /* "bx/seq/_twobit.pyx":86
+ *             for i from remainder - 1 >= i >= 0:
+ *                 dna[i] = valToNt[partial&3]
+ *                 partial = partial >> 2             # <<<<<<<<<<<<<<
+ *     # Restore DNA pointer
+ *     dna = PyString_AsString( dna_py )
+ */
+        __pyx_v_partial = (__pyx_v_partial >> 2);
+      }
+      goto __pyx_L11;
+    }
+    __pyx_L11:;
+  }
+  __pyx_L3:;
+
+  /* "bx/seq/_twobit.pyx":88
+ *                 partial = partial >> 2
+ *     # Restore DNA pointer
+ *     dna = PyString_AsString( dna_py )             # <<<<<<<<<<<<<<
+ *     # N's
+ *     n_block_count = len( seq.n_block_starts )
+ */
+  __pyx_v_dna = PyString_AsString(__pyx_v_dna_py);
+
+  /* "bx/seq/_twobit.pyx":90
+ *     dna = PyString_AsString( dna_py )
+ *     # N's
+ *     n_block_count = len( seq.n_block_starts )             # <<<<<<<<<<<<<<
+ *     if n_block_count > 0:
+ *         start_ix = bisect( seq.n_block_starts, fragStart ) - 1
+ */
+  __pyx_t_3 = PyObject_GetAttr(__pyx_v_seq, __pyx_n_s__n_block_starts); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 90; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_7 = PyObject_Length(__pyx_t_3); if (unlikely(__pyx_t_7 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 90; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __pyx_t_3 = PyInt_FromSsize_t(__pyx_t_7); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 90; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_v_n_block_count = __pyx_t_3;
+  __pyx_t_3 = 0;
+
+  /* "bx/seq/_twobit.pyx":91
+ *     # N's
+ *     n_block_count = len( seq.n_block_starts )
+ *     if n_block_count > 0:             # <<<<<<<<<<<<<<
+ *         start_ix = bisect( seq.n_block_starts, fragStart ) - 1
+ *         if start_ix < 0: start_ix = 0
+ */
+  __pyx_t_3 = PyObject_RichCompare(__pyx_v_n_block_count, __pyx_int_0, Py_GT); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 91; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 91; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  if (__pyx_t_5) {
+
+    /* "bx/seq/_twobit.pyx":92
+ *     n_block_count = len( seq.n_block_starts )
+ *     if n_block_count > 0:
+ *         start_ix = bisect( seq.n_block_starts, fragStart ) - 1             # <<<<<<<<<<<<<<
+ *         if start_ix < 0: start_ix = 0
+ *         for i from start_ix <= i < n_block_count:
+ */
+    __pyx_t_3 = __Pyx_GetName(__pyx_m, __pyx_n_s__bisect); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 92; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __pyx_t_1 = PyObject_GetAttr(__pyx_v_seq, __pyx_n_s__n_block_starts); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 92; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __pyx_t_4 = PyInt_FromLong(__pyx_v_fragStart); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 92; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 92; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
+    __Pyx_GIVEREF(__pyx_t_1);
+    PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_4);
+    __Pyx_GIVEREF(__pyx_t_4);
+    __pyx_t_1 = 0;
+    __pyx_t_4 = 0;
+    __pyx_t_4 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 92; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
+    __pyx_t_2 = PyNumber_Subtract(__pyx_t_4, __pyx_int_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 92; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    __pyx_v_start_ix = __pyx_t_2;
+    __pyx_t_2 = 0;
+
+    /* "bx/seq/_twobit.pyx":93
+ *     if n_block_count > 0:
+ *         start_ix = bisect( seq.n_block_starts, fragStart ) - 1
+ *         if start_ix < 0: start_ix = 0             # <<<<<<<<<<<<<<
+ *         for i from start_ix <= i < n_block_count:
+ *             s = seq.n_block_starts[i];
+ */
+    __pyx_t_2 = PyObject_RichCompare(__pyx_v_start_ix, __pyx_int_0, Py_LT); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 93; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 93; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    if (__pyx_t_5) {
+      __Pyx_INCREF(__pyx_int_0);
+      __Pyx_DECREF(__pyx_v_start_ix);
+      __pyx_v_start_ix = __pyx_int_0;
+      goto __pyx_L15;
+    }
+    __pyx_L15:;
+
+    /* "bx/seq/_twobit.pyx":94
+ *         start_ix = bisect( seq.n_block_starts, fragStart ) - 1
+ *         if start_ix < 0: start_ix = 0
+ *         for i from start_ix <= i < n_block_count:             # <<<<<<<<<<<<<<
+ *             s = seq.n_block_starts[i];
+ *             e = s + seq.n_block_sizes[i];
+ */
+    __pyx_t_6 = __Pyx_PyInt_AsInt(__pyx_v_start_ix); if (unlikely((__pyx_t_6 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 94; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_8 = __Pyx_PyInt_AsInt(__pyx_v_n_block_count); if (unlikely((__pyx_t_8 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 94; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    for (__pyx_v_i = __pyx_t_6; __pyx_v_i < __pyx_t_8; __pyx_v_i++) {
+
+      /* "bx/seq/_twobit.pyx":95
+ *         if start_ix < 0: start_ix = 0
+ *         for i from start_ix <= i < n_block_count:
+ *             s = seq.n_block_starts[i];             # <<<<<<<<<<<<<<
+ *             e = s + seq.n_block_sizes[i];
+ *             if (s >= fragEnd):
+ */
+      __pyx_t_2 = PyObject_GetAttr(__pyx_v_seq, __pyx_n_s__n_block_starts); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 95; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_2);
+      __pyx_t_4 = __Pyx_GetItemInt(__pyx_t_2, __pyx_v_i, sizeof(int), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 95; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+      __pyx_t_9 = __Pyx_PyInt_AsInt(__pyx_t_4); if (unlikely((__pyx_t_9 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 95; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      __pyx_v_s = __pyx_t_9;
+
+      /* "bx/seq/_twobit.pyx":96
+ *         for i from start_ix <= i < n_block_count:
+ *             s = seq.n_block_starts[i];
+ *             e = s + seq.n_block_sizes[i];             # <<<<<<<<<<<<<<
+ *             if (s >= fragEnd):
+ *                 break
+ */
+      __pyx_t_4 = PyInt_FromLong(__pyx_v_s); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 96; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __pyx_t_2 = PyObject_GetAttr(__pyx_v_seq, __pyx_n_s__n_block_sizes); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 96; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_2);
+      __pyx_t_3 = __Pyx_GetItemInt(__pyx_t_2, __pyx_v_i, sizeof(int), PyInt_FromLong); if (!__pyx_t_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 96; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+      __pyx_t_2 = PyNumber_Add(__pyx_t_4, __pyx_t_3); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 96; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_2);
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_t_9 = __Pyx_PyInt_AsInt(__pyx_t_2); if (unlikely((__pyx_t_9 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 96; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+      __pyx_v_e = __pyx_t_9;
+
+      /* "bx/seq/_twobit.pyx":97
+ *             s = seq.n_block_starts[i];
+ *             e = s + seq.n_block_sizes[i];
+ *             if (s >= fragEnd):             # <<<<<<<<<<<<<<
+ *                 break
+ *             if (s < fragStart):
+ */
+      __pyx_t_5 = (__pyx_v_s >= __pyx_v_fragEnd);
+      if (__pyx_t_5) {
+
+        /* "bx/seq/_twobit.pyx":98
+ *             e = s + seq.n_block_sizes[i];
+ *             if (s >= fragEnd):
+ *                 break             # <<<<<<<<<<<<<<
+ *             if (s < fragStart):
+ *                s = fragStart
+ */
+        goto __pyx_L17_break;
+        goto __pyx_L18;
+      }
+      __pyx_L18:;
+
+      /* "bx/seq/_twobit.pyx":99
+ *             if (s >= fragEnd):
+ *                 break
+ *             if (s < fragStart):             # <<<<<<<<<<<<<<
+ *                s = fragStart
+ *             if (e > fragEnd):
+ */
+      __pyx_t_5 = (__pyx_v_s < __pyx_v_fragStart);
+      if (__pyx_t_5) {
+
+        /* "bx/seq/_twobit.pyx":100
+ *                 break
+ *             if (s < fragStart):
+ *                s = fragStart             # <<<<<<<<<<<<<<
+ *             if (e > fragEnd):
+ *                e = fragEnd
+ */
+        __pyx_v_s = __pyx_v_fragStart;
+        goto __pyx_L19;
+      }
+      __pyx_L19:;
+
+      /* "bx/seq/_twobit.pyx":101
+ *             if (s < fragStart):
+ *                s = fragStart
+ *             if (e > fragEnd):             # <<<<<<<<<<<<<<
+ *                e = fragEnd
+ *             if (s < e):
+ */
+      __pyx_t_5 = (__pyx_v_e > __pyx_v_fragEnd);
+      if (__pyx_t_5) {
+
+        /* "bx/seq/_twobit.pyx":102
+ *                s = fragStart
+ *             if (e > fragEnd):
+ *                e = fragEnd             # <<<<<<<<<<<<<<
+ *             if (s < e):
+ *                 memset( dna + s - fragStart, c'N', e - s)
+ */
+        __pyx_v_e = __pyx_v_fragEnd;
+        goto __pyx_L20;
+      }
+      __pyx_L20:;
+
+      /* "bx/seq/_twobit.pyx":103
+ *             if (e > fragEnd):
+ *                e = fragEnd
+ *             if (s < e):             # <<<<<<<<<<<<<<
+ *                 memset( dna + s - fragStart, c'N', e - s)
+ *     # Mask
+ */
+      __pyx_t_5 = (__pyx_v_s < __pyx_v_e);
+      if (__pyx_t_5) {
+
+        /* "bx/seq/_twobit.pyx":104
+ *                e = fragEnd
+ *             if (s < e):
+ *                 memset( dna + s - fragStart, c'N', e - s)             # <<<<<<<<<<<<<<
+ *     # Mask
+ *     if do_mask:
+ */
+        memset(((__pyx_v_dna + __pyx_v_s) - __pyx_v_fragStart), 'N', (__pyx_v_e - __pyx_v_s));
+        goto __pyx_L21;
+      }
+      __pyx_L21:;
+    }
+    __pyx_L17_break:;
+    goto __pyx_L14;
+  }
+  __pyx_L14:;
+
+  /* "bx/seq/_twobit.pyx":106
+ *                 memset( dna + s - fragStart, c'N', e - s)
+ *     # Mask
+ *     if do_mask:             # <<<<<<<<<<<<<<
+ *         m_block_count = len( seq.masked_block_starts )
+ *         if m_block_count > 0:
+ */
+  if (__pyx_v_do_mask) {
+
+    /* "bx/seq/_twobit.pyx":107
+ *     # Mask
+ *     if do_mask:
+ *         m_block_count = len( seq.masked_block_starts )             # <<<<<<<<<<<<<<
+ *         if m_block_count > 0:
+ *             start_ix = bisect( seq.masked_block_starts, fragStart ) - 1
+ */
+    __pyx_t_2 = PyObject_GetAttr(__pyx_v_seq, __pyx_n_s__masked_block_starts); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 107; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_t_7 = PyObject_Length(__pyx_t_2); if (unlikely(__pyx_t_7 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 107; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    __pyx_t_2 = PyInt_FromSsize_t(__pyx_t_7); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 107; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_v_m_block_count = __pyx_t_2;
+    __pyx_t_2 = 0;
+
+    /* "bx/seq/_twobit.pyx":108
+ *     if do_mask:
+ *         m_block_count = len( seq.masked_block_starts )
+ *         if m_block_count > 0:             # <<<<<<<<<<<<<<
+ *             start_ix = bisect( seq.masked_block_starts, fragStart ) - 1
+ *             if start_ix < 0: start_ix = 0
+ */
+    __pyx_t_2 = PyObject_RichCompare(__pyx_v_m_block_count, __pyx_int_0, Py_GT); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    if (__pyx_t_5) {
+
+      /* "bx/seq/_twobit.pyx":109
+ *         m_block_count = len( seq.masked_block_starts )
+ *         if m_block_count > 0:
+ *             start_ix = bisect( seq.masked_block_starts, fragStart ) - 1             # <<<<<<<<<<<<<<
+ *             if start_ix < 0: start_ix = 0
+ *             for i from start_ix <= i < m_block_count:
+ */
+      __pyx_t_2 = __Pyx_GetName(__pyx_m, __pyx_n_s__bisect); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 109; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_2);
+      __pyx_t_3 = PyObject_GetAttr(__pyx_v_seq, __pyx_n_s__masked_block_starts); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 109; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_4 = PyInt_FromLong(__pyx_v_fragStart); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 109; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 109; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_1);
+      PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_3);
+      __Pyx_GIVEREF(__pyx_t_3);
+      PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_t_4);
+      __Pyx_GIVEREF(__pyx_t_4);
+      __pyx_t_3 = 0;
+      __pyx_t_4 = 0;
+      __pyx_t_4 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 109; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+      __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+      __pyx_t_1 = PyNumber_Subtract(__pyx_t_4, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 109; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_1);
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      __Pyx_XDECREF(__pyx_v_start_ix);
+      __pyx_v_start_ix = __pyx_t_1;
+      __pyx_t_1 = 0;
+
+      /* "bx/seq/_twobit.pyx":110
+ *         if m_block_count > 0:
+ *             start_ix = bisect( seq.masked_block_starts, fragStart ) - 1
+ *             if start_ix < 0: start_ix = 0             # <<<<<<<<<<<<<<
+ *             for i from start_ix <= i < m_block_count:
+ *                 s = seq.masked_block_starts[i];
+ */
+      __pyx_t_1 = PyObject_RichCompare(__pyx_v_start_ix, __pyx_int_0, Py_LT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+      if (__pyx_t_5) {
+        __Pyx_INCREF(__pyx_int_0);
+        __Pyx_DECREF(__pyx_v_start_ix);
+        __pyx_v_start_ix = __pyx_int_0;
+        goto __pyx_L24;
+      }
+      __pyx_L24:;
+
+      /* "bx/seq/_twobit.pyx":111
+ *             start_ix = bisect( seq.masked_block_starts, fragStart ) - 1
+ *             if start_ix < 0: start_ix = 0
+ *             for i from start_ix <= i < m_block_count:             # <<<<<<<<<<<<<<
+ *                 s = seq.masked_block_starts[i];
+ *                 e = s + seq.masked_block_sizes[i];
+ */
+      __pyx_t_8 = __Pyx_PyInt_AsInt(__pyx_v_start_ix); if (unlikely((__pyx_t_8 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 111; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_6 = __Pyx_PyInt_AsInt(__pyx_v_m_block_count); if (unlikely((__pyx_t_6 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 111; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      for (__pyx_v_i = __pyx_t_8; __pyx_v_i < __pyx_t_6; __pyx_v_i++) {
+
+        /* "bx/seq/_twobit.pyx":112
+ *             if start_ix < 0: start_ix = 0
+ *             for i from start_ix <= i < m_block_count:
+ *                 s = seq.masked_block_starts[i];             # <<<<<<<<<<<<<<
+ *                 e = s + seq.masked_block_sizes[i];
+ *                 if (s >= fragEnd):
+ */
+        __pyx_t_1 = PyObject_GetAttr(__pyx_v_seq, __pyx_n_s__masked_block_starts); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 112; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_1);
+        __pyx_t_4 = __Pyx_GetItemInt(__pyx_t_1, __pyx_v_i, sizeof(int), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 112; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_4);
+        __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+        __pyx_t_9 = __Pyx_PyInt_AsInt(__pyx_t_4); if (unlikely((__pyx_t_9 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 112; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+        __pyx_v_s = __pyx_t_9;
+
+        /* "bx/seq/_twobit.pyx":113
+ *             for i from start_ix <= i < m_block_count:
+ *                 s = seq.masked_block_starts[i];
+ *                 e = s + seq.masked_block_sizes[i];             # <<<<<<<<<<<<<<
+ *                 if (s >= fragEnd):
+ *                     break
+ */
+        __pyx_t_4 = PyInt_FromLong(__pyx_v_s); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_4);
+        __pyx_t_1 = PyObject_GetAttr(__pyx_v_seq, __pyx_n_s__masked_block_sizes); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_1);
+        __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_1, __pyx_v_i, sizeof(int), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_2);
+        __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+        __pyx_t_1 = PyNumber_Add(__pyx_t_4, __pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_1);
+        __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+        __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+        __pyx_t_9 = __Pyx_PyInt_AsInt(__pyx_t_1); if (unlikely((__pyx_t_9 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+        __pyx_v_e = __pyx_t_9;
+
+        /* "bx/seq/_twobit.pyx":114
+ *                 s = seq.masked_block_starts[i];
+ *                 e = s + seq.masked_block_sizes[i];
+ *                 if (s >= fragEnd):             # <<<<<<<<<<<<<<
+ *                     break
+ *                 if (s < fragStart):
+ */
+        __pyx_t_5 = (__pyx_v_s >= __pyx_v_fragEnd);
+        if (__pyx_t_5) {
+
+          /* "bx/seq/_twobit.pyx":115
+ *                 e = s + seq.masked_block_sizes[i];
+ *                 if (s >= fragEnd):
+ *                     break             # <<<<<<<<<<<<<<
+ *                 if (s < fragStart):
+ *                    s = fragStart
+ */
+          goto __pyx_L26_break;
+          goto __pyx_L27;
+        }
+        __pyx_L27:;
+
+        /* "bx/seq/_twobit.pyx":116
+ *                 if (s >= fragEnd):
+ *                     break
+ *                 if (s < fragStart):             # <<<<<<<<<<<<<<
+ *                    s = fragStart
+ *                 if (e > fragEnd):
+ */
+        __pyx_t_5 = (__pyx_v_s < __pyx_v_fragStart);
+        if (__pyx_t_5) {
+
+          /* "bx/seq/_twobit.pyx":117
+ *                     break
+ *                 if (s < fragStart):
+ *                    s = fragStart             # <<<<<<<<<<<<<<
+ *                 if (e > fragEnd):
+ *                    e = fragEnd
+ */
+          __pyx_v_s = __pyx_v_fragStart;
+          goto __pyx_L28;
+        }
+        __pyx_L28:;
+
+        /* "bx/seq/_twobit.pyx":118
+ *                 if (s < fragStart):
+ *                    s = fragStart
+ *                 if (e > fragEnd):             # <<<<<<<<<<<<<<
+ *                    e = fragEnd
+ *                 if (s < e):
+ */
+        __pyx_t_5 = (__pyx_v_e > __pyx_v_fragEnd);
+        if (__pyx_t_5) {
+
+          /* "bx/seq/_twobit.pyx":119
+ *                    s = fragStart
+ *                 if (e > fragEnd):
+ *                    e = fragEnd             # <<<<<<<<<<<<<<
+ *                 if (s < e):
+ *                     for j from s <= j < e:
+ */
+          __pyx_v_e = __pyx_v_fragEnd;
+          goto __pyx_L29;
+        }
+        __pyx_L29:;
+
+        /* "bx/seq/_twobit.pyx":120
+ *                 if (e > fragEnd):
+ *                    e = fragEnd
+ *                 if (s < e):             # <<<<<<<<<<<<<<
+ *                     for j from s <= j < e:
+ *                         dna[j-fragStart] = tolower( dna[j-fragStart] )
+ */
+        __pyx_t_5 = (__pyx_v_s < __pyx_v_e);
+        if (__pyx_t_5) {
+
+          /* "bx/seq/_twobit.pyx":121
+ *                    e = fragEnd
+ *                 if (s < e):
+ *                     for j from s <= j < e:             # <<<<<<<<<<<<<<
+ *                         dna[j-fragStart] = tolower( dna[j-fragStart] )
+ *     return dna_py
+ */
+          __pyx_t_9 = __pyx_v_e;
+          for (__pyx_v_j = __pyx_v_s; __pyx_v_j < __pyx_t_9; __pyx_v_j++) {
+
+            /* "bx/seq/_twobit.pyx":122
+ *                 if (s < e):
+ *                     for j from s <= j < e:
+ *                         dna[j-fragStart] = tolower( dna[j-fragStart] )             # <<<<<<<<<<<<<<
+ *     return dna_py
+ */
+            (__pyx_v_dna[(__pyx_v_j - __pyx_v_fragStart)]) = tolower((__pyx_v_dna[(__pyx_v_j - __pyx_v_fragStart)]));
+          }
+          goto __pyx_L30;
+        }
+        __pyx_L30:;
+      }
+      __pyx_L26_break:;
+      goto __pyx_L23;
+    }
+    __pyx_L23:;
+    goto __pyx_L22;
+  }
+  __pyx_L22:;
+
+  /* "bx/seq/_twobit.pyx":123
+ *                     for j from s <= j < e:
+ *                         dna[j-fragStart] = tolower( dna[j-fragStart] )
+ *     return dna_py             # <<<<<<<<<<<<<<
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __Pyx_INCREF(__pyx_v_dna_py);
+  __pyx_r = __pyx_v_dna_py;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_AddTraceback("bx.seq._twobit.read", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_dna_py);
+  __Pyx_XDECREF(__pyx_v_packed_py);
+  __Pyx_XDECREF(__pyx_v_n_block_count);
+  __Pyx_XDECREF(__pyx_v_start_ix);
+  __Pyx_XDECREF(__pyx_v_m_block_count);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyMethodDef __pyx_methods[] = {
+  {0, 0, 0, 0}
+};
+
+#if PY_MAJOR_VERSION >= 3
+static struct PyModuleDef __pyx_moduledef = {
+  #if PY_VERSION_HEX < 0x03020000
+    { PyObject_HEAD_INIT(NULL) NULL, 0, NULL },
+  #else
+    PyModuleDef_HEAD_INIT,
+  #endif
+    __Pyx_NAMESTR("_twobit"),
+    0, /* m_doc */
+    -1, /* m_size */
+    __pyx_methods /* m_methods */,
+    NULL, /* m_reload */
+    NULL, /* m_traverse */
+    NULL, /* m_clear */
+    NULL /* m_free */
+};
+#endif
+
+static __Pyx_StringTabEntry __pyx_string_tab[] = {
+  {&__pyx_kp_s_3, __pyx_k_3, sizeof(__pyx_k_3), 0, 0, 1, 0},
+  {&__pyx_n_s_4, __pyx_k_4, sizeof(__pyx_k_4), 0, 0, 1, 1},
+  {&__pyx_n_s____main__, __pyx_k____main__, sizeof(__pyx_k____main__), 0, 0, 1, 1},
+  {&__pyx_n_s____test__, __pyx_k____test__, sizeof(__pyx_k____test__), 0, 0, 1, 1},
+  {&__pyx_n_s__bisect, __pyx_k__bisect, sizeof(__pyx_k__bisect), 0, 0, 1, 1},
+  {&__pyx_n_s__dna, __pyx_k__dna, sizeof(__pyx_k__dna), 0, 0, 1, 1},
+  {&__pyx_n_s__dna_orig, __pyx_k__dna_orig, sizeof(__pyx_k__dna_orig), 0, 0, 1, 1},
+  {&__pyx_n_s__dna_py, __pyx_k__dna_py, sizeof(__pyx_k__dna_py), 0, 0, 1, 1},
+  {&__pyx_n_s__do_mask, __pyx_k__do_mask, sizeof(__pyx_k__do_mask), 0, 0, 1, 1},
+  {&__pyx_n_s__e, __pyx_k__e, sizeof(__pyx_k__e), 0, 0, 1, 1},
+  {&__pyx_n_s__file, __pyx_k__file, sizeof(__pyx_k__file), 0, 0, 1, 1},
+  {&__pyx_n_s__fragEnd, __pyx_k__fragEnd, sizeof(__pyx_k__fragEnd), 0, 0, 1, 1},
+  {&__pyx_n_s__fragStart, __pyx_k__fragStart, sizeof(__pyx_k__fragStart), 0, 0, 1, 1},
+  {&__pyx_n_s__i, __pyx_k__i, sizeof(__pyx_k__i), 0, 0, 1, 1},
+  {&__pyx_n_s__j, __pyx_k__j, sizeof(__pyx_k__j), 0, 0, 1, 1},
+  {&__pyx_n_s__m_block_count, __pyx_k__m_block_count, sizeof(__pyx_k__m_block_count), 0, 0, 1, 1},
+  {&__pyx_n_s__masked_block_sizes, __pyx_k__masked_block_sizes, sizeof(__pyx_k__masked_block_sizes), 0, 0, 1, 1},
+  {&__pyx_n_s__masked_block_starts, __pyx_k__masked_block_starts, sizeof(__pyx_k__masked_block_starts), 0, 0, 1, 1},
+  {&__pyx_n_s__midEnd, __pyx_k__midEnd, sizeof(__pyx_k__midEnd), 0, 0, 1, 1},
+  {&__pyx_n_s__midStart, __pyx_k__midStart, sizeof(__pyx_k__midStart), 0, 0, 1, 1},
+  {&__pyx_n_s__n_block_count, __pyx_k__n_block_count, sizeof(__pyx_k__n_block_count), 0, 0, 1, 1},
+  {&__pyx_n_s__n_block_sizes, __pyx_k__n_block_sizes, sizeof(__pyx_k__n_block_sizes), 0, 0, 1, 1},
+  {&__pyx_n_s__n_block_starts, __pyx_k__n_block_starts, sizeof(__pyx_k__n_block_starts), 0, 0, 1, 1},
+  {&__pyx_n_s__pEnd, __pyx_k__pEnd, sizeof(__pyx_k__pEnd), 0, 0, 1, 1},
+  {&__pyx_n_s__pOff, __pyx_k__pOff, sizeof(__pyx_k__pOff), 0, 0, 1, 1},
+  {&__pyx_n_s__pStart, __pyx_k__pStart, sizeof(__pyx_k__pStart), 0, 0, 1, 1},
+  {&__pyx_n_s__packByteCount, __pyx_k__packByteCount, sizeof(__pyx_k__packByteCount), 0, 0, 1, 1},
+  {&__pyx_n_s__packed, __pyx_k__packed, sizeof(__pyx_k__packed), 0, 0, 1, 1},
+  {&__pyx_n_s__packedEnd, __pyx_k__packedEnd, sizeof(__pyx_k__packedEnd), 0, 0, 1, 1},
+  {&__pyx_n_s__packedStart, __pyx_k__packedStart, sizeof(__pyx_k__packedStart), 0, 0, 1, 1},
+  {&__pyx_n_s__packed_py, __pyx_k__packed_py, sizeof(__pyx_k__packed_py), 0, 0, 1, 1},
+  {&__pyx_n_s__partCount, __pyx_k__partCount, sizeof(__pyx_k__partCount), 0, 0, 1, 1},
+  {&__pyx_n_s__partial, __pyx_k__partial, sizeof(__pyx_k__partial), 0, 0, 1, 1},
+  {&__pyx_n_s__read, __pyx_k__read, sizeof(__pyx_k__read), 0, 0, 1, 1},
+  {&__pyx_n_s__remainder, __pyx_k__remainder, sizeof(__pyx_k__remainder), 0, 0, 1, 1},
+  {&__pyx_n_s__s, __pyx_k__s, sizeof(__pyx_k__s), 0, 0, 1, 1},
+  {&__pyx_n_s__seek, __pyx_k__seek, sizeof(__pyx_k__seek), 0, 0, 1, 1},
+  {&__pyx_n_s__seq, __pyx_k__seq, sizeof(__pyx_k__seq), 0, 0, 1, 1},
+  {&__pyx_n_s__sequence_offset, __pyx_k__sequence_offset, sizeof(__pyx_k__sequence_offset), 0, 0, 1, 1},
+  {&__pyx_n_s__start_ix, __pyx_k__start_ix, sizeof(__pyx_k__start_ix), 0, 0, 1, 1},
+  {&__pyx_n_s__struct, __pyx_k__struct, sizeof(__pyx_k__struct), 0, 0, 1, 1},
+  {&__pyx_n_s__sys, __pyx_k__sys, sizeof(__pyx_k__sys), 0, 0, 1, 1},
+  {0, 0, 0, 0, 0, 0, 0}
+};
+static int __Pyx_InitCachedBuiltins(void) {
+  return 0;
+}
+
+static int __Pyx_InitCachedConstants(void) {
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0);
+
+  /* "bx/seq/_twobit.pyx":19
+ * valToNt = "TCAG"
+ * 
+ * def read( file, seq, int fragStart, int fragEnd, bint do_mask ):             # <<<<<<<<<<<<<<
+ *     """
+ *     Stolen directly from Jim Kent's twoBit.c
+ */
+  __pyx_k_tuple_1 = PyTuple_Pack(28, ((PyObject *)__pyx_n_s__file), ((PyObject *)__pyx_n_s__seq), ((PyObject *)__pyx_n_s__fragStart), ((PyObject *)__pyx_n_s__fragEnd), ((PyObject *)__pyx_n_s__do_mask), ((PyObject *)__pyx_n_s__packedStart), ((PyObject *)__pyx_n_s__packedEnd), ((PyObject *)__pyx_n_s__packByteCount), ((PyObject *)__pyx_n_s__pOff), ((PyObject *)__pyx_n_s__pStart), ((PyObject *)__pyx_n_s__pEnd), ((PyObject *)__pyx_n_s__midStart), ((PyObject *)__pyx_n_s__remainder), ((PyObject [...]
+  __Pyx_GOTREF(__pyx_k_tuple_1);
+  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_1));
+  __pyx_k_codeobj_2 = (PyObject*)__Pyx_PyCode_New(5, 0, 28, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_k_tuple_1, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_3, __pyx_n_s__read, 19, __pyx_empty_bytes); if (unlikely(!__pyx_k_codeobj_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 19; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_RefNannyFinishContext();
+  return 0;
+  __pyx_L1_error:;
+  __Pyx_RefNannyFinishContext();
+  return -1;
+}
+
+static int __Pyx_InitGlobals(void) {
+  if (__Pyx_InitStrings(__pyx_string_tab) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  __pyx_int_0 = PyInt_FromLong(0); if (unlikely(!__pyx_int_0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  __pyx_int_1 = PyInt_FromLong(1); if (unlikely(!__pyx_int_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  return 0;
+  __pyx_L1_error:;
+  return -1;
+}
+
+#if PY_MAJOR_VERSION < 3
+PyMODINIT_FUNC init_twobit(void); /*proto*/
+PyMODINIT_FUNC init_twobit(void)
+#else
+PyMODINIT_FUNC PyInit__twobit(void); /*proto*/
+PyMODINIT_FUNC PyInit__twobit(void)
+#endif
+{
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  __Pyx_RefNannyDeclarations
+  #if CYTHON_REFNANNY
+  __Pyx_RefNanny = __Pyx_RefNannyImportAPI("refnanny");
+  if (!__Pyx_RefNanny) {
+      PyErr_Clear();
+      __Pyx_RefNanny = __Pyx_RefNannyImportAPI("Cython.Runtime.refnanny");
+      if (!__Pyx_RefNanny)
+          Py_FatalError("failed to import 'refnanny' module");
+  }
+  #endif
+  __Pyx_RefNannySetupContext("PyMODINIT_FUNC PyInit__twobit(void)", 0);
+  if ( __Pyx_check_binary_version() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_bytes)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #ifdef __Pyx_CyFunction_USED
+  if (__Pyx_CyFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #endif
+  #ifdef __Pyx_FusedFunction_USED
+  if (__pyx_FusedFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #endif
+  #ifdef __Pyx_Generator_USED
+  if (__pyx_Generator_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #endif
+  /*--- Library function declarations ---*/
+  /*--- Threads initialization code ---*/
+  #if defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS
+  #ifdef WITH_THREAD /* Python build with threading support? */
+  PyEval_InitThreads();
+  #endif
+  #endif
+  /*--- Module creation code ---*/
+  #if PY_MAJOR_VERSION < 3
+  __pyx_m = Py_InitModule4(__Pyx_NAMESTR("_twobit"), __pyx_methods, 0, 0, PYTHON_API_VERSION); Py_XINCREF(__pyx_m);
+  #else
+  __pyx_m = PyModule_Create(&__pyx_moduledef);
+  #endif
+  if (unlikely(!__pyx_m)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #if PY_MAJOR_VERSION >= 3
+  {
+    PyObject *modules = PyImport_GetModuleDict(); if (unlikely(!modules)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (!PyDict_GetItemString(modules, "bx.seq._twobit")) {
+      if (unlikely(PyDict_SetItemString(modules, "bx.seq._twobit", __pyx_m) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+  }
+  #endif
+  __pyx_b = PyImport_AddModule(__Pyx_NAMESTR(__Pyx_BUILTIN_MODULE_NAME)); if (unlikely(!__pyx_b)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #if CYTHON_COMPILING_IN_PYPY
+  Py_INCREF(__pyx_b);
+  #endif
+  if (__Pyx_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  /*--- Initialize various global constants etc. ---*/
+  if (unlikely(__Pyx_InitGlobals() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (__pyx_module_is_main_bx__seq___twobit) {
+    if (__Pyx_SetAttrString(__pyx_m, "__name__", __pyx_n_s____main__) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  }
+  /*--- Builtin init code ---*/
+  if (unlikely(__Pyx_InitCachedBuiltins() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  /*--- Constants init code ---*/
+  if (unlikely(__Pyx_InitCachedConstants() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  /*--- Global init code ---*/
+  /*--- Variable export code ---*/
+  /*--- Function export code ---*/
+  /*--- Type init code ---*/
+  /*--- Type import code ---*/
+  /*--- Variable import code ---*/
+  /*--- Function import code ---*/
+  /*--- Execution code ---*/
+
+  /* "bx/seq/_twobit.pyx":12
+ *     void * memset( void *, int, int )
+ * 
+ * import struct, sys             # <<<<<<<<<<<<<<
+ * 
+ * from bisect import bisect
+ */
+  __pyx_t_1 = __Pyx_Import(((PyObject *)__pyx_n_s__struct), 0, -1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 12; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s__struct, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 12; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_1 = __Pyx_Import(((PyObject *)__pyx_n_s__sys), 0, -1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 12; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s__sys, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 12; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "bx/seq/_twobit.pyx":14
+ * import struct, sys
+ * 
+ * from bisect import bisect             # <<<<<<<<<<<<<<
+ * 
+ * cdef char* valToNt
+ */
+  __pyx_t_1 = PyList_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 14; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_INCREF(((PyObject *)__pyx_n_s__bisect));
+  PyList_SET_ITEM(__pyx_t_1, 0, ((PyObject *)__pyx_n_s__bisect));
+  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__bisect));
+  __pyx_t_2 = __Pyx_Import(((PyObject *)__pyx_n_s__bisect), ((PyObject *)__pyx_t_1), -1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 14; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+  __pyx_t_1 = PyObject_GetAttr(__pyx_t_2, __pyx_n_s__bisect);
+  if (__pyx_t_1 == NULL) {
+    if (PyErr_ExceptionMatches(PyExc_AttributeError)) __Pyx_RaiseImportError(__pyx_n_s__bisect);
+    if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 14; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s__bisect, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 14; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+  /* "bx/seq/_twobit.pyx":17
+ * 
+ * cdef char* valToNt
+ * valToNt = "TCAG"             # <<<<<<<<<<<<<<
+ * 
+ * def read( file, seq, int fragStart, int fragEnd, bint do_mask ):
+ */
+  __pyx_v_2bx_3seq_7_twobit_valToNt = __pyx_k__TCAG;
+
+  /* "bx/seq/_twobit.pyx":19
+ * valToNt = "TCAG"
+ * 
+ * def read( file, seq, int fragStart, int fragEnd, bint do_mask ):             # <<<<<<<<<<<<<<
+ *     """
+ *     Stolen directly from Jim Kent's twoBit.c
+ */
+  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_2bx_3seq_7_twobit_1read, NULL, __pyx_n_s_4); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 19; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s__read, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 19; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+  /* "bx/seq/_twobit.pyx":1
+ * cdef extern from "Python.h":             # <<<<<<<<<<<<<<
+ *     char * PyString_AsString( object )
+ *     object PyString_FromStringAndSize( char *, int )
+ */
+  __pyx_t_2 = PyDict_New(); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(((PyObject *)__pyx_t_2));
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s____test__, ((PyObject *)__pyx_t_2)) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  if (__pyx_m) {
+    __Pyx_AddTraceback("init bx.seq._twobit", __pyx_clineno, __pyx_lineno, __pyx_filename);
+    Py_DECREF(__pyx_m); __pyx_m = 0;
+  } else if (!PyErr_Occurred()) {
+    PyErr_SetString(PyExc_ImportError, "init bx.seq._twobit");
+  }
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  #if PY_MAJOR_VERSION < 3
+  return;
+  #else
+  return __pyx_m;
+  #endif
+}
+
+/* Runtime support code */
+#if CYTHON_REFNANNY
+static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) {
+    PyObject *m = NULL, *p = NULL;
+    void *r = NULL;
+    m = PyImport_ImportModule((char *)modname);
+    if (!m) goto end;
+    p = PyObject_GetAttrString(m, (char *)"RefNannyAPI");
+    if (!p) goto end;
+    r = PyLong_AsVoidPtr(p);
+end:
+    Py_XDECREF(p);
+    Py_XDECREF(m);
+    return (__Pyx_RefNannyAPIStruct *)r;
+}
+#endif /* CYTHON_REFNANNY */
+
+static void __Pyx_RaiseArgtupleInvalid(
+    const char* func_name,
+    int exact,
+    Py_ssize_t num_min,
+    Py_ssize_t num_max,
+    Py_ssize_t num_found)
+{
+    Py_ssize_t num_expected;
+    const char *more_or_less;
+    if (num_found < num_min) {
+        num_expected = num_min;
+        more_or_less = "at least";
+    } else {
+        num_expected = num_max;
+        more_or_less = "at most";
+    }
+    if (exact) {
+        more_or_less = "exactly";
+    }
+    PyErr_Format(PyExc_TypeError,
+                 "%s() takes %s %" CYTHON_FORMAT_SSIZE_T "d positional argument%s (%" CYTHON_FORMAT_SSIZE_T "d given)",
+                 func_name, more_or_less, num_expected,
+                 (num_expected == 1) ? "" : "s", num_found);
+}
+
+static void __Pyx_RaiseDoubleKeywordsError(
+    const char* func_name,
+    PyObject* kw_name)
+{
+    PyErr_Format(PyExc_TypeError,
+        #if PY_MAJOR_VERSION >= 3
+        "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
+        #else
+        "%s() got multiple values for keyword argument '%s'", func_name,
+        PyString_AsString(kw_name));
+        #endif
+}
+
+static int __Pyx_ParseOptionalKeywords(
+    PyObject *kwds,
+    PyObject **argnames[],
+    PyObject *kwds2,
+    PyObject *values[],
+    Py_ssize_t num_pos_args,
+    const char* function_name)
+{
+    PyObject *key = 0, *value = 0;
+    Py_ssize_t pos = 0;
+    PyObject*** name;
+    PyObject*** first_kw_arg = argnames + num_pos_args;
+    while (PyDict_Next(kwds, &pos, &key, &value)) {
+        name = first_kw_arg;
+        while (*name && (**name != key)) name++;
+        if (*name) {
+            values[name-argnames] = value;
+            continue;
+        }
+        name = first_kw_arg;
+        #if PY_MAJOR_VERSION < 3
+        if (likely(PyString_CheckExact(key)) || likely(PyString_Check(key))) {
+            while (*name) {
+                if ((CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**name) == PyString_GET_SIZE(key))
+                        && _PyString_Eq(**name, key)) {
+                    values[name-argnames] = value;
+                    break;
+                }
+                name++;
+            }
+            if (*name) continue;
+            else {
+                PyObject*** argname = argnames;
+                while (argname != first_kw_arg) {
+                    if ((**argname == key) || (
+                            (CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**argname) == PyString_GET_SIZE(key))
+                             && _PyString_Eq(**argname, key))) {
+                        goto arg_passed_twice;
+                    }
+                    argname++;
+                }
+            }
+        } else
+        #endif
+        if (likely(PyUnicode_Check(key))) {
+            while (*name) {
+                int cmp = (**name == key) ? 0 :
+                #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3
+                    (PyUnicode_GET_SIZE(**name) != PyUnicode_GET_SIZE(key)) ? 1 :
+                #endif
+                    PyUnicode_Compare(**name, key);
+                if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad;
+                if (cmp == 0) {
+                    values[name-argnames] = value;
+                    break;
+                }
+                name++;
+            }
+            if (*name) continue;
+            else {
+                PyObject*** argname = argnames;
+                while (argname != first_kw_arg) {
+                    int cmp = (**argname == key) ? 0 :
+                    #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3
+                        (PyUnicode_GET_SIZE(**argname) != PyUnicode_GET_SIZE(key)) ? 1 :
+                    #endif
+                        PyUnicode_Compare(**argname, key);
+                    if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad;
+                    if (cmp == 0) goto arg_passed_twice;
+                    argname++;
+                }
+            }
+        } else
+            goto invalid_keyword_type;
+        if (kwds2) {
+            if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
+        } else {
+            goto invalid_keyword;
+        }
+    }
+    return 0;
+arg_passed_twice:
+    __Pyx_RaiseDoubleKeywordsError(function_name, key);
+    goto bad;
+invalid_keyword_type:
+    PyErr_Format(PyExc_TypeError,
+        "%s() keywords must be strings", function_name);
+    goto bad;
+invalid_keyword:
+    PyErr_Format(PyExc_TypeError,
+    #if PY_MAJOR_VERSION < 3
+        "%s() got an unexpected keyword argument '%s'",
+        function_name, PyString_AsString(key));
+    #else
+        "%s() got an unexpected keyword argument '%U'",
+        function_name, key);
+    #endif
+bad:
+    return -1;
+}
+
+static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name) {
+    PyObject *result;
+    result = PyObject_GetAttr(dict, name);
+    if (!result) {
+        if (dict != __pyx_b) {
+            PyErr_Clear();
+            result = PyObject_GetAttr(__pyx_b, name);
+        }
+        if (!result) {
+            PyErr_SetObject(PyExc_NameError, name);
+        }
+    }
+    return result;
+}
+
+static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level) {
+    PyObject *empty_list = 0;
+    PyObject *module = 0;
+    PyObject *global_dict = 0;
+    PyObject *empty_dict = 0;
+    PyObject *list;
+    #if PY_VERSION_HEX < 0x03030000
+    PyObject *py_import = 0;
+    py_import = __Pyx_GetAttrString(__pyx_b, "__import__");
+    if (!py_import)
+        goto bad;
+    #endif
+    if (from_list)
+        list = from_list;
+    else {
+        empty_list = PyList_New(0);
+        if (!empty_list)
+            goto bad;
+        list = empty_list;
+    }
+    global_dict = PyModule_GetDict(__pyx_m);
+    if (!global_dict)
+        goto bad;
+    empty_dict = PyDict_New();
+    if (!empty_dict)
+        goto bad;
+    #if PY_VERSION_HEX >= 0x02050000
+    {
+        #if PY_MAJOR_VERSION >= 3
+        if (level == -1) {
+            if (strchr(__Pyx_MODULE_NAME, '.')) {
+                #if PY_VERSION_HEX < 0x03030000
+                PyObject *py_level = PyInt_FromLong(1);
+                if (!py_level)
+                    goto bad;
+                module = PyObject_CallFunctionObjArgs(py_import,
+                    name, global_dict, empty_dict, list, py_level, NULL);
+                Py_DECREF(py_level);
+                #else
+                module = PyImport_ImportModuleLevelObject(
+                    name, global_dict, empty_dict, list, 1);
+                #endif
+                if (!module) {
+                    if (!PyErr_ExceptionMatches(PyExc_ImportError))
+                        goto bad;
+                    PyErr_Clear();
+                }
+            }
+            level = 0; /* try absolute import on failure */
+        }
+        #endif
+        if (!module) {
+            #if PY_VERSION_HEX < 0x03030000
+            PyObject *py_level = PyInt_FromLong(level);
+            if (!py_level)
+                goto bad;
+            module = PyObject_CallFunctionObjArgs(py_import,
+                name, global_dict, empty_dict, list, py_level, NULL);
+            Py_DECREF(py_level);
+            #else
+            module = PyImport_ImportModuleLevelObject(
+                name, global_dict, empty_dict, list, level);
+            #endif
+        }
+    }
+    #else
+    if (level>0) {
+        PyErr_SetString(PyExc_RuntimeError, "Relative import is not supported for Python <=2.4.");
+        goto bad;
+    }
+    module = PyObject_CallFunctionObjArgs(py_import,
+        name, global_dict, empty_dict, list, NULL);
+    #endif
+bad:
+    #if PY_VERSION_HEX < 0x03030000
+    Py_XDECREF(py_import);
+    #endif
+    Py_XDECREF(empty_list);
+    Py_XDECREF(empty_dict);
+    return module;
+}
+
+static CYTHON_INLINE void __Pyx_RaiseImportError(PyObject *name) {
+#if PY_MAJOR_VERSION < 3
+    PyErr_Format(PyExc_ImportError, "cannot import name %.230s",
+                 PyString_AsString(name));
+#else
+    PyErr_Format(PyExc_ImportError, "cannot import name %S", name);
+#endif
+}
+
+static CYTHON_INLINE unsigned char __Pyx_PyInt_AsUnsignedChar(PyObject* x) {
+    const unsigned char neg_one = (unsigned char)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(unsigned char) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(unsigned char)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to unsigned char" :
+                    "value too large to convert to unsigned char");
+            }
+            return (unsigned char)-1;
+        }
+        return (unsigned char)val;
+    }
+    return (unsigned char)__Pyx_PyInt_AsUnsignedLong(x);
+}
+
+static CYTHON_INLINE unsigned short __Pyx_PyInt_AsUnsignedShort(PyObject* x) {
+    const unsigned short neg_one = (unsigned short)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(unsigned short) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(unsigned short)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to unsigned short" :
+                    "value too large to convert to unsigned short");
+            }
+            return (unsigned short)-1;
+        }
+        return (unsigned short)val;
+    }
+    return (unsigned short)__Pyx_PyInt_AsUnsignedLong(x);
+}
+
+static CYTHON_INLINE unsigned int __Pyx_PyInt_AsUnsignedInt(PyObject* x) {
+    const unsigned int neg_one = (unsigned int)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(unsigned int) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(unsigned int)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to unsigned int" :
+                    "value too large to convert to unsigned int");
+            }
+            return (unsigned int)-1;
+        }
+        return (unsigned int)val;
+    }
+    return (unsigned int)__Pyx_PyInt_AsUnsignedLong(x);
+}
+
+static CYTHON_INLINE char __Pyx_PyInt_AsChar(PyObject* x) {
+    const char neg_one = (char)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(char) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(char)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to char" :
+                    "value too large to convert to char");
+            }
+            return (char)-1;
+        }
+        return (char)val;
+    }
+    return (char)__Pyx_PyInt_AsLong(x);
+}
+
+static CYTHON_INLINE short __Pyx_PyInt_AsShort(PyObject* x) {
+    const short neg_one = (short)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(short) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(short)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to short" :
+                    "value too large to convert to short");
+            }
+            return (short)-1;
+        }
+        return (short)val;
+    }
+    return (short)__Pyx_PyInt_AsLong(x);
+}
+
+static CYTHON_INLINE int __Pyx_PyInt_AsInt(PyObject* x) {
+    const int neg_one = (int)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(int) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(int)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to int" :
+                    "value too large to convert to int");
+            }
+            return (int)-1;
+        }
+        return (int)val;
+    }
+    return (int)__Pyx_PyInt_AsLong(x);
+}
+
+static CYTHON_INLINE signed char __Pyx_PyInt_AsSignedChar(PyObject* x) {
+    const signed char neg_one = (signed char)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(signed char) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(signed char)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to signed char" :
+                    "value too large to convert to signed char");
+            }
+            return (signed char)-1;
+        }
+        return (signed char)val;
+    }
+    return (signed char)__Pyx_PyInt_AsSignedLong(x);
+}
+
+static CYTHON_INLINE signed short __Pyx_PyInt_AsSignedShort(PyObject* x) {
+    const signed short neg_one = (signed short)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(signed short) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(signed short)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to signed short" :
+                    "value too large to convert to signed short");
+            }
+            return (signed short)-1;
+        }
+        return (signed short)val;
+    }
+    return (signed short)__Pyx_PyInt_AsSignedLong(x);
+}
+
+static CYTHON_INLINE signed int __Pyx_PyInt_AsSignedInt(PyObject* x) {
+    const signed int neg_one = (signed int)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(signed int) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(signed int)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to signed int" :
+                    "value too large to convert to signed int");
+            }
+            return (signed int)-1;
+        }
+        return (signed int)val;
+    }
+    return (signed int)__Pyx_PyInt_AsSignedLong(x);
+}
+
+static CYTHON_INLINE int __Pyx_PyInt_AsLongDouble(PyObject* x) {
+    const int neg_one = (int)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(int) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(int)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to int" :
+                    "value too large to convert to int");
+            }
+            return (int)-1;
+        }
+        return (int)val;
+    }
+    return (int)__Pyx_PyInt_AsLong(x);
+}
+
+static CYTHON_INLINE unsigned long __Pyx_PyInt_AsUnsignedLong(PyObject* x) {
+    const unsigned long neg_one = (unsigned long)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to unsigned long");
+            return (unsigned long)-1;
+        }
+        return (unsigned long)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to unsigned long");
+                return (unsigned long)-1;
+            }
+            return (unsigned long)PyLong_AsUnsignedLong(x);
+        } else {
+            return (unsigned long)PyLong_AsLong(x);
+        }
+    } else {
+        unsigned long val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (unsigned long)-1;
+        val = __Pyx_PyInt_AsUnsignedLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE unsigned PY_LONG_LONG __Pyx_PyInt_AsUnsignedLongLong(PyObject* x) {
+    const unsigned PY_LONG_LONG neg_one = (unsigned PY_LONG_LONG)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to unsigned PY_LONG_LONG");
+            return (unsigned PY_LONG_LONG)-1;
+        }
+        return (unsigned PY_LONG_LONG)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to unsigned PY_LONG_LONG");
+                return (unsigned PY_LONG_LONG)-1;
+            }
+            return (unsigned PY_LONG_LONG)PyLong_AsUnsignedLongLong(x);
+        } else {
+            return (unsigned PY_LONG_LONG)PyLong_AsLongLong(x);
+        }
+    } else {
+        unsigned PY_LONG_LONG val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (unsigned PY_LONG_LONG)-1;
+        val = __Pyx_PyInt_AsUnsignedLongLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE long __Pyx_PyInt_AsLong(PyObject* x) {
+    const long neg_one = (long)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to long");
+            return (long)-1;
+        }
+        return (long)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to long");
+                return (long)-1;
+            }
+            return (long)PyLong_AsUnsignedLong(x);
+        } else {
+            return (long)PyLong_AsLong(x);
+        }
+    } else {
+        long val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (long)-1;
+        val = __Pyx_PyInt_AsLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE PY_LONG_LONG __Pyx_PyInt_AsLongLong(PyObject* x) {
+    const PY_LONG_LONG neg_one = (PY_LONG_LONG)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to PY_LONG_LONG");
+            return (PY_LONG_LONG)-1;
+        }
+        return (PY_LONG_LONG)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to PY_LONG_LONG");
+                return (PY_LONG_LONG)-1;
+            }
+            return (PY_LONG_LONG)PyLong_AsUnsignedLongLong(x);
+        } else {
+            return (PY_LONG_LONG)PyLong_AsLongLong(x);
+        }
+    } else {
+        PY_LONG_LONG val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (PY_LONG_LONG)-1;
+        val = __Pyx_PyInt_AsLongLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE signed long __Pyx_PyInt_AsSignedLong(PyObject* x) {
+    const signed long neg_one = (signed long)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to signed long");
+            return (signed long)-1;
+        }
+        return (signed long)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to signed long");
+                return (signed long)-1;
+            }
+            return (signed long)PyLong_AsUnsignedLong(x);
+        } else {
+            return (signed long)PyLong_AsLong(x);
+        }
+    } else {
+        signed long val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (signed long)-1;
+        val = __Pyx_PyInt_AsSignedLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE signed PY_LONG_LONG __Pyx_PyInt_AsSignedLongLong(PyObject* x) {
+    const signed PY_LONG_LONG neg_one = (signed PY_LONG_LONG)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to signed PY_LONG_LONG");
+            return (signed PY_LONG_LONG)-1;
+        }
+        return (signed PY_LONG_LONG)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to signed PY_LONG_LONG");
+                return (signed PY_LONG_LONG)-1;
+            }
+            return (signed PY_LONG_LONG)PyLong_AsUnsignedLongLong(x);
+        } else {
+            return (signed PY_LONG_LONG)PyLong_AsLongLong(x);
+        }
+    } else {
+        signed PY_LONG_LONG val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (signed PY_LONG_LONG)-1;
+        val = __Pyx_PyInt_AsSignedLongLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static int __Pyx_check_binary_version(void) {
+    char ctversion[4], rtversion[4];
+    PyOS_snprintf(ctversion, 4, "%d.%d", PY_MAJOR_VERSION, PY_MINOR_VERSION);
+    PyOS_snprintf(rtversion, 4, "%s", Py_GetVersion());
+    if (ctversion[0] != rtversion[0] || ctversion[2] != rtversion[2]) {
+        char message[200];
+        PyOS_snprintf(message, sizeof(message),
+                      "compiletime version %s of module '%.100s' "
+                      "does not match runtime version %s",
+                      ctversion, __Pyx_MODULE_NAME, rtversion);
+        #if PY_VERSION_HEX < 0x02050000
+        return PyErr_Warn(NULL, message);
+        #else
+        return PyErr_WarnEx(NULL, message, 1);
+        #endif
+    }
+    return 0;
+}
+
+static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) {
+    int start = 0, mid = 0, end = count - 1;
+    if (end >= 0 && code_line > entries[end].code_line) {
+        return count;
+    }
+    while (start < end) {
+        mid = (start + end) / 2;
+        if (code_line < entries[mid].code_line) {
+            end = mid;
+        } else if (code_line > entries[mid].code_line) {
+             start = mid + 1;
+        } else {
+            return mid;
+        }
+    }
+    if (code_line <= entries[mid].code_line) {
+        return mid;
+    } else {
+        return mid + 1;
+    }
+}
+static PyCodeObject *__pyx_find_code_object(int code_line) {
+    PyCodeObject* code_object;
+    int pos;
+    if (unlikely(!code_line) || unlikely(!__pyx_code_cache.entries)) {
+        return NULL;
+    }
+    pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line);
+    if (unlikely(pos >= __pyx_code_cache.count) || unlikely(__pyx_code_cache.entries[pos].code_line != code_line)) {
+        return NULL;
+    }
+    code_object = __pyx_code_cache.entries[pos].code_object;
+    Py_INCREF(code_object);
+    return code_object;
+}
+static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) {
+    int pos, i;
+    __Pyx_CodeObjectCacheEntry* entries = __pyx_code_cache.entries;
+    if (unlikely(!code_line)) {
+        return;
+    }
+    if (unlikely(!entries)) {
+        entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Malloc(64*sizeof(__Pyx_CodeObjectCacheEntry));
+        if (likely(entries)) {
+            __pyx_code_cache.entries = entries;
+            __pyx_code_cache.max_count = 64;
+            __pyx_code_cache.count = 1;
+            entries[0].code_line = code_line;
+            entries[0].code_object = code_object;
+            Py_INCREF(code_object);
+        }
+        return;
+    }
+    pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line);
+    if ((pos < __pyx_code_cache.count) && unlikely(__pyx_code_cache.entries[pos].code_line == code_line)) {
+        PyCodeObject* tmp = entries[pos].code_object;
+        entries[pos].code_object = code_object;
+        Py_DECREF(tmp);
+        return;
+    }
+    if (__pyx_code_cache.count == __pyx_code_cache.max_count) {
+        int new_max = __pyx_code_cache.max_count + 64;
+        entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Realloc(
+            __pyx_code_cache.entries, new_max*sizeof(__Pyx_CodeObjectCacheEntry));
+        if (unlikely(!entries)) {
+            return;
+        }
+        __pyx_code_cache.entries = entries;
+        __pyx_code_cache.max_count = new_max;
+    }
+    for (i=__pyx_code_cache.count; i>pos; i--) {
+        entries[i] = entries[i-1];
+    }
+    entries[pos].code_line = code_line;
+    entries[pos].code_object = code_object;
+    __pyx_code_cache.count++;
+    Py_INCREF(code_object);
+}
+
+#include "compile.h"
+#include "frameobject.h"
+#include "traceback.h"
+static PyCodeObject* __Pyx_CreateCodeObjectForTraceback(
+            const char *funcname, int c_line,
+            int py_line, const char *filename) {
+    PyCodeObject *py_code = 0;
+    PyObject *py_srcfile = 0;
+    PyObject *py_funcname = 0;
+    #if PY_MAJOR_VERSION < 3
+    py_srcfile = PyString_FromString(filename);
+    #else
+    py_srcfile = PyUnicode_FromString(filename);
+    #endif
+    if (!py_srcfile) goto bad;
+    if (c_line) {
+        #if PY_MAJOR_VERSION < 3
+        py_funcname = PyString_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line);
+        #else
+        py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line);
+        #endif
+    }
+    else {
+        #if PY_MAJOR_VERSION < 3
+        py_funcname = PyString_FromString(funcname);
+        #else
+        py_funcname = PyUnicode_FromString(funcname);
+        #endif
+    }
+    if (!py_funcname) goto bad;
+    py_code = __Pyx_PyCode_New(
+        0,            /*int argcount,*/
+        0,            /*int kwonlyargcount,*/
+        0,            /*int nlocals,*/
+        0,            /*int stacksize,*/
+        0,            /*int flags,*/
+        __pyx_empty_bytes, /*PyObject *code,*/
+        __pyx_empty_tuple, /*PyObject *consts,*/
+        __pyx_empty_tuple, /*PyObject *names,*/
+        __pyx_empty_tuple, /*PyObject *varnames,*/
+        __pyx_empty_tuple, /*PyObject *freevars,*/
+        __pyx_empty_tuple, /*PyObject *cellvars,*/
+        py_srcfile,   /*PyObject *filename,*/
+        py_funcname,  /*PyObject *name,*/
+        py_line,      /*int firstlineno,*/
+        __pyx_empty_bytes  /*PyObject *lnotab*/
+    );
+    Py_DECREF(py_srcfile);
+    Py_DECREF(py_funcname);
+    return py_code;
+bad:
+    Py_XDECREF(py_srcfile);
+    Py_XDECREF(py_funcname);
+    return NULL;
+}
+static void __Pyx_AddTraceback(const char *funcname, int c_line,
+                               int py_line, const char *filename) {
+    PyCodeObject *py_code = 0;
+    PyObject *py_globals = 0;
+    PyFrameObject *py_frame = 0;
+    py_code = __pyx_find_code_object(c_line ? c_line : py_line);
+    if (!py_code) {
+        py_code = __Pyx_CreateCodeObjectForTraceback(
+            funcname, c_line, py_line, filename);
+        if (!py_code) goto bad;
+        __pyx_insert_code_object(c_line ? c_line : py_line, py_code);
+    }
+    py_globals = PyModule_GetDict(__pyx_m);
+    if (!py_globals) goto bad;
+    py_frame = PyFrame_New(
+        PyThreadState_GET(), /*PyThreadState *tstate,*/
+        py_code,             /*PyCodeObject *code,*/
+        py_globals,          /*PyObject *globals,*/
+        0                    /*PyObject *locals*/
+    );
+    if (!py_frame) goto bad;
+    py_frame->f_lineno = py_line;
+    PyTraceBack_Here(py_frame);
+bad:
+    Py_XDECREF(py_code);
+    Py_XDECREF(py_frame);
+}
+
+static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
+    while (t->p) {
+        #if PY_MAJOR_VERSION < 3
+        if (t->is_unicode) {
+            *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
+        } else if (t->intern) {
+            *t->p = PyString_InternFromString(t->s);
+        } else {
+            *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
+        }
+        #else  /* Python 3+ has unicode identifiers */
+        if (t->is_unicode | t->is_str) {
+            if (t->intern) {
+                *t->p = PyUnicode_InternFromString(t->s);
+            } else if (t->encoding) {
+                *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL);
+            } else {
+                *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
+            }
+        } else {
+            *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
+        }
+        #endif
+        if (!*t->p)
+            return -1;
+        ++t;
+    }
+    return 0;
+}
+
+static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) {
+   int is_true = x == Py_True;
+   if (is_true | (x == Py_False) | (x == Py_None)) return is_true;
+   else return PyObject_IsTrue(x);
+}
+static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x) {
+  PyNumberMethods *m;
+  const char *name = NULL;
+  PyObject *res = NULL;
+#if PY_VERSION_HEX < 0x03000000
+  if (PyInt_Check(x) || PyLong_Check(x))
+#else
+  if (PyLong_Check(x))
+#endif
+    return Py_INCREF(x), x;
+  m = Py_TYPE(x)->tp_as_number;
+#if PY_VERSION_HEX < 0x03000000
+  if (m && m->nb_int) {
+    name = "int";
+    res = PyNumber_Int(x);
+  }
+  else if (m && m->nb_long) {
+    name = "long";
+    res = PyNumber_Long(x);
+  }
+#else
+  if (m && m->nb_int) {
+    name = "int";
+    res = PyNumber_Long(x);
+  }
+#endif
+  if (res) {
+#if PY_VERSION_HEX < 0x03000000
+    if (!PyInt_Check(res) && !PyLong_Check(res)) {
+#else
+    if (!PyLong_Check(res)) {
+#endif
+      PyErr_Format(PyExc_TypeError,
+                   "__%s__ returned non-%s (type %.200s)",
+                   name, name, Py_TYPE(res)->tp_name);
+      Py_DECREF(res);
+      return NULL;
+    }
+  }
+  else if (!PyErr_Occurred()) {
+    PyErr_SetString(PyExc_TypeError,
+                    "an integer is required");
+  }
+  return res;
+}
+static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) {
+  Py_ssize_t ival;
+  PyObject* x = PyNumber_Index(b);
+  if (!x) return -1;
+  ival = PyInt_AsSsize_t(x);
+  Py_DECREF(x);
+  return ival;
+}
+static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) {
+#if PY_VERSION_HEX < 0x02050000
+   if (ival <= LONG_MAX)
+       return PyInt_FromLong((long)ival);
+   else {
+       unsigned char *bytes = (unsigned char *) &ival;
+       int one = 1; int little = (int)*(unsigned char*)&one;
+       return _PyLong_FromByteArray(bytes, sizeof(size_t), little, 0);
+   }
+#else
+   return PyInt_FromSize_t(ival);
+#endif
+}
+static CYTHON_INLINE size_t __Pyx_PyInt_AsSize_t(PyObject* x) {
+   unsigned PY_LONG_LONG val = __Pyx_PyInt_AsUnsignedLongLong(x);
+   if (unlikely(val == (unsigned PY_LONG_LONG)-1 && PyErr_Occurred())) {
+       return (size_t)-1;
+   } else if (unlikely(val != (unsigned PY_LONG_LONG)(size_t)val)) {
+       PyErr_SetString(PyExc_OverflowError,
+                       "value too large to convert to size_t");
+       return (size_t)-1;
+   }
+   return (size_t)val;
+}
+
+
+#endif /* Py_PYTHON_H */
diff --git a/lib/bx/seq/_twobit.pyx b/lib/bx/seq/_twobit.pyx
new file mode 100644
index 0000000..3fd4e33
--- /dev/null
+++ b/lib/bx/seq/_twobit.pyx
@@ -0,0 +1,123 @@
+cdef extern from "Python.h":
+    char * PyString_AsString( object )
+    object PyString_FromStringAndSize( char *, int )
+    int _PyString_Resize( object, int ) except -1
+
+cdef extern from "ctype.h":
+    int tolower( int )
+    
+cdef extern from "string.h":
+    void * memset( void *, int, int )
+
+import struct, sys
+
+from bisect import bisect
+
+cdef char* valToNt
+valToNt = "TCAG"
+
+def read( file, seq, int fragStart, int fragEnd, bint do_mask ):
+    """
+    Stolen directly from Jim Kent's twoBit.c
+    """
+    cdef int packedStart, packedEnd, packByteCount
+    cdef int pOff, pStart, pEnd
+    cdef int midStart, remainder, partCount
+    cdef int i, j, s, e
+    cdef char * packed, * dna, *dna_orig
+    cdef char partial
+    packedStart = (fragStart>>2);
+    packedEnd = ((fragEnd+3)>>2);
+    packByteCount = packedEnd - packedStart;
+    # Empty string in which to write unpacked DNA
+    dna_py = PyString_FromStringAndSize( NULL, fragEnd - fragStart )
+    dna = PyString_AsString( dna_py )
+    # Read it
+    file.seek( seq.sequence_offset + packedStart )
+    packed_py = file.read( packByteCount )
+    packed = PyString_AsString( packed_py )
+    # Handle case where everything is in one packed byte 
+    if packByteCount == 1:
+        pOff = (packedStart<<2)
+        pStart = fragStart - pOff
+        pEnd = fragEnd - pOff
+        partial = packed[0]
+        assert pEnd <= 4
+        assert pStart >= 0
+        for i from pStart <= i < pEnd:
+            dna[0] = valToNt[(partial >> (6-i-i)) & 3]
+            dna = dna + 1
+    else:
+        # Handle partial first packed byte.
+        midStart = fragStart;
+        remainder = ( fragStart&3 )
+        if remainder > 0:
+            partial = packed[0]; packed = packed + 1
+            partCount = 4 - remainder;
+            for i from partCount - 1 >= i >= 0:
+                dna[i] = valToNt[ partial & 3 ]
+                partial = partial >> 2
+            midStart = midStart + partCount
+            dna = dna + partCount
+        # Handle middle bytes.
+        remainder = fragEnd&3
+        midEnd = fragEnd - remainder
+        i = midStart
+        while i < midEnd:
+            partial = packed[0]
+            packed = packed + 1;
+            dna[3] = valToNt[partial&3];
+            partial = partial >> 2
+            dna[2] = valToNt[partial&3];
+            partial = partial >> 2
+            dna[1] = valToNt[partial&3];
+            partial = partial >> 2
+            dna[0] = valToNt[partial&3];
+            dna = dna + 4;            
+            # Increment
+            i = i + 4
+            ## sys.stderr.write( "!!!< " + dna_py + " >!!!\n" ); sys.stderr.flush()
+        # End
+        if remainder > 0:
+            partial = packed[0];
+            partial = partial >> (8-remainder-remainder)
+            for i from remainder - 1 >= i >= 0:
+                dna[i] = valToNt[partial&3]
+                partial = partial >> 2
+    # Restore DNA pointer
+    dna = PyString_AsString( dna_py )
+    # N's
+    n_block_count = len( seq.n_block_starts )
+    if n_block_count > 0:
+        start_ix = bisect( seq.n_block_starts, fragStart ) - 1
+        if start_ix < 0: start_ix = 0            
+        for i from start_ix <= i < n_block_count:
+            s = seq.n_block_starts[i];
+            e = s + seq.n_block_sizes[i];
+            if (s >= fragEnd):
+                break
+            if (s < fragStart):
+               s = fragStart
+            if (e > fragEnd):
+               e = fragEnd
+            if (s < e):
+                memset( dna + s - fragStart, c'N', e - s)
+    # Mask
+    if do_mask:
+        m_block_count = len( seq.masked_block_starts )
+        if m_block_count > 0:
+            start_ix = bisect( seq.masked_block_starts, fragStart ) - 1
+            if start_ix < 0: start_ix = 0    
+            for i from start_ix <= i < m_block_count:
+                s = seq.masked_block_starts[i];
+                e = s + seq.masked_block_sizes[i];
+                if (s >= fragEnd):
+                    break
+                if (s < fragStart):
+                   s = fragStart
+                if (e > fragEnd):
+                   e = fragEnd
+                if (s < e):
+                    for j from s <= j < e:
+                        dna[j-fragStart] = tolower( dna[j-fragStart] )
+    return dna_py
diff --git a/lib/bx/seq/core.py b/lib/bx/seq/core.py
new file mode 100644
index 0000000..54c3325
--- /dev/null
+++ b/lib/bx/seq/core.py
@@ -0,0 +1,64 @@
+"""
+Support for "biological sequence" files.
+
+:Author: Bob Harris (rsharris at bx.psu.edu)
+
+See seq.py for more information
+"""
+
+import struct
+import fasta, nib, qdna
+
+# DNA reverse complement table
+
+DNA_COMP = "                                             -                  " \
+           " TVGH  CD  M KN   YSA BWXR       tvgh  cd  m kn   ysa bwxr      " \
+           "                                                                " \
+           "                                                                "
+
+def reverse_complement( text ):
+    return text.translate(DNA_COMP)[::-1]
+
+
+def seq_file (file, format=None, revcomp=False, name="", gap=None, contig=None):
+    if (format == None): format = infer_format(file)
+    if (contig != None) and (format not in ["fasta",None]):
+        raise ValueError("Contigs are not supported for format %s" % format)
+    if   (format == "fasta"): return fasta.FastaFile (file, revcomp=revcomp, name=name, gap=gap, contig=contig)
+    elif (format == "nib"):   return nib.NibFile     (file, revcomp=revcomp, name=name, gap=gap)
+    elif (format == "qdna"):  return qdna.QdnaFile   (file, revcomp=revcomp, name=name, gap=gap)
+    else:
+        if (format == None): format = ""
+        else:                format = " " + format
+        raise ValueError("Unknown sequence format%s in %s" % (format,file.name))
+
+
+def seq_reader (file, format=None, revcomp=False, name="", gap=None):
+    if   (format == None):    format = infer_format(file)
+    if   (format == "fasta"): return fasta.FastaReader (file, revcomp=revcomp, name=name, gap=gap)
+    elif (format == "nib"):   return nib.NibReader     (file, revcomp=revcomp, name=name, gap=gap)
+    elif (format == "qdna"):  return qdna.QdnaReader   (file, revcomp=revcomp, name=name, gap=gap)
+    else: raise ValueError("Unknown sequence format %s" % format)
+
+
+def seq_writer (outfile, format=None, name=""):
+    if   (format == "fasta"): return fasta.FastaWriter (outfile)
+    elif (format == "nib"):   return nib.NibWriter     (outfile)
+    elif (format == "qdna"):  return qdna.QdnaWriter   (outfile)
+    else: raise ValueError("Unknown sequence format %s" % format)
+
+
+def infer_format (file):
+    format = None
+    magic = struct.unpack(">L", file.read(4))[0]
+    if (magic == nib.NIB_MAGIC_NUMBER) or (magic == nib.NIB_MAGIC_NUMBER_SWAP):
+        format = "nib"
+    elif (magic == qdna.qdnaMagic) or (magic == qdna.qdnaMagicSwap):
+        format = "qdna"
+    else:
+        file.seek(0)
+        if (file.read(1) == ">"):
+            format = "fasta"
+    file.seek(0)
+    return format
+
diff --git a/lib/bx/seq/fasta.py b/lib/bx/seq/fasta.py
new file mode 100644
index 0000000..227ef95
--- /dev/null
+++ b/lib/bx/seq/fasta.py
@@ -0,0 +1,105 @@
+"""
+Classes to support FASTA files.
+
+:Author: Bob Harris (rsharris at bx.psu.edu)
+
+A FASTA file contains multiple sequences.  Each sequence is usually DNA.
+
+A typical FASTA file::
+
+   >mule
+   TAATACCCCGGATATATGTCCTCACATAGTTCGAGGTCGAGAAAAATGAC
+   TTCCCACCAAGTGGACTCAGCTCGAGTAAACGCCAACGATACGTCCATTA
+   GGTGTGTGCCgcaactagtcggacccgttgtgacggaaacaggtccccgc
+   caagtcacacgggcatgtcatggacTCTCGATCGTTCATCGCCTTCTTGG
+   GTACCGCAGCCGCAATTAAGCCGTGTCTTCTTCCCCCTTCAAACGGGAAT
+   CGTGTCGACTTCTTAGGAGCAGNNNNNNNNNNCTAACTCCAGAG
+   >donkey
+   TAATACCCCGGATATATGTCTTAACATAGTTCCAGGTCGAGAAGAATGAC
+   TTGCCACCAAGTGGACTCAGATTCAGTCAACGCGAACGATAAGTCCATTA
+   GGTGTGTACCgcaactagtgggacccgttgtgacggaaacaggtcaccgc
+   caagtcacacgtgcatgtcatgtacTCTCGATCGTTTATCGCCTTCTTGG
+   GTACCGCAGCCGAAATTAAGCCGTGTCTTCTTCCCACTTCAAACGGGAAT
+   CGTGTCGACTTTACAGGAACAGNNNNNNNNNNATAACGCCAGAG
+    ... more sequences
+
+Typical use:
+
+	for seq in bx.seq.fasta.FastaReader(sys.stdin):
+		print seq.name
+		print seq.get(0,seq.length)
+
+"""
+
+from bx.seq.seq import SeqFile,SeqReader
+import sys, string
+
+class FastaFile(SeqFile):
+
+    def __init__(self, file, revcomp=False, name="", gap=None, lookahead=None, contig=None):
+        SeqFile.__init__(self,file,revcomp,name,gap)
+        self.lookahead = lookahead
+        if (contig == None): contig = 1
+        assert (contig >= 1), "contig %d is not legal" % contig
+
+        # nota bene: certainly not the most efficient or elegant implementation
+
+        currContig = 1
+        while (True):
+            if (self.lookahead != None):
+                (line,self.lookahead) = (self.lookahead,None)
+            else:
+                line = self.file.readline()
+            if (line == ""): break
+            if not line:
+                break
+            if (line.startswith(">")):
+                if (self.text != None):
+                    if (currContig == contig):
+                        self.lookahead = line # (next sequence header)
+                        break
+                    currContig += 1
+                self.name = self.extract_name(line[1:])
+                self.text = []
+                continue
+            line = line.split() # (remove whitespace)
+            if (self.text == None): self.text = line # (allows headerless fasta)
+            else:                   self.text.extend(line)
+        assert (currContig == contig), \
+            "contig %d is not legal (file contains only %d)" % (contig,currContig)
+        if (self.text != None):
+            self.text   = "".join(self.text)
+            self.length = len(self.text)
+
+class FastaReader(SeqReader):
+    
+    def __init__(self, file, revcomp=False, name="", gap=None):
+        SeqReader.__init__(self,file,revcomp,name,gap)
+        self.lookahead = None
+
+    def next(self):
+        seq = FastaFile(self.file,self.revcomp,self.name,self.gap,self.lookahead)
+        if (seq.text == None): return
+        self.lookahead = seq.lookahead
+        self.seqs_read += 1
+        return seq
+
+
+class FastaWriter(object):
+
+    def __init__(self,file,columns=50):
+        self.file    = file
+        self.columns = columns
+
+    def write(self,seq):
+        print >>self.file,">%s" % seq.name
+        text = seq.text
+        if (self.columns != None) and (self.columns > 0):
+            text = "\n".join([text[ix:ix+self.columns] \
+                              for ix in range(0,len(text),self.columns)])
+        print >>self.file,text
+
+    def close(self):
+        assert (self.file != None)
+        self.file.close()
+        self.file = None
diff --git a/lib/bx/seq/fasta_tests.py b/lib/bx/seq/fasta_tests.py
new file mode 100644
index 0000000..803d355
--- /dev/null
+++ b/lib/bx/seq/fasta_tests.py
@@ -0,0 +1,37 @@
+"""
+Tests for `bx.seq.fasta`.
+"""
+
+import unittest
+import sys
+import os.path
+import fasta
+
+test_fa = "test_data/seq_tests/test.fa"
+
+# Same sequence data as stored in test.fa
+
+valid_seq = "TGGAGGCATTTGTGATTCAATAGATGCAGAAAGAAACCTTCCTAGAGCTG" \
+          + "GCGTTCTCTAACTAAAAGTGGAAAGTTCTGAGGAATGAGGACTGTTATAA" \
+          + "ATCCCACCCCACACCGCACCTTCTCCAGGGAAGTTTCATGGCCGTGAAGA" \
+          + "GGACAGAAAGTGAGAACCAAGATggaactgaataaacaagcttcacactg" \
+          + "ttagtttccccatatgcttaccttcccacagatgccaaccttggaggcct" \
+          + "aagaggcctagaatattatcctttgtctgatcatttctctacaaatttat" \
+          + "tgttctttgttaagatgctacataagcccaaattctaaccacccctttga" \
+          + "gttacccatcatcaagtttctcccatgtg"
+
+valid_seq_len = len( valid_seq )
+
+class FASTATestCase( unittest.TestCase ):
+
+    def test_get( self ):
+        fastafile = fasta.FastaFile( file(test_fa, "rb" ) )
+        check_get(fastafile, 0, valid_seq_len)
+        check_get(fastafile, 0, 40)
+        check_get(fastafile, valid_seq_len - 40, 40)
+
+def check_get( fastafile, start, len ):
+    assert fastafile.get( start, len ) == valid_seq[start:start+len]
+
+test_classes = [ FASTATestCase ]
+suite = unittest.TestSuite( [ unittest.makeSuite( c ) for c in test_classes ] )
diff --git a/lib/bx/seq/nib.py b/lib/bx/seq/nib.py
new file mode 100644
index 0000000..bdc4776
--- /dev/null
+++ b/lib/bx/seq/nib.py
@@ -0,0 +1,84 @@
+"""
+Classes to support nib files.
+
+:Author: James Taylor (james at bx.psu.edu), Bob Harris (rsharris at bx.psu.edu)
+
+A nib sequence is a sequence of DNA, using the 10 character alphabet A,C,G,T,N
+(upper and lower case).  The file is packed as 4 bits per character.
+
+nib file format
+---------------
+
+Fields can be in big- or little-endian format;  they must match the endianess
+of the magic number.
+
+============ =========== ======================================================
+offset 0x00: 6B E9 3D 3A big endian magic number (3A 3D E9 6B => little endian)
+offset 0x04: xx xx xx xx length of data sequence (counted in characters)
+offset 0x08:  ...        data sequence;  most significant nybble in each
+                         byte is first in sequence
+============ =========== ======================================================
+"""
+
+from __future__ import division
+
+from bx.seq.seq import SeqFile,SeqReader
+import sys, struct, string, math
+
+import _nib
+
+NIB_MAGIC_NUMBER = 0x6BE93D3A
+NIB_MAGIC_NUMBER_SWAP = 0x3A3DE96B
+NIB_MAGIC_SIZE = 4
+NIB_LENGTH_SIZE = 4
+
+class NibFile(SeqFile):
+
+    def __init__(self, file, revcomp=False, name="", gap=None):
+        SeqFile.__init__(self,file,revcomp,name,gap)
+
+        self.byte_order = ">"
+        magic = struct.unpack(">L", file.read(NIB_MAGIC_SIZE))[0]
+        if (magic != NIB_MAGIC_NUMBER):
+            if magic == NIB_MAGIC_NUMBER_SWAP: self.byte_order = "<"
+            else: raise Exception("Not a NIB file")
+        self.magic = magic
+        self.length = struct.unpack("%sL" % self.byte_order, file.read(NIB_LENGTH_SIZE))[0]
+
+    def raw_fetch(self, start, length):
+        # Check parameters
+        assert start >= 0, "Start must be greater than 0"
+        assert length >= 0, "Length must be greater than 0"
+        assert start + length <= self.length, "Interval beyond end of sequence"
+        # Read block of bytes containing sequence
+        block_start = int(math.floor(start / 2))
+        block_end = int(math.floor((start + length - 1) / 2))
+        block_len = block_end + 1 - block_start
+        self.file.seek(NIB_MAGIC_SIZE + NIB_LENGTH_SIZE + block_start)
+        raw = self.file.read(block_len)
+        # Unpack compressed block into a character string and return
+        return _nib.translate_raw_data( raw, start, length  )
+
+class NibReader(SeqReader):
+    
+    def __init__(self, file, revcomp=False, name="", gap=None):
+        SeqReader.__init__(self,file,revcomp,name,gap)
+
+    def next(self):
+        if (self.seqs_read != 0): return  # nib files have just one sequence
+        seq = NibFile(self.file,self.revcomp,self.name,self.gap)
+        self.seqs_read += 1
+        return seq
+
+
+class NibWriter(object):
+
+    def __init__(self,file):
+        self.file = file
+
+    def write(self,seq):
+        assert (False), "NibWriter.write() is not implemented yet"
+
+    def close(self):
+        self.file.close()
+
diff --git a/lib/bx/seq/nib_tests.py b/lib/bx/seq/nib_tests.py
new file mode 100644
index 0000000..64b0620
--- /dev/null
+++ b/lib/bx/seq/nib_tests.py
@@ -0,0 +1,51 @@
+"""
+Tests for `bx.seq.nib`.
+"""
+
+import unittest
+import sys
+import os.path
+import nib
+
+test_nib = "test_data/seq_tests/test.nib"
+
+# Same sequence data as stored in test.nib
+
+valid_seq = "TGGAGGCATTTGTGATTCAATAGATGCAGAAAGAAACCTTCCTAGAGCTG" \
+          + "GCGTTCTCTAACTAAAAGTGGAAAGTTCTGAGGAATGAGGACTGTTATAA" \
+          + "ATCCCACCCCACACCGCACCTTCTCCAGGGAAGTTTCATGGCCGTGAAGA" \
+          + "GGACAGAAAGTGAGAACCAAGATggaactgaataaacaagcttcacactg" \
+          + "ttagtttccccatatgcttaccttcccacagatgccaaccttggaggcct" \
+          + "aagaggcctagaatattatcctttgtctgatcatttctctacaaatttat" \
+          + "tgttctttgttaagatgctacataagcccaaattctaaccacccctttga" \
+          + "gttacccatcatcaagtttctcccatgtg"
+
+valid_seq_len = len( valid_seq )
+
+class NIBTestCase( unittest.TestCase ):
+
+    def test_get( self ):
+        nibfile = nib.NibFile( file( test_nib ) )
+        # Try all combinations of even / odd boundaries
+        check_get( nibfile, 0, 10 )
+        check_get( nibfile, 1, 10 )
+        check_get( nibfile, 0, 11 )
+        check_get( nibfile, 1, 11 )
+        # Test near end of file also
+        check_get( nibfile, valid_seq_len - 10, 10 )
+        check_get( nibfile, valid_seq_len - 11, 11 )
+        # Test really short gets
+        check_get( nibfile, 0, 0 )
+        check_get( nibfile, 1, 0 )
+        check_get( nibfile, 0, 1 )
+        check_get( nibfile, 1, 1 )
+        # Test negative length
+        self.assertRaises( AssertionError, nibfile.get, 20, -1 )
+
+def check_get( nibfile, start, len ):
+    ## print "expect: |%r|" % valid_seq[start:start+len]
+    ## print "actual: |%r|" % nibfile.get( start, len )
+    assert nibfile.get( start, len ) == valid_seq[start:start+len]
+
+test_classes = [ NIBTestCase ]
+suite = unittest.TestSuite( [ unittest.makeSuite( c ) for c in test_classes ] )
diff --git a/lib/bx/seq/qdna.py b/lib/bx/seq/qdna.py
new file mode 100644
index 0000000..0d39dc0
--- /dev/null
+++ b/lib/bx/seq/qdna.py
@@ -0,0 +1,283 @@
+"""
+Classes to support "quantum-DNA" files.
+
+:Author: Bob Harris (rsharris at bx.psu.edu)
+
+A quantum DNA sequence is a sequence of bytes, each representing a probability
+distribution (vector) over A, C, G, T.  The QdnaFile class encapsulates the
+sequence of bytes, while the mapping from byte value to probability vector is
+encapsulated by the QdnaCodebook class.
+
+qdna file format
+~~~~~~~~~~~~~~~~
+
+Fields can be in big- or little-endian format;  they must match the endianess
+of the magic number.
+
+============ ===========   ======================================================
+offset 0x00: C4 B4 71 97   big endian magic number (97 71 B4 C4 => little endian)
+offset 0x04: 00 00 02 00   version 2.0 (fourth byte is sub version)
+offset 0x08: 00 00 00 14   header length (in bytes, including this field)
+offset 0x0C: xx xx xx xx   S, offset (from file start) to data sequence
+offset 0x10: xx xx xx xx   N, offset to name, 0 indicates no name
+offset 0x14: xx xx xx xx   length of data sequence (counted in 'items')
+offset 0x18: xx xx xx xx   (for version >= 2.0) P, offset to named
+                           .. properties, 0 indicates no properties
+offset    N: ...           name (zero-terminated string)
+offset    S: ...           data sequence
+offset    P: ...           named properties (see below)
+============ ===========   ======================================================
+
+The named properties section consists of a list of pairs of zero-terminated
+strings.  The list itself is terminated by an empty string (i.e. another
+zero).  In each pair, the first is the name of the property and the second
+is its value.  Some names are recognized and handled in some specific manner
+(see list below this paragraph).  Any unrecognized name is simply added as
+an instance variable with that name, as long as it is not already an instance
+variable (in which case it is an error).
+
+Recognized properties (at present only one):
+  - codebook: A string in qdna code file format (see QdnaCodebook class for details).
+"""
+
+from bx.seq.seq import SeqFile,SeqReader
+import sys, struct, string
+from StringIO import StringIO
+
+qdnaMagic     = 0xC4B47197L    # big endian magic number for qdna files
+qdnaMagicSwap = 0x9771B4C4L
+
+class QdnaFile(SeqFile):
+
+    def __init__(self, file, revcomp=False, name="", gap=None, codebook=None):
+        SeqFile.__init__(self,file,revcomp,name,gap)
+        if (gap == None): self.gap = chr(0)
+        assert (revcomp == False), "reverse complement is not supported for qdna files"
+        self.codebook = codebook
+
+        self.byte_order = ">"
+        magic = struct.unpack(">L", file.read(4))[0]
+        if (magic != qdnaMagic):
+            if (magic == qdnaMagicSwap):
+                self.byte_order = "<"
+            else:
+                raise ValueError("not a quantum-dna file (magic=%08X)" % magic)
+
+        self.magic = magic
+
+        # process header
+
+        self.version = struct.unpack("%sL" % self.byte_order,
+                                     self.file.read(4))[0]
+        if (self.version not in [0x100,0x200]):
+            raise ValueError("unsupported quantum-dna (version=%08X)" % self.version)
+
+        self.headerLength = struct.unpack("%sL" % self.byte_order,
+                                          self.file.read(4))[0]
+        if (self.headerLength < 0x10):
+            raise ValueError("unsupported quantum-dna (header len=%08X)" % self.headerLength)
+        if (self.version == 0x100) and (self.headerLength != 0x10):
+            raise ValueError("unsupported quantum-dna (version 1.0 header len=%08X)" % self.headerLength)
+
+        self.seqOffset  = struct.unpack("%sL" % self.byte_order,
+                                        self.file.read(4))[0]
+        self.nameOffset = struct.unpack("%sL" % self.byte_order,
+                                        self.file.read(4))[0]
+        self.length     = struct.unpack("%sL" % self.byte_order,
+                                        self.file.read(4))[0]
+
+        self.propOffset = 0
+        if (self.headerLength >= 0x14):
+            self.propOffset = struct.unpack("%sL" % self.byte_order,
+                                            self.file.read(4))[0]
+
+        self.name = ""
+        if (self.nameOffset != 0):
+            self.file.seek(self.nameOffset)
+            self.name = self.read_string()
+
+        if (self.propOffset != 0):
+            self.file.seek(self.propOffset)
+            while (True):
+                name  = self.read_string()
+                if (len(name) == 0): break
+                value = self.read_string()
+                self.set_property(name,value)
+
+
+    def set_property(self,name,value):
+        if (name == "codebook"):
+            self.codebook = QdnaCodebook(StringIO(value))
+        else:
+            raise Exception("named properties as instance variables are not implemented yet")
+            # $$$ do this by adding a properties dict and __getitem__/__setitem__
+            # $$$ also need to write properties in QdnaWriter.write()
+
+
+    def read_string(self):
+        s = ""
+        while (True):
+            ch = self.file.read(1)
+            if (ch == chr(0)): break
+            s += ch
+        return s
+
+
+    def raw_fetch(self, start, length):
+        self.file.seek(self.seqOffset + start)
+        return self.file.read(length)
+
+
+    def get_quantum(self, start, length):
+        assert (self.codebook != None), \
+                "qdna sequence %s has no code book" % self.name
+        return [self.codebook[codeNum] for codeNum in self.raw_fetch(start,length)]
+
+
+class QdnaReader(SeqReader):
+
+    def __init__(self, file, revcomp=False, name="", gap=None, codebook=None):
+        SeqReader.__init__(self,file,revcomp,name,gap)
+        self.codebook = codebook
+
+    def next(self):
+        if (self.seqs_read != 0): return  # qdna files have just one sequence
+        seq = QdnaFile(self.file,self.revcomp,self.name,self.gap,self.codebook)
+        self.seqs_read += 1
+        return seq
+
+"""
+A QdnaCodebook maps code numbers to the corresponding probability vector.  The
+latter is a hash from symbols (usually "A", "C", "G", or "T") to the
+corresponsing probability.  Note that code numbers are of type string.
+
+qdna code file format:
+
+   The file is ascii text and looks something like what's shown below.  Lines
+   beginning with # are comments, and columns are assumed to represent A, C, G
+   and T (in that order).  Anything other than five columns is an error.  Note
+   that code number zero is usually reserved for gaps in quantum sequences, and
+   thus usually won't appear in a code file.  Note that code numbers are
+   two-digit hexadecimal (to match the textual displays of quantum sequences).
+
+      01  0.111002  0.072588  0.127196  0.689214
+      02  0.081057  0.023799  0.098657  0.796487
+      03  0.000260  0.003823  0.000336  0.995581
+       ... more lines, usually a total of 255 ...
+      FF  0.465900  0.008602  0.482301  0.043197
+"""
+
+class QdnaCodebook(object):
+
+    def __init__(self,file):
+        (self.alphabet,self.codeToProbs) = self.read_codebook(file)
+
+
+    def __str__(self):
+        codeSet = [codeNum for codeNum in self.codeToProbs]
+        codeSet.sort()
+        return "\n".join([self.vector_text(codeNum) for codeNum in codeSet])
+
+    def vector_text(self,codeNum):
+        if (codeNum in self.codeToProbs): vec = self.codeToProbs[codeNum]
+        else:                             vec = {}
+        for sym in self.alphabet:
+            if (sym not in vec):
+                vec[sym] = 0.0
+        return ("%02X\t" % ord(codeNum)) \
+            + "\t".join(["%.6f" % vec[sym] for sym in self.alphabet])
+
+
+    def __getitem__ (self,codeNum):
+        return self.codeToProbs[codeNum]
+
+
+    def __setitem__ (self,codeNum,value):
+        self.codeToProbs[codeNum] = value # value should be hash from symbol
+                                          # .. to probability
+
+
+    def read_codebook(self,codeF):
+        alphabet = "ACGT"
+        codeToProbs = {}
+
+        for (lineNum,line) in enumerate (codeF):
+            lineNum += 1
+            line = line.rstrip()
+            stripped = line.strip()
+            if (stripped == "") or (stripped.startswith("#")):
+                continue
+
+            fields = line.split(None)
+            if (len(fields) != 5):
+                raise ValueError("wrong vector size (line %d)" % lineNum)
+
+            try:
+                codeNum = int(fields[0],16)
+            except:
+                raise ValueError("bad character code %s (line %d)" \
+                    % (fields[0],lineNum))
+
+            if (not 0 <= codeNum <= 255):
+                raise ValueError("character code %s is outside the valid range (line %d)" \
+                     % (fields[0],lineNum))
+
+            if (chr(codeNum) in codeToProbs):
+                raise ValueError("character code %s appears more than once (line %d)" \
+                     % (fields[0],lineNum))
+
+            try:
+                vec = {}
+                for ix in range(1,5):
+                    p = float(fields[ix])
+                    if (p < 0) or (p > 1): raise ValueError
+                    vec[alphabet[ix-1]] = p
+            except:
+                raise ValueError("%s is a bad probability value (line %d)" \
+                     % (fields[ix],lineNum))
+
+            codeToProbs[chr(codeNum)] = vec
+
+        return (alphabet,codeToProbs)
+
+
+class QdnaWriter(object):
+
+    def __init__(self,file):
+        self.file = file
+
+    def write(self,seq):
+        text = seq.text
+        if (text == None): text = ""
+
+        version   = 0x200
+        headerLen = 0x014
+        offset    = headerLen + 8
+
+        nameOffset = 0
+        if (seq.name != None) and (seq.name != ""):
+            nameOffset =  0x01C
+            offset     += len(seq.name) + 1
+            name       =  seq.name + chr(0)
+
+        dataOffset =  offset
+        offset     += len(text)
+
+        assert (seq.codebook == None), \
+               "QdnaWriter.write() does not support codebooks yet"
+        propOffset = 0
+
+        self.file.write(struct.pack("%sL" % seq.byte_order,qdnaMagic))
+        self.file.write(struct.pack("%sL" % seq.byte_order,version))
+        self.file.write(struct.pack("%sL" % seq.byte_order,headerLen))
+        self.file.write(struct.pack("%sL" % seq.byte_order,dataOffset))
+        self.file.write(struct.pack("%sL" % seq.byte_order,nameOffset))
+        self.file.write(struct.pack("%sL" % seq.byte_order,len(text)))
+        self.file.write(struct.pack("%sL" % seq.byte_order,propOffset))
+        if (nameOffset != 0): self.file.write(name)
+        self.file.write(text)
+
+
+    def close(self):
+        self.file.close()
+
diff --git a/lib/bx/seq/qdna_tests.py b/lib/bx/seq/qdna_tests.py
new file mode 100644
index 0000000..947c0df
--- /dev/null
+++ b/lib/bx/seq/qdna_tests.py
@@ -0,0 +1,37 @@
+"""
+Tests for `bx.seq.qdna`.
+"""
+
+import unittest
+import sys
+import os.path
+import qdna
+
+test_qdna = "test_data/seq_tests/test.qdna"
+
+# Same sequence data as stored in test.qdna
+
+valid_seq = "C7wMwHQrMKqEtSREuUv5nsLinpTS8l7jXpbI7IipvCbHnhOdgx" \
+          + "5tzRgzYl4j85d:xSlvKPEKEIvZkfiX1YPkBi1Ibhfn9fTZd8gG" \
+          + "Wy284hJnwf93W4eHOjeRk7LuVYmH{UTYkYM:b4J4MruMq1ihhv" \
+          + "1Yl5W[xXEmi8[JuuLRgooBpy23PllMuUiIiKVIK5vzhjPPYp5Y" \
+          + "1eqPxo[e5I24KeCdTV94MZWNybUb:McC:1n4Jczk8JqnR4q1gY" \
+          + "HjLS4Bes3s5YvvWdKzS4VrFZy2erhd7YoWRoS[UK8JtSp1{Z1o" \
+          + "5:TpvN8mrmWrghiNw{S6nT8DSfF{1ff6kNGpI:FsZE2RgipTVO" \
+          + "mJN6vPm8MUgNYd7MDBEu37YOPzPjO1dr"
+
+valid_seq_len = len(valid_seq)
+
+class QDNATestCase(unittest.TestCase):
+
+    def test_get(self):
+        qdnafile = qdna.QdnaFile(file(test_qdna,"rb"))
+        check_get(qdnafile, 0, valid_seq_len)
+        check_get(qdnafile, 0, 40)
+        check_get(qdnafile, valid_seq_len - 40, 40)
+
+def check_get(qdnafile, start, len):
+    assert qdnafile.get(start, len) == valid_seq[start:start+len]
+
+test_classes = [ QDNATestCase ]
+suite = unittest.TestSuite( [ unittest.makeSuite( c ) for c in test_classes ] )
diff --git a/lib/bx/seq/seq.py b/lib/bx/seq/seq.py
new file mode 100644
index 0000000..727c700
--- /dev/null
+++ b/lib/bx/seq/seq.py
@@ -0,0 +1,135 @@
+"""
+Classes to support "biological sequence" files.
+
+:Author: Bob Harris (rsharris at bx.psu.edu)
+"""
+
+# DNA reverse complement table
+
+DNA_COMP = "                                             -                  " \
+           " TVGH  CD  M KN   YSA BWXR       tvgh  cd  m kn   ysa bwxr      " \
+           "                                                                " \
+           "                                                                "
+
+class SeqFile(object):
+    """
+    A biological sequence is a sequence of bytes or characters.  Usually these
+    represent DNA (A,C,G,T), proteins, or some variation of those.
+
+    class attributes:
+
+        file:    file object containing the sequence
+        revcomp: whether gets from this sequence should be reverse-complemented
+                 False => no reverse complement
+                 True  => (same as "-5'")
+                 "maf" => (same as "-5'")
+                 "+5'" => minus strand is from plus strand's 5' end (same as "-3'")
+                 "+3'" => minus strand is from plus strand's 3' end (same as "-5'")
+                 "-5'" => minus strand is from its 5' end (as per MAF file format)
+                 "-3'" => minus strand is from its 3' end (as per genome browser,
+                          but with origin-zero)
+        name:    usually a species and/or chromosome name (e.g. "mule.chr5");  if
+                 the file contains a name, that overrides this one
+        gap:     gap character that aligners should use for gaps in this sequence
+    """
+
+    def __init__(self, file=None, revcomp=False, name="", gap=None):
+        
+        
+        self.file = file
+        if   (revcomp == True):  self.revcomp = "-5'"
+        elif (revcomp == "+3'"): self.revcomp = "-5'"
+        elif (revcomp == "+5'"): self.revcomp = "-3'"
+        elif (revcomp == "maf"): self.revcomp = "-5'"
+        else:                    self.revcomp = revcomp
+        self.name = name
+        if (gap == None): self.gap = "-"
+        else:             self.gap = gap
+
+        self.text   = None  # (subclasses fill in text and
+        self.length = 0     #  length or they most override get())
+
+    def close(self):
+        assert (self.file != None)
+        self.file.close()
+        self.file = None
+
+    def extract_name(self,line):
+        try:
+            return line.split()[0]
+        except:
+            return ""
+
+    def set_text(self,text):
+        self.text   = text
+        self.length = len(text)
+
+    def __str__ (self):
+        text = ""
+        if (self.name != None): text += self.name + " "
+        text += self.get(0,self.length)
+        return text
+
+    def get(self, start, length):
+        """
+        Fetch subsequence starting at position `start` with length `length`. 
+        This method is picky about parameters, the requested interval must 
+        have non-negative length and fit entirely inside the NIB sequence,
+        the returned string will contain exactly 'length' characters, or an
+        AssertionError will be generated.
+        """
+        # Check parameters
+        assert length >= 0, "Length must be non-negative (got %d)" % length 
+        assert start >= 0,"Start must be greater than 0 (got %d)" % start
+        assert start + length <= self.length, \
+            "Interval beyond end of sequence (%s..%s > %s)" % ( start, start + length, self.length )
+        # Fetch sequence and reverse complement if necesary
+        if not self.revcomp:
+            return self.raw_fetch( start, length )
+        if self.revcomp == "-3'":
+            return self.reverse_complement(self.raw_fetch(start,length))
+        assert self.revcomp == "-5'", "unrecognized reverse complement scheme"
+        start = self.length - (start+length)
+        return self.reverse_complement(self.raw_fetch(start,length))
+
+    def raw_fetch(self, start, length):
+        return self.text[start:start+length]
+
+    def reverse_complement(self,text):
+        comp = [ch for ch in text.translate(DNA_COMP)]
+        comp.reverse()
+        return "".join(comp)
+
+
+class SeqReader(object):
+    """Iterate over all sequences in a file in order"""
+    
+    def __init__(self, file, revcomp=False, name="", gap=None):
+        self.file      = file
+        self.revcomp   = revcomp
+        self.name      = name
+        self.gap       = gap
+        self.seqs_read = 0
+
+    def close(self):
+        self.file.close()
+
+    def __iter__(self):
+        return SeqReaderIter(self)
+
+    def next(self):  # subclasses should override this method and return the
+        return       # .. next sequence (of type SeqFile or a subclass) read
+                     # .. from self.file
+
+
+class SeqReaderIter(object):
+    def __init__(self,reader):
+        self.reader = reader
+    def __iter__(self): 
+        return self
+    def next(self):
+        v = self.reader.next()
+        if not v: raise StopIteration
+        return v
+
+
diff --git a/lib/bx/seq/seq_tests.py b/lib/bx/seq/seq_tests.py
new file mode 100644
index 0000000..cafc017
--- /dev/null
+++ b/lib/bx/seq/seq_tests.py
@@ -0,0 +1,54 @@
+"""
+Tests for `bx.seq.seq`.
+"""
+
+
+import unittest
+import os.path
+import sys
+import bx.seq, fasta_tests, nib_tests, qdna_tests
+
+test_fa     = "test_data/seq_tests/test.fa"
+test2_fa    = "test_data/seq_tests/test2.fa"
+test_nib    = "test_data/seq_tests/test.nib"
+test_qdna   = "test_data/seq_tests/test.qdna"
+
+valid_fasta = fasta_tests.valid_seq
+valid_nib   = nib_tests.valid_seq
+valid_qdna  = qdna_tests.valid_seq
+
+# Same sequences as stored in test2.fa
+
+valid2_fa = [("apple",      "GGCGCTGCGATAAGGTTGCGACAACACGGACCTTCTTTTGCCTACCTCTGTTCTTGGCACG"),
+             ("orange",     "CGTGCCGAGAACAGAAAATACGCCGGGCGGTGCAGTAGTATCTTGGTATCCGATATGCAGG"),
+             ("grapefruit", "CCTGCATATCGACTAGTACACCCTCCCGAGGTACCCCACCCATCCCTCTTTTCTCGGCGCG")]
+
+class SEQTestCase (unittest.TestCase):
+
+    def test_get_fasta (self):
+        fastafile = bx.seq.seq_file (file (test_fa, "rb"))
+        check_get (fastafile, valid_fasta, 3, 40)
+
+    def test_get_nib (self):
+        nibfile = bx.seq.seq_file (file (test_nib, "rb"))
+        check_get (nibfile, valid_nib, 3, 40)
+
+    def test_get_qdna (self):
+        qdnafile = bx.seq.seq_file (file (test_qdna, "rb"))
+        check_get (qdnafile, valid_qdna, 3, 40)
+
+    def test_get_reader (self):
+        reader = bx.seq.seq_reader (file (test2_fa, "rb"))
+        for (ix,seq) in enumerate(reader):
+            assert (ix < len(valid2_fa)), "FastaReader returns too many sequences"
+            text = "%s" % seq
+            fields = text.split()
+            assert (len(fields) == 2), "SeqReader.__str__ returns incorrect sequence string \"%s\" (%d)" % text
+            assert (fields[0] == valid2_fa[ix][0]), "FastaReader returned the wrong name (%s,%s)" % (fields[0],valid2_fa[ix][0])
+            assert (fields[1] == valid2_fa[ix][1]), "FastaReader returned the wrong text (%s,%s)" % (fields[1],valid2_fa[ix][1])
+
+def check_get (seqfile, valid_seq, start, len):
+    assert seqfile.get (start, len) == valid_seq[start:start+len]
+
+test_classes = [SEQTestCase]
+suite = unittest.TestSuite ([unittest.makeSuite (c) for c in test_classes])
diff --git a/lib/bx/seq/twobit.py b/lib/bx/seq/twobit.py
new file mode 100644
index 0000000..c5a73aa
--- /dev/null
+++ b/lib/bx/seq/twobit.py
@@ -0,0 +1,126 @@
+"""
+Access to files containing sequence data in 'twobit' format.
+"""
+
+import sys
+import _twobit
+
+from struct import *
+from UserDict import DictMixin
+
+TWOBIT_MAGIC_NUMBER = 0x1A412743
+TWOBIT_MAGIC_NUMBER_SWAP = 0x4327411A
+TWOBIT_MAGIC_SIZE = 4
+
+TWOBIT_VERSION = 0
+
+class TwoBitSequence( object ):
+    def __init__( self, tbf, header_offset=None ):
+        self.tbf = tbf
+        self.header_offset = header_offset
+        self.sequence_offset = None
+        self.size = None
+        self.n_blocks = None
+        self.masked_blocks = None
+        self.loaded = False
+        
+    def __getitem__( self, slice ):
+        start, stop, stride = slice.indices( self.size )
+        assert stride == 1, "Striding in slices not supported"
+        if stop - start < 1:
+            return ""
+        return _twobit.read( self.tbf.file, self, start, stop, self.tbf.do_mask  )
+        
+    def __len__( self ):
+        return self.size
+        
+    def get( self, start, end ):
+        # Trim start / stop
+        if start < 0:
+            start = 0
+        if end > self.size:
+            end = self.size
+        out_size = end - start
+        if out_size < 1:
+            raise Exception( "end before start (%s,%s)" % ( start,end ) )
+        # Find position of packed portion
+        dna = _twobit.read( self.tbf.file, self, start, end, self.tbf.do_mask )
+        # Return
+        return dna
+        
+class TwoBitFile( DictMixin ):
+    def __init__( self, file, do_mask=True ):
+        self.do_mask = do_mask
+        # Read magic and determine byte order
+        self.byte_order = ">"
+        magic = unpack( ">L", file.read( TWOBIT_MAGIC_SIZE ) )[0]
+        if magic != TWOBIT_MAGIC_NUMBER:
+            if magic == TWOBIT_MAGIC_NUMBER_SWAP: 
+                self.byte_order = "<"
+            else: 
+                raise Exception( "Not a NIB file" )
+        self.magic = magic
+        self.file = file
+        # Read version
+        self.version = self.read( "L" )
+        if self.version != TWOBIT_VERSION:
+            raise Exception( "File is version '%d' but I only know about '%d'" % ( self.version, TWOBIT_VERSION ) )
+        # Number of sequences in file
+        self.seq_count = self.read( "L" )
+        # Header contains some reserved space
+        self.reserved = self.read( "L" )
+        # Read index of sequence names to offsets
+        index = dict()
+        for i in range( self.seq_count ):
+            name = self.read_p_string()
+            offset = self.read( "L" )
+            index[name] = TwoBitSequence( self, offset )
+        self.index = index
+
+    def __getitem__( self, name ):
+        seq = self.index[name]
+        if not seq.loaded:
+            self.load_sequence( name )
+        return seq
+        
+    def keys( self ):
+        return self.index.keys()
+        
+    def load_sequence( self, name ):
+        seq = self.index[name]
+        # Seek to start of sequence block
+        self.file.seek( seq.header_offset )
+        # Size of sequence
+        seq.size = self.read( "L" )
+        # Read N and masked block regions
+        seq.n_block_starts, seq.n_block_sizes = self.read_block_coords()
+        seq.masked_block_starts, seq.masked_block_sizes = self.read_block_coords()
+        # Reserved
+        self.read( "L" )
+        # Save start of actualt sequence
+        seq.sequence_offset = self.file.tell()
+        # Mark as loaded
+        seq.loaded = True
+        
+    def read_block_coords( self ):
+        blocks = []
+        block_count = self.read( "L" )
+        if block_count == 0:
+            return [], []
+        starts = self.read( str( block_count ) + "L", untuple=False )
+        sizes = self.read( str( block_count ) + "L", untuple=False  )
+        return list( starts ), list( sizes )
+        
+    def read( self, pattern, untuple=True ):
+        rval = unpack( self.byte_order + pattern, 
+                       self.file.read( calcsize( self.byte_order + pattern ) ) )
+        if untuple and len( rval ) == 1: 
+            return rval[0]
+        return rval
+        
+    def read_p_string( self ):
+        """
+        Read a length-prefixed string 
+        """
+        length = self.read( "B" )
+        return self.file.read( length )
diff --git a/lib/bx/seq/twobit_tests.py b/lib/bx/seq/twobit_tests.py
new file mode 100644
index 0000000..2412521
--- /dev/null
+++ b/lib/bx/seq/twobit_tests.py
@@ -0,0 +1,48 @@
+import sys
+import twobit
+import random
+
+def quick_fasta_iter( f ):
+    current_header = None
+    current_sequence = []
+    for line in f:
+        if line.startswith( "#" ):
+            continue
+        if line.startswith( ">" ):
+            if current_sequence:
+                ## print current_header, "".join( current_sequence )
+                yield current_header, "".join( current_sequence )
+                current_sequence = []
+            current_header = line.strip()[1:]
+        else:
+            current_sequence.append( "".join( line.split() ) )
+    if current_sequence:
+        yield current_header, "".join( current_sequence )
+        current_sequence = []
+
+def test():
+    """
+    Nose test generator
+    """
+    for t in "test", "testN", "testMask":
+        test_fa = "test_data/seq_tests/%s.fa" % t
+        test_twobit = "test_data/seq_tests/%s.2bit" % t
+        yield check_random_subseq_matches, test_fa, test_twobit
+
+def check_random_subseq_matches( test_fa, test_twobit ):
+    # Load Fasta data
+    expected = {}
+    for h, s in quick_fasta_iter( open( test_fa ) ):
+        expected[h] = s
+    # Open 2bit
+    t = twobit.TwoBitFile( open( test_twobit ) )
+    for k, s in expected.iteritems():
+        assert k in t.index
+        # assert t.index[k].size == len(s)
+        length = len(s)
+        for i in range( 100 ):
+            start = random.randint( 0, length-2 )
+            end = random.randint( start+1, length )
+            assert t[k].get(start, end) == s[start:end]
+            assert t[k][start:end] == s[start:end], \
+                "seq: %s, start: %d, end: %d\nExpected:\n%s\nActual:\n%s\n" % ( k, start, end, s[start:end], t.get( k, start, end ) )
diff --git a/lib/bx/seqmapping.py b/lib/bx/seqmapping.py
new file mode 100644
index 0000000..594c481
--- /dev/null
+++ b/lib/bx/seqmapping.py
@@ -0,0 +1,94 @@
+"""
+Classes for char-to-int mapping and int-to-int mapping.
+
+:Author: James Taylor (james at bx.psu.edu)
+
+The char-to-int mapping can be used to translate a list of strings
+over some alphabet to a single int array (example for encoding a multiple
+sequence alignment).
+
+The int-to-int mapping is particularly useful for creating partitions,
+and provides methods to merge/split symbols in the output mapping.
+
+The two forms of mapping can be combined, for example to encode a 
+multiple sequence alignment in a reduced alphabet defined by a partition
+of alignment columns. Many of the helper methods provided are for 
+solving such alignment oriented problems. 
+
+This code was originally written for the `ESPERR`_ project which includes
+software for searcing for alignment encodings that work well for specific
+classification problems using various Markov chain classifiers over the
+reduced encodings.
+
+Most of the core implementation is in the pyrex/C extension 
+"_seqmapping.pyx" for performance reasons (specifically to avoid the
+excessive bounds checking that would make a sequence/array lookup heavy
+problem like this slow in pure python).
+
+.. _ESPERR: http://www.bx.psu.edu/projects/esperr/
+"""
+
+from _seqmapping import *
+
+# Char->Int mapping for DNA characters with missing data
+                
+DNA = CharToIntArrayMapping()
+DNA.set_mapping( "a", 0 )
+DNA.set_mapping( "A", 0 )
+DNA.set_mapping( "c", 1 )
+DNA.set_mapping( "C", 1 )
+DNA.set_mapping( "g", 2 )
+DNA.set_mapping( "G", 2 )
+DNA.set_mapping( "t", 3 )
+DNA.set_mapping( "T", 3 )
+DNA.set_mapping( "-", 4 )
+DNA.set_mapping( "*", 5 )
+
+# Creating mappings
+
+def alignment_mapping_from_file( f, char_mapping=DNA ):
+    """
+    Create a mapping from a file of alignment columns.
+    """    
+    columns, symbols = [], []
+    for line in f:
+        column, symbol = line.split()
+        columns.append( column )
+        symbols.append( int( symbol ) )
+                
+    align_count = len( columns[0] )
+        
+    mapping = IntToIntMapping( char_mapping.get_out_size() ** align_count )
+        
+    for column, symbol in zip( columns, symbols ):
+        index = char_mapping.translate_list( list( column ) )[0]
+        mapping.set_mapping( index, symbol )
+
+    return align_count, mapping
+
+def second_mapping_from_file( f, first_mapping, char_mapping=DNA ):
+        
+    columns, symbols = [], []
+    for line in f:
+        column, symbol = line.split()
+        columns.append( column )
+        symbols.append( int( symbol ) )
+                
+    align_count = len( columns[0] )
+        
+    mapping = IntToIntMapping( first_mapping.get_out_size() )
+        
+    for column, symbol in zip( columns, symbols ):
+        index = char_mapping.translate_list( list( column ) )[0]
+        if first_mapping[index] >= 0:
+            mapping.set_mapping( first_mapping[index], symbol )
+
+    return mapping
+
+
+def identity_mapping( size ):
+    mapping = IntToIntMapping( size )
+    for i in range( size ):
+        mapping.set_mapping( i, i )
+    return mapping    
+    
diff --git a/lib/bx/seqmapping_tests.py b/lib/bx/seqmapping_tests.py
new file mode 100644
index 0000000..2f00a61
--- /dev/null
+++ b/lib/bx/seqmapping_tests.py
@@ -0,0 +1,86 @@
+"""
+Tests for `bx.seqmapping`.
+"""
+
+import sys
+
+import unittest
+import bx.seqmapping
+
+from numpy import array, allclose
+from StringIO import StringIO
+
+class CharMappingTests( unittest.TestCase ):
+    def test_DNA( self ):
+        assert( allclose( bx.seqmapping.DNA.translate( "ACGTacgt-?X" ),
+                          [ 0, 1, 2, 3, 0, 1, 2, 3, 4, -1, -1 ] ) )
+    def test_DNA_list( self ):
+        assert( allclose( bx.seqmapping.DNA.translate_list( [ "ACGTA", "TGCAX" ] ),
+                          [ 0 + 3*6, 1 + 2*6, 2 + 1*6, 3 + 0*6, -1 ] ) )
+    def test_other( self ):
+        m = bx.seqmapping.CharToIntArrayMapping()
+        m.set_mapping( "A", 0 )
+        m.set_mapping( "B", 7 )
+        assert( allclose( m.translate( "ABCCBA" ), [ 0, 7, -1, -1, 7, 0 ] ) )
+        
+class IntMappingTests( unittest.TestCase ):
+    def test_simple( self ):
+        m = bx.seqmapping.IntToIntMapping( 4 )
+        m.set_mapping( 0, 0 )
+        m.set_mapping( 2, 0 )
+        m.set_mapping( 1, 1 )
+        m.set_mapping( 3, 1 )
+        assert( allclose( m.translate( array( [ 0, 1, 2, 3, 4 ], 'i' ) ), array( [ 0, 1, 0, 1, -1 ] ) ) )
+   
+eight_species_mapping = """TTTTTTTT 0
+CCCCCCCC 4
+AAAAAAAA 1
+GGGGGGGG 5
+AAAAA*AA 2
+TTTTT*TT 0
+GGGGG*GG 5
+CCCCC*CC 4
+GGGG*GGG 5
+TTTT*TTT 2
+GGGAAGGG 5
+AAAA*AAA 2
+TTTTT*T* 2
+CCCCC*C* 4
+CCCTTCCC 4
+CCCC*CCC 4
+TTTT**TT 2
+AAAA**AA 2
+AAAAA*A* 2
+GGGGG*G* 5
+AAAAAGAA 2
+TTTTTCTT 2
+GGGAA*GG 5
+TTTT**T* 2
+TTTCCTTT 0
+AAAAAAA* 1
+CCCTT*CC 3
+TTTTTTT* 2
+CC*CC*CC 3
+AAAGGAAA 2
+------G- 2
+"""
+       
+rows = [ "AAATTGT-----ATGTCCATCCTTTAAAGGTCATTCCTTTAATGGTCTTTTCTGGACACCACTAGGGGTCAGAAGTAGTTCATCAAAC-----------------TTTCTTCCCTCCC-TACTTCAGTG",
+         "AAATTGT-----ATGTCCATCCTTTAAAGGTCATTCCTTTAATGGTCTTTTCTGGACACCACTAGGGGTCAGAAGTAGTTCATCAAAC-----------------TTTCTTCCCTCCC-TACTTCAGTG",
+         "AAATTTT-----ATGTCTATCCTTTAAAGGTCATTCCTCTAATAGTCTTTTCTGGACACCACTAGGGGTCAGAAGTAGTTCATTAAAC-----------------TTTCTTCCCTCCC-TACCTCAGTG",
+         "AAACTGT-----ATCACCACCTTTTTAAGGTCATTTCTCTAATGATCCTGTT-GCATACCAGTAGGGGGCAGAAGTGTTCCGCTGATTTCCGCCCTCCTCCCCACCCCCCCACCCCCC-TTATTCAAAG",
+         "*********************************************************************************************************************************",
+         "-TATTAT-----ATGGCCATGTTCAAAAGGTTGTTTCTCTAATGATTCCTTC-TGATACCAGTAGGGGTCAGAAGTGGTCCATTGATT---------------------CTTTTCCTC-TGATTC-AAG",
+         "AAATTGA--AAGATCTCACTCTTTGCCAGGTAGTCCATCTAAGGGTCACATATGGATACCAGCAGGGCCT-GAAGAAGCCCATTGAAT------------------------TTTCCC-ATCTTCAAGG",
+         "AAATTCATGATAGTGTCACTCTTAAATAGATGATTC--------TTCACAT---GATGCCAGCAGGGGGC-AGAGCAGGCTGTGAAAT------------------------TTTCCCTTTCTTCAAAG" ]
+
+class AlignmentMappingTests( unittest.TestCase ):
+    def test_largescale( self ):
+       f = StringIO( eight_species_mapping )
+       n, m = bx.seqmapping.alignment_mapping_from_file( f )
+       t = bx.seqmapping.DNA.translate_list( rows )
+       i = m.translate( t )
+        
+        
+test_classes = [ AlignmentMappingTests, CharMappingTests, IntMappingTests ]
+suite = unittest.TestSuite( [ unittest.makeSuite( c ) for c in test_classes ] )
diff --git a/lib/bx/tabular/__init__.py b/lib/bx/tabular/__init__.py
new file mode 100644
index 0000000..992c9c2
--- /dev/null
+++ b/lib/bx/tabular/__init__.py
@@ -0,0 +1,3 @@
+"""
+Support for working with delimited data files.
+"""
\ No newline at end of file
diff --git a/lib/bx/tabular/io.py b/lib/bx/tabular/io.py
new file mode 100644
index 0000000..f450f85
--- /dev/null
+++ b/lib/bx/tabular/io.py
@@ -0,0 +1,146 @@
+"""
+Reading and writing delimited data files (with headers and comments).
+"""
+
+import sys
+from itertools import *
+from UserDict import DictMixin
+
+FIRST_LINE_IS_HEADER = object()
+
+class ParseError( Exception ):
+    def __init__( self, *args, **kwargs ):
+        Exception.__init__( self, *args )
+        self.linenum = kwargs.get("linenum",None)
+    def __str__( self ):
+        if self.linenum:
+            return Exception.__str__( self ) + " on line " + str(self.linenum)
+        else:
+            return Exception.__str__( self )
+
+class TableRow( object ):
+    """
+    A row of a table
+    """
+    def __init__( self, reader, fields ):
+        self.reader = reader
+        self.fields = fields
+    def __getitem__( self, key ):
+        if type( key ) == int:
+            return self.fields[key]
+        elif type( key ) == str:
+            if self.reader.header:
+                return self.fields[ self.reader.header.field_to_column[key] ]
+            else:
+                raise TypeError( "column names only supported for files with headers" )
+        else:
+            raise TypeError( "field indices must be integers or strings" )
+    @property
+    def fieldnames( self ):
+        return self.reader.header.fields
+    def __str__( self ):
+        return "\t".join( self.fields )
+
+class Header( object ):
+    """
+    Header of a table -- contains column names and a mapping from them
+    to column indexes
+    """
+    def __init__( self, fields ):
+        self.set_fields( fields )
+    def set_fields( self, fields ):
+        self.fields = fields
+        self.field_to_column = dict( zip( fields, count() ) )
+    def __getitem__( self, key ):
+        if type( key ) == int:
+            return self.fields[key]
+        elif type( key ) == str:
+            if key in self.field_to_column:
+                return key
+        else:
+            raise TypeError( "field indices must be integers or strings" )
+    def __str__( self ):
+        return "#" + "\t".join( self.fields )
+        
+class Comment( object ):
+    def __init__( self, line ):
+        self.line = line
+    def __str__( self ):
+        if self.line.startswith("#"):
+            return self.line
+        return "#" + self.line
+
+class TableReader( object ):
+    """
+    Reader for iterating tabular data
+    """
+    def __init__( self, input, return_header=True, return_comments=True, force_header=None, comment_lines_startswith = ["#"] ):
+        self.input = input
+        self.return_comments = return_comments
+        self.return_header = return_header
+        self.input_iter = iter( input )
+        self.linenum = 0
+        self.header = force_header
+        self.comment_lines_startswith = comment_lines_startswith
+    def __iter__( self ):
+        return self
+    def next( self ):
+        line = self.input_iter.next()
+        self.linenum += 1
+        line = line.rstrip( "\r\n" )
+        # Catch blank lines (throw a warning?)
+        # This will end up adding a '#' at the beginning of blank lines
+        if line == '':
+            if self.return_comments:
+                return Comment( line )
+            else:
+                return self.next()
+        # Force header?
+        if self.header is FIRST_LINE_IS_HEADER and self.linenum == 1:
+            self.header = self.parse_header( line )
+            if self.return_header:
+                return self.header
+            else:
+                return self.next()
+        # Is it a comment line?
+        for comment_line_start in self.comment_lines_startswith:
+            if line.startswith( comment_line_start ):
+                # If a comment and the first line we assume it is a header
+                if self.header is None and self.linenum == 1:
+                    self.header = self.parse_header( line )
+                    if self.return_header:
+                        return self.header
+                    else:
+                        return self.next()
+                else:
+                    if self.return_comments:
+                        return self.parse_comment( line )
+                    else:
+                        return self.next()
+        # Not a comment, must be an interval
+        try:
+            return self.parse_row( line )
+        except ParseError, e:
+            e.linenum = self.linenum
+            raise e
+    def parse_header( self, line ):
+        if line.startswith("#"):
+            fields = line[1:].split( "\t" )
+        else:
+            fields = line.split( "\t" )
+        return Header( fields )
+    def parse_comment( self, line ):
+        return Comment( line )
+    def parse_row( self, line ):
+        return TableRow( self, line.split( "\t" ) )
+        
+        
+        
+        
+        
+        
+        
+        
+        
+        
+        
diff --git a/lib/bx/wiggle.py b/lib/bx/wiggle.py
new file mode 100644
index 0000000..d9d85e3
--- /dev/null
+++ b/lib/bx/wiggle.py
@@ -0,0 +1,78 @@
+"""
+Support for scores in the `wiggle`_ file format used by the UCSC Genome
+Browser.
+
+The positions in the wiggle format are 1-relative, however,
+the positions returned match the BED/interval format which is zero-based, half-open.
+
+.. _wiggle: http://genome.ucsc.edu/goldenPath/help/wiggle.html
+"""
+
+def parse_header( line ):
+    return dict( [ field.split( '=' ) for field in line.split()[1:] ] )
+
+def IntervalReader( f ):
+    """
+    Iterator yielding chrom, start, end, strand, value.
+    Values are zero-based, half-open.
+    Regions which lack a score are ignored.
+    """
+    current_chrom = None
+    current_pos = None
+    current_step = None
+
+    # always for wiggle data
+    strand = '+'
+
+    mode = "bed"
+
+    for line in f:
+        if line.isspace() or line.startswith( "track" ) or line.startswith( "#" ) or line.startswith( "browser" ):
+            continue
+        elif line.startswith( "variableStep" ):
+            header = parse_header( line )
+            current_chrom = header['chrom']
+            current_pos = None
+            current_step = None
+            if 'span' in header: current_span = int( header['span'] )
+            else: current_span = 1
+            mode = "variableStep"
+        elif line.startswith( "fixedStep" ):
+            header = parse_header( line )
+            current_chrom = header['chrom']
+            current_pos = int( header['start'] ) - 1
+            current_step = int( header['step'] )
+            if 'span' in header: current_span = int( header['span'] )
+            else: current_span = 1
+            mode = "fixedStep"
+        elif mode == "bed":
+            fields = line.split()
+            if len( fields ) > 3:
+                if len( fields ) > 5:
+                    yield fields[0], int( fields[1] ), int( fields[2] ), fields[5], float( fields[3] )
+                else:
+                    yield fields[0], int( fields[1] ), int( fields[2] ), strand, float( fields[3] )
+        elif mode == "variableStep":
+            fields = line.split()
+            pos = int( fields[0] ) - 1
+            yield current_chrom, pos, pos + current_span, strand, float( fields[1] )
+        elif mode == "fixedStep":
+            yield current_chrom, current_pos, current_pos + current_span, strand, float( line.split()[0] )
+            current_pos += current_step
+        else:
+            raise ValueError("Unexpected input line: %s" % line.strip())
+
+
+class Reader( object ):
+    """
+    Iterator yielding chrom, position, value.
+    Values are zero-based.
+    Regions which lack a score are ignored.
+    """
+    def __init__( self, f ):
+        self.file = f
+
+    def __iter__( self ):
+        for chrom, start, end, strand, val in IntervalReader( self.file ):
+            for pos in xrange( start, end ):
+                yield chrom, pos, val
diff --git a/lib/bx/wiggle_tests.py b/lib/bx/wiggle_tests.py
new file mode 100644
index 0000000..4cdc3a9
--- /dev/null
+++ b/lib/bx/wiggle_tests.py
@@ -0,0 +1,90 @@
+"""
+Tests for `bx.wiggle`.
+"""
+
+import unittest
+from bx import wiggle
+from StringIO import StringIO
+
+# A modified version of UCSC's example wiggle, taken from http://genome.ucsc.edu/goldenPath/help/wiggleExample.txt
+test_wig = """browser position chr19:59302001-59311000
+browser hide all
+browser pack refGene encodeRegions
+browser full altGraph
+#	5 base wide bar graph, autoScale is on by default == graphing
+#	limits will dynamically change to always show full range of data
+#	in viewing window, priority = 20 positions this as the second graph
+#	Note, zero-relative, half-open coordinate system in use for bed format
+track type=wiggle_0 name="Bed Format" description="BED format" visibility=full color=200,100,0 altColor=0,100,200 priority=20
+chr19 59302000 59302005 -1.0
+chr19 59302300 59302305 -0.75
+#	4 base wide bar graph at arbitrarily spaced positions,
+#	threshold line drawn at y=11.76
+#	autoScale off viewing range set to [0:25]
+#	priority = 10 positions this as the first graph
+#	Note, one-relative coordinate system in use for this format
+track type=wiggle_0 name="variableStep" description="variableStep format" visibility=full autoScale=off viewLimits=0.0:25.0 color=255,200,0 yLineMark=11.76 yLineOnOff=on priority=10
+variableStep chrom=chr19 span=4
+59304701 10.0
+59304901 12.5
+#	3 base wide points graph at every 300 bases, 50 pixel high graph
+#	autoScale off and viewing range set to [0:1000]
+#	priority = 30 positions this as the third graph
+#	Note, one-relative coordinate system in use for this format
+track type=wiggle_0 name="fixedStep" description="fixed step" visibility=full autoScale=off viewLimits=0:1000 color=0,200,100 maxHeightPixels=100:50:20 graphType=points priority=30
+fixedStep chrom=chr19 start=59307401 step=300 span=3
+1000
+ 900
+ 800
+"""
+
+interval_reader_result = [
+"chr19,59302000,59302005,+,-1.0",
+"chr19,59302300,59302305,+,-0.75",
+"chr19,59304700,59304704,+,10.0",
+"chr19,59304900,59304904,+,12.5",
+"chr19,59307400,59307403,+,1000.0",
+"chr19,59307700,59307703,+,900.0",
+"chr19,59308000,59308003,+,800.0"
+]
+
+position_reader_result = [
+"chr19,59302000,-1.0",
+"chr19,59302001,-1.0",
+"chr19,59302002,-1.0",
+"chr19,59302003,-1.0",
+"chr19,59302004,-1.0",
+"chr19,59302300,-0.75",
+"chr19,59302301,-0.75",
+"chr19,59302302,-0.75",
+"chr19,59302303,-0.75",
+"chr19,59302304,-0.75",
+"chr19,59304700,10.0",
+"chr19,59304701,10.0",
+"chr19,59304702,10.0",
+"chr19,59304703,10.0",
+"chr19,59304900,12.5",
+"chr19,59304901,12.5",
+"chr19,59304902,12.5",
+"chr19,59304903,12.5",
+"chr19,59307400,1000.0",
+"chr19,59307401,1000.0",
+"chr19,59307402,1000.0",
+"chr19,59307700,900.0",
+"chr19,59307701,900.0",
+"chr19,59307702,900.0",
+"chr19,59308000,800.0",
+"chr19,59308001,800.0",
+"chr19,59308002,800.0"
+]
+class TestWiggleReader(unittest.TestCase):
+    def test_reader(self):
+        #Test position reader
+        assert position_reader_result == [ ",".join( map( str, value ) ) for value in wiggle.Reader( StringIO( test_wig ) ) ]
+    
+    def test_interval_reader(self):
+        #Test interval reader reader
+        assert interval_reader_result == [ ",".join( map( str, value ) ) for value in wiggle.IntervalReader( StringIO( test_wig ) ) ]
+    
+if __name__ == '__main__':
+    unittest.main()
diff --git a/lib/bx_extras/__init__.py b/lib/bx_extras/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/lib/bx_extras/fpconst.py b/lib/bx_extras/fpconst.py
new file mode 100644
index 0000000..2865361
--- /dev/null
+++ b/lib/bx_extras/fpconst.py
@@ -0,0 +1,163 @@
+"""Utilities for handling IEEE 754 floating point special values
+
+This python module implements constants and functions for working with
+IEEE754 double-precision special values.  It provides constants for
+Not-a-Number (NaN), Positive Infinity (PosInf), and Negative Infinity
+(NegInf), as well as functions to test for these values.
+
+The code is implemented in pure python by taking advantage of the
+'struct' standard module. Care has been taken to generate proper
+results on both big-endian and little-endian machines. Some efficiency
+could be gained by translating the core routines into C.
+
+See <http://babbage.cs.qc.edu/courses/cs341/IEEE-754references.html>
+for reference material on the IEEE 754 floating point standard.
+
+Further information on this package is available at
+<http://www.analytics.washington.edu/statcomp/projects/rzope/fpconst/>.
+
+Author:    Gregory R. Warnes <gregory_r_warnes at groton.pfizer.com>
+Date::     2003-04-08
+Copyright: (c) 2003, Pfizer, Inc.
+"""
+
+__version__ = "0.7.0"
+ident = "$Id: fpconst.py,v 1.12 2004/05/22 04:38:17 warnes Exp $"
+
+import struct, operator
+
+# check endianess
+_big_endian = struct.pack('i',1)[0] != '\x01'
+
+# and define appropriate constants
+if(_big_endian): 
+    NaN    = struct.unpack('d', '\x7F\xF8\x00\x00\x00\x00\x00\x00')[0]
+    PosInf = struct.unpack('d', '\x7F\xF0\x00\x00\x00\x00\x00\x00')[0]
+    NegInf = -PosInf
+else:
+    NaN    = struct.unpack('d', '\x00\x00\x00\x00\x00\x00\xf8\xff')[0]
+    PosInf = struct.unpack('d', '\x00\x00\x00\x00\x00\x00\xf0\x7f')[0]
+    NegInf = -PosInf
+
+def _double_as_bytes(dval):
+    "Use struct.unpack to decode a double precision float into eight bytes"
+    tmp = list(struct.unpack('8B',struct.pack('d', dval)))
+    if not _big_endian:
+        tmp.reverse()
+    return tmp
+
+##
+## Functions to extract components of the IEEE 754 floating point format
+##
+
+def _sign(dval):
+    "Extract the sign bit from a double-precision floating point value"
+    bb = _double_as_bytes(dval)
+    return bb[0] >> 7 & 0x01
+
+def _exponent(dval):
+    """Extract the exponentent bits from a double-precision floating
+    point value.
+
+    Note that for normalized values, the exponent bits have an offset
+    of 1023. As a consequence, the actual exponentent is obtained
+    by subtracting 1023 from the value returned by this function
+    """
+    bb = _double_as_bytes(dval)
+    return (bb[0] << 4 | bb[1] >> 4) & 0x7ff
+
+def _mantissa(dval):
+    """Extract the _mantissa bits from a double-precision floating
+    point value."""
+
+    bb = _double_as_bytes(dval)
+    mantissa =  bb[1] & 0x0f << 48
+    mantissa += bb[2] << 40
+    mantissa += bb[3] << 32
+    mantissa += bb[4]
+    return mantissa 
+
+def _zero_mantissa(dval):
+    """Determine whether the mantissa bits of the given double are all
+    zero."""
+    bb = _double_as_bytes(dval)
+    return ((bb[1] & 0x0f) | reduce(operator.or_, bb[2:])) == 0
+
+##
+## Functions to test for IEEE 754 special values
+##
+
+def isNaN(value):
+    "Determine if the argument is a IEEE 754 NaN (Not a Number) value."
+    return (_exponent(value)==0x7ff and not _zero_mantissa(value))
+
+def isInf(value):
+    """Determine if the argument is an infinite IEEE 754 value (positive
+    or negative inifinity)"""
+    return (_exponent(value)==0x7ff and _zero_mantissa(value))
+
+def isFinite(value):
+    """Determine if the argument is an finite IEEE 754 value (i.e., is
+    not NaN, positive or negative inifinity)"""
+    return (_exponent(value)!=0x7ff)
+
+def isPosInf(value):
+    "Determine if the argument is a IEEE 754 positive infinity value"
+    return (_sign(value)==0 and _exponent(value)==0x7ff and \
+            _zero_mantissa(value))
+
+def isNegInf(value):
+    "Determine if the argument is a IEEE 754 negative infinity value"
+    return (_sign(value)==1 and _exponent(value)==0x7ff and \
+            _zero_mantissa(value))
+
+##
+## Functions to test public functions.
+## 
+
+def test_isNaN():
+    assert( not isNaN(PosInf) )
+    assert( not isNaN(NegInf) )
+    assert(     isNaN(NaN   ) )
+    assert( not isNaN(   1.0) )
+    assert( not isNaN(  -1.0) )
+
+def test_isInf():
+    assert(     isInf(PosInf) )
+    assert(     isInf(NegInf) )
+    assert( not isInf(NaN   ) )
+    assert( not isInf(   1.0) )
+    assert( not isInf(  -1.0) )
+
+def test_isFinite():
+    assert( not isFinite(PosInf) )
+    assert( not isFinite(NegInf) )
+    assert( not isFinite(NaN   ) )
+    assert(     isFinite(   1.0) )
+    assert(     isFinite(  -1.0) )
+
+def test_isPosInf():
+    assert(     isPosInf(PosInf) )
+    assert( not isPosInf(NegInf) )
+    assert( not isPosInf(NaN   ) )
+    assert( not isPosInf(   1.0) )
+    assert( not isPosInf(  -1.0) )
+
+def test_isNegInf():
+    assert( not isNegInf(PosInf) )
+    assert(     isNegInf(NegInf) )
+    assert( not isNegInf(NaN   ) )
+    assert( not isNegInf(   1.0) )
+    assert( not isNegInf(  -1.0) )
+
+# overall test
+def test():
+    test_isNaN()
+    test_isInf()
+    test_isFinite()
+    test_isPosInf()
+    test_isNegInf()
+    
+if __name__ == "__main__":
+    test()
+
diff --git a/lib/bx_extras/lrucache.py b/lib/bx_extras/lrucache.py
new file mode 100644
index 0000000..e95305d
--- /dev/null
+++ b/lib/bx_extras/lrucache.py
@@ -0,0 +1,230 @@
+# lrucache.py -- a simple LRU (Least-Recently-Used) cache class
+
+# Copyright 2004 Evan Prodromou <evan at bad.dynu.ca>
+# Licensed under the Academic Free License 2.1
+
+# arch-tag: LRU cache main module
+
+"""a simple LRU (Least-Recently-Used) cache module
+
+This module provides very simple LRU (Least-Recently-Used) cache
+functionality.
+
+An *in-memory cache* is useful for storing the results of an
+'expensive' process (one that takes a lot of time or resources) for
+later re-use. Typical examples are accessing data from the filesystem,
+a database, or a network location. If you know you'll need to re-read
+the data again, it can help to keep it in a cache.
+
+You *can* use a Python dictionary as a cache for some purposes.
+However, if the results you're caching are large, or you have a lot of
+possible results, this can be impractical memory-wise.
+
+An *LRU cache*, on the other hand, only keeps _some_ of the results in
+memory, which keeps you from overusing resources. The cache is bounded
+by a maximum size; if you try to add more values to the cache, it will
+automatically discard the values that you haven't read or written to
+in the longest time. In other words, the least-recently-used items are
+discarded. [1]_
+
+.. [1]: 'Discarded' here means 'removed from the cache'.
+
+"""
+
+# TODO: Remove this file in favor of functools.lru_cache
+# when the minimum Python version is high enough
+
+import time
+from heapq import heappush, heappop, heapify
+
+__version__ = "0.2"
+__all__ = ['CacheKeyError', 'LRUCache', 'DEFAULT_SIZE']
+__docformat__ = 'reStructuredText en'
+
+DEFAULT_SIZE = 16
+"""Default size of a new LRUCache object, if no 'size' argument is given."""
+
+class CacheKeyError(KeyError):
+    """Error raised when cache requests fail
+
+    When a cache record is accessed which no longer exists (or never did),
+    this error is raised. To avoid it, you may want to check for the existence
+    of a cache record before reading or deleting it."""
+    pass
+
+class LRUCache(object):
+    """Least-Recently-Used (LRU) cache.
+
+    Instances of this class provide a least-recently-used (LRU) cache. They
+    emulate a Python mapping type. You can use an LRU cache more or less like
+    a Python dictionary, with the exception that objects you put into the
+    cache may be discarded before you take them out.
+
+    Some example usage::
+
+    cache = LRUCache(32) # new cache
+    cache['foo'] = get_file_contents('foo') # or whatever
+
+    if 'foo' in cache: # if it's still in cache...
+	    # use cached version
+        contents = cache['foo']
+    else:
+	    # recalculate
+        contents = get_file_contents('foo')
+	    # store in cache for next time
+        cache['foo'] = contents
+
+    print cache.size # Maximum size
+
+    print len(cache) # 0 <= len(cache) <= cache.size
+
+    cache.size = 10 # Auto-shrink on size assignment
+
+    for i in range(50): # note: larger than cache size
+        cache[i] = i
+
+    if 0 not in cache: print 'Zero was discarded.'
+
+    if 42 in cache:
+        del cache[42] # Manual deletion
+
+    for j in cache:   # iterate (in LRU order)
+        print j, cache[j] # iterator produces keys, not values
+    """
+
+    class __Node(object):
+        """Record of a cached value. Not for public consumption."""
+
+        def __init__(self, key, obj, timestamp):
+            object.__init__(self)
+            self.key = key
+            self.obj = obj
+            self.atime = timestamp
+            self.mtime = self.atime
+
+        def __lt__(self, other):
+            return self.atime < other.atime
+
+        def __eq__(self, other):
+            return self.atime == other.atime
+
+        def __le__(self, other):
+            return self.__lt__(other) or self.__eq__(other)
+
+        def __gt__(self, other):
+            return not (self.__lt__(other) or self.__eq__(other))
+
+        def __ge__(self, other):
+            return not self.__lt__(other)
+
+        def __ne__(self, other):
+            return not self.__eq__(other)
+
+        def __repr__(self):
+            return "<%s %s => %s (%s)>" % \
+                   (self.__class__, self.key, self.obj,
+                    time.asctime(time.localtime(self.atime)))
+
+    def __init__(self, size=DEFAULT_SIZE):
+        # Check arguments
+        if size <= 0:
+            raise ValueError, size
+        elif type(size) is not type(0):
+            raise TypeError, size
+        object.__init__(self)
+        self.__heap = []
+        self.__dict = {}
+        self.size = size
+        """Maximum size of the cache.
+        If more than 'size' elements are added to the cache,
+        the least-recently-used ones will be discarded."""
+
+    def __len__(self):
+        return len(self.__heap)
+
+    def __contains__(self, key):
+        return self.__dict.has_key(key)
+
+    def __setitem__(self, key, obj):
+        if self.__dict.has_key(key):
+            node = self.__dict[key]
+            node.obj = obj
+            node.atime = time.time()
+            node.mtime = node.atime
+            heapify(self.__heap)
+        else:
+            # size may have been reset, so we loop
+            while len(self.__heap) >= self.size:
+                lru = heappop(self.__heap)
+                del self.__dict[lru.key]
+            node = self.__Node(key, obj, time.time())
+            self.__dict[key] = node
+            heappush(self.__heap, node)
+
+    def __getitem__(self, key):
+        if not self.__dict.has_key(key):
+            raise CacheKeyError(key)
+        else:
+            node = self.__dict[key]
+            node.atime = time.time()
+            heapify(self.__heap)
+            return node.obj
+
+    def __delitem__(self, key):
+        if not self.__dict.has_key(key):
+            raise CacheKeyError(key)
+        else:
+            node = self.__dict[key]
+            del self.__dict[key]
+            self.__heap.remove(node)
+            heapify(self.__heap)
+            return node.obj
+
+    def __iter__(self):
+        copy = self.__heap[:]
+        while len(copy) > 0:
+            node = heappop(copy)
+            yield node.key
+        raise StopIteration
+
+    def __setattr__(self, name, value):
+        object.__setattr__(self, name, value)
+        # automagically shrink heap on resize
+        if name == 'size':
+            while len(self.__heap) > value:
+                lru = heappop(self.__heap)
+                del self.__dict[lru.key]
+
+    def __repr__(self):
+        return "<%s (%d elements)>" % (str(self.__class__), len(self.__heap))
+
+    def mtime(self, key):
+        """Return the last modification time for the cache record with key.
+        May be useful for cache instances where the stored values can get
+        'stale', such as caching file or network resource contents."""
+        if not self.__dict.has_key(key):
+            raise CacheKeyError(key)
+        else:
+            node = self.__dict[key]
+            return node.mtime
+
+if __name__ == "__main__":
+    cache = LRUCache(25)
+    print cache
+    for i in range(50):
+        cache[i] = str(i)
+    print cache
+    if 46 in cache:
+        del cache[46]
+    print cache
+    cache.size = 10
+    print cache
+    cache[46] = '46'
+    print cache
+    print len(cache)
+    for c in cache:
+        print c
+    print cache
+    print cache.mtime(46)
+    for c in cache:
+        print c
diff --git a/lib/bx_extras/pstat.py b/lib/bx_extras/pstat.py
new file mode 100644
index 0000000..8492dbd
--- /dev/null
+++ b/lib/bx_extras/pstat.py
@@ -0,0 +1,1062 @@
+# Copyright (c) 1999-2000 Gary Strangman; All Rights Reserved.
+#
+# This software is distributable under the terms of the GNU
+# General Public License (GPL) v2, the text of which can be found at
+# http://www.gnu.org/copyleft/gpl.html. Installing, importing or otherwise
+# using this module constitutes acceptance of the terms of this License.
+#
+# Disclaimer
+#
+# This software is provided "as-is".  There are no expressed or implied
+# warranties of any kind, including, but not limited to, the warranties
+# of merchantability and fittness for a given application.  In no event
+# shall Gary Strangman be liable for any direct, indirect, incidental,
+# special, exemplary or consequential damages (including, but not limited
+# to, loss of use, data or profits, or business interruption) however
+# caused and on any theory of liability, whether in contract, strict
+# liability or tort (including negligence or otherwise) arising in any way
+# out of the use of this software, even if advised of the possibility of
+# such damage.
+#
+# Comments and/or additions are welcome (send e-mail to:
+# strang at nmr.mgh.harvard.edu).
+#
+"""
+pstat.py module
+
+#################################################
+#######  Written by:  Gary Strangman  ###########
+#######  Last modified:  Jun 29, 2001 ###########
+#################################################
+
+This module provides some useful list and array manipulation routines
+modeled after those found in the |Stat package by Gary Perlman, plus a
+number of other useful list/file manipulation functions.  The list-based
+functions include:
+
+      abut (source,*args)
+      simpleabut (source, addon)
+      colex (listoflists,cnums)
+      collapse (listoflists,keepcols,collapsecols,fcn1=None,fcn2=None,cfcn=None)
+      dm (listoflists,criterion)
+      flat (l)
+      linexand (listoflists,columnlist,valuelist)
+      linexor (listoflists,columnlist,valuelist)
+      linedelimited (inlist,delimiter)
+      lineincols (inlist,colsize)
+      lineincustcols (inlist,colsizes)
+      list2string (inlist)
+      makelol(inlist)
+      makestr(x)
+      printcc (lst,extra=2)
+      printincols (listoflists,colsize)
+      pl (listoflists)
+      printl(listoflists)
+      replace (lst,oldval,newval)
+      recode (inlist,listmap,cols='all')
+      remap (listoflists,criterion)
+      roundlist (inlist,num_digits_to_round_floats_to)
+      sortby(listoflists,sortcols)
+      unique (inlist)
+      duplicates(inlist)
+      writedelimited (listoflists, delimiter, file, writetype='w')
+
+Some of these functions have alternate versions which are defined only if
+Numeric (NumPy) can be imported.  These functions are generally named as
+above, with an 'a' prefix.
+
+      aabut (source, *args)
+      acolex (a,indices,axis=1)
+      acollapse (a,keepcols,collapsecols,sterr=0,ns=0)
+      adm (a,criterion)
+      alinexand (a,columnlist,valuelist)
+      alinexor (a,columnlist,valuelist)
+      areplace (a,oldval,newval)
+      arecode (a,listmap,col='all')
+      arowcompare (row1, row2)
+      arowsame (row1, row2)
+      asortrows(a,axis=0)
+      aunique(inarray)
+      aduplicates(inarray)
+
+Currently, the code is all but completely un-optimized.  In many cases, the
+array versions of functions amount simply to aliases to built-in array
+functions/methods.  Their inclusion here is for function name consistency.
+"""
+
+## CHANGE LOG:
+## ==========
+## 01-11-15 ... changed list2string() to accept a delimiter
+## 01-06-29 ... converted exec()'s to eval()'s to make compatible with Py2.1
+## 01-05-31 ... added duplicates() and aduplicates() functions
+## 00-12-28 ... license made GPL, docstring and import requirements
+## 99-11-01 ... changed version to 0.3
+## 99-08-30 ... removed get, getstrings, put, aget, aput (into io.py)
+## 03/27/99 ... added areplace function, made replace fcn recursive
+## 12/31/98 ... added writefc function for ouput to fixed column sizes
+## 12/07/98 ... fixed import problem (failed on collapse() fcn)
+##              added __version__ variable (now 0.2)
+## 12/05/98 ... updated doc-strings
+##              added features to collapse() function
+##              added flat() function for lists
+##              fixed a broken asortrows()
+## 11/16/98 ... fixed minor bug in aput for 1D arrays
+##
+## 11/08/98 ... fixed aput to output large arrays correctly
+
+import stats  # required 3rd party module
+import string, copy
+from types import *
+
+__version__ = 0.4
+
+###===========================  LIST FUNCTIONS  ==========================
+###
+### Here are the list functions, DEFINED FOR ALL SYSTEMS.
+### Array functions (for NumPy-enabled computers) appear below.
+###
+
+def abut (source,*args):
+    """
+Like the |Stat abut command.  It concatenates two lists side-by-side
+and returns the result.  '2D' lists are also accomodated for either argument
+(source or addon).  CAUTION:  If one list is shorter, it will be repeated
+until it is as long as the longest list.  If this behavior is not desired,
+use pstat.simpleabut().
+
+Usage:   abut(source, args)   where args=any # of lists
+Returns: a list of lists as long as the LONGEST list past, source on the
+         'left', lists in <args> attached consecutively on the 'right'
+"""
+
+    if type(source) not in [ListType,TupleType]:
+        source = [source]
+    for addon in args:
+        if type(addon) not in [ListType,TupleType]:
+            addon = [addon]
+        if len(addon) < len(source):                # is source list longer?
+            if len(source) % len(addon) == 0:        # are they integer multiples?
+                repeats = len(source)/len(addon)    # repeat addon n times
+                origadd = copy.deepcopy(addon)
+                for i in range(repeats-1):
+                    addon = addon + origadd
+            else:
+                repeats = len(source)/len(addon)+1  # repeat addon x times,
+                origadd = copy.deepcopy(addon)      #    x is NOT an integer
+                for i in range(repeats-1):
+                    addon = addon + origadd
+                    addon = addon[0:len(source)]
+        elif len(source) < len(addon):                # is addon list longer?
+            if len(addon) % len(source) == 0:        # are they integer multiples?
+                repeats = len(addon)/len(source)    # repeat source n times
+                origsour = copy.deepcopy(source)
+                for i in range(repeats-1):
+                    source = source + origsour
+            else:
+                repeats = len(addon)/len(source)+1  # repeat source x times,
+                origsour = copy.deepcopy(source)    #   x is NOT an integer
+                for i in range(repeats-1):
+                    source = source + origsour
+                source = source[0:len(addon)]
+
+        source = simpleabut(source,addon)
+    return source
+
+
+def simpleabut (source, addon):
+    """
+Concatenates two lists as columns and returns the result.  '2D' lists
+are also accomodated for either argument (source or addon).  This DOES NOT
+repeat either list to make the 2 lists of equal length.  Beware of list pairs
+with different lengths ... the resulting list will be the length of the
+FIRST list passed.
+
+Usage:   simpleabut(source,addon)  where source, addon=list (or list-of-lists)
+Returns: a list of lists as long as source, with source on the 'left' and
+                 addon on the 'right'
+"""
+    if type(source) not in [ListType,TupleType]:
+        source = [source]
+    if type(addon) not in [ListType,TupleType]:
+        addon = [addon]
+    minlen = min(len(source),len(addon))
+    list = copy.deepcopy(source)                # start abut process
+    if type(source[0]) not in [ListType,TupleType]:
+        if type(addon[0]) not in [ListType,TupleType]:
+            for i in range(minlen):
+                list[i] = [source[i]] + [addon[i]]        # source/addon = column
+        else:
+            for i in range(minlen):
+                list[i] = [source[i]] + addon[i]        # addon=list-of-lists
+    else:
+        if type(addon[0]) not in [ListType,TupleType]:
+            for i in range(minlen):
+                list[i] = source[i] + [addon[i]]        # source=list-of-lists
+        else:
+            for i in range(minlen):
+                list[i] = source[i] + addon[i]        # source/addon = list-of-lists
+    source = list
+    return source
+
+
+def colex (listoflists,cnums):
+    """
+Extracts from listoflists the columns specified in the list 'cnums'
+(cnums can be an integer, a sequence of integers, or a string-expression that
+corresponds to a slice operation on the variable x ... e.g., 'x[3:]' will colex
+columns 3 onward from the listoflists).
+
+Usage:   colex (listoflists,cnums)
+Returns: a list-of-lists corresponding to the columns from listoflists
+         specified by cnums, in the order the column numbers appear in cnums
+"""
+    global index
+    column = 0
+    if type(cnums) in [ListType,TupleType]:   # if multiple columns to get
+        index = cnums[0]
+        column = map(lambda x: x[index], listoflists)
+        for col in cnums[1:]:
+            index = col
+            column = abut(column,map(lambda x: x[index], listoflists))
+    elif type(cnums) == StringType:              # if an 'x[3:]' type expr.
+        evalstring = 'map(lambda x: x'+cnums+', listoflists)'
+        column = eval(evalstring)
+    else:                                     # else it's just 1 col to get
+        index = cnums
+        column = map(lambda x: x[index], listoflists)
+    return column
+
+
+def collapse (listoflists,keepcols,collapsecols,fcn1=None,fcn2=None,cfcn=None):
+     """
+Averages data in collapsecol, keeping all unique items in keepcols
+(using unique, which keeps unique LISTS of column numbers), retaining the
+unique sets of values in keepcols, the mean for each.  Setting fcn1
+and/or fcn2 to point to a function rather than None (e.g., stats.sterr, len)
+will append those results (e.g., the sterr, N) after each calculated mean.
+cfcn is the collapse function to apply (defaults to mean, defined here in the
+pstat module to avoid circular imports with stats.py, but harmonicmean or
+others could be passed).
+
+Usage:    collapse (listoflists,keepcols,collapsecols,fcn1=None,fcn2=None,cfcn=None)
+Returns: a list of lists with all unique permutations of entries appearing in
+     columns ("conditions") specified by keepcols, abutted with the result of
+     cfcn (if cfcn=None, defaults to the mean) of each column specified by
+     collapsecols.
+"""
+     def collmean (inlist):
+         s = 0
+         for item in inlist:
+             s = s + item
+         return s/float(len(inlist))
+
+     if type(keepcols) not in [ListType,TupleType]:
+         keepcols = [keepcols]
+     if type(collapsecols) not in [ListType,TupleType]:
+         collapsecols = [collapsecols]
+     if cfcn == None:
+         cfcn = collmean
+     if keepcols == []:
+         means = [0]*len(collapsecols)
+         for i in range(len(collapsecols)):
+             avgcol = colex(listoflists,collapsecols[i])
+             means[i] = cfcn(avgcol)
+             if fcn1:
+                 try:
+                     test = fcn1(avgcol)
+                 except:
+                     test = 'N/A'
+                     means[i] = [means[i], test]
+             if fcn2:
+                 try:
+                     test = fcn2(avgcol)
+                 except:
+                     test = 'N/A'
+                 try:
+                     means[i] = means[i] + [len(avgcol)]
+                 except TypeError:
+                     means[i] = [means[i],len(avgcol)]
+         return means
+     else:
+         values = colex(listoflists,keepcols)
+         uniques = unique(values)
+         uniques.sort()
+         newlist = []
+         if type(keepcols) not in [ListType,TupleType]:  keepcols = [keepcols]
+         for item in uniques:
+             if type(item) not in [ListType,TupleType]:  item =[item]
+             tmprows = linexand(listoflists,keepcols,item)
+             for col in collapsecols:
+                 avgcol = colex(tmprows,col)
+                 item.append(cfcn(avgcol))
+                 if fcn1 <> None:
+                     try:
+                         test = fcn1(avgcol)
+                     except:
+                         test = 'N/A'
+                     item.append(test)
+                 if fcn2 <> None:
+                     try:
+                         test = fcn2(avgcol)
+                     except:
+                         test = 'N/A'
+                     item.append(test)
+                 newlist.append(item)
+         return newlist
+
+
+def dm (listoflists,criterion):
+    """
+Returns rows from the passed list of lists that meet the criteria in
+the passed criterion expression (a string as a function of x; e.g., 'x[3]>=9'
+will return all rows where the 4th column>=9 and "x[2]=='N'" will return rows
+with column 2 equal to the string 'N').
+
+Usage:   dm (listoflists, criterion)
+Returns: rows from listoflists that meet the specified criterion.
+"""
+    function = 'filter(lambda x: '+criterion+',listoflists)'
+    lines = eval(function)
+    return lines
+
+
+def flat(l):
+    """
+Returns the flattened version of a '2D' list.  List-correlate to the a.flat()
+method of NumPy arrays.
+
+Usage:    flat(l)
+"""
+    newl = []
+    for i in range(len(l)):
+        for j in range(len(l[i])):
+            newl.append(l[i][j])
+    return newl
+
+
+def linexand (listoflists,columnlist,valuelist):
+    """
+Returns the rows of a list of lists where col (from columnlist) = val
+(from valuelist) for EVERY pair of values (columnlist[i],valuelists[i]).
+len(columnlist) must equal len(valuelist).
+
+Usage:   linexand (listoflists,columnlist,valuelist)
+Returns: the rows of listoflists where columnlist[i]=valuelist[i] for ALL i
+"""
+    if type(columnlist) not in [ListType,TupleType]:
+        columnlist = [columnlist]
+    if type(valuelist) not in [ListType,TupleType]:
+        valuelist = [valuelist]
+    criterion = ''
+    for i in range(len(columnlist)):
+        if type(valuelist[i])==StringType:
+            critval = '\'' + valuelist[i] + '\''
+        else:
+            critval = str(valuelist[i])
+        criterion = criterion + ' x['+str(columnlist[i])+']=='+critval+' and'
+    criterion = criterion[0:-3]         # remove the "and" after the last crit
+    function = 'filter(lambda x: '+criterion+',listoflists)'
+    lines = eval(function)
+    return lines
+
+
+def linexor (listoflists,columnlist,valuelist):
+    """
+Returns the rows of a list of lists where col (from columnlist) = val
+(from valuelist) for ANY pair of values (colunmlist[i],valuelist[i[).
+One value is required for each column in columnlist.  If only one value
+exists for columnlist but multiple values appear in valuelist, the
+valuelist values are all assumed to pertain to the same column.
+
+Usage:   linexor (listoflists,columnlist,valuelist)
+Returns: the rows of listoflists where columnlist[i]=valuelist[i] for ANY i
+"""
+    if type(columnlist) not in [ListType,TupleType]:
+        columnlist = [columnlist]
+    if type(valuelist) not in [ListType,TupleType]:
+        valuelist = [valuelist]
+    criterion = ''
+    if len(columnlist) == 1 and len(valuelist) > 1:
+        columnlist = columnlist*len(valuelist)
+    for i in range(len(columnlist)):          # build an exec string
+        if type(valuelist[i])==StringType:
+            critval = '\'' + valuelist[i] + '\''
+        else:
+            critval = str(valuelist[i])
+        criterion = criterion + ' x['+str(columnlist[i])+']=='+critval+' or'
+    criterion = criterion[0:-2]         # remove the "or" after the last crit
+    function = 'filter(lambda x: '+criterion+',listoflists)'
+    lines = eval(function)
+    return lines
+
+
+def linedelimited (inlist,delimiter):
+    """
+Returns a string composed of elements in inlist, with each element
+separated by 'delimiter.'  Used by function writedelimited.  Use '\t'
+for tab-delimiting.
+
+Usage:   linedelimited (inlist,delimiter)
+"""
+    outstr = ''
+    for item in inlist:
+        if type(item) <> StringType:
+            item = str(item)
+        outstr = outstr + item + delimiter
+    outstr = outstr[0:-1]
+    return outstr
+
+
+def lineincols (inlist,colsize):
+    """
+Returns a string composed of elements in inlist, with each element
+right-aligned in columns of (fixed) colsize.
+
+Usage:   lineincols (inlist,colsize)   where colsize is an integer
+"""
+    outstr = ''
+    for item in inlist:
+        if type(item) <> StringType:
+            item = str(item)
+        size = len(item)
+        if size <= colsize:
+            for i in range(colsize-size):
+                outstr = outstr + ' '
+            outstr = outstr + item
+        else:
+            outstr = outstr + item[0:colsize+1]
+    return outstr
+
+
+def lineincustcols (inlist,colsizes):
+    """
+Returns a string composed of elements in inlist, with each element
+right-aligned in a column of width specified by a sequence colsizes.  The
+length of colsizes must be greater than or equal to the number of columns
+in inlist.
+
+Usage:   lineincustcols (inlist,colsizes)
+Returns: formatted string created from inlist
+"""
+    outstr = ''
+    for i in range(len(inlist)):
+        if type(inlist[i]) <> StringType:
+            item = str(inlist[i])
+        else:
+            item = inlist[i]
+        size = len(item)
+        if size <= colsizes[i]:
+            for j in range(colsizes[i]-size):
+                outstr = outstr + ' '
+            outstr = outstr + item
+        else:
+            outstr = outstr + item[0:colsizes[i]+1]
+    return outstr
+
+
+def list2string (inlist,delimit=' '):
+    """
+Converts a 1D list to a single long string for file output, using
+the string.join function.
+
+Usage:   list2string (inlist,delimit=' ')
+Returns: the string created from inlist
+"""
+    stringlist = map(makestr,inlist)
+    return string.join(stringlist,delimit)
+
+
+def makelol(inlist):
+    """
+Converts a 1D list to a 2D list (i.e., a list-of-lists).  Useful when you
+want to use put() to write a 1D list one item per line in the file.
+
+Usage:   makelol(inlist)
+Returns: if l = [1,2,'hi'] then returns [[1],[2],['hi']] etc.
+"""
+    x = []
+    for item in inlist:
+        x.append([item])
+    return x
+
+
+def makestr (x):
+    if type(x) <> StringType:
+        x = str(x)
+    return x
+
+
+def printcc (lst,extra=2):
+    """
+Prints a list of lists in columns, customized by the max size of items
+within the columns (max size of items in col, plus 'extra' number of spaces).
+Use 'dashes' or '\\n' in the list-of-lists to print dashes or blank lines,
+respectively.
+
+Usage:   printcc (lst,extra=2)
+Returns: None
+"""
+    if type(lst[0]) not in [ListType,TupleType]:
+        lst = [lst]
+    rowstokill = []
+    list2print = copy.deepcopy(lst)
+    for i in range(len(lst)):
+        if lst[i] == ['\n'] or lst[i]=='\n' or lst[i]=='dashes' or lst[i]=='' or lst[i]==['']:
+            rowstokill = rowstokill + [i]
+    rowstokill.reverse()   # delete blank rows from the end
+    for row in rowstokill:
+        del list2print[row]
+    maxsize = [0]*len(list2print[0])
+    for col in range(len(list2print[0])):
+        items = colex(list2print,col)
+        items = map(makestr,items)
+        maxsize[col] = max(map(len,items)) + extra
+    for row in lst:
+        if row == ['\n'] or row == '\n' or row == '' or row == ['']:
+            print
+        elif row == ['dashes'] or row == 'dashes':
+            dashes = [0]*len(maxsize)
+            for j in range(len(maxsize)):
+                dashes[j] = '-'*(maxsize[j]-2)
+            print lineincustcols(dashes,maxsize)
+        else:
+            print lineincustcols(row,maxsize)
+    return None
+
+
+def printincols (listoflists,colsize):
+    """
+Prints a list of lists in columns of (fixed) colsize width, where
+colsize is an integer.
+
+Usage:   printincols (listoflists,colsize)
+Returns: None
+"""
+    for row in listoflists:
+        print lineincols(row,colsize)
+    return None
+
+
+def pl (listoflists):
+    """
+Prints a list of lists, 1 list (row) at a time.
+
+Usage:   pl(listoflists)
+Returns: None
+"""
+    for row in listoflists:
+        if row[-1] == '\n':
+            print row,
+        else:
+            print row
+    return None
+
+
+def printl(listoflists):
+    """Alias for pl."""
+    pl(listoflists)
+    return
+
+
+def replace (inlst,oldval,newval):
+    """
+Replaces all occurrences of 'oldval' with 'newval', recursively.
+
+Usage:   replace (inlst,oldval,newval)
+"""
+    lst = inlst*1
+    for i in range(len(lst)):
+        if type(lst[i]) not in [ListType,TupleType]:
+            if lst[i]==oldval: lst[i]=newval
+        else:
+            lst[i] = replace(lst[i],oldval,newval)
+    return lst
+
+
+def recode (inlist,listmap,cols=None):
+    """
+Changes the values in a list to a new set of values (useful when
+you need to recode data from (e.g.) strings to numbers.  cols defaults
+to None (meaning all columns are recoded).
+
+Usage:   recode (inlist,listmap,cols=None)  cols=recode cols, listmap=2D list
+Returns: inlist with the appropriate values replaced with new ones
+"""
+    lst = copy.deepcopy(inlist)
+    if cols != None:
+        if type(cols) not in [ListType,TupleType]:
+            cols = [cols]
+        for col in cols:
+            for row in range(len(lst)):
+                try:
+                    idx = colex(listmap,0).index(lst[row][col])
+                    lst[row][col] = listmap[idx][1]
+                except ValueError:
+                    pass
+    else:
+        for row in range(len(lst)):
+            for col in range(len(lst)):
+                try:
+                    idx = colex(listmap,0).index(lst[row][col])
+                    lst[row][col] = listmap[idx][1]
+                except ValueError:
+                    pass
+    return lst
+
+
+def remap (listoflists,criterion):
+    """
+Remaps values in a given column of a 2D list (listoflists).  This requires
+a criterion as a function of 'x' so that the result of the following is
+returned ... map(lambda x: 'criterion',listoflists).
+
+Usage:   remap(listoflists,criterion)    criterion=string
+Returns: remapped version of listoflists
+"""
+    function = 'map(lambda x: '+criterion+',listoflists)'
+    lines = eval(function)
+    return lines
+
+
+def roundlist (inlist,digits):
+    """
+Goes through each element in a 1D or 2D inlist, and applies the following
+function to all elements of FloatType ... round(element,digits).
+
+Usage:   roundlist(inlist,digits)
+Returns: list with rounded floats
+"""
+    if type(inlist[0]) in [IntType, FloatType]:
+        inlist = [inlist]
+    l = inlist*1
+    for i in range(len(l)):
+        for j in range(len(l[i])):
+            if type(l[i][j])==FloatType:
+                l[i][j] = round(l[i][j],digits)
+    return l
+
+
+def sortby(listoflists,sortcols):
+    """
+Sorts a list of lists on the column(s) specified in the sequence
+sortcols.
+
+Usage:   sortby(listoflists,sortcols)
+Returns: sorted list, unchanged column ordering
+"""
+    newlist = abut(colex(listoflists,sortcols),listoflists)
+    newlist.sort()
+    try:
+        numcols = len(sortcols)
+    except TypeError:
+        numcols = 1
+    crit = '[' + str(numcols) + ':]'
+    newlist = colex(newlist,crit)
+    return newlist
+
+
+def unique (inlist):
+    """
+Returns all unique items in the passed list.  If the a list-of-lists
+is passed, unique LISTS are found (i.e., items in the first dimension are
+compared).
+
+Usage:   unique (inlist)
+Returns: the unique elements (or rows) in inlist
+"""
+    uniques = []
+    for item in inlist:
+        if item not in uniques:
+            uniques.append(item)
+    return uniques
+
+def duplicates(inlist):
+    """
+Returns duplicate items in the FIRST dimension of the passed list.
+
+Usage:   duplicates (inlist)
+"""
+    dups = []
+    for i in range(len(inlist)):
+        if inlist[i] in inlist[i+1:]:
+            dups.append(inlist[i])
+    return dups
+
+
+def nonrepeats(inlist):
+    """
+Returns items that are NOT duplicated in the first dim of the passed list.
+
+Usage:   nonrepeats (inlist)
+"""
+    nonrepeats = []
+    for i in range(len(inlist)):
+        if inlist.count(inlist[i]) == 1:
+            nonrepeats.append(inlist[i])
+    return nonrepeats
+
+
+#===================   PSTAT ARRAY FUNCTIONS  =====================
+#===================   PSTAT ARRAY FUNCTIONS  =====================
+#===================   PSTAT ARRAY FUNCTIONS  =====================
+#===================   PSTAT ARRAY FUNCTIONS  =====================
+#===================   PSTAT ARRAY FUNCTIONS  =====================
+#===================   PSTAT ARRAY FUNCTIONS  =====================
+#===================   PSTAT ARRAY FUNCTIONS  =====================
+#===================   PSTAT ARRAY FUNCTIONS  =====================
+#===================   PSTAT ARRAY FUNCTIONS  =====================
+#===================   PSTAT ARRAY FUNCTIONS  =====================
+#===================   PSTAT ARRAY FUNCTIONS  =====================
+#===================   PSTAT ARRAY FUNCTIONS  =====================
+#===================   PSTAT ARRAY FUNCTIONS  =====================
+#===================   PSTAT ARRAY FUNCTIONS  =====================
+#===================   PSTAT ARRAY FUNCTIONS  =====================
+#===================   PSTAT ARRAY FUNCTIONS  =====================
+
+try:                         # DEFINE THESE *ONLY* IF NUMERIC IS AVAILABLE
+ import Numeric
+ N = Numeric
+
+ def aabut (source, *args):
+    """
+Like the |Stat abut command.  It concatenates two arrays column-wise
+and returns the result.  CAUTION:  If one array is shorter, it will be
+repeated until it is as long as the other.
+
+Usage:   aabut (source, args)    where args=any # of arrays
+Returns: an array as long as the LONGEST array past, source appearing on the
+         'left', arrays in <args> attached on the 'right'.
+"""
+    if len(source.shape)==1:
+        width = 1
+        source = N.resize(source,[source.shape[0],width])
+    else:
+        width = source.shape[1]
+    for addon in args:
+        if len(addon.shape)==1:
+            width = 1
+            addon = N.resize(addon,[source.shape[0],width])
+        else:
+            width = source.shape[1]
+        if len(addon) < len(source):
+            addon = N.resize(addon,[source.shape[0],addon.shape[1]])
+        elif len(source) < len(addon):
+            source = N.resize(source,[addon.shape[0],source.shape[1]])
+        source = N.concatenate((source,addon),1)
+    return source
+
+
+ def acolex (a,indices,axis=1):
+    """
+Extracts specified indices (a list) from passed array, along passed
+axis (column extraction is default).  BEWARE: A 1D array is presumed to be a
+column-array (and that the whole array will be returned as a column).
+
+Usage:   acolex (a,indices,axis=1)
+Returns: the columns of a specified by indices
+"""
+    if type(indices) not in [ListType,TupleType,N.ArrayType]:
+        indices = [indices]
+    if len(N.shape(a)) == 1:
+        cols = N.resize(a,[a.shape[0],1])
+    else:
+        cols = N.take(a,indices,axis)
+    return cols
+
+
+ def acollapse (a,keepcols,collapsecols,fcn1=None,fcn2=None,cfcn=None):
+    """
+Averages data in collapsecol, keeping all unique items in keepcols
+(using unique, which keeps unique LISTS of column numbers), retaining
+the unique sets of values in keepcols, the mean for each.  If stderror or
+N of the mean are desired, set either or both parameters to 1.
+
+Usage:   acollapse (a,keepcols,collapsecols,fcn1=None,fcn2=None,cfcn=None)
+Returns: unique 'conditions' specified by the contents of columns specified
+         by keepcols, abutted with the mean(s) of column(s) specified by
+         collapsecols
+"""
+    def acollmean (inarray):
+        return N.sum(N.ravel(inarray))
+
+    if cfcn == None:
+        cfcn = acollmean
+    if keepcols == []:
+        avgcol = acolex(a,collapsecols)
+        means = N.sum(avgcol)/float(len(avgcol))
+        if fcn1<>None:
+            try:
+                test = fcn1(avgcol)
+            except:
+                test = N.array(['N/A']*len(means))
+            means = aabut(means,test)
+        if fcn2<>None:
+            try:
+                test = fcn2(avgcol)
+            except:
+                test = N.array(['N/A']*len(means))
+            means = aabut(means,test)
+        return means
+    else:
+        if type(keepcols) not in [ListType,TupleType,N.ArrayType]:
+            keepcols = [keepcols]
+        values = colex(a,keepcols)   # so that "item" can be appended (below)
+        uniques = unique(values)  # get a LIST, so .sort keeps rows intact
+        uniques.sort()
+        newlist = []
+        for item in uniques:
+            if type(item) not in [ListType,TupleType,N.ArrayType]:
+                item =[item]
+            tmprows = alinexand(a,keepcols,item)
+            for col in collapsecols:
+                avgcol = acolex(tmprows,col)
+                item.append(acollmean(avgcol))
+                if fcn1<>None:
+                    try:
+                        test = fcn1(avgcol)
+                    except:
+                        test = 'N/A'
+                    item.append(test)
+                if fcn2<>None:
+                    try:
+                        test = fcn2(avgcol)
+                    except:
+                        test = 'N/A'
+                    item.append(test)
+                newlist.append(item)
+        try:
+            new_a = N.array(newlist)
+        except TypeError:
+            new_a = N.array(newlist,'O')
+        return new_a
+
+
+ def adm (a,criterion):
+    """
+Returns rows from the passed list of lists that meet the criteria in
+the passed criterion expression (a string as a function of x).
+
+Usage:   adm (a,criterion)   where criterion is like 'x[2]==37'
+"""
+    function = 'filter(lambda x: '+criterion+',a)'
+    lines = eval(function)
+    try:
+        lines = N.array(lines)
+    except:
+        lines = N.array(lines,'O')
+    return lines
+
+
+ def isstring(x):
+    if type(x)==StringType:
+        return 1
+    else:
+        return 0
+
+
+ def alinexand (a,columnlist,valuelist):
+    """
+Returns the rows of an array where col (from columnlist) = val
+(from valuelist).  One value is required for each column in columnlist.
+
+Usage:   alinexand (a,columnlist,valuelist)
+Returns: the rows of a where columnlist[i]=valuelist[i] for ALL i
+"""
+    if type(columnlist) not in [ListType,TupleType,N.ArrayType]:
+        columnlist = [columnlist]
+    if type(valuelist) not in [ListType,TupleType,N.ArrayType]:
+        valuelist = [valuelist]
+    criterion = ''
+    for i in range(len(columnlist)):
+        if type(valuelist[i])==StringType:
+            critval = '\'' + valuelist[i] + '\''
+        else:
+            critval = str(valuelist[i])
+        criterion = criterion + ' x['+str(columnlist[i])+']=='+critval+' and'
+    criterion = criterion[0:-3]         # remove the "and" after the last crit
+    return adm(a,criterion)
+
+
+ def alinexor (a,columnlist,valuelist):
+    """
+Returns the rows of an array where col (from columnlist) = val (from
+valuelist).  One value is required for each column in columnlist.
+The exception is if either columnlist or valuelist has only 1 value,
+in which case that item will be expanded to match the length of the
+other list.
+
+Usage:   alinexor (a,columnlist,valuelist)
+Returns: the rows of a where columnlist[i]=valuelist[i] for ANY i
+"""
+    if type(columnlist) not in [ListType,TupleType,N.ArrayType]:
+        columnlist = [columnlist]
+    if type(valuelist) not in [ListType,TupleType,N.ArrayType]:
+        valuelist = [valuelist]
+    criterion = ''
+    if len(columnlist) == 1 and len(valuelist) > 1:
+        columnlist = columnlist*len(valuelist)
+    elif len(valuelist) == 1 and len(columnlist) > 1:
+        valuelist = valuelist*len(columnlist)
+    for i in range(len(columnlist)):
+        if type(valuelist[i])==StringType:
+            critval = '\'' + valuelist[i] + '\''
+        else:
+            critval = str(valuelist[i])
+        criterion = criterion + ' x['+str(columnlist[i])+']=='+critval+' or'
+    criterion = criterion[0:-2]         # remove the "or" after the last crit
+    return adm(a,criterion)
+
+
+ def areplace (a,oldval,newval):
+    """
+Replaces all occurrences of oldval with newval in array a.
+
+Usage:   areplace(a,oldval,newval)
+"""
+    newa = N.not_equal(a,oldval)*a
+    return newa+N.equal(a,oldval)*newval
+
+
+ def arecode (a,listmap,col='all'):
+    """
+Remaps the values in an array to a new set of values (useful when
+you need to recode data from (e.g.) strings to numbers as most stats
+packages require.  Can work on SINGLE columns, or 'all' columns at once.
+
+Usage:   arecode (a,listmap,col='all')
+Returns: a version of array a where listmap[i][0] = (instead) listmap[i][1]
+"""
+    ashape = a.shape
+    if col == 'all':
+        work = a.flat
+    else:
+        work = acolex(a,col)
+        work = work.flat
+    for pair in listmap:
+        if type(pair[1]) == StringType or work.typecode()=='O' or a.typecode()=='O':
+            work = N.array(work,'O')
+            a = N.array(a,'O')
+            for i in range(len(work)):
+                if work[i]==pair[0]:
+                    work[i] = pair[1]
+            if col == 'all':
+                return N.reshape(work,ashape)
+            else:
+                return N.concatenate([a[:,0:col],work[:,N.NewAxis],a[:,col+1:]],1)
+        else:   # must be a non-Object type array and replacement
+            work = N.where(N.equal(work,pair[0]),pair[1],work)
+            return N.concatenate([a[:,0:col],work[:,N.NewAxis],a[:,col+1:]],1)
+
+
+ def arowcompare(row1, row2):
+    """
+Compares two numeric rows from an array,
+
+Usage:   arowcompare(row1,row2)
+Returns: an array of equal length containing 1s where the two rows had
+         identical elements and 0 otherwise
+"""
+    return N.equal(row1,row2)
+
+
+ def arowsame(row1, row2):
+    """
+Compares two rows from an array, regardless of whether it is an
+array of numbers or of python objects (which requires the cmp function).
+
+Usage:   arowsame(row1,row2)
+Returns: 1 if the two rows are identical, 0 otherwise.
+"""
+    cmpval = N.alltrue(arowcompare(row1,row2))
+    return cmpval
+
+
+ def asortrows(a,axis=0):
+    """
+Sorts an array "by rows".  This differs from the Numeric.sort() function,
+which sorts elements WITHIN the given axis.  Instead, this function keeps
+the elements along the given axis intact, but shifts them 'up or down'
+relative to one another.
+
+Usage:   asortrows(a,axis=0)
+Returns: sorted version of a
+"""
+    if axis != 0:
+        a = N.swapaxes(a, axis, 0)
+    l = a.tolist()
+    l.sort()           # or l.sort(_sort)
+    y = N.array(l)
+    if axis != 0:
+        y = N.swapaxes(y, axis, 0)
+    return y
+
+
+ def aunique(inarray):
+    """
+Returns unique items in the FIRST dimension of the passed array. Only
+works on arrays NOT including string items.
+
+Usage:   aunique (inarray)
+"""
+    uniques = N.array([inarray[0]])
+    if len(uniques.shape) == 1:            # IF IT'S A 1D ARRAY
+        for item in inarray[1:]:
+            if N.add.reduce(N.equal(uniques,item).flat) == 0:
+                try:
+                    uniques = N.concatenate([uniques,N.array[N.NewAxis,:]])
+                except TypeError:
+                    uniques = N.concatenate([uniques,N.array([item])])
+    else:                                  # IT MUST BE A 2+D ARRAY
+        if inarray.typecode() != 'O':  # not an Object array
+            for item in inarray[1:]:
+                if not N.sum(N.alltrue(N.equal(uniques,item),1)):
+                    try:
+                        uniques = N.concatenate( [uniques,item[N.NewAxis,:]] )
+                    except TypeError:    # the item to add isn't a list
+                        uniques = N.concatenate([uniques,N.array([item])])
+                else:
+                    pass  # this item is already in the uniques array
+        else:   # must be an Object array, alltrue/equal functions don't work
+            for item in inarray[1:]:
+                newflag = 1
+                for unq in uniques:  # NOTE: cmp --> 0=same, -1=<, 1=>
+                    # TODO fix this
+                    test = N.sum(abs(N.array(map(cmp,item,unq))))
+                    if test == 0:   # if item identical to any 1 row in uniques
+                        newflag = 0 # then not a novel item to add
+                        break
+                if newflag == 1:
+                    try:
+                        uniques = N.concatenate( [uniques,item[N.NewAxis,:]] )
+                    except TypeError:    # the item to add isn't a list
+                        uniques = N.concatenate([uniques,N.array([item])])
+    return uniques
+
+
+ def aduplicates(inarray):
+    """
+Returns duplicate items in the FIRST dimension of the passed array. Only
+works on arrays NOT including string items.
+
+Usage:   aunique (inarray)
+"""
+    inarray = N.array(inarray)
+    if len(inarray.shape) == 1:            # IF IT'S A 1D ARRAY
+        dups = []
+        inarray = inarray.tolist()
+        for i in range(len(inarray)):
+            if inarray[i] in inarray[i+1:]:
+                dups.append(inarray[i])
+        dups = aunique(dups)
+    else:                                  # IT MUST BE A 2+D ARRAY
+        dups = []
+        aslist = inarray.tolist()
+        for i in range(len(aslist)):
+            if aslist[i] in aslist[i+1:]:
+                dups.append(aslist[i])
+        dups = unique(dups)
+        dups = N.array(dups)
+    return dups
+
+except ImportError:    # IF NUMERIC ISN'T AVAILABLE, SKIP ALL arrayfuncs
+ pass
diff --git a/lib/bx_extras/pyparsing.py b/lib/bx_extras/pyparsing.py
new file mode 100644
index 0000000..f963a92
--- /dev/null
+++ b/lib/bx_extras/pyparsing.py
@@ -0,0 +1,3601 @@
+# module pyparsing.py
+#
+# Copyright (c) 2003-2008  Paul T. McGuire
+#
+# 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.
+#
+#from __future__ import generators
+
+__doc__ = \
+"""
+pyparsing module - Classes and methods to define and execute parsing grammars
+
+The pyparsing module is an alternative approach to creating and executing simple grammars,
+vs. the traditional lex/yacc approach, or the use of regular expressions.  With pyparsing, you
+don't need to learn a new syntax for defining grammars or matching expressions - the parsing module
+provides a library of classes that you use to construct the grammar directly in Python.
+
+Here is a program to parse "Hello, World!" (or any greeting of the form "<salutation>, <addressee>!")::
+
+    from pyparsing import Word, alphas
+
+    # define grammar of a greeting
+    greet = Word( alphas ) + "," + Word( alphas ) + "!"
+
+    hello = "Hello, World!"
+    print hello, "->", greet.parseString( hello )
+
+The program outputs the following::
+
+    Hello, World! -> ['Hello', ',', 'World', '!']
+
+The Python representation of the grammar is quite readable, owing to the self-explanatory
+class names, and the use of '+', '|' and '^' operators.
+
+The parsed results returned from parseString() can be accessed as a nested list, a dictionary, or an
+object with named attributes.
+
+The pyparsing module handles some of the problems that are typically vexing when writing text parsers:
+ - extra or missing whitespace (the above program will also handle "Hello,World!", "Hello  ,  World  !", etc.)
+ - quoted strings
+ - embedded comments
+"""
+
+__version__ = "1.5.0"
+__versionTime__ = "28 May 2008 10:05"
+__author__ = "Paul McGuire <ptmcg at users.sourceforge.net>"
+
+import string
+from weakref import ref as wkref
+import copy,sys
+import warnings
+import re
+import sre_constants
+import xml.sax.saxutils
+#~ sys.stderr.write( "testing pyparsing module, version %s, %s\n" % (__version__,__versionTime__ ) )
+
+__all__ = [
+'And', 'CaselessKeyword', 'CaselessLiteral', 'CharsNotIn', 'Combine', 'Dict', 'Each', 'Empty',
+'FollowedBy', 'Forward', 'GoToColumn', 'Group', 'Keyword', 'LineEnd', 'LineStart', 'Literal',
+'MatchFirst', 'NoMatch', 'NotAny', 'OneOrMore', 'OnlyOnce', 'Optional', 'Or',
+'ParseBaseException', 'ParseElementEnhance', 'ParseException', 'ParseExpression', 'ParseFatalException',
+'ParseResults', 'ParseSyntaxException', 'ParserElement', 'QuotedString', 'RecursiveGrammarException',
+'Regex', 'SkipTo', 'StringEnd', 'StringStart', 'Suppress', 'Token', 'TokenConverter', 'Upcase',
+'White', 'Word', 'WordEnd', 'WordStart', 'ZeroOrMore',
+'alphanums', 'alphas', 'alphas8bit', 'anyCloseTag', 'anyOpenTag', 'cStyleComment', 'col',
+'commaSeparatedList', 'commonHTMLEntity', 'countedArray', 'cppStyleComment', 'dblQuotedString',
+'dblSlashComment', 'delimitedList', 'dictOf', 'downcaseTokens', 'empty', 'getTokensEndLoc', 'hexnums',
+'htmlComment', 'javaStyleComment', 'keepOriginalText', 'line', 'lineEnd', 'lineStart', 'lineno',
+'makeHTMLTags', 'makeXMLTags', 'matchOnlyAtCol', 'matchPreviousExpr', 'matchPreviousLiteral',
+'nestedExpr', 'nullDebugAction', 'nums', 'oneOf', 'opAssoc', 'operatorPrecedence', 'printables',
+'punc8bit', 'pythonStyleComment', 'quotedString', 'removeQuotes', 'replaceHTMLEntity',
+'replaceWith', 'restOfLine', 'sglQuotedString', 'srange', 'stringEnd',
+'stringStart', 'traceParseAction', 'unicodeString', 'upcaseTokens', 'withAttribute',
+'indentedBlock',
+]
+
+
+"""
+Detect if we are running version 3.X and make appropriate changes
+Robert A. Clark
+"""
+if sys.version_info[0] > 2:
+    _PY3K = True
+    _MAX_INT = sys.maxsize
+    basestring = str
+else:
+    _PY3K = False
+    _MAX_INT = sys.maxint
+
+if not _PY3K:
+    def _ustr(obj):
+        """Drop-in replacement for str(obj) that tries to be Unicode friendly. It first tries
+           str(obj). If that fails with a UnicodeEncodeError, then it tries unicode(obj). It
+           then < returns the unicode object | encodes it with the default encoding | ... >.
+        """
+        try:
+            # If this works, then _ustr(obj) has the same behaviour as str(obj), so
+            # it won't break any existing code.
+            return str(obj)
+
+        except UnicodeEncodeError:
+            # The Python docs (http://docs.python.org/ref/customization.html#l2h-182)
+            # state that "The return value must be a string object". However, does a
+            # unicode object (being a subclass of basestring) count as a "string
+            # object"?
+            # If so, then return a unicode object:
+            return unicode(obj)
+            # Else encode it... but how? There are many choices... :)
+            # Replace unprintables with escape codes?
+            #return unicode(obj).encode(sys.getdefaultencoding(), 'backslashreplace_errors')
+            # Replace unprintables with question marks?
+            #return unicode(obj).encode(sys.getdefaultencoding(), 'replace')
+            # ...
+else:
+    _ustr = str
+
+def _str2dict(strg):
+    return dict( [(c,0) for c in strg] )
+    #~ return set( [c for c in strg] )
+
+class _Constants(object):
+    pass
+
+if not _PY3K:
+    alphas     = string.lowercase + string.uppercase
+else:
+    alphas     = string.ascii_lowercase + string.ascii_uppercase
+nums       = string.digits
+hexnums    = nums + "ABCDEFabcdef"
+alphanums  = alphas + nums
+_bslash = "\\"
+printables = "".join( [ c for c in string.printable if c not in string.whitespace ] )
+
+class ParseBaseException(Exception):
+    """base exception class for all parsing runtime exceptions"""
+    __slots__ = ( "loc","msg","pstr","parserElement" )
+    # Performance tuning: we construct a *lot* of these, so keep this
+    # constructor as small and fast as possible
+    def __init__( self, pstr, loc=0, msg=None, elem=None ):
+        self.loc = loc
+        if msg is None:
+            self.msg = pstr
+            self.pstr = ""
+        else:
+            self.msg = msg
+            self.pstr = pstr
+        self.parserElement = elem
+
+    def __getattr__( self, aname ):
+        """supported attributes by name are:
+            - lineno - returns the line number of the exception text
+            - col - returns the column number of the exception text
+            - line - returns the line containing the exception text
+        """
+        if( aname == "lineno" ):
+            return lineno( self.loc, self.pstr )
+        elif( aname in ("col", "column") ):
+            return col( self.loc, self.pstr )
+        elif( aname == "line" ):
+            return line( self.loc, self.pstr )
+        else:
+            raise AttributeError(aname)
+
+    def __str__( self ):
+        return "%s (at char %d), (line:%d, col:%d)" % \
+                ( self.msg, self.loc, self.lineno, self.column )
+    def __repr__( self ):
+        return _ustr(self)
+    def markInputline( self, markerString = ">!<" ):
+        """Extracts the exception line from the input string, and marks
+           the location of the exception with a special symbol.
+        """
+        line_str = self.line
+        line_column = self.column - 1
+        if markerString:
+            line_str = "".join( [line_str[:line_column],
+                                markerString, line_str[line_column:]])
+        return line_str.strip()
+
+class ParseException(ParseBaseException):
+    """exception thrown when parse expressions don't match class;
+       supported attributes by name are:
+        - lineno - returns the line number of the exception text
+        - col - returns the column number of the exception text
+        - line - returns the line containing the exception text
+    """
+    pass
+
+class ParseFatalException(ParseBaseException):
+    """user-throwable exception thrown when inconsistent parse content
+       is found; stops all parsing immediately"""
+    pass
+
+class ParseSyntaxException(ParseFatalException):
+    """just like ParseFatalException, but thrown internally when an
+       ErrorStop indicates that parsing is to stop immediately because
+       an unbacktrackable syntax error has been found"""
+    def __init__(self, pe):
+        super(ParseSyntaxException, self).__init__(
+                                    pe.pstr, pe.loc, pe.msg, pe.parserElement)
+
+#~ class ReparseException(ParseBaseException):
+    #~ """Experimental class - parse actions can raise this exception to cause
+       #~ pyparsing to reparse the input string:
+        #~ - with a modified input string, and/or
+        #~ - with a modified start location
+       #~ Set the values of the ReparseException in the constructor, and raise the
+       #~ exception in a parse action to cause pyparsing to use the new string/location.
+       #~ Setting the values as None causes no change to be made.
+       #~ """
+    #~ def __init_( self, newstring, restartLoc ):
+        #~ self.newParseText = newstring
+        #~ self.reparseLoc = restartLoc
+
+class RecursiveGrammarException(Exception):
+    """exception thrown by validate() if the grammar could be improperly recursive"""
+    def __init__( self, parseElementList ):
+        self.parseElementTrace = parseElementList
+
+    def __str__( self ):
+        return "RecursiveGrammarException: %s" % self.parseElementTrace
+
+class _ParseResultsWithOffset(object):
+    def __init__(self,p1,p2):
+        self.tup = (p1,p2)
+    def __getitem__(self,i):
+        return self.tup[i]
+    def __repr__(self):
+        return repr(self.tup)
+
+class ParseResults(object):
+    """Structured parse results, to provide multiple means of access to the parsed data:
+       - as a list (len(results))
+       - by list index (results[0], results[1], etc.)
+       - by attribute (results.<resultsName>)
+       """
+    __slots__ = ( "__toklist", "__tokdict", "__doinit", "__name", "__parent", "__accumNames", "__weakref__" )
+    def __new__(cls, toklist, name=None, asList=True, modal=True ):
+        if isinstance(toklist, cls):
+            return toklist
+        retobj = object.__new__(cls)
+        retobj.__doinit = True
+        return retobj
+
+    # Performance tuning: we construct a *lot* of these, so keep this
+    # constructor as small and fast as possible
+    def __init__( self, toklist, name=None, asList=True, modal=True ):
+        if self.__doinit:
+            self.__doinit = False
+            self.__name = None
+            self.__parent = None
+            self.__accumNames = {}
+            if isinstance(toklist, list):
+                self.__toklist = toklist[:]
+            else:
+                self.__toklist = [toklist]
+            self.__tokdict = dict()
+
+        # this line is related to debugging the asXML bug
+        #~ asList = False
+
+        if name:
+            if not modal:
+                self.__accumNames[name] = 0
+            if isinstance(name,int):
+                name = _ustr(name) # will always return a str, but use _ustr for consistency
+            self.__name = name
+            if not toklist in (None,'',[]):
+                if isinstance(toklist,basestring):
+                    toklist = [ toklist ]
+                if asList:
+                    if isinstance(toklist,ParseResults):
+                        self[name] = _ParseResultsWithOffset(toklist.copy(),-1)
+                    else:
+                        self[name] = _ParseResultsWithOffset(ParseResults(toklist[0]),-1)
+                    self[name].__name = name
+                else:
+                    try:
+                        self[name] = toklist[0]
+                    except (KeyError,TypeError):
+                        self[name] = toklist
+
+    def __getitem__( self, i ):
+        if isinstance( i, (int,slice) ):
+            return self.__toklist[i]
+        else:
+            if i not in self.__accumNames:
+                return self.__tokdict[i][-1][0]
+            else:
+                return ParseResults([ v[0] for v in self.__tokdict[i] ])
+
+    def __setitem__( self, k, v ):
+        if isinstance(v,_ParseResultsWithOffset):
+            self.__tokdict[k] = self.__tokdict.get(k,list()) + [v]
+            sub = v[0]
+        elif isinstance(k,int):
+            self.__toklist[k] = v
+            sub = v
+        else:
+            self.__tokdict[k] = self.__tokdict.get(k,list()) + [_ParseResultsWithOffset(v,0)]
+            sub = v
+        if isinstance(sub,ParseResults):
+            sub.__parent = wkref(self)
+
+    def __delitem__( self, i ):
+        if isinstance(i,(int,slice)):
+            mylen = len( self.__toklist )
+            del self.__toklist[i]
+
+            # convert int to slice
+            if isinstance(i, int):
+                if i < 0:
+                    i += mylen
+                i = slice(i, i+1)
+            # get removed indices
+            removed = list(range(*i.indices(mylen)))
+            removed.reverse()
+            # fixup indices in token dictionary
+            for name in self.__tokdict:
+                occurrences = self.__tokdict[name]
+                for j in removed:
+                    for k, (value, position) in enumerate(occurrences):
+                        occurrences[k] = _ParseResultsWithOffset(value, position - (position > j))
+        else:
+            del self.__tokdict[i]
+
+    def __contains__( self, k ):
+        return k in self.__tokdict
+
+    def __len__( self ): return len( self.__toklist )
+    def __bool__(self): return len( self.__toklist ) > 0
+    __nonzero__ = __bool__
+    def __iter__( self ): return iter( self.__toklist )
+    def __reversed__( self ): return iter( reversed(self.__toklist) )
+    def keys( self ):
+        """Returns all named result keys."""
+        return self.__tokdict.keys()
+
+    def pop( self, index=-1 ):
+        """Removes and returns item at specified index (default=last).
+           Will work with either numeric indices or dict-key indicies."""
+        ret = self[index]
+        del self[index]
+        return ret
+
+    def get(self, key, defaultValue=None):
+        """Returns named result matching the given key, or if there is no
+           such name, then returns the given defaultValue or None if no
+           defaultValue is specified."""
+        if key in self:
+            return self[key]
+        else:
+            return defaultValue
+
+    def insert( self, index, insStr ):
+        self.__toklist.insert(index, insStr)
+        # fixup indices in token dictionary
+        for name in self.__tokdict:
+            occurrences = self.__tokdict[name]
+            for k, (value, position) in enumerate(occurrences):
+                occurrences[k] = _ParseResultsWithOffset(value, position + (position > j))
+
+    def items( self ):
+        """Returns all named result keys and values as a list of tuples."""
+        return [(k,self[k]) for k in self.__tokdict]
+
+    def values( self ):
+        """Returns all named result values."""
+        return [ v[-1][0] for v in self.__tokdict.values() ]
+
+    def __getattr__( self, name ):
+        if name not in self.__slots__:
+            if name in self.__tokdict:
+                if name not in self.__accumNames:
+                    return self.__tokdict[name][-1][0]
+                else:
+                    return ParseResults([ v[0] for v in self.__tokdict[name] ])
+            else:
+                return ""
+        return None
+
+    def __add__( self, other ):
+        ret = self.copy()
+        ret += other
+        return ret
+
+    def __iadd__( self, other ):
+        if other.__tokdict:
+            offset = len(self.__toklist)
+            addoffset = ( lambda a: (a<0 and offset) or (a+offset) )
+            otheritems = other.__tokdict.items()
+            otherdictitems = [(k, _ParseResultsWithOffset(v[0],addoffset(v[1])) )
+                                for (k,vlist) in otheritems for v in vlist]
+            for k,v in otherdictitems:
+                self[k] = v
+                if isinstance(v[0],ParseResults):
+                    v[0].__parent = wkref(self)
+        self.__toklist += other.__toklist
+        self.__accumNames.update( other.__accumNames )
+        del other
+        return self
+
+    def __repr__( self ):
+        return "(%s, %s)" % ( repr( self.__toklist ), repr( self.__tokdict ) )
+
+    def __str__( self ):
+        out = "["
+        sep = ""
+        for i in self.__toklist:
+            if isinstance(i, ParseResults):
+                out += sep + _ustr(i)
+            else:
+                out += sep + repr(i)
+            sep = ", "
+        out += "]"
+        return out
+
+    def _asStringList( self, sep='' ):
+        out = []
+        for item in self.__toklist:
+            if out and sep:
+                out.append(sep)
+            if isinstance( item, ParseResults ):
+                out += item._asStringList()
+            else:
+                out.append( _ustr(item) )
+        return out
+
+    def asList( self ):
+        """Returns the parse results as a nested list of matching tokens, all converted to strings."""
+        out = []
+        for res in self.__toklist:
+            if isinstance(res,ParseResults):
+                out.append( res.asList() )
+            else:
+                out.append( res )
+        return out
+
+    def asDict( self ):
+        """Returns the named parse results as dictionary."""
+        return dict( self.items() )
+
+    def copy( self ):
+        """Returns a new copy of a ParseResults object."""
+        ret = ParseResults( self.__toklist )
+        ret.__tokdict = self.__tokdict.copy()
+        ret.__parent = self.__parent
+        ret.__accumNames.update( self.__accumNames )
+        ret.__name = self.__name
+        return ret
+
+    def asXML( self, doctag=None, namedItemsOnly=False, indent="", formatted=True ):
+        """Returns the parse results as XML. Tags are created for tokens and lists that have defined results names."""
+        nl = "\n"
+        out = []
+        namedItems = dict( [ (v[1],k) for (k,vlist) in self.__tokdict.items()
+                                                            for v in vlist ] )
+        nextLevelIndent = indent + "  "
+
+        # collapse out indents if formatting is not desired
+        if not formatted:
+            indent = ""
+            nextLevelIndent = ""
+            nl = ""
+
+        selfTag = None
+        if doctag is not None:
+            selfTag = doctag
+        else:
+            if self.__name:
+                selfTag = self.__name
+
+        if not selfTag:
+            if namedItemsOnly:
+                return ""
+            else:
+                selfTag = "ITEM"
+
+        out += [ nl, indent, "<", selfTag, ">" ]
+
+        worklist = self.__toklist
+        for i,res in enumerate(worklist):
+            if isinstance(res,ParseResults):
+                if i in namedItems:
+                    out += [ res.asXML(namedItems[i],
+                                        namedItemsOnly and doctag is None,
+                                        nextLevelIndent,
+                                        formatted)]
+                else:
+                    out += [ res.asXML(None,
+                                        namedItemsOnly and doctag is None,
+                                        nextLevelIndent,
+                                        formatted)]
+            else:
+                # individual token, see if there is a name for it
+                resTag = None
+                if i in namedItems:
+                    resTag = namedItems[i]
+                if not resTag:
+                    if namedItemsOnly:
+                        continue
+                    else:
+                        resTag = "ITEM"
+                xmlBodyText = xml.sax.saxutils.escape(_ustr(res))
+                out += [ nl, nextLevelIndent, "<", resTag, ">",
+                                                xmlBodyText,
+                                                "</", resTag, ">" ]
+
+        out += [ nl, indent, "</", selfTag, ">" ]
+        return "".join(out)
+
+    def __lookup(self,sub):
+        for k,vlist in self.__tokdict.items():
+            for v,loc in vlist:
+                if sub is v:
+                    return k
+        return None
+
+    def getName(self):
+        """Returns the results name for this token expression."""
+        if self.__name:
+            return self.__name
+        elif self.__parent:
+            par = self.__parent()
+            if par:
+                return par.__lookup(self)
+            else:
+                return None
+        elif (len(self) == 1 and
+               len(self.__tokdict) == 1 and
+               self.__tokdict.values()[0][0][1] in (0,-1)):
+            return self.__tokdict.keys()[0]
+        else:
+            return None
+
+    def dump(self,indent='',depth=0):
+        """Diagnostic method for listing out the contents of a ParseResults.
+           Accepts an optional indent argument so that this string can be embedded
+           in a nested display of other data."""
+        out = []
+        out.append( indent+_ustr(self.asList()) )
+        keys = self.items()
+        keys.sort()
+        for k,v in keys:
+            if out:
+                out.append('\n')
+            out.append( "%s%s- %s: " % (indent,('  '*depth), k) )
+            if isinstance(v,ParseResults):
+                if v.keys():
+                    #~ out.append('\n')
+                    out.append( v.dump(indent,depth+1) )
+                    #~ out.append('\n')
+                else:
+                    out.append(_ustr(v))
+            else:
+                out.append(_ustr(v))
+        #~ out.append('\n')
+        return "".join(out)
+
+    # add support for pickle protocol
+    def __getstate__(self):
+        return ( self.__toklist,
+                 ( self.__tokdict.copy(),
+                   self.__parent is not None and self.__parent() or None,
+                   self.__accumNames,
+                   self.__name ) )
+
+    def __setstate__(self,state):
+        self.__toklist = state[0]
+        self.__tokdict, \
+        par, \
+        inAccumNames, \
+        self.__name = state[1]
+        self.__accumNames = {}
+        self.__accumNames.update(inAccumNames)
+        if par is not None:
+            self.__parent = wkref(par)
+        else:
+            self.__parent = None
+
+
+def col (loc,strg):
+    """Returns current column within a string, counting newlines as line separators.
+   The first column is number 1.
+
+   Note: the default parsing behavior is to expand tabs in the input string
+   before starting the parsing process.  See L{I{ParserElement.parseString}<ParserElement.parseString>} for more information
+   on parsing strings containing <TAB>s, and suggested methods to maintain a
+   consistent view of the parsed string, the parse location, and line and column
+   positions within the parsed string.
+   """
+    return (loc<len(strg) and strg[loc] == '\n') and 1 or loc - strg.rfind("\n", 0, loc)
+
+def lineno(loc,strg):
+    """Returns current line number within a string, counting newlines as line separators.
+   The first line is number 1.
+
+   Note: the default parsing behavior is to expand tabs in the input string
+   before starting the parsing process.  See L{I{ParserElement.parseString}<ParserElement.parseString>} for more information
+   on parsing strings containing <TAB>s, and suggested methods to maintain a
+   consistent view of the parsed string, the parse location, and line and column
+   positions within the parsed string.
+   """
+    return strg.count("\n",0,loc) + 1
+
+def line( loc, strg ):
+    """Returns the line of text containing loc within a string, counting newlines as line separators.
+       """
+    lastCR = strg.rfind("\n", 0, loc)
+    nextCR = strg.find("\n", loc)
+    if nextCR > 0:
+        return strg[lastCR+1:nextCR]
+    else:
+        return strg[lastCR+1:]
+
+def _defaultStartDebugAction( instring, loc, expr ):
+    print ("Match " + _ustr(expr) + " at loc " + _ustr(loc) + "(%d,%d)" % ( lineno(loc,instring), col(loc,instring) ))
+
+def _defaultSuccessDebugAction( instring, startloc, endloc, expr, toks ):
+    print ("Matched " + _ustr(expr) + " -> " + str(toks.asList()))
+
+def _defaultExceptionDebugAction( instring, loc, expr, exc ):
+    print ("Exception raised:" + _ustr(exc))
+
+def nullDebugAction(*args):
+    """'Do-nothing' debug action, to suppress debugging output during parsing."""
+    pass
+
+class ParserElement(object):
+    """Abstract base level parser element class."""
+    DEFAULT_WHITE_CHARS = " \n\t\r"
+
+    def setDefaultWhitespaceChars( chars ):
+        """Overrides the default whitespace chars
+        """
+        ParserElement.DEFAULT_WHITE_CHARS = chars
+    setDefaultWhitespaceChars = staticmethod(setDefaultWhitespaceChars)
+
+    def __init__( self, savelist=False ):
+        self.parseAction = list()
+        self.failAction = None
+        #~ self.name = "<unknown>"  # don't define self.name, let subclasses try/except upcall
+        self.strRepr = None
+        self.resultsName = None
+        self.saveAsList = savelist
+        self.skipWhitespace = True
+        self.whiteChars = ParserElement.DEFAULT_WHITE_CHARS
+        self.copyDefaultWhiteChars = True
+        self.mayReturnEmpty = False # used when checking for left-recursion
+        self.keepTabs = False
+        self.ignoreExprs = list()
+        self.debug = False
+        self.streamlined = False
+        self.mayIndexError = True # used to optimize exception handling for subclasses that don't advance parse index
+        self.errmsg = ""
+        self.modalResults = True # used to mark results names as modal (report only last) or cumulative (list all)
+        self.debugActions = ( None, None, None ) #custom debug actions
+        self.re = None
+        self.callPreparse = True # used to avoid redundant calls to preParse
+        self.callDuringTry = False
+
+    def copy( self ):
+        """Make a copy of this ParserElement.  Useful for defining different parse actions
+           for the same parsing pattern, using copies of the original parse element."""
+        cpy = copy.copy( self )
+        cpy.parseAction = self.parseAction[:]
+        cpy.ignoreExprs = self.ignoreExprs[:]
+        if self.copyDefaultWhiteChars:
+            cpy.whiteChars = ParserElement.DEFAULT_WHITE_CHARS
+        return cpy
+
+    def setName( self, name ):
+        """Define name for this expression, for use in debugging."""
+        self.name = name
+        self.errmsg = "Expected " + self.name
+        if hasattr(self,"exception"):
+            self.exception.msg = self.errmsg
+        return self
+
+    def setResultsName( self, name, listAllMatches=False ):
+        """Define name for referencing matching tokens as a nested attribute
+           of the returned parse results.
+           NOTE: this returns a *copy* of the original ParserElement object;
+           this is so that the client can define a basic element, such as an
+           integer, and reference it in multiple places with different names.
+        """
+        newself = self.copy()
+        newself.resultsName = name
+        newself.modalResults = not listAllMatches
+        return newself
+
+    def setBreak(self,breakFlag = True):
+        """Method to invoke the Python pdb debugger when this element is
+           about to be parsed. Set breakFlag to True to enable, False to
+           disable.
+        """
+        if breakFlag:
+            _parseMethod = self._parse
+            def breaker(instring, loc, doActions=True, callPreParse=True):
+                import pdb
+                pdb.set_trace()
+                _parseMethod( instring, loc, doActions, callPreParse )
+            breaker._originalParseMethod = _parseMethod
+            self._parse = breaker
+        else:
+            if hasattr(self._parse,"_originalParseMethod"):
+                self._parse = self._parse._originalParseMethod
+        return self
+
+    def _normalizeParseActionArgs( f ):
+        """Internal method used to decorate parse actions that take fewer than 3 arguments,
+           so that all parse actions can be called as f(s,l,t)."""
+        STAR_ARGS = 4
+
+        try:
+            restore = None
+            if isinstance(f,type):
+                restore = f
+                f = f.__init__
+            if not _PY3K:
+                codeObj = f.func_code
+            else:
+                codeObj = f.code
+            if codeObj.co_flags & STAR_ARGS:
+                return f
+            numargs = codeObj.co_argcount
+            if not _PY3K:
+                if hasattr(f,"im_self"):
+                    numargs -= 1
+            else:
+                if hasattr(f,"__self__"):
+                    numargs -= 1
+            if restore:
+                f = restore
+        except AttributeError:
+            try:
+                if not _PY3K:
+                    call_im_func_code = f.__call__.im_func.func_code
+                else:
+                    call_im_func_code = f.__code__
+
+                # not a function, must be a callable object, get info from the
+                # im_func binding of its bound __call__ method
+                if call_im_func_code.co_flags & STAR_ARGS:
+                    return f
+                numargs = call_im_func_code.co_argcount
+                if not _PY3K:
+                    if hasattr(f.__call__,"im_self"):
+                        numargs -= 1
+                else:
+                    if hasattr(f.__call__,"__self__"):
+                        numargs -= 0
+            except AttributeError:
+                if not _PY3K:
+                    call_func_code = f.__call__.func_code
+                else:
+                    call_func_code = f.__call__.__code__
+                # not a bound method, get info directly from __call__ method
+                if call_func_code.co_flags & STAR_ARGS:
+                    return f
+                numargs = call_func_code.co_argcount
+                if not _PY3K:
+                    if hasattr(f.__call__,"im_self"):
+                        numargs -= 1
+                else:
+                    if hasattr(f.__call__,"__self__"):
+                        numargs -= 1
+
+
+        #~ print ("adding function %s with %d args" % (f.func_name,numargs))
+        if numargs == 3:
+            return f
+        else:
+            if numargs > 3:
+                def tmp(s,l,t):
+                    return f(f.__call__.__self__, s,l,t)
+            if numargs == 2:
+                def tmp(s,l,t):
+                    return f(l,t)
+            elif numargs == 1:
+                def tmp(s,l,t):
+                    return f(t)
+            else: #~ numargs == 0:
+                def tmp(s,l,t):
+                    return f()
+            try:
+                tmp.__name__ = f.__name__
+            except (AttributeError,TypeError):
+                # no need for special handling if attribute doesnt exist
+                pass
+            try:
+                tmp.__doc__ = f.__doc__
+            except (AttributeError,TypeError):
+                # no need for special handling if attribute doesnt exist
+                pass
+            try:
+                tmp.__dict__.update(f.__dict__)
+            except (AttributeError,TypeError):
+                # no need for special handling if attribute doesnt exist
+                pass
+            return tmp
+    _normalizeParseActionArgs = staticmethod(_normalizeParseActionArgs)
+
+    def setParseAction( self, *fns, **kwargs ):
+        """Define action to perform when successfully matching parse element definition.
+           Parse action fn is a callable method with 0-3 arguments, called as fn(s,loc,toks),
+           fn(loc,toks), fn(toks), or just fn(), where:
+            - s   = the original string being parsed (see note below)
+            - loc = the location of the matching substring
+            - toks = a list of the matched tokens, packaged as a ParseResults object
+           If the functions in fns modify the tokens, they can return them as the return
+           value from fn, and the modified list of tokens will replace the original.
+           Otherwise, fn does not need to return any value.
+
+           Note: the default parsing behavior is to expand tabs in the input string
+           before starting the parsing process.  See L{I{parseString}<parseString>} for more information
+           on parsing strings containing <TAB>s, and suggested methods to maintain a
+           consistent view of the parsed string, the parse location, and line and column
+           positions within the parsed string.
+           """
+        self.parseAction = list(map(self._normalizeParseActionArgs, list(fns)))
+        self.callDuringTry = ("callDuringTry" in kwargs and kwargs["callDuringTry"])
+        return self
+
+    def addParseAction( self, *fns, **kwargs ):
+        """Add parse action to expression's list of parse actions. See L{I{setParseAction}<setParseAction>}."""
+        self.parseAction += list(map(self._normalizeParseActionArgs, list(fns)))
+        self.callDuringTry = self.callDuringTry or ("callDuringTry" in kwargs and kwargs["callDuringTry"])
+        return self
+
+    def setFailAction( self, fn ):
+        """Define action to perform if parsing fails at this expression.
+           Fail acton fn is a callable function that takes the arguments
+           fn(s,loc,expr,err) where:
+            - s = string being parsed
+            - loc = location where expression match was attempted and failed
+            - expr = the parse expression that failed
+            - err = the exception thrown
+           The function returns no value.  It may throw ParseFatalException
+           if it is desired to stop parsing immediately."""
+        self.failAction = fn
+        return self
+
+    def _skipIgnorables( self, instring, loc ):
+        exprsFound = True
+        while exprsFound:
+            exprsFound = False
+            for e in self.ignoreExprs:
+                try:
+                    while 1:
+                        loc,dummy = e._parse( instring, loc )
+                        exprsFound = True
+                except ParseException:
+                    pass
+        return loc
+
+    def preParse( self, instring, loc ):
+        if self.ignoreExprs:
+            loc = self._skipIgnorables( instring, loc )
+
+        if self.skipWhitespace:
+            wt = self.whiteChars
+            instrlen = len(instring)
+            while loc < instrlen and instring[loc] in wt:
+                loc += 1
+
+        return loc
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        return loc, []
+
+    def postParse( self, instring, loc, tokenlist ):
+        return tokenlist
+
+    #~ @profile
+    def _parseNoCache( self, instring, loc, doActions=True, callPreParse=True ):
+        debugging = ( self.debug ) #and doActions )
+
+        if debugging or self.failAction:
+            #~ print ("Match",self,"at loc",loc,"(%d,%d)" % ( lineno(loc,instring), col(loc,instring) ))
+            if (self.debugActions[0] ):
+                self.debugActions[0]( instring, loc, self )
+            if callPreParse and self.callPreparse:
+                preloc = self.preParse( instring, loc )
+            else:
+                preloc = loc
+            tokensStart = loc
+            try:
+                try:
+                    loc,tokens = self.parseImpl( instring, preloc, doActions )
+                except IndexError:
+                    raise ParseException( instring, len(instring), self.errmsg, self )
+            except ParseBaseException, err:
+                #~ print ("Exception raised:", err)
+                if self.debugActions[2]:
+                    self.debugActions[2]( instring, tokensStart, self, err )
+                if self.failAction:
+                    self.failAction( instring, tokensStart, self, err )
+                raise
+        else:
+            if callPreParse and self.callPreparse:
+                preloc = self.preParse( instring, loc )
+            else:
+                preloc = loc
+            tokensStart = loc
+            if self.mayIndexError or loc >= len(instring):
+                try:
+                    loc,tokens = self.parseImpl( instring, preloc, doActions )
+                except IndexError:
+                    raise ParseException( instring, len(instring), self.errmsg, self )
+            else:
+                loc,tokens = self.parseImpl( instring, preloc, doActions )
+
+        tokens = self.postParse( instring, loc, tokens )
+
+        retTokens = ParseResults( tokens, self.resultsName, asList=self.saveAsList, modal=self.modalResults )
+        if self.parseAction and (doActions or self.callDuringTry):
+            if debugging:
+                try:
+                    for fn in self.parseAction:
+                        tokens = fn( instring, tokensStart, retTokens )
+                        if tokens is not None:
+                            retTokens = ParseResults( tokens,
+                                                      self.resultsName,
+                                                      asList=self.saveAsList and isinstance(tokens,(ParseResults,list)),
+                                                      modal=self.modalResults )
+                except ParseBaseException, err:
+                    #~ print "Exception raised in user parse action:", err
+                    if (self.debugActions[2] ):
+                        self.debugActions[2]( instring, tokensStart, self, err )
+                    raise
+            else:
+                for fn in self.parseAction:
+                    tokens = fn( instring, tokensStart, retTokens )
+                    if tokens is not None:
+                        retTokens = ParseResults( tokens,
+                                                  self.resultsName,
+                                                  asList=self.saveAsList and isinstance(tokens,(ParseResults,list)),
+                                                  modal=self.modalResults )
+
+        if debugging:
+            #~ print ("Matched",self,"->",retTokens.asList())
+            if (self.debugActions[1] ):
+                self.debugActions[1]( instring, tokensStart, loc, self, retTokens )
+
+        return loc, retTokens
+
+    def tryParse( self, instring, loc ):
+        try:
+            return self._parse( instring, loc, doActions=False )[0]
+        except ParseFatalException:
+            raise ParseException( instring, loc, self.errmsg, self)
+
+    # this method gets repeatedly called during backtracking with the same arguments -
+    # we can cache these arguments and save ourselves the trouble of re-parsing the contained expression
+    def _parseCache( self, instring, loc, doActions=True, callPreParse=True ):
+        lookup = (self,instring,loc,callPreParse,doActions)
+        if lookup in ParserElement._exprArgCache:
+            value = ParserElement._exprArgCache[ lookup ]
+            if isinstance(value,Exception):
+                raise value
+            return value
+        else:
+            try:
+                value = self._parseNoCache( instring, loc, doActions, callPreParse )
+                ParserElement._exprArgCache[ lookup ] = (value[0],value[1].copy())
+                return value
+            except ParseBaseException, pe:
+                ParserElement._exprArgCache[ lookup ] = pe
+                raise
+
+    _parse = _parseNoCache
+
+    # argument cache for optimizing repeated calls when backtracking through recursive expressions
+    _exprArgCache = {}
+    def resetCache():
+        ParserElement._exprArgCache.clear()
+    resetCache = staticmethod(resetCache)
+
+    _packratEnabled = False
+    def enablePackrat():
+        """Enables "packrat" parsing, which adds memoizing to the parsing logic.
+           Repeated parse attempts at the same string location (which happens
+           often in many complex grammars) can immediately return a cached value,
+           instead of re-executing parsing/validating code.  Memoizing is done of
+           both valid results and parsing exceptions.
+
+           This speedup may break existing programs that use parse actions that
+           have side-effects.  For this reason, packrat parsing is disabled when
+           you first import pyparsing.  To activate the packrat feature, your
+           program must call the class method ParserElement.enablePackrat().  If
+           your program uses psyco to "compile as you go", you must call
+           enablePackrat before calling psyco.full().  If you do not do this,
+           Python will crash.  For best results, call enablePackrat() immediately
+           after importing pyparsing.
+        """
+        if not ParserElement._packratEnabled:
+            ParserElement._packratEnabled = True
+            ParserElement._parse = ParserElement._parseCache
+    enablePackrat = staticmethod(enablePackrat)
+
+    def parseString( self, instring, parseAll=False ):
+        """Execute the parse expression with the given string.
+           This is the main interface to the client code, once the complete
+           expression has been built.
+
+           If you want the grammar to require that the entire input string be
+           successfully parsed, then set parseAll to True (equivalent to ending
+           the grammar with StringEnd()).
+
+           Note: parseString implicitly calls expandtabs() on the input string,
+           in order to report proper column numbers in parse actions.
+           If the input string contains tabs and
+           the grammar uses parse actions that use the loc argument to index into the
+           string being parsed, you can ensure you have a consistent view of the input
+           string by:
+            - calling parseWithTabs on your grammar before calling parseString
+              (see L{I{parseWithTabs}<parseWithTabs>})
+            - define your parse action using the full (s,loc,toks) signature, and
+              reference the input string using the parse action's s argument
+            - explictly expand the tabs in your input string before calling
+              parseString
+        """
+        ParserElement.resetCache()
+        if not self.streamlined:
+            self.streamline()
+            #~ self.saveAsList = True
+        for e in self.ignoreExprs:
+            e.streamline()
+        if not self.keepTabs:
+            instring = instring.expandtabs()
+        loc, tokens = self._parse( instring, 0 )
+        if parseAll:
+            StringEnd()._parse( instring, loc )
+        return tokens
+
+    def scanString( self, instring, maxMatches=_MAX_INT ):
+        """Scan the input string for expression matches.  Each match will return the
+           matching tokens, start location, and end location.  May be called with optional
+           maxMatches argument, to clip scanning after 'n' matches are found.
+
+           Note that the start and end locations are reported relative to the string
+           being parsed.  See L{I{parseString}<parseString>} for more information on parsing
+           strings with embedded tabs."""
+        if not self.streamlined:
+            self.streamline()
+        for e in self.ignoreExprs:
+            e.streamline()
+
+        if not self.keepTabs:
+            instring = _ustr(instring).expandtabs()
+        instrlen = len(instring)
+        loc = 0
+        preparseFn = self.preParse
+        parseFn = self._parse
+        ParserElement.resetCache()
+        matches = 0
+        while loc <= instrlen and matches < maxMatches:
+            try:
+                preloc = preparseFn( instring, loc )
+                nextLoc,tokens = parseFn( instring, preloc, callPreParse=False )
+            except ParseException:
+                loc = preloc+1
+            else:
+                matches += 1
+                yield tokens, preloc, nextLoc
+                loc = nextLoc
+
+    def transformString( self, instring ):
+        """Extension to scanString, to modify matching text with modified tokens that may
+           be returned from a parse action.  To use transformString, define a grammar and
+           attach a parse action to it that modifies the returned token list.
+           Invoking transformString() on a target string will then scan for matches,
+           and replace the matched text patterns according to the logic in the parse
+           action.  transformString() returns the resulting transformed string."""
+        out = []
+        lastE = 0
+        # force preservation of <TAB>s, to minimize unwanted transformation of string, and to
+        # keep string locs straight between transformString and scanString
+        self.keepTabs = True
+        for t,s,e in self.scanString( instring ):
+            out.append( instring[lastE:s] )
+            if t:
+                if isinstance(t,ParseResults):
+                    out += t.asList()
+                elif isinstance(t,list):
+                    out += t
+                else:
+                    out.append(t)
+            lastE = e
+        out.append(instring[lastE:])
+        return "".join(map(_ustr,out))
+
+    def searchString( self, instring, maxMatches=_MAX_INT ):
+        """Another extension to scanString, simplifying the access to the tokens found
+           to match the given parse expression.  May be called with optional
+           maxMatches argument, to clip searching after 'n' matches are found.
+        """
+        return ParseResults([ t for t,s,e in self.scanString( instring, maxMatches ) ])
+
+    def __add__(self, other ):
+        """Implementation of + operator - returns And"""
+        if isinstance( other, basestring ):
+            other = Literal( other )
+        if not isinstance( other, ParserElement ):
+            warnings.warn("Cannot combine element of type %s with ParserElement" % type(other),
+                    SyntaxWarning, stacklevel=2)
+            return None
+        return And( [ self, other ] )
+
+    def __radd__(self, other ):
+        """Implementation of + operator when left operand is not a ParserElement"""
+        if isinstance( other, basestring ):
+            other = Literal( other )
+        if not isinstance( other, ParserElement ):
+            warnings.warn("Cannot combine element of type %s with ParserElement" % type(other),
+                    SyntaxWarning, stacklevel=2)
+            return None
+        return other + self
+
+    def __sub__(self, other):
+        """Implementation of - operator, returns And with error stop"""
+        if isinstance( other, basestring ):
+            other = Literal( other )
+        if not isinstance( other, ParserElement ):
+            warnings.warn("Cannot combine element of type %s with ParserElement" % type(other),
+                    SyntaxWarning, stacklevel=2)
+            return None
+        return And( [ self, And._ErrorStop(), other ] )
+
+    def __rsub__(self, other ):
+        """Implementation of - operator when left operand is not a ParserElement"""
+        if isinstance( other, basestring ):
+            other = Literal( other )
+        if not isinstance( other, ParserElement ):
+            warnings.warn("Cannot combine element of type %s with ParserElement" % type(other),
+                    SyntaxWarning, stacklevel=2)
+            return None
+        return other - self
+
+    def __mul__(self,other):
+        if isinstance(other,int):
+            minElements, optElements = other,0
+        elif isinstance(other,tuple):
+            if len(other)==0:
+                other = (None,None)
+            elif len(other)==1:
+                other = (other[0],None)
+            if len(other)==2:
+                if other[0] is None:
+                    other = (0, other[1])
+                if isinstance(other[0],int) and other[1] is None:
+                    if other[0] == 0:
+                        return ZeroOrMore(self)
+                    if other[0] == 1:
+                        return OneOrMore(self)
+                    else:
+                        return self*other[0] + ZeroOrMore(self)
+                elif isinstance(other[0],int) and isinstance(other[1],int):
+                    minElements, optElements = other
+                    optElements -= minElements
+                else:
+                    raise TypeError("cannot multiply 'ParserElement' and ('%s','%s') objects", type(other[0]),type(other[1]))
+            else:
+                raise TypeError("can only multiply 'ParserElement' and int or (int,int) objects")
+        else:
+            raise TypeError("cannot multiply 'ParserElement' and '%s' objects", type(other))
+
+        if minElements < 0:
+            raise ValueError("cannot multiply ParserElement by negative value")
+        if optElements < 0:
+            raise ValueError("second tuple value must be greater or equal to first tuple value")
+        if minElements == optElements == 0:
+            raise ValueError("cannot multiply ParserElement by 0 or (0,0)")
+
+        if (optElements):
+            def makeOptionalList(n):
+                if n>1:
+                    return Optional(self + makeOptionalList(n-1))
+                else:
+                    return Optional(self)
+            if minElements:
+                if minElements == 1:
+                    ret = self + makeOptionalList(optElements)
+                else:
+                    ret = And([self]*minElements) + makeOptionalList(optElements)
+            else:
+                ret = makeOptionalList(optElements)
+        else:
+            if minElements == 1:
+                ret = self
+            else:
+                ret = And([self]*minElements)
+        return ret
+
+    def __rmul__(self, other):
+        return self.__mul__(other)
+
+    def __or__(self, other ):
+        """Implementation of | operator - returns MatchFirst"""
+        if isinstance( other, basestring ):
+            other = Literal( other )
+        if not isinstance( other, ParserElement ):
+            warnings.warn("Cannot combine element of type %s with ParserElement" % type(other),
+                    SyntaxWarning, stacklevel=2)
+            return None
+        return MatchFirst( [ self, other ] )
+
+    def __ror__(self, other ):
+        """Implementation of | operator when left operand is not a ParserElement"""
+        if isinstance( other, basestring ):
+            other = Literal( other )
+        if not isinstance( other, ParserElement ):
+            warnings.warn("Cannot combine element of type %s with ParserElement" % type(other),
+                    SyntaxWarning, stacklevel=2)
+            return None
+        return other | self
+
+    def __xor__(self, other ):
+        """Implementation of ^ operator - returns Or"""
+        if isinstance( other, basestring ):
+            other = Literal( other )
+        if not isinstance( other, ParserElement ):
+            warnings.warn("Cannot combine element of type %s with ParserElement" % type(other),
+                    SyntaxWarning, stacklevel=2)
+            return None
+        return Or( [ self, other ] )
+
+    def __rxor__(self, other ):
+        """Implementation of ^ operator when left operand is not a ParserElement"""
+        if isinstance( other, basestring ):
+            other = Literal( other )
+        if not isinstance( other, ParserElement ):
+            warnings.warn("Cannot combine element of type %s with ParserElement" % type(other),
+                    SyntaxWarning, stacklevel=2)
+            return None
+        return other ^ self
+
+    def __and__(self, other ):
+        """Implementation of & operator - returns Each"""
+        if isinstance( other, basestring ):
+            other = Literal( other )
+        if not isinstance( other, ParserElement ):
+            warnings.warn("Cannot combine element of type %s with ParserElement" % type(other),
+                    SyntaxWarning, stacklevel=2)
+            return None
+        return Each( [ self, other ] )
+
+    def __rand__(self, other ):
+        """Implementation of & operator when left operand is not a ParserElement"""
+        if isinstance( other, basestring ):
+            other = Literal( other )
+        if not isinstance( other, ParserElement ):
+            warnings.warn("Cannot combine element of type %s with ParserElement" % type(other),
+                    SyntaxWarning, stacklevel=2)
+            return None
+        return other & self
+
+    def __invert__( self ):
+        """Implementation of ~ operator - returns NotAny"""
+        return NotAny( self )
+
+    def __call__(self, name):
+        """Shortcut for setResultsName, with listAllMatches=default::
+             userdata = Word(alphas).setResultsName("name") + Word(nums+"-").setResultsName("socsecno")
+           could be written as::
+             userdata = Word(alphas)("name") + Word(nums+"-")("socsecno")
+           """
+        return self.setResultsName(name)
+
+    def suppress( self ):
+        """Suppresses the output of this ParserElement; useful to keep punctuation from
+           cluttering up returned output.
+        """
+        return Suppress( self )
+
+    def leaveWhitespace( self ):
+        """Disables the skipping of whitespace before matching the characters in the
+           ParserElement's defined pattern.  This is normally only used internally by
+           the pyparsing module, but may be needed in some whitespace-sensitive grammars.
+        """
+        self.skipWhitespace = False
+        return self
+
+    def setWhitespaceChars( self, chars ):
+        """Overrides the default whitespace chars
+        """
+        self.skipWhitespace = True
+        self.whiteChars = chars
+        self.copyDefaultWhiteChars = False
+        return self
+
+    def parseWithTabs( self ):
+        """Overrides default behavior to expand <TAB>s to spaces before parsing the input string.
+           Must be called before parseString when the input grammar contains elements that
+           match <TAB> characters."""
+        self.keepTabs = True
+        return self
+
+    def ignore( self, other ):
+        """Define expression to be ignored (e.g., comments) while doing pattern
+           matching; may be called repeatedly, to define multiple comment or other
+           ignorable patterns.
+        """
+        if isinstance( other, Suppress ):
+            if other not in self.ignoreExprs:
+                self.ignoreExprs.append( other )
+        else:
+            self.ignoreExprs.append( Suppress( other ) )
+        return self
+
+    def setDebugActions( self, startAction, successAction, exceptionAction ):
+        """Enable display of debugging messages while doing pattern matching."""
+        self.debugActions = (startAction or _defaultStartDebugAction,
+                             successAction or _defaultSuccessDebugAction,
+                             exceptionAction or _defaultExceptionDebugAction)
+        self.debug = True
+        return self
+
+    def setDebug( self, flag=True ):
+        """Enable display of debugging messages while doing pattern matching.
+           Set flag to True to enable, False to disable."""
+        if flag:
+            self.setDebugActions( _defaultStartDebugAction, _defaultSuccessDebugAction, _defaultExceptionDebugAction )
+        else:
+            self.debug = False
+        return self
+
+    def __str__( self ):
+        return self.name
+
+    def __repr__( self ):
+        return _ustr(self)
+
+    def streamline( self ):
+        self.streamlined = True
+        self.strRepr = None
+        return self
+
+    def checkRecursion( self, parseElementList ):
+        pass
+
+    def validate( self, validateTrace=[] ):
+        """Check defined expressions for valid structure, check for infinite recursive definitions."""
+        self.checkRecursion( [] )
+
+    def parseFile( self, file_or_filename ):
+        """Execute the parse expression on the given file or filename.
+           If a filename is specified (instead of a file object),
+           the entire file is opened, read, and closed before parsing.
+        """
+        try:
+            file_contents = file_or_filename.read()
+        except AttributeError:
+            f = open(file_or_filename, "rb")
+            file_contents = f.read()
+            f.close()
+        return self.parseString(file_contents)
+
+    def getException(self):
+        return ParseException("",0,self.errmsg,self)
+
+    def __getattr__(self,aname):
+        if aname == "myException":
+            self.myException = ret = self.getException();
+            return ret;
+        else:
+            raise AttributeError("no such attribute " + aname)
+
+    def __eq__(self,other):
+        if isinstance(other, basestring):
+            try:
+                (self + StringEnd()).parseString(_ustr(other))
+                return True
+            except ParseBaseException:
+                return False
+        else:
+            return super(ParserElement,self)==other
+
+    def __hash__(self):
+        return hash(id(self))
+
+    def __req__(self,other):
+        return self == other
+
+
+class Token(ParserElement):
+    """Abstract ParserElement subclass, for defining atomic matching patterns."""
+    def __init__( self ):
+        super(Token,self).__init__( savelist=False )
+        #self.myException = ParseException("",0,"",self)
+
+    def setName(self, name):
+        s = super(Token,self).setName(name)
+        self.errmsg = "Expected " + self.name
+        #s.myException.msg = self.errmsg
+        return s
+
+
+class Empty(Token):
+    """An empty token, will always match."""
+    def __init__( self ):
+        super(Empty,self).__init__()
+        self.name = "Empty"
+        self.mayReturnEmpty = True
+        self.mayIndexError = False
+
+
+class NoMatch(Token):
+    """A token that will never match."""
+    def __init__( self ):
+        super(NoMatch,self).__init__()
+        self.name = "NoMatch"
+        self.mayReturnEmpty = True
+        self.mayIndexError = False
+        self.errmsg = "Unmatchable token"
+        #self.myException.msg = self.errmsg
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        exc = self.myException
+        exc.loc = loc
+        exc.pstr = instring
+        raise exc
+
+
+class Literal(Token):
+    """Token to exactly match a specified string."""
+    def __init__( self, matchString ):
+        super(Literal,self).__init__()
+        self.match = matchString
+        self.matchLen = len(matchString)
+        try:
+            self.firstMatchChar = matchString[0]
+        except IndexError:
+            warnings.warn("null string passed to Literal; use Empty() instead",
+                            SyntaxWarning, stacklevel=2)
+            self.__class__ = Empty
+        self.name = '"%s"' % _ustr(self.match)
+        self.errmsg = "Expected " + self.name
+        self.mayReturnEmpty = False
+        #self.myException.msg = self.errmsg
+        self.mayIndexError = False
+
+    # Performance tuning: this routine gets called a *lot*
+    # if this is a single character match string  and the first character matches,
+    # short-circuit as quickly as possible, and avoid calling startswith
+    #~ @profile
+    def parseImpl( self, instring, loc, doActions=True ):
+        if (instring[loc] == self.firstMatchChar and
+            (self.matchLen==1 or instring.startswith(self.match,loc)) ):
+            return loc+self.matchLen, self.match
+        #~ raise ParseException( instring, loc, self.errmsg )
+        exc = self.myException
+        exc.loc = loc
+        exc.pstr = instring
+        raise exc
+_L = Literal
+
+class Keyword(Token):
+    """Token to exactly match a specified string as a keyword, that is, it must be
+       immediately followed by a non-keyword character.  Compare with Literal::
+         Literal("if") will match the leading 'if' in 'ifAndOnlyIf'.
+         Keyword("if") will not; it will only match the leading 'if in 'if x=1', or 'if(y==2)'
+       Accepts two optional constructor arguments in addition to the keyword string:
+       identChars is a string of characters that would be valid identifier characters,
+       defaulting to all alphanumerics + "_" and "$"; caseless allows case-insensitive
+       matching, default is False.
+    """
+    DEFAULT_KEYWORD_CHARS = alphanums+"_$"
+
+    def __init__( self, matchString, identChars=DEFAULT_KEYWORD_CHARS, caseless=False ):
+        super(Keyword,self).__init__()
+        self.match = matchString
+        self.matchLen = len(matchString)
+        try:
+            self.firstMatchChar = matchString[0]
+        except IndexError:
+            warnings.warn("null string passed to Keyword; use Empty() instead",
+                            SyntaxWarning, stacklevel=2)
+        self.name = '"%s"' % self.match
+        self.errmsg = "Expected " + self.name
+        self.mayReturnEmpty = False
+        #self.myException.msg = self.errmsg
+        self.mayIndexError = False
+        self.caseless = caseless
+        if caseless:
+            self.caselessmatch = matchString.upper()
+            identChars = identChars.upper()
+        self.identChars = _str2dict(identChars)
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        if self.caseless:
+            if ( (instring[ loc:loc+self.matchLen ].upper() == self.caselessmatch) and
+                 (loc >= len(instring)-self.matchLen or instring[loc+self.matchLen].upper() not in self.identChars) and
+                 (loc == 0 or instring[loc-1].upper() not in self.identChars) ):
+                return loc+self.matchLen, self.match
+        else:
+            if (instring[loc] == self.firstMatchChar and
+                (self.matchLen==1 or instring.startswith(self.match,loc)) and
+                (loc >= len(instring)-self.matchLen or instring[loc+self.matchLen] not in self.identChars) and
+                (loc == 0 or instring[loc-1] not in self.identChars) ):
+                return loc+self.matchLen, self.match
+        #~ raise ParseException( instring, loc, self.errmsg )
+        exc = self.myException
+        exc.loc = loc
+        exc.pstr = instring
+        raise exc
+
+    def copy(self):
+        c = super(Keyword,self).copy()
+        c.identChars = Keyword.DEFAULT_KEYWORD_CHARS
+        return c
+
+    def setDefaultKeywordChars( chars ):
+        """Overrides the default Keyword chars
+        """
+        Keyword.DEFAULT_KEYWORD_CHARS = chars
+    setDefaultKeywordChars = staticmethod(setDefaultKeywordChars)
+
+
+class CaselessLiteral(Literal):
+    """Token to match a specified string, ignoring case of letters.
+       Note: the matched results will always be in the case of the given
+       match string, NOT the case of the input text.
+    """
+    def __init__( self, matchString ):
+        super(CaselessLiteral,self).__init__( matchString.upper() )
+        # Preserve the defining literal.
+        self.returnString = matchString
+        self.name = "'%s'" % self.returnString
+        self.errmsg = "Expected " + self.name
+        #self.myException.msg = self.errmsg
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        if instring[ loc:loc+self.matchLen ].upper() == self.match:
+            return loc+self.matchLen, self.returnString
+        #~ raise ParseException( instring, loc, self.errmsg )
+        exc = self.myException
+        exc.loc = loc
+        exc.pstr = instring
+        raise exc
+
+class CaselessKeyword(Keyword):
+    def __init__( self, matchString, identChars=Keyword.DEFAULT_KEYWORD_CHARS ):
+        super(CaselessKeyword,self).__init__( matchString, identChars, caseless=True )
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        if ( (instring[ loc:loc+self.matchLen ].upper() == self.caselessmatch) and
+             (loc >= len(instring)-self.matchLen or instring[loc+self.matchLen].upper() not in self.identChars) ):
+            return loc+self.matchLen, self.match
+        #~ raise ParseException( instring, loc, self.errmsg )
+        exc = self.myException
+        exc.loc = loc
+        exc.pstr = instring
+        raise exc
+
+class Word(Token):
+    """Token for matching words composed of allowed character sets.
+       Defined with string containing all allowed initial characters,
+       an optional string containing allowed body characters (if omitted,
+       defaults to the initial character set), and an optional minimum,
+       maximum, and/or exact length.  The default value for min is 1 (a
+       minimum value < 1 is not valid); the default values for max and exact
+       are 0, meaning no maximum or exact length restriction.
+    """
+    def __init__( self, initChars, bodyChars=None, min=1, max=0, exact=0, asKeyword=False ):
+        super(Word,self).__init__()
+        self.initCharsOrig = initChars
+        self.initChars = _str2dict(initChars)
+        if bodyChars :
+            self.bodyCharsOrig = bodyChars
+            self.bodyChars = _str2dict(bodyChars)
+        else:
+            self.bodyCharsOrig = initChars
+            self.bodyChars = _str2dict(initChars)
+
+        self.maxSpecified = max > 0
+
+        if min < 1:
+            raise ValueError("cannot specify a minimum length < 1; use Optional(Word()) if zero-length word is permitted")
+
+        self.minLen = min
+
+        if max > 0:
+            self.maxLen = max
+        else:
+            self.maxLen = _MAX_INT
+
+        if exact > 0:
+            self.maxLen = exact
+            self.minLen = exact
+
+        self.name = _ustr(self)
+        self.errmsg = "Expected " + self.name
+        #self.myException.msg = self.errmsg
+        self.mayIndexError = False
+        self.asKeyword = asKeyword
+
+        if ' ' not in self.initCharsOrig+self.bodyCharsOrig and (min==1 and max==0 and exact==0):
+            if self.bodyCharsOrig == self.initCharsOrig:
+                self.reString = "[%s]+" % _escapeRegexRangeChars(self.initCharsOrig)
+            elif len(self.bodyCharsOrig) == 1:
+                self.reString = "%s[%s]*" % \
+                                      (re.escape(self.initCharsOrig),
+                                      _escapeRegexRangeChars(self.bodyCharsOrig),)
+            else:
+                self.reString = "[%s][%s]*" % \
+                                      (_escapeRegexRangeChars(self.initCharsOrig),
+                                      _escapeRegexRangeChars(self.bodyCharsOrig),)
+            if self.asKeyword:
+                self.reString = r"\b"+self.reString+r"\b"
+            try:
+                self.re = re.compile( self.reString )
+            except:
+                self.re = None
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        if self.re:
+            result = self.re.match(instring,loc)
+            if not result:
+                exc = self.myException
+                exc.loc = loc
+                exc.pstr = instring
+                raise exc
+
+            loc = result.end()
+            return loc,result.group()
+
+        if not(instring[ loc ] in self.initChars):
+            #~ raise ParseException( instring, loc, self.errmsg )
+            exc = self.myException
+            exc.loc = loc
+            exc.pstr = instring
+            raise exc
+        start = loc
+        loc += 1
+        instrlen = len(instring)
+        bodychars = self.bodyChars
+        maxloc = start + self.maxLen
+        maxloc = min( maxloc, instrlen )
+        while loc < maxloc and instring[loc] in bodychars:
+            loc += 1
+
+        throwException = False
+        if loc - start < self.minLen:
+            throwException = True
+        if self.maxSpecified and loc < instrlen and instring[loc] in bodychars:
+            throwException = True
+        if self.asKeyword:
+            if (start>0 and instring[start-1] in bodychars) or (loc<instrlen and instring[loc] in bodychars):
+                throwException = True
+
+        if throwException:
+            #~ raise ParseException( instring, loc, self.errmsg )
+            exc = self.myException
+            exc.loc = loc
+            exc.pstr = instring
+            raise exc
+
+        return loc, instring[start:loc]
+
+    def __str__( self ):
+        try:
+            return super(Word,self).__str__()
+        except:
+            pass
+
+
+        if self.strRepr is None:
+
+            def charsAsStr(s):
+                if len(s)>4:
+                    return s[:4]+"..."
+                else:
+                    return s
+
+            if ( self.initCharsOrig != self.bodyCharsOrig ):
+                self.strRepr = "W:(%s,%s)" % ( charsAsStr(self.initCharsOrig), charsAsStr(self.bodyCharsOrig) )
+            else:
+                self.strRepr = "W:(%s)" % charsAsStr(self.initCharsOrig)
+
+        return self.strRepr
+
+
+class Regex(Token):
+    """Token for matching strings that match a given regular expression.
+       Defined with string specifying the regular expression in a form recognized by the inbuilt Python re module.
+    """
+    def __init__( self, pattern, flags=0):
+        """The parameters pattern and flags are passed to the re.compile() function as-is. See the Python re module for an explanation of the acceptable patterns and flags."""
+        super(Regex,self).__init__()
+
+        if len(pattern) == 0:
+            warnings.warn("null string passed to Regex; use Empty() instead",
+                    SyntaxWarning, stacklevel=2)
+
+        self.pattern = pattern
+        self.flags = flags
+
+        try:
+            self.re = re.compile(self.pattern, self.flags)
+            self.reString = self.pattern
+        except sre_constants.error:
+            warnings.warn("invalid pattern (%s) passed to Regex" % pattern,
+                SyntaxWarning, stacklevel=2)
+            raise
+
+        self.name = _ustr(self)
+        self.errmsg = "Expected " + self.name
+        #self.myException.msg = self.errmsg
+        self.mayIndexError = False
+        self.mayReturnEmpty = True
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        result = self.re.match(instring,loc)
+        if not result:
+            exc = self.myException
+            exc.loc = loc
+            exc.pstr = instring
+            raise exc
+
+        loc = result.end()
+        d = result.groupdict()
+        ret = ParseResults(result.group())
+        if d:
+            for k in d:
+                ret[k] = d[k]
+        return loc,ret
+
+    def __str__( self ):
+        try:
+            return super(Regex,self).__str__()
+        except:
+            pass
+
+        if self.strRepr is None:
+            self.strRepr = "Re:(%s)" % repr(self.pattern)
+
+        return self.strRepr
+
+
+class QuotedString(Token):
+    """Token for matching strings that are delimited by quoting characters.
+    """
+    def __init__( self, quoteChar, escChar=None, escQuote=None, multiline=False, unquoteResults=True, endQuoteChar=None):
+        """
+           Defined with the following parameters:
+            - quoteChar - string of one or more characters defining the quote delimiting string
+            - escChar - character to escape quotes, typically backslash (default=None)
+            - escQuote - special quote sequence to escape an embedded quote string (such as SQL's "" to escape an embedded ") (default=None)
+            - multiline - boolean indicating whether quotes can span multiple lines (default=False)
+            - unquoteResults - boolean indicating whether the matched text should be unquoted (default=True)
+            - endQuoteChar - string of one or more characters defining the end of the quote delimited string (default=None => same as quoteChar)
+        """
+        super(QuotedString,self).__init__()
+
+        # remove white space from quote chars - wont work anyway
+        quoteChar = quoteChar.strip()
+        if len(quoteChar) == 0:
+            warnings.warn("quoteChar cannot be the empty string",SyntaxWarning,stacklevel=2)
+            raise SyntaxError()
+
+        if endQuoteChar is None:
+            endQuoteChar = quoteChar
+        else:
+            endQuoteChar = endQuoteChar.strip()
+            if len(endQuoteChar) == 0:
+                warnings.warn("endQuoteChar cannot be the empty string",SyntaxWarning,stacklevel=2)
+                raise SyntaxError()
+
+        self.quoteChar = quoteChar
+        self.quoteCharLen = len(quoteChar)
+        self.firstQuoteChar = quoteChar[0]
+        self.endQuoteChar = endQuoteChar
+        self.endQuoteCharLen = len(endQuoteChar)
+        self.escChar = escChar
+        self.escQuote = escQuote
+        self.unquoteResults = unquoteResults
+
+        if multiline:
+            self.flags = re.MULTILINE | re.DOTALL
+            self.pattern = r'%s(?:[^%s%s]' % \
+                ( re.escape(self.quoteChar),
+                  _escapeRegexRangeChars(self.endQuoteChar[0]),
+                  (escChar is not None and _escapeRegexRangeChars(escChar) or '') )
+        else:
+            self.flags = 0
+            self.pattern = r'%s(?:[^%s\n\r%s]' % \
+                ( re.escape(self.quoteChar),
+                  _escapeRegexRangeChars(self.endQuoteChar[0]),
+                  (escChar is not None and _escapeRegexRangeChars(escChar) or '') )
+        if len(self.endQuoteChar) > 1:
+            self.pattern += (
+                '|(?:' + ')|(?:'.join(["%s[^%s]" % (re.escape(self.endQuoteChar[:i]),
+                                               _escapeRegexRangeChars(self.endQuoteChar[i]))
+                                    for i in range(len(self.endQuoteChar)-1,0,-1)]) + ')'
+                )
+        if escQuote:
+            self.pattern += (r'|(?:%s)' % re.escape(escQuote))
+        if escChar:
+            self.pattern += (r'|(?:%s.)' % re.escape(escChar))
+            self.escCharReplacePattern = re.escape(self.escChar)+"(.)"
+        self.pattern += (r')*%s' % re.escape(self.endQuoteChar))
+
+        try:
+            self.re = re.compile(self.pattern, self.flags)
+            self.reString = self.pattern
+        except sre_constants.error:
+            warnings.warn("invalid pattern (%s) passed to Regex" % self.pattern,
+                SyntaxWarning, stacklevel=2)
+            raise
+
+        self.name = _ustr(self)
+        self.errmsg = "Expected " + self.name
+        #self.myException.msg = self.errmsg
+        self.mayIndexError = False
+        self.mayReturnEmpty = True
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        result = instring[loc] == self.firstQuoteChar and self.re.match(instring,loc) or None
+        if not result:
+            exc = self.myException
+            exc.loc = loc
+            exc.pstr = instring
+            raise exc
+
+        loc = result.end()
+        ret = result.group()
+
+        if self.unquoteResults:
+
+            # strip off quotes
+            ret = ret[self.quoteCharLen:-self.endQuoteCharLen]
+
+            if isinstance(ret,basestring):
+                # replace escaped characters
+                if self.escChar:
+                    ret = re.sub(self.escCharReplacePattern,"\g<1>",ret)
+
+                # replace escaped quotes
+                if self.escQuote:
+                    ret = ret.replace(self.escQuote, self.endQuoteChar)
+
+        return loc, ret
+
+    def __str__( self ):
+        try:
+            return super(QuotedString,self).__str__()
+        except:
+            pass
+
+        if self.strRepr is None:
+            self.strRepr = "quoted string, starting with %s ending with %s" % (self.quoteChar, self.endQuoteChar)
+
+        return self.strRepr
+
+
+class CharsNotIn(Token):
+    """Token for matching words composed of characters *not* in a given set.
+       Defined with string containing all disallowed characters, and an optional
+       minimum, maximum, and/or exact length.  The default value for min is 1 (a
+       minimum value < 1 is not valid); the default values for max and exact
+       are 0, meaning no maximum or exact length restriction.
+    """
+    def __init__( self, notChars, min=1, max=0, exact=0 ):
+        super(CharsNotIn,self).__init__()
+        self.skipWhitespace = False
+        self.notChars = notChars
+
+        if min < 1:
+            raise ValueError("cannot specify a minimum length < 1; use Optional(CharsNotIn()) if zero-length char group is permitted")
+
+        self.minLen = min
+
+        if max > 0:
+            self.maxLen = max
+        else:
+            self.maxLen = _MAX_INT
+
+        if exact > 0:
+            self.maxLen = exact
+            self.minLen = exact
+
+        self.name = _ustr(self)
+        self.errmsg = "Expected " + self.name
+        self.mayReturnEmpty = ( self.minLen == 0 )
+        #self.myException.msg = self.errmsg
+        self.mayIndexError = False
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        if instring[loc] in self.notChars:
+            #~ raise ParseException( instring, loc, self.errmsg )
+            exc = self.myException
+            exc.loc = loc
+            exc.pstr = instring
+            raise exc
+
+        start = loc
+        loc += 1
+        notchars = self.notChars
+        maxlen = min( start+self.maxLen, len(instring) )
+        while loc < maxlen and \
+              (instring[loc] not in notchars):
+            loc += 1
+
+        if loc - start < self.minLen:
+            #~ raise ParseException( instring, loc, self.errmsg )
+            exc = self.myException
+            exc.loc = loc
+            exc.pstr = instring
+            raise exc
+
+        return loc, instring[start:loc]
+
+    def __str__( self ):
+        try:
+            return super(CharsNotIn, self).__str__()
+        except:
+            pass
+
+        if self.strRepr is None:
+            if len(self.notChars) > 4:
+                self.strRepr = "!W:(%s...)" % self.notChars[:4]
+            else:
+                self.strRepr = "!W:(%s)" % self.notChars
+
+        return self.strRepr
+
+class White(Token):
+    """Special matching class for matching whitespace.  Normally, whitespace is ignored
+       by pyparsing grammars.  This class is included when some whitespace structures
+       are significant.  Define with a string containing the whitespace characters to be
+       matched; default is " \\t\\n".  Also takes optional min, max, and exact arguments,
+       as defined for the Word class."""
+    whiteStrs = {
+        " " : "<SPC>",
+        "\t": "<TAB>",
+        "\n": "<LF>",
+        "\r": "<CR>",
+        "\f": "<FF>",
+        }
+    def __init__(self, ws=" \t\r\n", min=1, max=0, exact=0):
+        super(White,self).__init__()
+        self.matchWhite = ws
+        self.setWhitespaceChars( "".join([c for c in self.whiteChars if c not in self.matchWhite]) )
+        #~ self.leaveWhitespace()
+        self.name = ("".join([White.whiteStrs[c] for c in self.matchWhite]))
+        self.mayReturnEmpty = True
+        self.errmsg = "Expected " + self.name
+        #self.myException.msg = self.errmsg
+
+        self.minLen = min
+
+        if max > 0:
+            self.maxLen = max
+        else:
+            self.maxLen = _MAX_INT
+
+        if exact > 0:
+            self.maxLen = exact
+            self.minLen = exact
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        if not(instring[ loc ] in self.matchWhite):
+            #~ raise ParseException( instring, loc, self.errmsg )
+            exc = self.myException
+            exc.loc = loc
+            exc.pstr = instring
+            raise exc
+        start = loc
+        loc += 1
+        maxloc = start + self.maxLen
+        maxloc = min( maxloc, len(instring) )
+        while loc < maxloc and instring[loc] in self.matchWhite:
+            loc += 1
+
+        if loc - start < self.minLen:
+            #~ raise ParseException( instring, loc, self.errmsg )
+            exc = self.myException
+            exc.loc = loc
+            exc.pstr = instring
+            raise exc
+
+        return loc, instring[start:loc]
+
+
+class _PositionToken(Token):
+    def __init__( self ):
+        super(_PositionToken,self).__init__()
+        self.name=self.__class__.__name__
+        self.mayReturnEmpty = True
+        self.mayIndexError = False
+
+class GoToColumn(_PositionToken):
+    """Token to advance to a specific column of input text; useful for tabular report scraping."""
+    def __init__( self, colno ):
+        super(GoToColumn,self).__init__()
+        self.col = colno
+
+    def preParse( self, instring, loc ):
+        if col(loc,instring) != self.col:
+            instrlen = len(instring)
+            if self.ignoreExprs:
+                loc = self._skipIgnorables( instring, loc )
+            while loc < instrlen and instring[loc].isspace() and col( loc, instring ) != self.col :
+                loc += 1
+        return loc
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        thiscol = col( loc, instring )
+        if thiscol > self.col:
+            raise ParseException( instring, loc, "Text not in expected column", self )
+        newloc = loc + self.col - thiscol
+        ret = instring[ loc: newloc ]
+        return newloc, ret
+
+class LineStart(_PositionToken):
+    """Matches if current position is at the beginning of a line within the parse string"""
+    def __init__( self ):
+        super(LineStart,self).__init__()
+        self.setWhitespaceChars( " \t" )
+        self.errmsg = "Expected start of line"
+        #self.myException.msg = self.errmsg
+
+    def preParse( self, instring, loc ):
+        preloc = super(LineStart,self).preParse(instring,loc)
+        if instring[preloc] == "\n":
+            loc += 1
+        return loc
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        if not( loc==0 or
+            (loc == self.preParse( instring, 0 )) or
+            (instring[loc-1] == "\n") ): #col(loc, instring) != 1:
+            #~ raise ParseException( instring, loc, "Expected start of line" )
+            exc = self.myException
+            exc.loc = loc
+            exc.pstr = instring
+            raise exc
+        return loc, []
+
+class LineEnd(_PositionToken):
+    """Matches if current position is at the end of a line within the parse string"""
+    def __init__( self ):
+        super(LineEnd,self).__init__()
+        self.setWhitespaceChars( " \t" )
+        self.errmsg = "Expected end of line"
+        #self.myException.msg = self.errmsg
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        if loc<len(instring):
+            if instring[loc] == "\n":
+                return loc+1, "\n"
+            else:
+                #~ raise ParseException( instring, loc, "Expected end of line" )
+                exc = self.myException
+                exc.loc = loc
+                exc.pstr = instring
+                raise exc
+        elif loc == len(instring):
+            return loc+1, []
+        else:
+            exc = self.myException
+            exc.loc = loc
+            exc.pstr = instring
+            raise exc
+
+class StringStart(_PositionToken):
+    """Matches if current position is at the beginning of the parse string"""
+    def __init__( self ):
+        super(StringStart,self).__init__()
+        self.errmsg = "Expected start of text"
+        #self.myException.msg = self.errmsg
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        if loc != 0:
+            # see if entire string up to here is just whitespace and ignoreables
+            if loc != self.preParse( instring, 0 ):
+                #~ raise ParseException( instring, loc, "Expected start of text" )
+                exc = self.myException
+                exc.loc = loc
+                exc.pstr = instring
+                raise exc
+        return loc, []
+
+class StringEnd(_PositionToken):
+    """Matches if current position is at the end of the parse string"""
+    def __init__( self ):
+        super(StringEnd,self).__init__()
+        self.errmsg = "Expected end of text"
+        #self.myException.msg = self.errmsg
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        if loc < len(instring):
+            #~ raise ParseException( instring, loc, "Expected end of text" )
+            exc = self.myException
+            exc.loc = loc
+            exc.pstr = instring
+            raise exc
+        elif loc == len(instring):
+            return loc+1, []
+        elif loc > len(instring):
+            return loc, []
+        else:
+            exc = self.myException
+            exc.loc = loc
+            exc.pstr = instring
+            raise exc
+
+class WordStart(_PositionToken):
+    """Matches if the current position is at the beginning of a Word, and
+       is not preceded by any character in a given set of wordChars
+       (default=printables). To emulate the \b behavior of regular expressions,
+       use WordStart(alphanums). WordStart will also match at the beginning of
+       the string being parsed, or at the beginning of a line.
+    """
+    def __init__(self, wordChars = printables):
+        super(WordStart,self).__init__()
+        self.wordChars = _str2dict(wordChars)
+        self.errmsg = "Not at the start of a word"
+
+    def parseImpl(self, instring, loc, doActions=True ):
+        if loc != 0:
+            if (instring[loc-1] in self.wordChars or
+                instring[loc] not in self.wordChars):
+                exc = self.myException
+                exc.loc = loc
+                exc.pstr = instring
+                raise exc
+        return loc, []
+
+class WordEnd(_PositionToken):
+    """Matches if the current position is at the end of a Word, and
+       is not followed by any character in a given set of wordChars
+       (default=printables). To emulate the \b behavior of regular expressions,
+       use WordEnd(alphanums). WordEnd will also match at the end of
+       the string being parsed, or at the end of a line.
+    """
+    def __init__(self, wordChars = printables):
+        super(WordEnd,self).__init__()
+        self.wordChars = _str2dict(wordChars)
+        self.skipWhitespace = False
+        self.errmsg = "Not at the end of a word"
+
+    def parseImpl(self, instring, loc, doActions=True ):
+        instrlen = len(instring)
+        if instrlen>0 and loc<instrlen:
+            if (instring[loc] in self.wordChars or
+                instring[loc-1] not in self.wordChars):
+                #~ raise ParseException( instring, loc, "Expected end of word" )
+                exc = self.myException
+                exc.loc = loc
+                exc.pstr = instring
+                raise exc
+        return loc, []
+
+
+class ParseExpression(ParserElement):
+    """Abstract subclass of ParserElement, for combining and post-processing parsed tokens."""
+    def __init__( self, exprs, savelist = False ):
+        super(ParseExpression,self).__init__(savelist)
+        if isinstance( exprs, list ):
+            self.exprs = exprs
+        elif isinstance( exprs, basestring ):
+            self.exprs = [ Literal( exprs ) ]
+        else:
+            self.exprs = [ exprs ]
+        self.callPreparse = False
+
+    def __getitem__( self, i ):
+        return self.exprs[i]
+
+    def append( self, other ):
+        self.exprs.append( other )
+        self.strRepr = None
+        return self
+
+    def leaveWhitespace( self ):
+        """Extends leaveWhitespace defined in base class, and also invokes leaveWhitespace on
+           all contained expressions."""
+        self.skipWhitespace = False
+        self.exprs = [ e.copy() for e in self.exprs ]
+        for e in self.exprs:
+            e.leaveWhitespace()
+        return self
+
+    def ignore( self, other ):
+        if isinstance( other, Suppress ):
+            if other not in self.ignoreExprs:
+                super( ParseExpression, self).ignore( other )
+                for e in self.exprs:
+                    e.ignore( self.ignoreExprs[-1] )
+        else:
+            super( ParseExpression, self).ignore( other )
+            for e in self.exprs:
+                e.ignore( self.ignoreExprs[-1] )
+        return self
+
+    def __str__( self ):
+        try:
+            return super(ParseExpression,self).__str__()
+        except:
+            pass
+
+        if self.strRepr is None:
+            self.strRepr = "%s:(%s)" % ( self.__class__.__name__, _ustr(self.exprs) )
+        return self.strRepr
+
+    def streamline( self ):
+        super(ParseExpression,self).streamline()
+
+        for e in self.exprs:
+            e.streamline()
+
+        # collapse nested And's of the form And( And( And( a,b), c), d) to And( a,b,c,d )
+        # but only if there are no parse actions or resultsNames on the nested And's
+        # (likewise for Or's and MatchFirst's)
+        if ( len(self.exprs) == 2 ):
+            other = self.exprs[0]
+            if ( isinstance( other, self.__class__ ) and
+                  not(other.parseAction) and
+                  other.resultsName is None and
+                  not other.debug ):
+                self.exprs = other.exprs[:] + [ self.exprs[1] ]
+                self.strRepr = None
+                self.mayReturnEmpty |= other.mayReturnEmpty
+                self.mayIndexError  |= other.mayIndexError
+
+            other = self.exprs[-1]
+            if ( isinstance( other, self.__class__ ) and
+                  not(other.parseAction) and
+                  other.resultsName is None and
+                  not other.debug ):
+                self.exprs = self.exprs[:-1] + other.exprs[:]
+                self.strRepr = None
+                self.mayReturnEmpty |= other.mayReturnEmpty
+                self.mayIndexError  |= other.mayIndexError
+
+        return self
+
+    def setResultsName( self, name, listAllMatches=False ):
+        ret = super(ParseExpression,self).setResultsName(name,listAllMatches)
+        return ret
+
+    def validate( self, validateTrace=[] ):
+        tmp = validateTrace[:]+[self]
+        for e in self.exprs:
+            e.validate(tmp)
+        self.checkRecursion( [] )
+
+class And(ParseExpression):
+    """Requires all given ParseExpressions to be found in the given order.
+       Expressions may be separated by whitespace.
+       May be constructed using the '+' operator.
+    """
+
+    class _ErrorStop(Empty):
+        def __new__(cls,*args,**kwargs):
+            return And._ErrorStop.instance
+    _ErrorStop.instance = Empty()
+    _ErrorStop.instance.leaveWhitespace()
+
+    def __init__( self, exprs, savelist = True ):
+        super(And,self).__init__(exprs, savelist)
+        self.mayReturnEmpty = True
+        for e in self.exprs:
+            if not e.mayReturnEmpty:
+                self.mayReturnEmpty = False
+                break
+        self.setWhitespaceChars( exprs[0].whiteChars )
+        self.skipWhitespace = exprs[0].skipWhitespace
+        self.callPreparse = True
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        # pass False as last arg to _parse for first element, since we already
+        # pre-parsed the string as part of our And pre-parsing
+        loc, resultlist = self.exprs[0]._parse( instring, loc, doActions, callPreParse=False )
+        errorStop = False
+        for e in self.exprs[1:]:
+            if e is And._ErrorStop.instance:
+                errorStop = True
+                continue
+            if errorStop:
+                try:
+                    loc, exprtokens = e._parse( instring, loc, doActions )
+                except ParseBaseException, pe:
+                    raise ParseSyntaxException(pe)
+                except IndexError, ie:
+                    raise ParseSyntaxException( ParseException(instring, len(instring), self.errmsg, self) )
+            else:
+                loc, exprtokens = e._parse( instring, loc, doActions )
+            if exprtokens or exprtokens.keys():
+                resultlist += exprtokens
+        return loc, resultlist
+
+    def __iadd__(self, other ):
+        if isinstance( other, basestring ):
+            other = Literal( other )
+        return self.append( other ) #And( [ self, other ] )
+
+    def checkRecursion( self, parseElementList ):
+        subRecCheckList = parseElementList[:] + [ self ]
+        for e in self.exprs:
+            e.checkRecursion( subRecCheckList )
+            if not e.mayReturnEmpty:
+                break
+
+    def __str__( self ):
+        if hasattr(self,"name"):
+            return self.name
+
+        if self.strRepr is None:
+            self.strRepr = "{" + " ".join( [ _ustr(e) for e in self.exprs ] ) + "}"
+
+        return self.strRepr
+
+
+class Or(ParseExpression):
+    """Requires that at least one ParseExpression is found.
+       If two expressions match, the expression that matches the longest string will be used.
+       May be constructed using the '^' operator.
+    """
+    def __init__( self, exprs, savelist = False ):
+        super(Or,self).__init__(exprs, savelist)
+        self.mayReturnEmpty = False
+        for e in self.exprs:
+            if e.mayReturnEmpty:
+                self.mayReturnEmpty = True
+                break
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        maxExcLoc = -1
+        maxMatchLoc = -1
+        maxException = None
+        for e in self.exprs:
+            try:
+                loc2 = e.tryParse( instring, loc )
+            except ParseException, err:
+                if err.loc > maxExcLoc:
+                    maxException = err
+                    maxExcLoc = err.loc
+            except IndexError:
+                if len(instring) > maxExcLoc:
+                    maxException = ParseException(instring,len(instring),e.errmsg,self)
+                    maxExcLoc = len(instring)
+            else:
+                if loc2 > maxMatchLoc:
+                    maxMatchLoc = loc2
+                    maxMatchExp = e
+
+        if maxMatchLoc < 0:
+            if maxException is not None:
+                raise maxException
+            else:
+                raise ParseException(instring, loc, "no defined alternatives to match", self)
+
+        return maxMatchExp._parse( instring, loc, doActions )
+
+    def __ixor__(self, other ):
+        if isinstance( other, basestring ):
+            other = Literal( other )
+        return self.append( other ) #Or( [ self, other ] )
+
+    def __str__( self ):
+        if hasattr(self,"name"):
+            return self.name
+
+        if self.strRepr is None:
+            self.strRepr = "{" + " ^ ".join( [ _ustr(e) for e in self.exprs ] ) + "}"
+
+        return self.strRepr
+
+    def checkRecursion( self, parseElementList ):
+        subRecCheckList = parseElementList[:] + [ self ]
+        for e in self.exprs:
+            e.checkRecursion( subRecCheckList )
+
+
+class MatchFirst(ParseExpression):
+    """Requires that at least one ParseExpression is found.
+       If two expressions match, the first one listed is the one that will match.
+       May be constructed using the '|' operator.
+    """
+    def __init__( self, exprs, savelist = False ):
+        super(MatchFirst,self).__init__(exprs, savelist)
+        if exprs:
+            self.mayReturnEmpty = False
+            for e in self.exprs:
+                if e.mayReturnEmpty:
+                    self.mayReturnEmpty = True
+                    break
+        else:
+            self.mayReturnEmpty = True
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        maxExcLoc = -1
+        maxException = None
+        for e in self.exprs:
+            try:
+                ret = e._parse( instring, loc, doActions )
+                return ret
+            except ParseException, err:
+                if err.loc > maxExcLoc:
+                    maxException = err
+                    maxExcLoc = err.loc
+            except IndexError:
+                if len(instring) > maxExcLoc:
+                    maxException = ParseException(instring,len(instring),e.errmsg,self)
+                    maxExcLoc = len(instring)
+
+        # only got here if no expression matched, raise exception for match that made it the furthest
+        else:
+            if maxException is not None:
+                raise maxException
+            else:
+                raise ParseException(instring, loc, "no defined alternatives to match", self)
+
+    def __ior__(self, other ):
+        if isinstance( other, basestring ):
+            other = Literal( other )
+        return self.append( other ) #MatchFirst( [ self, other ] )
+
+    def __str__( self ):
+        if hasattr(self,"name"):
+            return self.name
+
+        if self.strRepr is None:
+            self.strRepr = "{" + " | ".join( [ _ustr(e) for e in self.exprs ] ) + "}"
+
+        return self.strRepr
+
+    def checkRecursion( self, parseElementList ):
+        subRecCheckList = parseElementList[:] + [ self ]
+        for e in self.exprs:
+            e.checkRecursion( subRecCheckList )
+
+
+class Each(ParseExpression):
+    """Requires all given ParseExpressions to be found, but in any order.
+       Expressions may be separated by whitespace.
+       May be constructed using the '&' operator.
+    """
+    def __init__( self, exprs, savelist = True ):
+        super(Each,self).__init__(exprs, savelist)
+        self.mayReturnEmpty = True
+        for e in self.exprs:
+            if not e.mayReturnEmpty:
+                self.mayReturnEmpty = False
+                break
+        self.skipWhitespace = True
+        self.initExprGroups = True
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        if self.initExprGroups:
+            self.optionals = [ e.expr for e in self.exprs if isinstance(e,Optional) ]
+            self.multioptionals = [ e.expr for e in self.exprs if isinstance(e,ZeroOrMore) ]
+            self.multirequired = [ e.expr for e in self.exprs if isinstance(e,OneOrMore) ]
+            self.required = [ e for e in self.exprs if not isinstance(e,(Optional,ZeroOrMore,OneOrMore)) ]
+            self.required += self.multirequired
+            self.initExprGroups = False
+        tmpLoc = loc
+        tmpReqd = self.required[:]
+        tmpOpt  = self.optionals[:]
+        matchOrder = []
+
+        keepMatching = True
+        while keepMatching:
+            tmpExprs = tmpReqd + tmpOpt + self.multioptionals + self.multirequired
+            failed = []
+            for e in tmpExprs:
+                try:
+                    tmpLoc = e.tryParse( instring, tmpLoc )
+                except ParseException:
+                    failed.append(e)
+                else:
+                    matchOrder.append(e)
+                    if e in tmpReqd:
+                        tmpReqd.remove(e)
+                    elif e in tmpOpt:
+                        tmpOpt.remove(e)
+            if len(failed) == len(tmpExprs):
+                keepMatching = False
+
+        if tmpReqd:
+            missing = ", ".join( [ _ustr(e) for e in tmpReqd ] )
+            raise ParseException(instring,loc,"Missing one or more required elements (%s)" % missing )
+
+        # add any unmatched Optionals, in case they have default values defined
+        matchOrder += list(e for e in self.exprs if isinstance(e,Optional) and e.expr in tmpOpt)
+
+        resultlist = []
+        for e in matchOrder:
+            loc,results = e._parse(instring,loc,doActions)
+            resultlist.append(results)
+
+        finalResults = ParseResults([])
+        for r in resultlist:
+            dups = {}
+            for k in r.keys():
+                if k in finalResults.keys():
+                    tmp = ParseResults(finalResults[k])
+                    tmp += ParseResults(r[k])
+                    dups[k] = tmp
+            finalResults += ParseResults(r)
+            for k,v in dups.items():
+                finalResults[k] = v
+        return loc, finalResults
+
+    def __str__( self ):
+        if hasattr(self,"name"):
+            return self.name
+
+        if self.strRepr is None:
+            self.strRepr = "{" + " & ".join( [ _ustr(e) for e in self.exprs ] ) + "}"
+
+        return self.strRepr
+
+    def checkRecursion( self, parseElementList ):
+        subRecCheckList = parseElementList[:] + [ self ]
+        for e in self.exprs:
+            e.checkRecursion( subRecCheckList )
+
+
+class ParseElementEnhance(ParserElement):
+    """Abstract subclass of ParserElement, for combining and post-processing parsed tokens."""
+    def __init__( self, expr, savelist=False ):
+        super(ParseElementEnhance,self).__init__(savelist)
+        if isinstance( expr, basestring ):
+            expr = Literal(expr)
+        self.expr = expr
+        self.strRepr = None
+        if expr is not None:
+            self.mayIndexError = expr.mayIndexError
+            self.mayReturnEmpty = expr.mayReturnEmpty
+            self.setWhitespaceChars( expr.whiteChars )
+            self.skipWhitespace = expr.skipWhitespace
+            self.saveAsList = expr.saveAsList
+            self.callPreparse = expr.callPreparse
+            self.ignoreExprs.extend(expr.ignoreExprs)
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        if self.expr is not None:
+            return self.expr._parse( instring, loc, doActions, callPreParse=False )
+        else:
+            raise ParseException("",loc,self.errmsg,self)
+
+    def leaveWhitespace( self ):
+        self.skipWhitespace = False
+        self.expr = self.expr.copy()
+        if self.expr is not None:
+            self.expr.leaveWhitespace()
+        return self
+
+    def ignore( self, other ):
+        if isinstance( other, Suppress ):
+            if other not in self.ignoreExprs:
+                super( ParseElementEnhance, self).ignore( other )
+                if self.expr is not None:
+                    self.expr.ignore( self.ignoreExprs[-1] )
+        else:
+            super( ParseElementEnhance, self).ignore( other )
+            if self.expr is not None:
+                self.expr.ignore( self.ignoreExprs[-1] )
+        return self
+
+    def streamline( self ):
+        super(ParseElementEnhance,self).streamline()
+        if self.expr is not None:
+            self.expr.streamline()
+        return self
+
+    def checkRecursion( self, parseElementList ):
+        if self in parseElementList:
+            raise RecursiveGrammarException( parseElementList+[self] )
+        subRecCheckList = parseElementList[:] + [ self ]
+        if self.expr is not None:
+            self.expr.checkRecursion( subRecCheckList )
+
+    def validate( self, validateTrace=[] ):
+        tmp = validateTrace[:]+[self]
+        if self.expr is not None:
+            self.expr.validate(tmp)
+        self.checkRecursion( [] )
+
+    def __str__( self ):
+        try:
+            return super(ParseElementEnhance,self).__str__()
+        except:
+            pass
+
+        if self.strRepr is None and self.expr is not None:
+            self.strRepr = "%s:(%s)" % ( self.__class__.__name__, _ustr(self.expr) )
+        return self.strRepr
+
+
+class FollowedBy(ParseElementEnhance):
+    """Lookahead matching of the given parse expression.  FollowedBy
+    does *not* advance the parsing position within the input string, it only
+    verifies that the specified parse expression matches at the current
+    position.  FollowedBy always returns a null token list."""
+    def __init__( self, expr ):
+        super(FollowedBy,self).__init__(expr)
+        self.mayReturnEmpty = True
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        self.expr.tryParse( instring, loc )
+        return loc, []
+
+
+class NotAny(ParseElementEnhance):
+    """Lookahead to disallow matching with the given parse expression.  NotAny
+    does *not* advance the parsing position within the input string, it only
+    verifies that the specified parse expression does *not* match at the current
+    position.  Also, NotAny does *not* skip over leading whitespace. NotAny
+    always returns a null token list.  May be constructed using the '~' operator."""
+    def __init__( self, expr ):
+        super(NotAny,self).__init__(expr)
+        #~ self.leaveWhitespace()
+        self.skipWhitespace = False  # do NOT use self.leaveWhitespace(), don't want to propagate to exprs
+        self.mayReturnEmpty = True
+        self.errmsg = "Found unwanted token, "+_ustr(self.expr)
+        #self.myException = ParseException("",0,self.errmsg,self)
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        try:
+            self.expr.tryParse( instring, loc )
+        except (ParseException,IndexError):
+            pass
+        else:
+            #~ raise ParseException(instring, loc, self.errmsg )
+            exc = self.myException
+            exc.loc = loc
+            exc.pstr = instring
+            raise exc
+        return loc, []
+
+    def __str__( self ):
+        if hasattr(self,"name"):
+            return self.name
+
+        if self.strRepr is None:
+            self.strRepr = "~{" + _ustr(self.expr) + "}"
+
+        return self.strRepr
+
+
+class ZeroOrMore(ParseElementEnhance):
+    """Optional repetition of zero or more of the given expression."""
+    def __init__( self, expr ):
+        super(ZeroOrMore,self).__init__(expr)
+        self.mayReturnEmpty = True
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        tokens = []
+        try:
+            loc, tokens = self.expr._parse( instring, loc, doActions, callPreParse=False )
+            hasIgnoreExprs = ( len(self.ignoreExprs) > 0 )
+            while 1:
+                if hasIgnoreExprs:
+                    preloc = self._skipIgnorables( instring, loc )
+                else:
+                    preloc = loc
+                loc, tmptokens = self.expr._parse( instring, preloc, doActions )
+                if tmptokens or tmptokens.keys():
+                    tokens += tmptokens
+        except (ParseException,IndexError):
+            pass
+
+        return loc, tokens
+
+    def __str__( self ):
+        if hasattr(self,"name"):
+            return self.name
+
+        if self.strRepr is None:
+            self.strRepr = "[" + _ustr(self.expr) + "]..."
+
+        return self.strRepr
+
+    def setResultsName( self, name, listAllMatches=False ):
+        ret = super(ZeroOrMore,self).setResultsName(name,listAllMatches)
+        ret.saveAsList = True
+        return ret
+
+
+class OneOrMore(ParseElementEnhance):
+    """Repetition of one or more of the given expression."""
+    def parseImpl( self, instring, loc, doActions=True ):
+        # must be at least one
+        loc, tokens = self.expr._parse( instring, loc, doActions, callPreParse=False )
+        try:
+            hasIgnoreExprs = ( len(self.ignoreExprs) > 0 )
+            while 1:
+                if hasIgnoreExprs:
+                    preloc = self._skipIgnorables( instring, loc )
+                else:
+                    preloc = loc
+                loc, tmptokens = self.expr._parse( instring, preloc, doActions )
+                if tmptokens or tmptokens.keys():
+                    tokens += tmptokens
+        except (ParseException,IndexError):
+            pass
+
+        return loc, tokens
+
+    def __str__( self ):
+        if hasattr(self,"name"):
+            return self.name
+
+        if self.strRepr is None:
+            self.strRepr = "{" + _ustr(self.expr) + "}..."
+
+        return self.strRepr
+
+    def setResultsName( self, name, listAllMatches=False ):
+        ret = super(OneOrMore,self).setResultsName(name,listAllMatches)
+        ret.saveAsList = True
+        return ret
+
+class _NullToken(object):
+    def __bool__(self):
+        return False
+    __nonzero__ = __bool__
+    def __str__(self):
+        return ""
+
+_optionalNotMatched = _NullToken()
+class Optional(ParseElementEnhance):
+    """Optional matching of the given expression.
+       A default return string can also be specified, if the optional expression
+       is not found.
+    """
+    def __init__( self, exprs, default=_optionalNotMatched ):
+        super(Optional,self).__init__( exprs, savelist=False )
+        self.defaultValue = default
+        self.mayReturnEmpty = True
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        try:
+            loc, tokens = self.expr._parse( instring, loc, doActions, callPreParse=False )
+        except (ParseException,IndexError):
+            if self.defaultValue is not _optionalNotMatched:
+                if self.expr.resultsName:
+                    tokens = ParseResults([ self.defaultValue ])
+                    tokens[self.expr.resultsName] = self.defaultValue
+                else:
+                    tokens = [ self.defaultValue ]
+            else:
+                tokens = []
+        return loc, tokens
+
+    def __str__( self ):
+        if hasattr(self,"name"):
+            return self.name
+
+        if self.strRepr is None:
+            self.strRepr = "[" + _ustr(self.expr) + "]"
+
+        return self.strRepr
+
+
+class SkipTo(ParseElementEnhance):
+    """Token for skipping over all undefined text until the matched expression is found.
+       If include is set to true, the matched expression is also consumed.  The ignore
+       argument is used to define grammars (typically quoted strings and comments) that
+       might contain false matches.
+    """
+    def __init__( self, other, include=False, ignore=None ):
+        super( SkipTo, self ).__init__( other )
+        if ignore is not None:
+            self.expr = self.expr.copy()
+            self.expr.ignore(ignore)
+        self.mayReturnEmpty = True
+        self.mayIndexError = False
+        self.includeMatch = include
+        self.asList = False
+        self.errmsg = "No match found for "+_ustr(self.expr)
+        #self.myException = ParseException("",0,self.errmsg,self)
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        startLoc = loc
+        instrlen = len(instring)
+        expr = self.expr
+        while loc <= instrlen:
+            try:
+                loc = expr._skipIgnorables( instring, loc )
+                expr._parse( instring, loc, doActions=False, callPreParse=False )
+                if self.includeMatch:
+                    skipText = instring[startLoc:loc]
+                    loc,mat = expr._parse(instring,loc,doActions,callPreParse=False)
+                    if mat:
+                        skipRes = ParseResults( skipText )
+                        skipRes += mat
+                        return loc, [ skipRes ]
+                    else:
+                        return loc, [ skipText ]
+                else:
+                    return loc, [ instring[startLoc:loc] ]
+            except (ParseException,IndexError):
+                loc += 1
+        exc = self.myException
+        exc.loc = loc
+        exc.pstr = instring
+        raise exc
+
+class Forward(ParseElementEnhance):
+    """Forward declaration of an expression to be defined later -
+       used for recursive grammars, such as algebraic infix notation.
+       When the expression is known, it is assigned to the Forward variable using the '<<' operator.
+
+       Note: take care when assigning to Forward not to overlook precedence of operators.
+       Specifically, '|' has a lower precedence than '<<', so that::
+          fwdExpr << a | b | c
+       will actually be evaluated as::
+          (fwdExpr << a) | b | c
+       thereby leaving b and c out as parseable alternatives.  It is recommended that you
+       explicitly group the values inserted into the Forward::
+          fwdExpr << (a | b | c)
+    """
+    def __init__( self, other=None ):
+        super(Forward,self).__init__( other, savelist=False )
+
+    def __lshift__( self, other ):
+        if isinstance( other, basestring ):
+            other = Literal(other)
+        self.expr = other
+        self.mayReturnEmpty = other.mayReturnEmpty
+        self.strRepr = None
+        self.mayIndexError = self.expr.mayIndexError
+        self.mayReturnEmpty = self.expr.mayReturnEmpty
+        self.setWhitespaceChars( self.expr.whiteChars )
+        self.skipWhitespace = self.expr.skipWhitespace
+        self.saveAsList = self.expr.saveAsList
+        self.ignoreExprs.extend(self.expr.ignoreExprs)
+        return None
+
+    def leaveWhitespace( self ):
+        self.skipWhitespace = False
+        return self
+
+    def streamline( self ):
+        if not self.streamlined:
+            self.streamlined = True
+            if self.expr is not None:
+                self.expr.streamline()
+        return self
+
+    def validate( self, validateTrace=[] ):
+        if self not in validateTrace:
+            tmp = validateTrace[:]+[self]
+            if self.expr is not None:
+                self.expr.validate(tmp)
+        self.checkRecursion([])
+
+    def __str__( self ):
+        if hasattr(self,"name"):
+            return self.name
+
+        self.__class__ = _ForwardNoRecurse
+        try:
+            if self.expr is not None:
+                retString = _ustr(self.expr)
+            else:
+                retString = "None"
+        finally:
+            self.__class__ = Forward
+        return "Forward: "+retString
+
+    def copy(self):
+        if self.expr is not None:
+            return super(Forward,self).copy()
+        else:
+            ret = Forward()
+            ret << self
+            return ret
+
+class _ForwardNoRecurse(Forward):
+    def __str__( self ):
+        return "..."
+
+class TokenConverter(ParseElementEnhance):
+    """Abstract subclass of ParseExpression, for converting parsed results."""
+    def __init__( self, expr, savelist=False ):
+        super(TokenConverter,self).__init__( expr )#, savelist )
+        self.saveAsList = False
+
+class Upcase(TokenConverter):
+    """Converter to upper case all matching tokens."""
+    def __init__(self, *args):
+        super(Upcase,self).__init__(*args)
+        warnings.warn("Upcase class is deprecated, use upcaseTokens parse action instead",
+                       DeprecationWarning,stacklevel=2)
+
+    def postParse( self, instring, loc, tokenlist ):
+        return list(map( string.upper, tokenlist ))
+
+
+class Combine(TokenConverter):
+    """Converter to concatenate all matching tokens to a single string.
+       By default, the matching patterns must also be contiguous in the input string;
+       this can be disabled by specifying 'adjacent=False' in the constructor.
+    """
+    def __init__( self, expr, joinString="", adjacent=True ):
+        super(Combine,self).__init__( expr )
+        # suppress whitespace-stripping in contained parse expressions, but re-enable it on the Combine itself
+        if adjacent:
+            self.leaveWhitespace()
+        self.adjacent = adjacent
+        self.skipWhitespace = True
+        self.joinString = joinString
+
+    def ignore( self, other ):
+        if self.adjacent:
+            ParserElement.ignore(self, other)
+        else:
+            super( Combine, self).ignore( other )
+        return self
+
+    def postParse( self, instring, loc, tokenlist ):
+        retToks = tokenlist.copy()
+        del retToks[:]
+        retToks += ParseResults([ "".join(tokenlist._asStringList(self.joinString)) ], modal=self.modalResults)
+
+        if self.resultsName and len(retToks.keys())>0:
+            return [ retToks ]
+        else:
+            return retToks
+
+class Group(TokenConverter):
+    """Converter to return the matched tokens as a list - useful for returning tokens of ZeroOrMore and OneOrMore expressions."""
+    def __init__( self, expr ):
+        super(Group,self).__init__( expr )
+        self.saveAsList = True
+
+    def postParse( self, instring, loc, tokenlist ):
+        return [ tokenlist ]
+
+class Dict(TokenConverter):
+    """Converter to return a repetitive expression as a list, but also as a dictionary.
+       Each element can also be referenced using the first token in the expression as its key.
+       Useful for tabular report scraping when the first column can be used as a item key.
+    """
+    def __init__( self, exprs ):
+        super(Dict,self).__init__( exprs )
+        self.saveAsList = True
+
+    def postParse( self, instring, loc, tokenlist ):
+        for i,tok in enumerate(tokenlist):
+            if len(tok) == 0:
+                continue
+            ikey = tok[0]
+            if isinstance(ikey,int):
+                ikey = _ustr(tok[0]).strip()
+            if len(tok)==1:
+                tokenlist[ikey] = _ParseResultsWithOffset("",i)
+            elif len(tok)==2 and not isinstance(tok[1],ParseResults):
+                tokenlist[ikey] = _ParseResultsWithOffset(tok[1],i)
+            else:
+                dictvalue = tok.copy() #ParseResults(i)
+                del dictvalue[0]
+                if len(dictvalue)!= 1 or (isinstance(dictvalue,ParseResults) and dictvalue.keys()):
+                    tokenlist[ikey] = _ParseResultsWithOffset(dictvalue,i)
+                else:
+                    tokenlist[ikey] = _ParseResultsWithOffset(dictvalue[0],i)
+
+        if self.resultsName:
+            return [ tokenlist ]
+        else:
+            return tokenlist
+
+
+class Suppress(TokenConverter):
+    """Converter for ignoring the results of a parsed expression."""
+    def postParse( self, instring, loc, tokenlist ):
+        return []
+
+    def suppress( self ):
+        return self
+
+
+class OnlyOnce(object):
+    """Wrapper for parse actions, to ensure they are only called once."""
+    def __init__(self, methodCall):
+        self.callable = ParserElement._normalizeParseActionArgs(methodCall)
+        self.called = False
+    def __call__(self,s,l,t):
+        if not self.called:
+            results = self.callable(s,l,t)
+            self.called = True
+            return results
+        raise ParseException(s,l,"")
+    def reset(self):
+        self.called = False
+
+def traceParseAction(f):
+    """Decorator for debugging parse actions."""
+    f = ParserElement._normalizeParseActionArgs(f)
+    def z(*paArgs):
+        thisFunc = f.func_name
+        s,l,t = paArgs[-3:]
+        if len(paArgs)>3:
+            thisFunc = paArgs[0].__class__.__name__ + '.' + thisFunc
+        sys.stderr.write( ">>entering %s(line: '%s', %d, %s)\n" % (thisFunc,line(l,s),l,t) )
+        try:
+            ret = f(*paArgs)
+        except Exception, exc:
+            sys.stderr.write( "<<leaving %s (exception: %s)\n" % (thisFunc,exc) )
+            raise
+        sys.stderr.write( "<<leaving %s (ret: %s)\n" % (thisFunc,ret) )
+        return ret
+    try:
+        z.__name__ = f.__name__
+    except AttributeError:
+        pass
+    return z
+
+#
+# global helpers
+#
+def delimitedList( expr, delim=",", combine=False ):
+    """Helper to define a delimited list of expressions - the delimiter defaults to ','.
+       By default, the list elements and delimiters can have intervening whitespace, and
+       comments, but this can be overridden by passing 'combine=True' in the constructor.
+       If combine is set to True, the matching tokens are returned as a single token
+       string, with the delimiters included; otherwise, the matching tokens are returned
+       as a list of tokens, with the delimiters suppressed.
+    """
+    dlName = _ustr(expr)+" ["+_ustr(delim)+" "+_ustr(expr)+"]..."
+    if combine:
+        return Combine( expr + ZeroOrMore( delim + expr ) ).setName(dlName)
+    else:
+        return ( expr + ZeroOrMore( Suppress( delim ) + expr ) ).setName(dlName)
+
+def countedArray( expr ):
+    """Helper to define a counted list of expressions.
+       This helper defines a pattern of the form::
+           integer expr expr expr...
+       where the leading integer tells how many expr expressions follow.
+       The matched tokens returns the array of expr tokens as a list - the leading count token is suppressed.
+    """
+    arrayExpr = Forward()
+    def countFieldParseAction(s,l,t):
+        n = int(t[0])
+        arrayExpr << (n and Group(And([expr]*n)) or Group(empty))
+        return []
+    return ( Word(nums).setName("arrayLen").setParseAction(countFieldParseAction, callDuringTry=True) + arrayExpr )
+
+def _flatten(L):
+    if type(L) is not list: return [L]
+    if L == []: return L
+    return _flatten(L[0]) + _flatten(L[1:])
+
+def matchPreviousLiteral(expr):
+    """Helper to define an expression that is indirectly defined from
+       the tokens matched in a previous expression, that is, it looks
+       for a 'repeat' of a previous expression.  For example::
+           first = Word(nums)
+           second = matchPreviousLiteral(first)
+           matchExpr = first + ":" + second
+       will match "1:1", but not "1:2".  Because this matches a
+       previous literal, will also match the leading "1:1" in "1:10".
+       If this is not desired, use matchPreviousExpr.
+       Do *not* use with packrat parsing enabled.
+    """
+    rep = Forward()
+    def copyTokenToRepeater(s,l,t):
+        if t:
+            if len(t) == 1:
+                rep << t[0]
+            else:
+                # flatten t tokens
+                tflat = _flatten(t.asList())
+                rep << And( [ Literal(tt) for tt in tflat ] )
+        else:
+            rep << Empty()
+    expr.addParseAction(copyTokenToRepeater, callDuringTry=True)
+    return rep
+
+def matchPreviousExpr(expr):
+    """Helper to define an expression that is indirectly defined from
+       the tokens matched in a previous expression, that is, it looks
+       for a 'repeat' of a previous expression.  For example::
+           first = Word(nums)
+           second = matchPreviousExpr(first)
+           matchExpr = first + ":" + second
+       will match "1:1", but not "1:2".  Because this matches by
+       expressions, will *not* match the leading "1:1" in "1:10";
+       the expressions are evaluated first, and then compared, so
+       "1" is compared with "10".
+       Do *not* use with packrat parsing enabled.
+    """
+    rep = Forward()
+    e2 = expr.copy()
+    rep << e2
+    def copyTokenToRepeater(s,l,t):
+        matchTokens = _flatten(t.asList())
+        def mustMatchTheseTokens(s,l,t):
+            theseTokens = _flatten(t.asList())
+            if  theseTokens != matchTokens:
+                raise ParseException("",0,"")
+        rep.setParseAction( mustMatchTheseTokens, callDuringTry=True )
+    expr.addParseAction(copyTokenToRepeater, callDuringTry=True)
+    return rep
+
+def _escapeRegexRangeChars(s):
+    #~  escape these chars: ^-]
+    for c in r"\^-]":
+        s = s.replace(c,"\\"+c)
+    s = s.replace("\n",r"\n")
+    s = s.replace("\t",r"\t")
+    return _ustr(s)
+
+def oneOf( strs, caseless=False, useRegex=True ):
+    """Helper to quickly define a set of alternative Literals, and makes sure to do
+       longest-first testing when there is a conflict, regardless of the input order,
+       but returns a MatchFirst for best performance.
+
+       Parameters:
+        - strs - a string of space-delimited literals, or a list of string literals
+        - caseless - (default=False) - treat all literals as caseless
+        - useRegex - (default=True) - as an optimization, will generate a Regex
+          object; otherwise, will generate a MatchFirst object (if caseless=True, or
+          if creating a Regex raises an exception)
+    """
+    if caseless:
+        isequal = ( lambda a,b: a.upper() == b.upper() )
+        masks = ( lambda a,b: b.upper().startswith(a.upper()) )
+        parseElementClass = CaselessLiteral
+    else:
+        isequal = ( lambda a,b: a == b )
+        masks = ( lambda a,b: b.startswith(a) )
+        parseElementClass = Literal
+
+    if isinstance(strs,(list,tuple)):
+        symbols = strs[:]
+    elif isinstance(strs,basestring):
+        symbols = strs.split()
+    else:
+        warnings.warn("Invalid argument to oneOf, expected string or list",
+                SyntaxWarning, stacklevel=2)
+
+    i = 0
+    while i < len(symbols)-1:
+        cur = symbols[i]
+        for j,other in enumerate(symbols[i+1:]):
+            if ( isequal(other, cur) ):
+                del symbols[i+j+1]
+                break
+            elif ( masks(cur, other) ):
+                del symbols[i+j+1]
+                symbols.insert(i,other)
+                cur = other
+                break
+        else:
+            i += 1
+
+    if not caseless and useRegex:
+        #~ print (strs,"->", "|".join( [ _escapeRegexChars(sym) for sym in symbols] ))
+        try:
+            if len(symbols)==len("".join(symbols)):
+                return Regex( "[%s]" % "".join( [ _escapeRegexRangeChars(sym) for sym in symbols] ) )
+            else:
+                return Regex( "|".join( [ re.escape(sym) for sym in symbols] ) )
+        except:
+            warnings.warn("Exception creating Regex for oneOf, building MatchFirst",
+                    SyntaxWarning, stacklevel=2)
+
+
+    # last resort, just use MatchFirst
+    return MatchFirst( [ parseElementClass(sym) for sym in symbols ] )
+
+def dictOf( key, value ):
+    """Helper to easily and clearly define a dictionary by specifying the respective patterns
+       for the key and value.  Takes care of defining the Dict, ZeroOrMore, and Group tokens
+       in the proper order.  The key pattern can include delimiting markers or punctuation,
+       as long as they are suppressed, thereby leaving the significant key text.  The value
+       pattern can include named results, so that the Dict results can include named token
+       fields.
+    """
+    return Dict( ZeroOrMore( Group ( key + value ) ) )
+
+# convenience constants for positional expressions
+empty       = Empty().setName("empty")
+lineStart   = LineStart().setName("lineStart")
+lineEnd     = LineEnd().setName("lineEnd")
+stringStart = StringStart().setName("stringStart")
+stringEnd   = StringEnd().setName("stringEnd")
+
+_escapedPunc = Word( _bslash, r"\[]-*.$+^?()~ ", exact=2 ).setParseAction(lambda s,l,t:t[0][1])
+_printables_less_backslash = "".join([ c for c in printables if c not in  r"\]" ])
+_escapedHexChar = Combine( Suppress(_bslash + "0x") + Word(hexnums) ).setParseAction(lambda s,l,t:unichr(int(t[0],16)))
+_escapedOctChar = Combine( Suppress(_bslash) + Word("0","01234567") ).setParseAction(lambda s,l,t:unichr(int(t[0],8)))
+_singleChar = _escapedPunc | _escapedHexChar | _escapedOctChar | Word(_printables_less_backslash,exact=1)
+_charRange = Group(_singleChar + Suppress("-") + _singleChar)
+_reBracketExpr = Literal("[") + Optional("^").setResultsName("negate") + Group( OneOrMore( _charRange | _singleChar ) ).setResultsName("body") + "]"
+
+_expanded = lambda p: (isinstance(p,ParseResults) and ''.join([ unichr(c) for c in range(ord(p[0]),ord(p[1])+1) ]) or p)
+
+def srange(s):
+    r"""Helper to easily define string ranges for use in Word construction.  Borrows
+       syntax from regexp '[]' string range definitions::
+          srange("[0-9]")   -> "0123456789"
+          srange("[a-z]")   -> "abcdefghijklmnopqrstuvwxyz"
+          srange("[a-z$_]") -> "abcdefghijklmnopqrstuvwxyz$_"
+       The input string must be enclosed in []'s, and the returned string is the expanded
+       character set joined into a single string.
+       The values enclosed in the []'s may be::
+          a single character
+          an escaped character with a leading backslash (such as \- or \])
+          an escaped hex character with a leading '\0x' (\0x21, which is a '!' character)
+          an escaped octal character with a leading '\0' (\041, which is a '!' character)
+          a range of any of the above, separated by a dash ('a-z', etc.)
+          any combination of the above ('aeiouy', 'a-zA-Z0-9_$', etc.)
+    """
+    try:
+        return "".join([_expanded(part) for part in _reBracketExpr.parseString(s).body])
+    except:
+        return ""
+
+def matchOnlyAtCol(n):
+    """Helper method for defining parse actions that require matching at a specific
+       column in the input text.
+    """
+    def verifyCol(strg,locn,toks):
+        if col(locn,strg) != n:
+            raise ParseException(strg,locn,"matched token not at column %d" % n)
+    return verifyCol
+
+def replaceWith(replStr):
+    """Helper method for common parse actions that simply return a literal value.  Especially
+       useful when used with transformString().
+    """
+    def _replFunc(*args):
+        return [replStr]
+    return _replFunc
+
+def removeQuotes(s,l,t):
+    """Helper parse action for removing quotation marks from parsed quoted strings.
+       To use, add this parse action to quoted string using::
+         quotedString.setParseAction( removeQuotes )
+    """
+    return t[0][1:-1]
+
+def upcaseTokens(s,l,t):
+    """Helper parse action to convert tokens to upper case."""
+    return [ tt.upper() for tt in map(_ustr,t) ]
+
+def downcaseTokens(s,l,t):
+    """Helper parse action to convert tokens to lower case."""
+    return [ tt.lower() for tt in map(_ustr,t) ]
+
+def keepOriginalText(s,startLoc,t):
+    """Helper parse action to preserve original parsed text,
+       overriding any nested parse actions."""
+    try:
+        endloc = getTokensEndLoc()
+    except ParseException:
+        raise ParseFatalException("incorrect usage of keepOriginalText - may only be called as a parse action")
+    del t[:]
+    t += ParseResults(s[startLoc:endloc])
+    return t
+
+def getTokensEndLoc():
+    """Method to be called from within a parse action to determine the end
+       location of the parsed tokens."""
+    import inspect
+    fstack = inspect.stack()
+    try:
+        # search up the stack (through intervening argument normalizers) for correct calling routine
+        for f in fstack[2:]:
+            if f[3] == "_parseNoCache":
+                endloc = f[0].f_locals["loc"]
+                return endloc
+        else:
+            raise ParseFatalException("incorrect usage of getTokensEndLoc - may only be called from within a parse action")
+    finally:
+        del fstack
+
+def _makeTags(tagStr, xml):
+    """Internal helper to construct opening and closing tag expressions, given a tag name"""
+    if isinstance(tagStr,basestring):
+        resname = tagStr
+        tagStr = Keyword(tagStr, caseless=not xml)
+    else:
+        resname = tagStr.name
+
+    tagAttrName = Word(alphas,alphanums+"_-:")
+    if (xml):
+        tagAttrValue = dblQuotedString.copy().setParseAction( removeQuotes )
+        openTag = Suppress("<") + tagStr + \
+                Dict(ZeroOrMore(Group( tagAttrName + Suppress("=") + tagAttrValue ))) + \
+                Optional("/",default=[False]).setResultsName("empty").setParseAction(lambda s,l,t:t[0]=='/') + Suppress(">")
+    else:
+        printablesLessRAbrack = "".join( [ c for c in printables if c not in ">" ] )
+        tagAttrValue = quotedString.copy().setParseAction( removeQuotes ) | Word(printablesLessRAbrack)
+        openTag = Suppress("<") + tagStr + \
+                Dict(ZeroOrMore(Group( tagAttrName.setParseAction(downcaseTokens) + \
+                Optional( Suppress("=") + tagAttrValue ) ))) + \
+                Optional("/",default=[False]).setResultsName("empty").setParseAction(lambda s,l,t:t[0]=='/') + Suppress(">")
+    closeTag = Combine(_L("</") + tagStr + ">")
+
+    openTag = openTag.setResultsName("start"+"".join(resname.replace(":"," ").title().split())).setName("<%s>" % tagStr)
+    closeTag = closeTag.setResultsName("end"+"".join(resname.replace(":"," ").title().split())).setName("</%s>" % tagStr)
+
+    return openTag, closeTag
+
+def makeHTMLTags(tagStr):
+    """Helper to construct opening and closing tag expressions for HTML, given a tag name"""
+    return _makeTags( tagStr, False )
+
+def makeXMLTags(tagStr):
+    """Helper to construct opening and closing tag expressions for XML, given a tag name"""
+    return _makeTags( tagStr, True )
+
+def withAttribute(*args,**attrDict):
+    """Helper to create a validating parse action to be used with start tags created
+       with makeXMLTags or makeHTMLTags. Use withAttribute to qualify a starting tag
+       with a required attribute value, to avoid false matches on common tags such as
+       <TD> or <DIV>.
+
+       Call withAttribute with a series of attribute names and values. Specify the list
+       of filter attributes names and values as:
+        - keyword arguments, as in (class="Customer",align="right"), or
+        - a list of name-value tuples, as in ( ("ns1:class", "Customer"), ("ns2:align","right") )
+       For attribute names with a namespace prefix, you must use the second form.  Attribute
+       names are matched insensitive to upper/lower case.
+
+       To verify that the attribute exists, but without specifying a value, pass
+       withAttribute.ANY_VALUE as the value.
+       """
+    if args:
+        attrs = args[:]
+    else:
+        attrs = attrDict.items()
+    attrs = [(k,v) for k,v in attrs]
+    def pa(s,l,tokens):
+        for attrName,attrValue in attrs:
+            if attrName not in tokens:
+                raise ParseException(s,l,"no matching attribute " + attrName)
+            if attrValue != withAttribute.ANY_VALUE and tokens[attrName] != attrValue:
+                raise ParseException(s,l,"attribute '%s' has value '%s', must be '%s'" %
+                                            (attrName, tokens[attrName], attrValue))
+    return pa
+withAttribute.ANY_VALUE = object()
+
+opAssoc = _Constants()
+opAssoc.LEFT = object()
+opAssoc.RIGHT = object()
+
+def operatorPrecedence( baseExpr, opList ):
+    """Helper method for constructing grammars of expressions made up of
+       operators working in a precedence hierarchy.  Operators may be unary or
+       binary, left- or right-associative.  Parse actions can also be attached
+       to operator expressions.
+
+       Parameters:
+        - baseExpr - expression representing the most basic element for the nested
+        - opList - list of tuples, one for each operator precedence level in the
+          expression grammar; each tuple is of the form
+          (opExpr, numTerms, rightLeftAssoc, parseAction), where:
+           - opExpr is the pyparsing expression for the operator;
+              may also be a string, which will be converted to a Literal;
+              if numTerms is 3, opExpr is a tuple of two expressions, for the
+              two operators separating the 3 terms
+           - numTerms is the number of terms for this operator (must
+              be 1, 2, or 3)
+           - rightLeftAssoc is the indicator whether the operator is
+              right or left associative, using the pyparsing-defined
+              constants opAssoc.RIGHT and opAssoc.LEFT.
+           - parseAction is the parse action to be associated with
+              expressions matching this operator expression (the
+              parse action tuple member may be omitted)
+    """
+    ret = Forward()
+    lastExpr = baseExpr | ( Suppress('(') + ret + Suppress(')') )
+    for i,operDef in enumerate(opList):
+        opExpr,arity,rightLeftAssoc,pa = (operDef + (None,))[:4]
+        if arity == 3:
+            if opExpr is None or len(opExpr) != 2:
+                raise ValueError("if numterms=3, opExpr must be a tuple or list of two expressions")
+            opExpr1, opExpr2 = opExpr
+        thisExpr = Forward()#.setName("expr%d" % i)
+        if rightLeftAssoc == opAssoc.LEFT:
+            if arity == 1:
+                matchExpr = FollowedBy(lastExpr + opExpr) + Group( lastExpr + OneOrMore( opExpr ) )
+            elif arity == 2:
+                if opExpr is not None:
+                    matchExpr = FollowedBy(lastExpr + opExpr + lastExpr) + Group( lastExpr + OneOrMore( opExpr + lastExpr ) )
+                else:
+                    matchExpr = FollowedBy(lastExpr+lastExpr) + Group( lastExpr + OneOrMore(lastExpr) )
+            elif arity == 3:
+                matchExpr = FollowedBy(lastExpr + opExpr1 + lastExpr + opExpr2 + lastExpr) + \
+                            Group( lastExpr + opExpr1 + lastExpr + opExpr2 + lastExpr )
+            else:
+                raise ValueError("operator must be unary (1), binary (2), or ternary (3)")
+        elif rightLeftAssoc == opAssoc.RIGHT:
+            if arity == 1:
+                # try to avoid LR with this extra test
+                if not isinstance(opExpr, Optional):
+                    opExpr = Optional(opExpr)
+                matchExpr = FollowedBy(opExpr.expr + thisExpr) + Group( opExpr + thisExpr )
+            elif arity == 2:
+                if opExpr is not None:
+                    matchExpr = FollowedBy(lastExpr + opExpr + thisExpr) + Group( lastExpr + OneOrMore( opExpr + thisExpr ) )
+                else:
+                    matchExpr = FollowedBy(lastExpr + thisExpr) + Group( lastExpr + OneOrMore( thisExpr ) )
+            elif arity == 3:
+                matchExpr = FollowedBy(lastExpr + opExpr1 + thisExpr + opExpr2 + thisExpr) + \
+                            Group( lastExpr + opExpr1 + thisExpr + opExpr2 + thisExpr )
+            else:
+                raise ValueError("operator must be unary (1), binary (2), or ternary (3)")
+        else:
+            raise ValueError("operator must indicate right or left associativity")
+        if pa:
+            matchExpr.setParseAction( pa )
+        thisExpr << ( matchExpr | lastExpr )
+        lastExpr = thisExpr
+    ret << lastExpr
+    return ret
+
+dblQuotedString = Regex(r'"(?:[^"\n\r\\]|(?:"")|(?:\\x[0-9a-fA-F]+)|(?:\\.))*"').setName("string enclosed in double quotes")
+sglQuotedString = Regex(r"'(?:[^'\n\r\\]|(?:'')|(?:\\x[0-9a-fA-F]+)|(?:\\.))*'").setName("string enclosed in single quotes")
+quotedString = Regex(r'''(?:"(?:[^"\n\r\\]|(?:"")|(?:\\x[0-9a-fA-F]+)|(?:\\.))*")|(?:'(?:[^'\n\r\\]|(?:'')|(?:\\x[0-9a-fA-F]+)|(?:\\.))*')''').setName("quotedString using single or double quotes")
+unicodeString = Combine(_L('u') + quotedString.copy())
+
+def nestedExpr(opener="(", closer=")", content=None, ignoreExpr=quotedString):
+    """Helper method for defining nested lists enclosed in opening and closing
+       delimiters ("(" and ")" are the default).
+
+       Parameters:
+        - opener - opening character for a nested list (default="("); can also be a pyparsing expression
+        - closer - closing character for a nested list (default=")"); can also be a pyparsing expression
+        - content - expression for items within the nested lists (default=None)
+        - ignoreExpr - expression for ignoring opening and closing delimiters (default=quotedString)
+
+       If an expression is not provided for the content argument, the nested
+       expression will capture all whitespace-delimited content between delimiters
+       as a list of separate values.
+
+       Use the ignoreExpr argument to define expressions that may contain
+       opening or closing characters that should not be treated as opening
+       or closing characters for nesting, such as quotedString or a comment
+       expression.  Specify multiple expressions using an Or or MatchFirst.
+       The default is quotedString, but if no expressions are to be ignored,
+       then pass None for this argument.
+    """
+    if opener == closer:
+        raise ValueError("opening and closing strings cannot be the same")
+    if content is None:
+        if isinstance(opener,basestring) and isinstance(closer,basestring):
+            if ignoreExpr is not None:
+                content = (Combine(OneOrMore(~ignoreExpr +
+                                CharsNotIn(opener+closer+ParserElement.DEFAULT_WHITE_CHARS,exact=1))
+                            ).setParseAction(lambda t:t[0].strip()))
+            else:
+                content = (empty+CharsNotIn(opener+closer+ParserElement.DEFAULT_WHITE_CHARS).setParseAction(lambda t:t[0].strip()))
+        else:
+            raise ValueError("opening and closing arguments must be strings if no content expression is given")
+    ret = Forward()
+    if ignoreExpr is not None:
+        ret << Group( Suppress(opener) + ZeroOrMore( ignoreExpr | ret | content ) + Suppress(closer) )
+    else:
+        ret << Group( Suppress(opener) + ZeroOrMore( ret | content )  + Suppress(closer) )
+    return ret
+
+def indentedBlock(blockStatementExpr, indentStack, indent=True):
+    """Helper method for defining space-delimited indentation blocks, such as 
+       those used to define block statements in Python source code.
+       
+       Parameters:
+        - blockStatementExpr - expression defining syntax of statement that 
+            is repeated within the indented block
+        - indentStack - list created by caller to manage indentation stack
+            (multiple statementWithIndentedBlock expressions within a single grammar
+            should share a common indentStack)
+        - indent - boolean indicating whether block must be indented beyond the 
+            the current level; set to False for block of left-most statements
+            (default=True)
+
+       A valid block must contain at least one blockStatement.
+    """
+    def checkPeerIndent(s,l,t):
+        if l >= len(s): return
+        curCol = col(l,s)
+        if curCol != indentStack[-1]:
+            if curCol > indentStack[-1]:
+                raise ParseFatalException(s,l,"illegal nesting")
+            raise ParseException(s,l,"not a peer entry")
+
+    def checkSubIndent(s,l,t):
+        curCol = col(l,s)
+        if curCol > indentStack[-1]:
+            indentStack.append( curCol )
+        else:
+            raise ParseException(s,l,"not a subentry")
+
+    def checkUnindent(s,l,t):
+        if l >= len(s): return
+        curCol = col(l,s)
+        if not(indentStack and curCol < indentStack[-1] and curCol <= indentStack[-2]):
+            raise ParseException(s,l,"not an unindent")
+        indentStack.pop()
+
+    NL = OneOrMore(LineEnd().setWhitespaceChars("\t ").suppress())
+    INDENT = Empty() + Empty().setParseAction(checkSubIndent)
+    PEER   = Empty().setParseAction(checkPeerIndent)
+    UNDENT = Empty().setParseAction(checkUnindent)
+    if indent:
+        smExpr = Group( Optional(NL) +
+            FollowedBy(blockStatementExpr) +
+            INDENT + (OneOrMore( PEER + Group(blockStatementExpr) + Optional(NL) )) + UNDENT)
+    else:
+        smExpr = Group( Optional(NL) +
+            (OneOrMore( PEER + Group(blockStatementExpr) + Optional(NL) )) )
+    blockStatementExpr.ignore("\\" + LineEnd())
+    return smExpr
+
+alphas8bit = srange(r"[\0xc0-\0xd6\0xd8-\0xf6\0xf8-\0xff]")
+punc8bit = srange(r"[\0xa1-\0xbf\0xd7\0xf7]")
+
+anyOpenTag,anyCloseTag = makeHTMLTags(Word(alphas,alphanums+"_:"))
+commonHTMLEntity = Combine(_L("&") + oneOf("gt lt amp nbsp quot").setResultsName("entity") +";")
+_htmlEntityMap = dict(zip("gt lt amp nbsp quot".split(),"><& '"))
+replaceHTMLEntity = lambda t : t.entity in _htmlEntityMap and _htmlEntityMap[t.entity] or None
+
+# it's easy to get these comment structures wrong - they're very common, so may as well make them available
+cStyleComment = Regex(r"/\*(?:[^*]*\*+)+?/").setName("C style comment")
+
+htmlComment = Regex(r"<!--[\s\S]*?-->")
+restOfLine = Regex(r".*").leaveWhitespace()
+dblSlashComment = Regex(r"\/\/(\\\n|.)*").setName("// comment")
+cppStyleComment = Regex(r"/(?:\*(?:[^*]*\*+)+?/|/[^\n]*(?:\n[^\n]*)*?(?:(?<!\\)|\Z))").setName("C++ style comment")
+
+javaStyleComment = cppStyleComment
+pythonStyleComment = Regex(r"#.*").setName("Python style comment")
+_noncomma = "".join( [ c for c in printables if c != "," ] )
+_commasepitem = Combine(OneOrMore(Word(_noncomma) +
+                                  Optional( Word(" \t") +
+                                            ~Literal(",") + ~LineEnd() ) ) ).streamline().setName("commaItem")
+commaSeparatedList = delimitedList( Optional( quotedString | _commasepitem, default="") ).setName("commaSeparatedList")
+
+
+if __name__ == "__main__":
+
+    def test( teststring ):
+        try:
+            tokens = simpleSQL.parseString( teststring )
+            tokenlist = tokens.asList()
+            print (teststring + "->"   + str(tokenlist))
+            print ("tokens = "         + str(tokens))
+            print ("tokens.columns = " + str(tokens.columns))
+            print ("tokens.tables = "  + str(tokens.tables))
+            print (tokens.asXML("SQL",True))
+        except ParseBaseException,err:
+            print (teststring + "->")
+            print (err.line)
+            print (" "*(err.column-1) + "^")
+            print (err)
+        print()
+
+    selectToken    = CaselessLiteral( "select" )
+    fromToken      = CaselessLiteral( "from" )
+
+    ident          = Word( alphas, alphanums + "_$" )
+    columnName     = delimitedList( ident, ".", combine=True ).setParseAction( upcaseTokens )
+    columnNameList = Group( delimitedList( columnName ) )#.setName("columns")
+    tableName      = delimitedList( ident, ".", combine=True ).setParseAction( upcaseTokens )
+    tableNameList  = Group( delimitedList( tableName ) )#.setName("tables")
+    simpleSQL      = ( selectToken + \
+                     ( '*' | columnNameList ).setResultsName( "columns" ) + \
+                     fromToken + \
+                     tableNameList.setResultsName( "tables" ) )
+
+    test( "SELECT * from XYZZY, ABC" )
+    test( "select * from SYS.XYZZY" )
+    test( "Select A from Sys.dual" )
+    test( "Select AA,BB,CC from Sys.dual" )
+    test( "Select A, B, C from Sys.dual" )
+    test( "Select A, B, C from Sys.dual" )
+    test( "Xelect A, B, C from Sys.dual" )
+    test( "Select A, B, C frox Sys.dual" )
+    test( "Select" )
+    test( "Select ^^^ frox Sys.dual" )
+    test( "Select A, B, C from Sys.dual, Table2   " )
diff --git a/lib/bx_extras/stats.py b/lib/bx_extras/stats.py
new file mode 100644
index 0000000..32b71e2
--- /dev/null
+++ b/lib/bx_extras/stats.py
@@ -0,0 +1,4344 @@
+# Copyright (c) 1999-2002 Gary Strangman; All Rights Reserved.
+#
+# This software is distributable under the terms of the GNU
+# General Public License (GPL) v2, the text of which can be found at
+# http://www.gnu.org/copyleft/gpl.html. Installing, importing or otherwise
+# using this module constitutes acceptance of the terms of this License.
+#
+# Disclaimer
+# 
+# This software is provided "as-is".  There are no expressed or implied
+# warranties of any kind, including, but not limited to, the warranties
+# of merchantability and fittness for a given application.  In no event
+# shall Gary Strangman be liable for any direct, indirect, incidental,
+# special, exemplary or consequential damages (including, but not limited
+# to, loss of use, data or profits, or business interruption) however
+# caused and on any theory of liability, whether in contract, strict
+# liability or tort (including negligence or otherwise) arising in any way
+# out of the use of this software, even if advised of the possibility of
+# such damage.
+#
+# Comments and/or additions are welcome (send e-mail to:
+# strang at nmr.mgh.harvard.edu).
+# 
+"""
+stats.py module
+
+(Requires pstat.py module.)
+
+#################################################
+#######  Written by:  Gary Strangman  ###########
+#######  Last modified:  May 10, 2002 ###########
+#################################################
+
+A collection of basic statistical functions for python.  The function
+names appear below.
+
+IMPORTANT:  There are really *3* sets of functions.  The first set has an 'l'
+prefix, which can be used with list or tuple arguments.  The second set has
+an 'a' prefix, which can accept NumPy array arguments.  These latter
+functions are defined only when NumPy is available on the system.  The third
+type has NO prefix (i.e., has the name that appears below).  Functions of
+this set are members of a "Dispatch" class, c/o David Ascher.  This class
+allows different functions to be called depending on the type of the passed
+arguments.  Thus, stats.mean is a member of the Dispatch class and
+stats.mean(range(20)) will call stats.lmean(range(20)) while
+stats.mean(Numeric.arange(20)) will call stats.amean(Numeric.arange(20)).
+This is a handy way to keep consistent function names when different
+argument types require different functions to be called.  Having
+implementated the Dispatch class, however, means that to get info on
+a given function, you must use the REAL function name ... that is
+"print stats.lmean.__doc__" or "print stats.amean.__doc__" work fine,
+while "print stats.mean.__doc__" will print the doc for the Dispatch
+class.  NUMPY FUNCTIONS ('a' prefix) generally have more argument options
+but should otherwise be consistent with the corresponding list functions.
+
+Disclaimers:  The function list is obviously incomplete and, worse, the
+functions are not optimized.  All functions have been tested (some more
+so than others), but they are far from bulletproof.  Thus, as with any
+free software, no warranty or guarantee is expressed or implied. :-)  A
+few extra functions that don't appear in the list below can be found by
+interested treasure-hunters.  These functions don't necessarily have
+both list and array versions but were deemed useful
+
+CENTRAL TENDENCY:  geometricmean
+                   harmonicmean
+                   mean
+                   median
+                   medianscore
+                   mode
+
+MOMENTS:  moment
+          variation
+          skew
+          kurtosis
+          skewtest   (for Numpy arrays only)
+          kurtosistest (for Numpy arrays only)
+          normaltest (for Numpy arrays only)
+
+ALTERED VERSIONS:  tmean  (for Numpy arrays only)
+                   tvar   (for Numpy arrays only)
+                   tmin   (for Numpy arrays only)
+                   tmax   (for Numpy arrays only)
+                   tstdev (for Numpy arrays only)
+                   tsem   (for Numpy arrays only)
+                   describe
+
+FREQUENCY STATS:  itemfreq
+                  scoreatpercentile
+                  percentileofscore
+                  histogram
+                  cumfreq
+                  relfreq
+
+VARIABILITY:  obrientransform
+              samplevar
+              samplestdev
+              signaltonoise (for Numpy arrays only)
+              var
+              stdev
+              sterr
+              sem
+              z
+              zs
+              zmap (for Numpy arrays only)
+
+TRIMMING FCNS:  threshold (for Numpy arrays only)
+                trimboth
+                trim1
+                round (round all vals to 'n' decimals; Numpy only)
+
+CORRELATION FCNS:  covariance  (for Numpy arrays only)
+                   correlation (for Numpy arrays only)
+                   paired
+                   pearsonr
+                   spearmanr
+                   pointbiserialr
+                   kendalltau
+                   linregress
+
+INFERENTIAL STATS:  ttest_1samp
+                    ttest_ind
+                    ttest_rel
+                    chisquare
+                    ks_2samp
+                    mannwhitneyu
+                    ranksums
+                    wilcoxont
+                    kruskalwallish
+                    friedmanchisquare
+
+PROBABILITY CALCS:  chisqprob
+                    erfcc
+                    zprob
+                    ksprob
+                    fprob
+                    betacf
+                    gammln 
+                    betai
+
+ANOVA FUNCTIONS:  F_oneway
+                  F_value
+
+SUPPORT FUNCTIONS:  writecc
+                    incr
+                    sign  (for Numpy arrays only)
+                    sum
+                    cumsum
+                    ss
+                    summult
+                    sumdiffsquared
+                    square_of_sums
+                    shellsort
+                    rankdata
+                    outputpairedstats
+                    findwithin
+"""
+## CHANGE LOG:
+## ===========
+## 02-11-19 ... fixed attest_ind and attest_rel for div-by-zero Overflows
+## 02-05-10 ... fixed lchisqprob indentation (failed when df=even)
+## 00-12-28 ... removed aanova() to separate module, fixed licensing to
+##                   match Python License, fixed doc string & imports
+## 00-04-13 ... pulled all "global" statements, except from aanova()
+##              added/fixed lots of documentation, removed io.py dependency
+##              changed to version 0.5
+## 99-11-13 ... added asign() function
+## 99-11-01 ... changed version to 0.4 ... enough incremental changes now
+## 99-10-25 ... added acovariance and acorrelation functions
+## 99-10-10 ... fixed askew/akurtosis to avoid divide-by-zero errors
+##              added aglm function (crude, but will be improved)
+## 99-10-04 ... upgraded acumsum, ass, asummult, asamplevar, avar, etc. to
+##                   all handle lists of 'dimension's and keepdims
+##              REMOVED ar0, ar2, ar3, ar4 and replaced them with around
+##              reinserted fixes for abetai to avoid math overflows
+## 99-09-05 ... rewrote achisqprob/aerfcc/aksprob/afprob/abetacf/abetai to
+##                   handle multi-dimensional arrays (whew!)
+## 99-08-30 ... fixed l/amoment, l/askew, l/akurtosis per D'Agostino (1990)
+##              added anormaltest per same reference
+##              re-wrote azprob to calc arrays of probs all at once
+## 99-08-22 ... edited attest_ind printing section so arrays could be rounded
+## 99-08-19 ... fixed amean and aharmonicmean for non-error(!) overflow on
+##                   short/byte arrays (mean of #s btw 100-300 = -150??)
+## 99-08-09 ... fixed asum so that the None case works for Byte arrays
+## 99-08-08 ... fixed 7/3 'improvement' to handle t-calcs on N-D arrays
+## 99-07-03 ... improved attest_ind, attest_rel (zero-division errortrap)
+## 99-06-24 ... fixed bug(?) in attest_ind (n1=a.shape[0])
+## 04/11/99 ... added asignaltonoise, athreshold functions, changed all
+##                   max/min in array section to N.maximum/N.minimum,
+##                   fixed square_of_sums to prevent integer overflow
+## 04/10/99 ... !!! Changed function name ... sumsquared ==> square_of_sums
+## 03/18/99 ... Added ar0, ar2, ar3 and ar4 rounding functions
+## 02/28/99 ... Fixed aobrientransform to return an array rather than a list
+## 01/15/99 ... Essentially ceased updating list-versions of functions (!!!)
+## 01/13/99 ... CHANGED TO VERSION 0.3
+##              fixed bug in a/lmannwhitneyu p-value calculation
+## 12/31/98 ... fixed variable-name bug in ldescribe
+## 12/19/98 ... fixed bug in findwithin (fcns needed pstat. prefix)
+## 12/16/98 ... changed amedianscore to return float (not array) for 1 score
+## 12/14/98 ... added atmin and atmax functions
+##              removed umath from import line (not needed)
+##              l/ageometricmean modified to reduce chance of overflows (take
+##                   nth root first, then multiply)
+## 12/07/98 ... added __version__variable (now 0.2)
+##              removed all 'stats.' from anova() fcn
+## 12/06/98 ... changed those functions (except shellsort) that altered
+##                   arguments in-place ... cumsum, ranksort, ...
+##              updated (and fixed some) doc-strings
+## 12/01/98 ... added anova() function (requires NumPy)
+##              incorporated Dispatch class
+## 11/12/98 ... added functionality to amean, aharmonicmean, ageometricmean
+##              added 'asum' function (added functionality to N.add.reduce)
+##              fixed both moment and amoment (two errors)
+##              changed name of skewness and askewness to skew and askew
+##              fixed (a)histogram (which sometimes counted points <lowerlimit)
+
+import pstat               # required 3rd party module
+import math, string, copy  # required python modules
+from types import *
+
+__version__ = 0.6
+
+############# DISPATCH CODE ##############
+
+
+class Dispatch:
+    """
+The Dispatch class, care of David Ascher, allows different functions to
+be called depending on the argument types.  This way, there can be one
+function name regardless of the argument type.  To access function doc
+in stats.py module, prefix the function with an 'l' or 'a' for list or
+array arguments, respectively.  That is, print stats.lmean.__doc__ or
+print stats.amean.__doc__ or whatever.
+"""
+
+    def __init__(self, *tuples):
+        self._dispatch = {}
+        for func, types in tuples:
+            for t in types:
+                if t in self._dispatch.keys():
+                    raise ValueError, "can't have two dispatches on "+str(t)
+                self._dispatch[t] = func
+        self._types = self._dispatch.keys()
+
+    def __call__(self, arg1, *args, **kw):
+        if type(arg1) not in self._types:
+            raise TypeError, "don't know how to dispatch %s arguments" %  type(arg1)
+        return apply(self._dispatch[type(arg1)], (arg1,) + args, kw)
+
+
+##########################################################################
+########################   LIST-BASED FUNCTIONS   ########################
+##########################################################################
+
+### Define these regardless
+
+####################################
+#######  CENTRAL TENDENCY  #########
+####################################
+
+def lgeometricmean (inlist):
+    """
+Calculates the geometric mean of the values in the passed list.
+That is:  n-th root of (x1 * x2 * ... * xn).  Assumes a '1D' list.
+
+Usage:   lgeometricmean(inlist)
+"""
+    mult = 1.0
+    one_over_n = 1.0/len(inlist)
+    for item in inlist:
+        mult = mult * pow(item,one_over_n)
+    return mult
+
+
+def lharmonicmean (inlist):
+    """
+Calculates the harmonic mean of the values in the passed list.
+That is:  n / (1/x1 + 1/x2 + ... + 1/xn).  Assumes a '1D' list.
+
+Usage:   lharmonicmean(inlist)
+"""
+    sum = 0
+    for item in inlist:
+        sum = sum + 1.0/item
+    return len(inlist) / sum
+
+
+def lmean (inlist):
+    """
+Returns the arithematic mean of the values in the passed list.
+Assumes a '1D' list, but will function on the 1st dim of an array(!).
+
+Usage:   lmean(inlist)
+"""
+    sum = 0
+    for item in inlist:
+        sum = sum + item
+    return sum/float(len(inlist))
+
+
+def lmedian (inlist,numbins=1000):
+    """
+Returns the computed median value of a list of numbers, given the
+number of bins to use for the histogram (more bins brings the computed value
+closer to the median score, default number of bins = 1000).  See G.W.
+Heiman's Basic Stats (1st Edition), or CRC Probability & Statistics.
+
+Usage:   lmedian (inlist, numbins=1000)
+"""
+    (hist, smallest, binsize, extras) = histogram(inlist,numbins) # make histog
+    cumhist = cumsum(hist)              # make cumulative histogram
+    for i in range(len(cumhist)):        # get 1st(!) index holding 50%ile score
+        if cumhist[i]>=len(inlist)/2.0:
+            cfbin = i
+            break
+    LRL = smallest + binsize*cfbin        # get lower read limit of that bin
+    cfbelow = cumhist[cfbin-1]
+    freq = float(hist[cfbin])                # frequency IN the 50%ile bin
+    median = LRL + ((len(inlist)/2.0 - cfbelow)/float(freq))*binsize  # median formula
+    return median
+
+
+def lmedianscore (inlist):
+    """
+Returns the 'middle' score of the passed list.  If there is an even
+number of scores, the mean of the 2 middle scores is returned.
+
+Usage:   lmedianscore(inlist)
+"""
+
+    newlist = copy.deepcopy(inlist)
+    newlist.sort()
+    if len(newlist) % 2 == 0:   # if even number of scores, average middle 2
+        index = len(newlist)/2  # integer division correct
+        median = float(newlist[index] + newlist[index-1]) /2
+    else:
+        index = len(newlist)/2  # int divsion gives mid value when count from 0
+        median = newlist[index]
+    return median
+
+
+def lmode(inlist):
+    """
+Returns a list of the modal (most common) score(s) in the passed
+list.  If there is more than one such score, all are returned.  The
+bin-count for the mode(s) is also returned.
+
+Usage:   lmode(inlist)
+Returns: bin-count for mode(s), a list of modal value(s)
+"""
+
+    scores = pstat.unique(inlist)
+    scores.sort()
+    freq = []
+    for item in scores:
+        freq.append(inlist.count(item))
+    maxfreq = max(freq)
+    mode = []
+    stillmore = 1
+    while stillmore:
+        try:
+            indx = freq.index(maxfreq)
+            mode.append(scores[indx])
+            del freq[indx]
+            del scores[indx]
+        except ValueError:
+            stillmore=0
+    return maxfreq, mode
+
+
+####################################
+############  MOMENTS  #############
+####################################
+
+def lmoment(inlist,moment=1):
+    """
+Calculates the nth moment about the mean for a sample (defaults to
+the 1st moment).  Used to calculate coefficients of skewness and kurtosis.
+
+Usage:   lmoment(inlist,moment=1)
+Returns: appropriate moment (r) from ... 1/n * SUM((inlist(i)-mean)**r)
+"""
+    if moment == 1:
+        return 0.0
+    else:
+        mn = mean(inlist)
+        n = len(inlist)
+        s = 0
+        for x in inlist:
+            s = s + (x-mn)**moment
+        return s/float(n)
+
+
+def lvariation(inlist):
+    """
+Returns the coefficient of variation, as defined in CRC Standard
+Probability and Statistics, p.6.
+
+Usage:   lvariation(inlist)
+"""
+    return 100.0*samplestdev(inlist)/float(mean(inlist))
+
+
+def lskew(inlist):
+    """
+Returns the skewness of a distribution, as defined in Numerical
+Recipies (alternate defn in CRC Standard Probability and Statistics, p.6.)
+
+Usage:   lskew(inlist)
+"""
+    return moment(inlist,3)/pow(moment(inlist,2),1.5)
+
+
+def lkurtosis(inlist):
+    """
+Returns the kurtosis of a distribution, as defined in Numerical
+Recipies (alternate defn in CRC Standard Probability and Statistics, p.6.)
+
+Usage:   lkurtosis(inlist)
+"""
+    return moment(inlist,4)/pow(moment(inlist,2),2.0)
+
+
+def ldescribe(inlist):
+    """
+Returns some descriptive statistics of the passed list (assumed to be 1D).
+
+Usage:   ldescribe(inlist)
+Returns: n, mean, standard deviation, skew, kurtosis
+"""
+    n = len(inlist)
+    mm = (min(inlist),max(inlist))
+    m = mean(inlist)
+    sd = stdev(inlist)
+    sk = skew(inlist)
+    kurt = kurtosis(inlist)
+    return n, mm, m, sd, sk, kurt
+
+
+####################################
+#######  FREQUENCY STATS  ##########
+####################################
+
+def litemfreq(inlist):
+    """
+Returns a list of pairs.  Each pair consists of one of the scores in inlist
+and it's frequency count.  Assumes a 1D list is passed.
+
+Usage:   litemfreq(inlist)
+Returns: a 2D frequency table (col [0:n-1]=scores, col n=frequencies)
+"""
+    scores = pstat.unique(inlist)
+    scores.sort()
+    freq = []
+    for item in scores:
+        freq.append(inlist.count(item))
+    return pstat.abut(scores, freq)
+
+
+def lscoreatpercentile (inlist, percent):
+    """
+Returns the score at a given percentile relative to the distribution
+given by inlist.
+
+Usage:   lscoreatpercentile(inlist,percent)
+"""
+    if percent > 1:
+        print "\nDividing percent>1 by 100 in lscoreatpercentile().\n"
+        percent = percent / 100.0
+    targetcf = percent*len(inlist)
+    h, lrl, binsize, extras = histogram(inlist)
+    cumhist = cumsum(copy.deepcopy(h))
+    for i in range(len(cumhist)):
+        if cumhist[i] >= targetcf:
+            break
+    score = binsize * ((targetcf - cumhist[i-1]) / float(h[i])) + (lrl+binsize*i)
+    return score
+
+
+def lpercentileofscore (inlist, score,histbins=10,defaultlimits=None):
+    """
+Returns the percentile value of a score relative to the distribution
+given by inlist.  Formula depends on the values used to histogram the data(!).
+
+Usage:   lpercentileofscore(inlist,score,histbins=10,defaultlimits=None)
+"""
+
+    h, lrl, binsize, extras = histogram(inlist,histbins,defaultlimits)
+    cumhist = cumsum(copy.deepcopy(h))
+    i = int((score - lrl)/float(binsize))
+    pct = (cumhist[i-1]+((score-(lrl+binsize*i))/float(binsize))*h[i])/float(len(inlist)) * 100
+    return pct
+
+
+def lhistogram (inlist,numbins=10,defaultreallimits=None,printextras=0):
+    """
+Returns (i) a list of histogram bin counts, (ii) the smallest value
+of the histogram binning, and (iii) the bin width (the last 2 are not
+necessarily integers).  Default number of bins is 10.  If no sequence object
+is given for defaultreallimits, the routine picks (usually non-pretty) bins
+spanning all the numbers in the inlist.
+
+Usage:   lhistogram (inlist, numbins=10, defaultreallimits=None,suppressoutput=0)
+Returns: list of bin values, lowerreallimit, binsize, extrapoints
+"""
+    if (defaultreallimits <> None):
+        if type(defaultreallimits) not in [ListType,TupleType] or len(defaultreallimits)==1: # only one limit given, assumed to be lower one & upper is calc'd
+            lowerreallimit = defaultreallimits
+            upperreallimit = 1.0001 * max(inlist)
+        else: # assume both limits given
+            lowerreallimit = defaultreallimits[0]
+            upperreallimit = defaultreallimits[1]
+        binsize = (upperreallimit-lowerreallimit)/float(numbins)
+    else:     # no limits given for histogram, both must be calc'd
+        estbinwidth=(max(inlist)-min(inlist))/float(numbins) + 1 # 1=>cover all
+        binsize = ((max(inlist)-min(inlist)+estbinwidth))/float(numbins)
+        lowerreallimit = min(inlist) - binsize/2 #lower real limit,1st bin
+    bins = [0]*(numbins)
+    extrapoints = 0
+    for num in inlist:
+        try:
+            if (num-lowerreallimit) < 0:
+                extrapoints = extrapoints + 1
+            else:
+                bintoincrement = int((num-lowerreallimit)/float(binsize))
+                bins[bintoincrement] = bins[bintoincrement] + 1
+        except:
+            extrapoints = extrapoints + 1
+    if (extrapoints > 0 and printextras == 1):
+        print '\nPoints outside given histogram range =',extrapoints
+    return (bins, lowerreallimit, binsize, extrapoints)
+
+
+def lcumfreq(inlist,numbins=10,defaultreallimits=None):
+    """
+Returns a cumulative frequency histogram, using the histogram function.
+
+Usage:   lcumfreq(inlist,numbins=10,defaultreallimits=None)
+Returns: list of cumfreq bin values, lowerreallimit, binsize, extrapoints
+"""
+    h,l,b,e = histogram(inlist,numbins,defaultreallimits)
+    cumhist = cumsum(copy.deepcopy(h))
+    return cumhist,l,b,e
+
+
+def lrelfreq(inlist,numbins=10,defaultreallimits=None):
+    """
+Returns a relative frequency histogram, using the histogram function.
+
+Usage:   lrelfreq(inlist,numbins=10,defaultreallimits=None)
+Returns: list of cumfreq bin values, lowerreallimit, binsize, extrapoints
+"""
+    h,l,b,e = histogram(inlist,numbins,defaultreallimits)
+    for i in range(len(h)):
+        h[i] = h[i]/float(len(inlist))
+    return h,l,b,e
+
+
+####################################
+#####  VARIABILITY FUNCTIONS  ######
+####################################
+
+def lobrientransform(*args):
+    """
+Computes a transform on input data (any number of columns).  Used to
+test for homogeneity of variance prior to running one-way stats.  From
+Maxwell and Delaney, p.112.
+
+Usage:   lobrientransform(*args)
+Returns: transformed data for use in an ANOVA
+"""
+    TINY = 1e-10
+    k = len(args)
+    n = [0.0]*k
+    v = [0.0]*k
+    m = [0.0]*k
+    nargs = []
+    for i in range(k):
+        nargs.append(copy.deepcopy(args[i]))
+        n[i] = float(len(nargs[i]))
+        v[i] = var(nargs[i])
+        m[i] = mean(nargs[i])
+    for j in range(k):
+        for i in range(n[j]):
+            t1 = (n[j]-1.5)*n[j]*(nargs[j][i]-m[j])**2
+            t2 = 0.5*v[j]*(n[j]-1.0)
+            t3 = (n[j]-1.0)*(n[j]-2.0)
+            nargs[j][i] = (t1-t2) / float(t3)
+    check = 1
+    for j in range(k):
+        if v[j] - mean(nargs[j]) > TINY:
+            check = 0
+    if check <> 1:
+        raise ValueError, 'Problem in obrientransform.'
+    else:
+        return nargs
+
+
+def lsamplevar (inlist):
+    """
+Returns the variance of the values in the passed list using
+N for the denominator (i.e., DESCRIBES the sample variance only).
+
+Usage:   lsamplevar(inlist)
+"""
+    n = len(inlist)
+    mn = mean(inlist)
+    deviations = []
+    for item in inlist:
+        deviations.append(item-mn)
+    return ss(deviations)/float(n)
+
+
+def lsamplestdev (inlist):
+    """
+Returns the standard deviation of the values in the passed list using
+N for the denominator (i.e., DESCRIBES the sample stdev only).
+
+Usage:   lsamplestdev(inlist)
+"""
+    return math.sqrt(samplevar(inlist))
+
+
+def lvar (inlist):
+    """
+Returns the variance of the values in the passed list using N-1
+for the denominator (i.e., for estimating population variance).
+
+Usage:   lvar(inlist)
+"""
+    n = len(inlist)
+    mn = mean(inlist)
+    deviations = [0]*len(inlist)
+    for i in range(len(inlist)):
+        deviations[i] = inlist[i] - mn
+    return ss(deviations)/float(n-1)
+
+
+def lstdev (inlist):
+    """
+Returns the standard deviation of the values in the passed list
+using N-1 in the denominator (i.e., to estimate population stdev).
+
+Usage:   lstdev(inlist)
+"""
+    return math.sqrt(var(inlist))
+
+
+def lsterr(inlist):
+    """
+Returns the standard error of the values in the passed list using N-1
+in the denominator (i.e., to estimate population standard error).
+
+Usage:   lsterr(inlist)
+"""
+    return stdev(inlist) / float(math.sqrt(len(inlist)))
+
+
+def lsem (inlist):
+    """
+Returns the estimated standard error of the mean (sx-bar) of the
+values in the passed list.  sem = stdev / sqrt(n)
+
+Usage:   lsem(inlist)
+"""
+    sd = stdev(inlist)
+    n = len(inlist)
+    return sd/math.sqrt(n)
+
+
+def lz (inlist, score):
+    """
+Returns the z-score for a given input score, given that score and the
+list from which that score came.  Not appropriate for population calculations.
+
+Usage:   lz(inlist, score)
+"""
+    z = (score-mean(inlist))/samplestdev(inlist)
+    return z
+
+
+def lzs (inlist):
+    """
+Returns a list of z-scores, one for each score in the passed list.
+
+Usage:   lzs(inlist)
+"""
+    zscores = []
+    for item in inlist:
+        zscores.append(z(inlist,item))
+    return zscores
+
+
+####################################
+#######  TRIMMING FUNCTIONS  #######
+####################################
+
+def ltrimboth (l,proportiontocut):
+    """
+Slices off the passed proportion of items from BOTH ends of the passed
+list (i.e., with proportiontocut=0.1, slices 'leftmost' 10% AND 'rightmost'
+10% of scores.  Assumes list is sorted by magnitude.  Slices off LESS if
+proportion results in a non-integer slice index (i.e., conservatively
+slices off proportiontocut).
+
+Usage:   ltrimboth (l,proportiontocut)
+Returns: trimmed version of list l
+"""
+    lowercut = int(proportiontocut*len(l))
+    uppercut = len(l) - lowercut
+    return l[lowercut:uppercut]
+
+
+def ltrim1 (l,proportiontocut,tail='right'):
+    """
+Slices off the passed proportion of items from ONE end of the passed
+list (i.e., if proportiontocut=0.1, slices off 'leftmost' or 'rightmost'
+10% of scores).  Slices off LESS if proportion results in a non-integer
+slice index (i.e., conservatively slices off proportiontocut).
+
+Usage:   ltrim1 (l,proportiontocut,tail='right')  or set tail='left'
+Returns: trimmed version of list l
+"""
+    if tail == 'right':
+        lowercut = 0
+        uppercut = len(l) - int(proportiontocut*len(l))
+    elif tail == 'left':
+        lowercut = int(proportiontocut*len(l))
+        uppercut = len(l)
+    return l[lowercut:uppercut]
+
+
+####################################
+#####  CORRELATION FUNCTIONS  ######
+####################################
+
+def lpaired(x,y):
+    """
+Interactively determines the type of data and then runs the
+appropriated statistic for paired group data.
+
+Usage:   lpaired(x,y)
+Returns: appropriate statistic name, value, and probability
+"""
+    samples = ''
+    while samples not in ['i','r','I','R','c','C']:
+        print '\nIndependent or related samples, or correlation (i,r,c): ',
+        samples = raw_input()
+
+    if samples in ['i','I','r','R']:
+        print '\nComparing variances ...',
+# USE O'BRIEN'S TEST FOR HOMOGENEITY OF VARIANCE, Maxwell & delaney, p.112
+        r = obrientransform(x,y)
+        f,p = F_oneway(pstat.colex(r,0),pstat.colex(r,1))
+        if p<0.05:
+            vartype='unequal, p='+str(round(p,4))
+        else:
+            vartype='equal'
+        print vartype
+        if samples in ['i','I']:
+            if vartype[0]=='e':
+                t,p = ttest_ind(x,y,0)
+                print '\nIndependent samples t-test:  ', round(t,4),round(p,4)
+            else:
+                if len(x)>20 or len(y)>20:
+                    z,p = ranksums(x,y)
+                    print '\nRank Sums test (NONparametric, n>20):  ', round(z,4),round(p,4)
+                else:
+                    u,p = mannwhitneyu(x,y)
+                    print '\nMann-Whitney U-test (NONparametric, ns<20):  ', round(u,4),round(p,4)
+
+        else:  # RELATED SAMPLES
+            if vartype[0]=='e':
+                t,p = ttest_rel(x,y,0)
+                print '\nRelated samples t-test:  ', round(t,4),round(p,4)
+            else:
+                t,p = ranksums(x,y)
+                print '\nWilcoxon T-test (NONparametric):  ', round(t,4),round(p,4)
+    else:  # CORRELATION ANALYSIS
+        corrtype = ''
+        while corrtype not in ['c','C','r','R','d','D']:
+            print '\nIs the data Continuous, Ranked, or Dichotomous (c,r,d): ',
+            corrtype = raw_input()
+        if corrtype in ['c','C']:
+            m,b,r,p,see = linregress(x,y)
+            print '\nLinear regression for continuous variables ...'
+            lol = [['Slope','Intercept','r','Prob','SEestimate'],[round(m,4),round(b,4),round(r,4),round(p,4),round(see,4)]]
+            pstat.printcc(lol)
+        elif corrtype in ['r','R']:
+            r,p = spearmanr(x,y)
+            print '\nCorrelation for ranked variables ...'
+            print "Spearman's r: ",round(r,4),round(p,4)
+        else: # DICHOTOMOUS
+            r,p = pointbiserialr(x,y)
+            print '\nAssuming x contains a dichotomous variable ...'
+            print 'Point Biserial r: ',round(r,4),round(p,4)
+    print '\n\n'
+    return None
+
+
+def lpearsonr(x,y):
+    """
+Calculates a Pearson correlation coefficient and the associated
+probability value.  Taken from Heiman's Basic Statistics for the Behav.
+Sci (2nd), p.195.
+
+Usage:   lpearsonr(x,y)      where x and y are equal-length lists
+Returns: Pearson's r value, two-tailed p-value
+"""
+    TINY = 1.0e-30
+    if len(x) <> len(y):
+        raise ValueError, 'Input values not paired in pearsonr.  Aborting.'
+    n = len(x)
+    x = map(float,x)
+    y = map(float,y)
+    xmean = mean(x)
+    ymean = mean(y)
+    r_num = n*(summult(x,y)) - sum(x)*sum(y)
+    r_den = math.sqrt((n*ss(x) - square_of_sums(x))*(n*ss(y)-square_of_sums(y)))
+    r = (r_num / r_den)  # denominator already a float
+    df = n-2
+    t = r*math.sqrt(df/((1.0-r+TINY)*(1.0+r+TINY)))
+    prob = betai(0.5*df,0.5,df/float(df+t*t))
+    return r, prob
+
+
+def lspearmanr(x,y):
+    """
+Calculates a Spearman rank-order correlation coefficient.  Taken
+from Heiman's Basic Statistics for the Behav. Sci (1st), p.192.
+
+Usage:   lspearmanr(x,y)      where x and y are equal-length lists
+Returns: Spearman's r, two-tailed p-value
+"""
+    TINY = 1e-30
+    if len(x) <> len(y):
+        raise ValueError, 'Input values not paired in spearmanr.  Aborting.'
+    n = len(x)
+    rankx = rankdata(x)
+    ranky = rankdata(y)
+    dsq = sumdiffsquared(rankx,ranky)
+    rs = 1 - 6*dsq / float(n*(n**2-1))
+    t = rs * math.sqrt((n-2) / ((rs+1.0)*(1.0-rs)))
+    df = n-2
+    probrs = betai(0.5*df,0.5,df/(df+t*t))  # t already a float
+# probability values for rs are from part 2 of the spearman function in
+# Numerical Recipies, p.510.  They are close to tables, but not exact. (?)
+    return rs, probrs
+
+
+def lpointbiserialr(x,y):
+    """
+Calculates a point-biserial correlation coefficient and the associated
+probability value.  Taken from Heiman's Basic Statistics for the Behav.
+Sci (1st), p.194.
+
+Usage:   lpointbiserialr(x,y)      where x,y are equal-length lists
+Returns: Point-biserial r, two-tailed p-value
+"""
+    TINY = 1e-30
+    if len(x) <> len(y):
+        raise ValueError, 'INPUT VALUES NOT PAIRED IN pointbiserialr.  ABORTING.'
+    data = pstat.abut(x,y)
+    categories = pstat.unique(x)
+    if len(categories) <> 2:
+        raise ValueError, "Exactly 2 categories required for pointbiserialr()."
+    else:   # there are 2 categories, continue
+        codemap = pstat.abut(categories,range(2))
+        recoded = pstat.recode(data,codemap,0)
+        x = pstat.linexand(data,0,categories[0])
+        y = pstat.linexand(data,0,categories[1])
+        xmean = mean(pstat.colex(x,1))
+        ymean = mean(pstat.colex(y,1))
+        n = len(data)
+        adjust = math.sqrt((len(x)/float(n))*(len(y)/float(n)))
+        rpb = (ymean - xmean)/samplestdev(pstat.colex(data,1))*adjust
+        df = n-2
+        t = rpb*math.sqrt(df/((1.0-rpb+TINY)*(1.0+rpb+TINY)))
+        prob = betai(0.5*df,0.5,df/(df+t*t))  # t already a float
+        return rpb, prob
+
+
+def lkendalltau(x,y):
+    """
+Calculates Kendall's tau ... correlation of ordinal data.  Adapted
+from function kendl1 in Numerical Recipies.  Needs good test-routine.@@@
+
+Usage:   lkendalltau(x,y)
+Returns: Kendall's tau, two-tailed p-value
+"""
+    n1 = 0
+    n2 = 0
+    iss = 0
+    for j in range(len(x)-1):
+        for k in range(j,len(y)):
+            a1 = x[j] - x[k]
+            a2 = y[j] - y[k]
+            aa = a1 * a2
+            if (aa):             # neither list has a tie
+                n1 = n1 + 1
+                n2 = n2 + 1
+                if aa > 0:
+                    iss = iss + 1
+                else:
+                    iss = iss -1
+            else:
+                if (a1):
+                    n1 = n1 + 1
+                else:
+                    n2 = n2 + 1
+    tau = iss / math.sqrt(n1*n2)
+    svar = (4.0*len(x)+10.0) / (9.0*len(x)*(len(x)-1))
+    z = tau / math.sqrt(svar)
+    prob = erfcc(abs(z)/1.4142136)
+    return tau, prob
+
+
+def llinregress(x,y):
+    """
+Calculates a regression line on x,y pairs.  
+
+Usage:   llinregress(x,y)      x,y are equal-length lists of x-y coordinates
+Returns: slope, intercept, r, two-tailed prob, sterr-of-estimate
+"""
+    TINY = 1.0e-20
+    if len(x) <> len(y):
+        raise ValueError, 'Input values not paired in linregress.  Aborting.'
+    n = len(x)
+    x = map(float,x)
+    y = map(float,y)
+    xmean = mean(x)
+    ymean = mean(y)
+    r_num = float(n*(summult(x,y)) - sum(x)*sum(y))
+    r_den = math.sqrt((n*ss(x) - square_of_sums(x))*(n*ss(y)-square_of_sums(y)))
+    r = r_num / r_den
+    z = 0.5*math.log((1.0+r+TINY)/(1.0-r+TINY))
+    df = n-2
+    t = r*math.sqrt(df/((1.0-r+TINY)*(1.0+r+TINY)))
+    prob = betai(0.5*df,0.5,df/(df+t*t))
+    slope = r_num / float(n*ss(x) - square_of_sums(x))
+    intercept = ymean - slope*xmean
+    sterrest = math.sqrt(1-r*r)*samplestdev(y)
+    return slope, intercept, r, prob, sterrest
+
+
+####################################
+#####  INFERENTIAL STATISTICS  #####
+####################################
+
+def lttest_1samp(a,popmean,printit=0,name='Sample',writemode='a'):
+    """
+Calculates the t-obtained for the independent samples T-test on ONE group
+of scores a, given a population mean.  If printit=1, results are printed
+to the screen.  If printit='filename', the results are output to 'filename'
+using the given writemode (default=append).  Returns t-value, and prob.
+
+Usage:   lttest_1samp(a,popmean,Name='Sample',printit=0,writemode='a')
+Returns: t-value, two-tailed prob
+"""
+    x = mean(a)
+    v = var(a)
+    n = len(a)
+    df = n-1
+    svar = ((n-1)*v)/float(df)
+    t = (x-popmean)/math.sqrt(svar*(1.0/n))
+    prob = betai(0.5*df,0.5,float(df)/(df+t*t))
+
+    if printit <> 0:
+        statname = 'Single-sample T-test.'
+        outputpairedstats(printit,writemode,
+                          'Population','--',popmean,0,0,0,
+                          name,n,x,v,min(a),max(a),
+                          statname,t,prob)
+    return t,prob
+
+
+def lttest_ind (a, b, printit=0, name1='Samp1', name2='Samp2', writemode='a'):
+    """
+Calculates the t-obtained T-test on TWO INDEPENDENT samples of
+scores a, and b.  From Numerical Recipies, p.483.  If printit=1, results
+are printed to the screen.  If printit='filename', the results are output
+to 'filename' using the given writemode (default=append).  Returns t-value,
+and prob.
+
+Usage:   lttest_ind(a,b,printit=0,name1='Samp1',name2='Samp2',writemode='a')
+Returns: t-value, two-tailed prob
+"""
+    x1 = mean(a)
+    x2 = mean(b)
+    v1 = stdev(a)**2
+    v2 = stdev(b)**2
+    n1 = len(a)
+    n2 = len(b)
+    df = n1+n2-2
+    svar = ((n1-1)*v1+(n2-1)*v2)/float(df)
+    t = (x1-x2)/math.sqrt(svar*(1.0/n1 + 1.0/n2))
+    prob = betai(0.5*df,0.5,df/(df+t*t))
+
+    if printit <> 0:
+        statname = 'Independent samples T-test.'
+        outputpairedstats(printit,writemode,
+                          name1,n1,x1,v1,min(a),max(a),
+                          name2,n2,x2,v2,min(b),max(b),
+                          statname,t,prob)
+    return t,prob
+
+
+def lttest_rel (a,b,printit=0,name1='Sample1',name2='Sample2',writemode='a'):
+    """
+Calculates the t-obtained T-test on TWO RELATED samples of scores,
+a and b.  From Numerical Recipies, p.483.  If printit=1, results are
+printed to the screen.  If printit='filename', the results are output to
+'filename' using the given writemode (default=append).  Returns t-value,
+and prob.
+
+Usage:   lttest_rel(a,b,printit=0,name1='Sample1',name2='Sample2',writemode='a')
+Returns: t-value, two-tailed prob
+"""
+    if len(a)<>len(b):
+        raise ValueError, 'Unequal length lists in ttest_rel.'
+    x1 = mean(a)
+    x2 = mean(b)
+    v1 = var(a)
+    v2 = var(b)
+    n = len(a)
+    cov = 0
+    for i in range(len(a)):
+        cov = cov + (a[i]-x1) * (b[i]-x2)
+    df = n-1
+    cov = cov / float(df)
+    sd = math.sqrt((v1+v2 - 2.0*cov)/float(n))
+    t = (x1-x2)/sd
+    prob = betai(0.5*df,0.5,df/(df+t*t))
+
+    if printit <> 0:
+        statname = 'Related samples T-test.'
+        outputpairedstats(printit,writemode,
+                          name1,n,x1,v1,min(a),max(a),
+                          name2,n,x2,v2,min(b),max(b),
+                          statname,t,prob)
+    return t, prob
+
+
+def lchisquare(f_obs,f_exp=None):
+    """
+Calculates a one-way chi square for list of observed frequencies and returns
+the result.  If no expected frequencies are given, the total N is assumed to
+be equally distributed across all groups.
+
+Usage:   lchisquare(f_obs, f_exp=None)   f_obs = list of observed cell freq.
+Returns: chisquare-statistic, associated p-value
+"""
+    k = len(f_obs)                 # number of groups
+    if f_exp == None:
+        f_exp = [sum(f_obs)/float(k)] * len(f_obs) # create k bins with = freq.
+    chisq = 0
+    for i in range(len(f_obs)):
+        chisq = chisq + (f_obs[i]-f_exp[i])**2 / float(f_exp[i])
+    return chisq, chisqprob(chisq, k-1)
+
+
+def lks_2samp (data1,data2):
+    """
+Computes the Kolmogorov-Smirnof statistic on 2 samples.  From
+Numerical Recipies in C, page 493.
+
+Usage:   lks_2samp(data1,data2)   data1&2 are lists of values for 2 conditions
+Returns: KS D-value, associated p-value
+"""
+    j1 = 0
+    j2 = 0
+    fn1 = 0.0
+    fn2 = 0.0
+    n1 = len(data1)
+    n2 = len(data2)
+    en1 = n1
+    en2 = n2
+    d = 0.0
+    data1.sort()
+    data2.sort()
+    while j1 < n1 and j2 < n2:
+        d1=data1[j1]
+        d2=data2[j2]
+        if d1 <= d2:
+            fn1 = (j1)/float(en1)
+            j1 = j1 + 1
+        if d2 <= d1:
+            fn2 = (j2)/float(en2)
+            j2 = j2 + 1
+        dt = (fn2-fn1)
+        if math.fabs(dt) > math.fabs(d):
+            d = dt
+    try:
+        en = math.sqrt(en1*en2/float(en1+en2))
+        prob = ksprob((en+0.12+0.11/en)*abs(d))
+    except:
+        prob = 1.0
+    return d, prob
+
+
+def lmannwhitneyu(x,y):
+    """
+Calculates a Mann-Whitney U statistic on the provided scores and
+returns the result.  Use only when the n in each condition is < 20 and
+you have 2 independent samples of ranks.  NOTE: Mann-Whitney U is
+significant if the u-obtained is LESS THAN or equal to the critical
+value of U found in the tables.  Equivalent to Kruskal-Wallis H with
+just 2 groups.
+
+Usage:   lmannwhitneyu(data)
+Returns: u-statistic, one-tailed p-value (i.e., p(z(U)))
+"""
+    n1 = len(x)
+    n2 = len(y)
+    ranked = rankdata(x+y)
+    rankx = ranked[0:n1]       # get the x-ranks
+    ranky = ranked[n1:]        # the rest are y-ranks
+    u1 = n1*n2 + (n1*(n1+1))/2.0 - sum(rankx)  # calc U for x
+    u2 = n1*n2 - u1                            # remainder is U for y
+    bigu = max(u1,u2)
+    smallu = min(u1,u2)
+    T = math.sqrt(tiecorrect(ranked))  # correction factor for tied scores
+    if T == 0:
+        raise ValueError, 'All numbers are identical in lmannwhitneyu'
+    sd = math.sqrt(T*n1*n2*(n1+n2+1)/12.0)
+    z = abs((bigu-n1*n2/2.0) / sd)  # normal approximation for prob calc
+    return smallu, 1.0 - zprob(z)
+
+
+def ltiecorrect(rankvals):
+    """
+Corrects for ties in Mann Whitney U and Kruskal Wallis H tests.  See
+Siegel, S. (1956) Nonparametric Statistics for the Behavioral Sciences.
+New York: McGraw-Hill.  Code adapted from |Stat rankind.c code.
+
+Usage:   ltiecorrect(rankvals)
+Returns: T correction factor for U or H
+"""
+    sorted,posn = shellsort(rankvals)
+    n = len(sorted)
+    T = 0.0
+    i = 0
+    while (i<n-1):
+        if sorted[i] == sorted[i+1]:
+            nties = 1
+            while (i<n-1) and (sorted[i] == sorted[i+1]):
+                nties = nties +1
+                i = i +1
+            T = T + nties**3 - nties
+        i = i+1
+    T = T / float(n**3-n)
+    return 1.0 - T
+
+
+def lranksums(x,y):
+    """
+Calculates the rank sums statistic on the provided scores and
+returns the result.  Use only when the n in each condition is > 20 and you
+have 2 independent samples of ranks.
+
+Usage:   lranksums(x,y)
+Returns: a z-statistic, two-tailed p-value
+"""
+    n1 = len(x)
+    n2 = len(y)
+    alldata = x+y
+    ranked = rankdata(alldata)
+    x = ranked[:n1]
+    y = ranked[n1:]
+    s = sum(x)
+    expected = n1*(n1+n2+1) / 2.0
+    z = (s - expected) / math.sqrt(n1*n2*(n1+n2+1)/12.0)
+    prob = 2*(1.0 -zprob(abs(z)))
+    return z, prob
+
+
+def lwilcoxont(x,y):
+    """
+Calculates the Wilcoxon T-test for related samples and returns the
+result.  A non-parametric T-test.
+
+Usage:   lwilcoxont(x,y)
+Returns: a t-statistic, two-tail probability estimate
+"""
+    if len(x) <> len(y):
+        raise ValueError, 'Unequal N in wilcoxont.  Aborting.'
+    d=[]
+    for i in range(len(x)):
+        diff = x[i] - y[i]
+        if diff <> 0:
+            d.append(diff)
+    count = len(d)
+    absd = map(abs,d)
+    absranked = rankdata(absd)
+    r_plus = 0.0
+    r_minus = 0.0
+    for i in range(len(absd)):
+        if d[i] < 0:
+            r_minus = r_minus + absranked[i]
+        else:
+            r_plus = r_plus + absranked[i]
+    wt = min(r_plus, r_minus)
+    mn = count * (count+1) * 0.25
+    se =  math.sqrt(count*(count+1)*(2.0*count+1.0)/24.0)
+    z = math.fabs(wt-mn) / se
+    prob = 2*(1.0 -zprob(abs(z)))
+    return wt, prob
+
+
+def lkruskalwallish(*args):
+    """
+The Kruskal-Wallis H-test is a non-parametric ANOVA for 3 or more
+groups, requiring at least 5 subjects in each group.  This function
+calculates the Kruskal-Wallis H-test for 3 or more independent samples
+and returns the result.  
+
+Usage:   lkruskalwallish(*args)
+Returns: H-statistic (corrected for ties), associated p-value
+"""
+    args = list(args)
+    n = [0]*len(args)
+    all = []
+    n = map(len,args)
+    for i in range(len(args)):
+        all = all + args[i]
+    ranked = rankdata(all)
+    T = tiecorrect(ranked)
+    for i in range(len(args)):
+        args[i] = ranked[0:n[i]]
+        del ranked[0:n[i]]
+    rsums = []
+    for i in range(len(args)):
+        rsums.append(sum(args[i])**2)
+        rsums[i] = rsums[i] / float(n[i])
+    ssbn = sum(rsums)
+    totaln = sum(n)
+    h = 12.0 / (totaln*(totaln+1)) * ssbn - 3*(totaln+1)
+    df = len(args) - 1
+    if T == 0:
+        raise ValueError, 'All numbers are identical in lkruskalwallish'
+    h = h / float(T)
+    return h, chisqprob(h,df)
+
+
+def lfriedmanchisquare(*args):
+    """
+Friedman Chi-Square is a non-parametric, one-way within-subjects
+ANOVA.  This function calculates the Friedman Chi-square test for repeated
+measures and returns the result, along with the associated probability
+value.  It assumes 3 or more repeated measures.  Only 3 levels requires a
+minimum of 10 subjects in the study.  Four levels requires 5 subjects per
+level(??).
+
+Usage:   lfriedmanchisquare(*args)
+Returns: chi-square statistic, associated p-value
+"""
+    k = len(args)
+    if k < 3:
+        raise ValueError, 'Less than 3 levels.  Friedman test not appropriate.'
+    n = len(args[0])
+    data = apply(pstat.abut,tuple(args))
+    for i in range(len(data)):
+        data[i] = rankdata(data[i])
+    ssbn = 0
+    for i in range(k):
+        ssbn = ssbn + sum(args[i])**2
+    chisq = 12.0 / (k*n*(k+1)) * ssbn - 3*n*(k+1)
+    return chisq, chisqprob(chisq,k-1)
+
+
+####################################
+####  PROBABILITY CALCULATIONS  ####
+####################################
+
+def lchisqprob(chisq,df):
+    """
+Returns the (1-tailed) probability value associated with the provided
+chi-square value and df.  Adapted from chisq.c in Gary Perlman's |Stat.
+
+Usage:   lchisqprob(chisq,df)
+"""
+    BIG = 20.0
+    def ex(x):
+        BIG = 20.0
+        if x < -BIG:
+            return 0.0
+        else:
+            return math.exp(x)
+
+    if chisq <=0 or df < 1:
+        return 1.0
+    a = 0.5 * chisq
+    if df%2 == 0:
+        even = 1
+    else:
+        even = 0
+    if df > 1:
+        y = ex(-a)
+    if even:
+        s = y
+    else:
+        s = 2.0 * zprob(-math.sqrt(chisq))
+    if (df > 2):
+        chisq = 0.5 * (df - 1.0)
+        if even:
+            z = 1.0
+        else:
+            z = 0.5
+        if a > BIG:
+            if even:
+                e = 0.0
+            else:
+                e = math.log(math.sqrt(math.pi))
+            c = math.log(a)
+            while (z <= chisq):
+                e = math.log(z) + e
+                s = s + ex(c*z-a-e)
+                z = z + 1.0
+            return s
+        else:
+            if even:
+                e = 1.0
+            else:
+                e = 1.0 / math.sqrt(math.pi) / math.sqrt(a)
+            c = 0.0
+            while (z <= chisq):
+                e = e * (a/float(z))
+                c = c + e
+                z = z + 1.0
+            return (c*y+s)
+    else:
+        return s
+
+
+def lerfcc(x):
+    """
+Returns the complementary error function erfc(x) with fractional
+error everywhere less than 1.2e-7.  Adapted from Numerical Recipies.
+
+Usage:   lerfcc(x)
+"""
+    z = abs(x)
+    t = 1.0 / (1.0+0.5*z)
+    ans = t * math.exp(-z*z-1.26551223 + t*(1.00002368+t*(0.37409196+t*(0.09678418+t*(-0.18628806+t*(0.27886807+t*(-1.13520398+t*(1.48851587+t*(-0.82215223+t*0.17087277)))))))))
+    if x >= 0:
+        return ans
+    else:
+        return 2.0 - ans
+
+
+def lzprob(z):
+    """
+Returns the area under the normal curve 'to the left of' the given z value.
+Thus, 
+    for z<0, zprob(z) = 1-tail probability
+    for z>0, 1.0-zprob(z) = 1-tail probability
+    for any z, 2.0*(1.0-zprob(abs(z))) = 2-tail probability
+Adapted from z.c in Gary Perlman's |Stat.
+
+Usage:   lzprob(z)
+"""
+    Z_MAX = 6.0    # maximum meaningful z-value
+    if z == 0.0:
+        x = 0.0
+    else:
+        y = 0.5 * math.fabs(z)
+        if y >= (Z_MAX*0.5):
+            x = 1.0
+        elif (y < 1.0):
+            w = y*y
+            x = ((((((((0.000124818987 * w
+                        -0.001075204047) * w +0.005198775019) * w
+                      -0.019198292004) * w +0.059054035642) * w
+                    -0.151968751364) * w +0.319152932694) * w
+                  -0.531923007300) * w +0.797884560593) * y * 2.0
+        else:
+            y = y - 2.0
+            x = (((((((((((((-0.000045255659 * y
+                             +0.000152529290) * y -0.000019538132) * y
+                           -0.000676904986) * y +0.001390604284) * y
+                         -0.000794620820) * y -0.002034254874) * y
+                       +0.006549791214) * y -0.010557625006) * y
+                     +0.011630447319) * y -0.009279453341) * y
+                   +0.005353579108) * y -0.002141268741) * y
+                 +0.000535310849) * y +0.999936657524
+    if z > 0.0:
+        prob = ((x+1.0)*0.5)
+    else:
+        prob = ((1.0-x)*0.5)
+    return prob
+
+
+def lksprob(alam):
+    """
+Computes a Kolmolgorov-Smirnov t-test significance level.  Adapted from
+Numerical Recipies.
+
+Usage:   lksprob(alam)
+"""
+    fac = 2.0
+    sum = 0.0
+    termbf = 0.0
+    a2 = -2.0*alam*alam
+    for j in range(1,201):
+        term = fac*math.exp(a2*j*j)
+        sum = sum + term
+        if math.fabs(term) <= (0.001*termbf) or math.fabs(term) < (1.0e-8*sum):
+            return sum
+        fac = -fac
+        termbf = math.fabs(term)
+    return 1.0             # Get here only if fails to converge; was 0.0!!
+
+
+def lfprob (dfnum, dfden, F):
+    """
+Returns the (1-tailed) significance level (p-value) of an F
+statistic given the degrees of freedom for the numerator (dfR-dfF) and
+the degrees of freedom for the denominator (dfF).
+
+Usage:   lfprob(dfnum, dfden, F)   where usually dfnum=dfbn, dfden=dfwn
+"""
+    p = betai(0.5*dfden, 0.5*dfnum, dfden/float(dfden+dfnum*F))
+    return p
+
+
+def lbetacf(a,b,x):
+    """
+This function evaluates the continued fraction form of the incomplete
+Beta function, betai.  (Adapted from: Numerical Recipies in C.)
+
+Usage:   lbetacf(a,b,x)
+"""
+    ITMAX = 200
+    EPS = 3.0e-7
+
+    bm = az = am = 1.0
+    qab = a+b
+    qap = a+1.0
+    qam = a-1.0
+    bz = 1.0-qab*x/qap
+    for i in range(ITMAX+1):
+        em = float(i+1)
+        tem = em + em
+        d = em*(b-em)*x/((qam+tem)*(a+tem))
+        ap = az + d*am
+        bp = bz+d*bm
+        d = -(a+em)*(qab+em)*x/((qap+tem)*(a+tem))
+        app = ap+d*az
+        bpp = bp+d*bz
+        aold = az
+        am = ap/bpp
+        bm = bp/bpp
+        az = app/bpp
+        bz = 1.0
+        if (abs(az-aold)<(EPS*abs(az))):
+            return az
+    print 'a or b too big, or ITMAX too small in Betacf.'
+
+
+def lgammln(xx):
+    """
+Returns the gamma function of xx.
+    Gamma(z) = Integral(0,infinity) of t^(z-1)exp(-t) dt.
+(Adapted from: Numerical Recipies in C.)
+
+Usage:   lgammln(xx)
+"""
+
+    coeff = [76.18009173, -86.50532033, 24.01409822, -1.231739516,
+             0.120858003e-2, -0.536382e-5]
+    x = xx - 1.0
+    tmp = x + 5.5
+    tmp = tmp - (x+0.5)*math.log(tmp)
+    ser = 1.0
+    for j in range(len(coeff)):
+        x = x + 1
+        ser = ser + coeff[j]/x
+    return -tmp + math.log(2.50662827465*ser)
+
+
+def lbetai(a,b,x):
+    """
+Returns the incomplete beta function:
+
+    I-sub-x(a,b) = 1/B(a,b)*(Integral(0,x) of t^(a-1)(1-t)^(b-1) dt)
+
+where a,b>0 and B(a,b) = G(a)*G(b)/(G(a+b)) where G(a) is the gamma
+function of a.  The continued fraction formulation is implemented here,
+using the betacf function.  (Adapted from: Numerical Recipies in C.)
+
+Usage:   lbetai(a,b,x)
+"""
+    if (x<0.0 or x>1.0):
+        raise ValueError, 'Bad x in lbetai'
+    if (x==0.0 or x==1.0):
+        bt = 0.0
+    else:
+        bt = math.exp(gammln(a+b)-gammln(a)-gammln(b)+a*math.log(x)+b*
+                      math.log(1.0-x))
+    if (x<(a+1.0)/(a+b+2.0)):
+        return bt*betacf(a,b,x)/float(a)
+    else:
+        return 1.0-bt*betacf(b,a,1.0-x)/float(b)
+
+
+####################################
+#######  ANOVA CALCULATIONS  #######
+####################################
+
+def lF_oneway(*lists):
+    """
+Performs a 1-way ANOVA, returning an F-value and probability given
+any number of groups.  From Heiman, pp.394-7.
+
+Usage:   F_oneway(*lists)    where *lists is any number of lists, one per
+                                  treatment group
+Returns: F value, one-tailed p-value
+"""
+    a = len(lists)           # ANOVA on 'a' groups, each in it's own list
+    means = [0]*a
+    vars = [0]*a
+    ns = [0]*a
+    alldata = []
+    tmp = map(N.array,lists)
+    means = map(amean,tmp)
+    vars = map(avar,tmp)
+    ns = map(len,lists)
+    for i in range(len(lists)):
+        alldata = alldata + lists[i]
+    alldata = N.array(alldata)
+    bign = len(alldata)
+    sstot = ass(alldata)-(asquare_of_sums(alldata)/float(bign))
+    ssbn = 0
+    for list in lists:
+        ssbn = ssbn + asquare_of_sums(N.array(list))/float(len(list))
+    ssbn = ssbn - (asquare_of_sums(alldata)/float(bign))
+    sswn = sstot-ssbn
+    dfbn = a-1
+    dfwn = bign - a
+    msb = ssbn/float(dfbn)
+    msw = sswn/float(dfwn)
+    f = msb/msw
+    prob = fprob(dfbn,dfwn,f)
+    return f, prob
+
+
+def lF_value (ER,EF,dfnum,dfden):
+    """
+Returns an F-statistic given the following:
+        ER  = error associated with the null hypothesis (the Restricted model)
+        EF  = error associated with the alternate hypothesis (the Full model)
+        dfR-dfF = degrees of freedom of the numerator
+        dfF = degrees of freedom associated with the denominator/Full model
+
+Usage:   lF_value(ER,EF,dfnum,dfden)
+"""
+    return ((ER-EF)/float(dfnum) / (EF/float(dfden)))
+
+
+####################################
+########  SUPPORT FUNCTIONS  #######
+####################################
+
+def writecc (listoflists,file,writetype='w',extra=2):
+    """
+Writes a list of lists to a file in columns, customized by the max
+size of items within the columns (max size of items in col, +2 characters)
+to specified file.  File-overwrite is the default.
+
+Usage:   writecc (listoflists,file,writetype='w',extra=2)
+Returns: None
+"""
+    if type(listoflists[0]) not in [ListType,TupleType]:
+        listoflists = [listoflists]
+    outfile = open(file,writetype)
+    rowstokill = []
+    list2print = copy.deepcopy(listoflists)
+    for i in range(len(listoflists)):
+        if listoflists[i] == ['\n'] or listoflists[i]=='\n' or listoflists[i]=='dashes':
+            rowstokill = rowstokill + [i]
+    rowstokill.reverse()
+    for row in rowstokill:
+        del list2print[row]
+    maxsize = [0]*len(list2print[0])
+    for col in range(len(list2print[0])):
+        items = pstat.colex(list2print,col)
+        items = map(pstat.makestr,items)
+        maxsize[col] = max(map(len,items)) + extra
+    for row in listoflists:
+        if row == ['\n'] or row == '\n':
+            outfile.write('\n')
+        elif row == ['dashes'] or row == 'dashes':
+            dashes = [0]*len(maxsize)
+            for j in range(len(maxsize)):
+                dashes[j] = '-'*(maxsize[j]-2)
+            outfile.write(pstat.lineincustcols(dashes,maxsize))
+        else:
+            outfile.write(pstat.lineincustcols(row,maxsize))
+        outfile.write('\n')
+    outfile.close()
+    return None
+
+
+def lincr(l,cap):        # to increment a list up to a max-list of 'cap'
+    """
+Simulate a counting system from an n-dimensional list.
+
+Usage:   lincr(l,cap)   l=list to increment, cap=max values for each list pos'n
+Returns: next set of values for list l, OR -1 (if overflow)
+"""
+    l[0] = l[0] + 1     # e.g., [0,0,0] --> [2,4,3] (=cap)
+    for i in range(len(l)):
+        if l[i] > cap[i] and i < len(l)-1: # if carryover AND not done
+            l[i] = 0
+            l[i+1] = l[i+1] + 1
+        elif l[i] > cap[i] and i == len(l)-1: # overflow past last column, must be finished
+            l = -1
+    return l
+
+
+def lsum (inlist):
+    """
+Returns the sum of the items in the passed list.
+
+Usage:   lsum(inlist)
+"""
+    s = 0
+    for item in inlist:
+        s = s + item
+    return s
+
+
+def lcumsum (inlist):
+    """
+Returns a list consisting of the cumulative sum of the items in the
+passed list.
+
+Usage:   lcumsum(inlist)
+"""
+    newlist = copy.deepcopy(inlist)
+    for i in range(1,len(newlist)):
+        newlist[i] = newlist[i] + newlist[i-1]
+    return newlist
+
+
+def lss(inlist):
+    """
+Squares each value in the passed list, adds up these squares and
+returns the result.
+
+Usage:   lss(inlist)
+"""
+    ss = 0
+    for item in inlist:
+        ss = ss + item*item
+    return ss
+
+
+def lsummult (list1,list2):
+    """
+Multiplies elements in list1 and list2, element by element, and
+returns the sum of all resulting multiplications.  Must provide equal
+length lists.
+
+Usage:   lsummult(list1,list2)
+"""
+    if len(list1) <> len(list2):
+        raise ValueError, "Lists not equal length in summult."
+    s = 0
+    for item1,item2 in pstat.abut(list1,list2):
+        s = s + item1*item2
+    return s
+
+
+def lsumdiffsquared(x,y):
+    """
+Takes pairwise differences of the values in lists x and y, squares
+these differences, and returns the sum of these squares.
+
+Usage:   lsumdiffsquared(x,y)
+Returns: sum[(x[i]-y[i])**2]
+"""
+    sds = 0
+    for i in range(len(x)):
+        sds = sds + (x[i]-y[i])**2
+    return sds
+
+
+def lsquare_of_sums(inlist):
+    """
+Adds the values in the passed list, squares the sum, and returns
+the result.
+
+Usage:   lsquare_of_sums(inlist)
+Returns: sum(inlist[i])**2
+"""
+    s = sum(inlist)
+    return float(s)*s
+
+
+def lshellsort(inlist):
+    """
+Shellsort algorithm.  Sorts a 1D-list.
+
+Usage:   lshellsort(inlist)
+Returns: sorted-inlist, sorting-index-vector (for original list)
+"""
+    n = len(inlist)
+    svec = copy.deepcopy(inlist)
+    ivec = range(n)
+    gap = n/2   # integer division needed
+    while gap >0:
+        for i in range(gap,n):
+            for j in range(i-gap,-1,-gap):
+                while j>=0 and svec[j]>svec[j+gap]:
+                    temp        = svec[j]
+                    svec[j]     = svec[j+gap]
+                    svec[j+gap] = temp
+                    itemp       = ivec[j]
+                    ivec[j]     = ivec[j+gap]
+                    ivec[j+gap] = itemp
+        gap = gap / 2  # integer division needed
+# svec is now sorted inlist, and ivec has the order svec[i] = vec[ivec[i]]
+    return svec, ivec
+
+
+def lrankdata(inlist):
+    """
+Ranks the data in inlist, dealing with ties appropritely.  Assumes
+a 1D inlist.  Adapted from Gary Perlman's |Stat ranksort.
+
+Usage:   lrankdata(inlist)
+Returns: a list of length equal to inlist, containing rank scores
+"""
+    n = len(inlist)
+    svec, ivec = shellsort(inlist)
+    sumranks = 0
+    dupcount = 0
+    newlist = [0]*n
+    for i in range(n):
+        sumranks = sumranks + i
+        dupcount = dupcount + 1
+        if i==n-1 or svec[i] <> svec[i+1]:
+            averank = sumranks / float(dupcount) + 1
+            for j in range(i-dupcount+1,i+1):
+                newlist[ivec[j]] = averank
+            sumranks = 0
+            dupcount = 0
+    return newlist
+
+
+def outputpairedstats(fname,writemode,name1,n1,m1,se1,min1,max1,name2,n2,m2,se2,min2,max2,statname,stat,prob):
+    """
+Prints or write to a file stats for two groups, using the name, n,
+mean, sterr, min and max for each group, as well as the statistic name,
+its value, and the associated p-value.
+
+Usage:   outputpairedstats(fname,writemode,
+                           name1,n1,mean1,stderr1,min1,max1,
+                           name2,n2,mean2,stderr2,min2,max2,
+                           statname,stat,prob)
+Returns: None
+"""
+    suffix = ''                       # for *s after the p-value
+    try:
+        x = prob.shape
+        prob = prob[0]
+    except:
+        pass
+    if  prob < 0.001:  suffix = '  ***'
+    elif prob < 0.01:  suffix = '  **'
+    elif prob < 0.05:  suffix = '  *'
+    title = [['Name','N','Mean','SD','Min','Max']]
+    lofl = title+[[name1,n1,round(m1,3),round(math.sqrt(se1),3),min1,max1],
+                  [name2,n2,round(m2,3),round(math.sqrt(se2),3),min2,max2]]
+    if type(fname)<>StringType or len(fname)==0:
+        print
+        print statname
+        print
+        pstat.printcc(lofl)
+        print
+        try:
+            if stat.shape == ():
+                stat = stat[0]
+            if prob.shape == ():
+                prob = prob[0]
+        except:
+            pass
+        print 'Test statistic = ',round(stat,3),'   p = ',round(prob,3),suffix
+        print
+    else:
+        file = open(fname,writemode)
+        file.write('\n'+statname+'\n\n')
+        file.close()
+        writecc(lofl,fname,'a')
+        file = open(fname,'a')
+        try:
+            if stat.shape == ():
+                stat = stat[0]
+            if prob.shape == ():
+                prob = prob[0]
+        except:
+            pass
+        file.write(pstat.list2string(['\nTest statistic = ',round(stat,4),'   p = ',round(prob,4),suffix,'\n\n']))
+        file.close()
+    return None
+
+
+def lfindwithin (data):
+    """
+Returns an integer representing a binary vector, where 1=within-
+subject factor, 0=between.  Input equals the entire data 2D list (i.e.,
+column 0=random factor, column -1=measured values (those two are skipped).
+Note: input data is in |Stat format ... a list of lists ("2D list") with 
+one row per measured value, first column=subject identifier, last column=
+score, one in-between column per factor (these columns contain level
+designations on each factor).  See also stats.anova.__doc__.
+
+Usage:   lfindwithin(data)     data in |Stat format
+"""
+
+    numfact = len(data[0])-1
+    withinvec = 0
+    for col in range(1,numfact):
+        examplelevel = pstat.unique(pstat.colex(data,col))[0]
+        rows = pstat.linexand(data,col,examplelevel)  # get 1 level of this factor
+        factsubjs = pstat.unique(pstat.colex(rows,0))
+        allsubjs = pstat.unique(pstat.colex(data,0))
+        if len(factsubjs) == len(allsubjs):  # fewer Ss than scores on this factor?
+            withinvec = withinvec + (1 << col)
+    return withinvec
+
+
+#########################################################
+#########################################################
+####### DISPATCH LISTS AND TUPLES TO ABOVE FCNS #########
+#########################################################
+#########################################################
+
+## CENTRAL TENDENCY:
+geometricmean = Dispatch ( (lgeometricmean, (ListType, TupleType)), )
+harmonicmean = Dispatch ( (lharmonicmean, (ListType, TupleType)), )
+mean = Dispatch ( (lmean, (ListType, TupleType)), )
+median = Dispatch ( (lmedian, (ListType, TupleType)), )
+medianscore = Dispatch ( (lmedianscore, (ListType, TupleType)), )
+mode = Dispatch ( (lmode, (ListType, TupleType)), )
+
+## MOMENTS:
+moment = Dispatch ( (lmoment, (ListType, TupleType)), )
+variation = Dispatch ( (lvariation, (ListType, TupleType)), )
+skew = Dispatch ( (lskew, (ListType, TupleType)), )
+kurtosis = Dispatch ( (lkurtosis, (ListType, TupleType)), )
+describe = Dispatch ( (ldescribe, (ListType, TupleType)), )
+
+## FREQUENCY STATISTICS:
+itemfreq = Dispatch ( (litemfreq, (ListType, TupleType)), )
+scoreatpercentile = Dispatch ( (lscoreatpercentile, (ListType, TupleType)), )
+percentileofscore = Dispatch ( (lpercentileofscore, (ListType, TupleType)), )
+histogram = Dispatch ( (lhistogram, (ListType, TupleType)), )
+cumfreq = Dispatch ( (lcumfreq, (ListType, TupleType)), )
+relfreq = Dispatch ( (lrelfreq, (ListType, TupleType)), )
+
+## VARIABILITY:
+obrientransform = Dispatch ( (lobrientransform, (ListType, TupleType)), )
+samplevar = Dispatch ( (lsamplevar, (ListType, TupleType)), )
+samplestdev = Dispatch ( (lsamplestdev, (ListType, TupleType)), )
+var = Dispatch ( (lvar, (ListType, TupleType)), )
+stdev = Dispatch ( (lstdev, (ListType, TupleType)), )
+sterr = Dispatch ( (lsterr, (ListType, TupleType)), )
+sem = Dispatch ( (lsem, (ListType, TupleType)), )
+z = Dispatch ( (lz, (ListType, TupleType)), )
+zs = Dispatch ( (lzs, (ListType, TupleType)), )
+
+## TRIMMING FCNS:
+trimboth = Dispatch ( (ltrimboth, (ListType, TupleType)), )
+trim1 = Dispatch ( (ltrim1, (ListType, TupleType)), )
+
+## CORRELATION FCNS:
+paired = Dispatch ( (lpaired, (ListType, TupleType)), )
+pearsonr = Dispatch ( (lpearsonr, (ListType, TupleType)), )
+spearmanr = Dispatch ( (lspearmanr, (ListType, TupleType)), )
+pointbiserialr = Dispatch ( (lpointbiserialr, (ListType, TupleType)), )
+kendalltau = Dispatch ( (lkendalltau, (ListType, TupleType)), )
+linregress = Dispatch ( (llinregress, (ListType, TupleType)), )
+
+## INFERENTIAL STATS:
+ttest_1samp = Dispatch ( (lttest_1samp, (ListType, TupleType)), )
+ttest_ind = Dispatch ( (lttest_ind, (ListType, TupleType)), )
+ttest_rel = Dispatch ( (lttest_rel, (ListType, TupleType)), )
+chisquare = Dispatch ( (lchisquare, (ListType, TupleType)), )
+ks_2samp = Dispatch ( (lks_2samp, (ListType, TupleType)), )
+mannwhitneyu = Dispatch ( (lmannwhitneyu, (ListType, TupleType)), )
+ranksums = Dispatch ( (lranksums, (ListType, TupleType)), )
+tiecorrect = Dispatch ( (ltiecorrect, (ListType, TupleType)), )
+wilcoxont = Dispatch ( (lwilcoxont, (ListType, TupleType)), )
+kruskalwallish = Dispatch ( (lkruskalwallish, (ListType, TupleType)), )
+friedmanchisquare = Dispatch ( (lfriedmanchisquare, (ListType, TupleType)), )
+
+## PROBABILITY CALCS:
+chisqprob = Dispatch ( (lchisqprob, (IntType, FloatType)), )
+zprob = Dispatch ( (lzprob, (IntType, FloatType)), )
+ksprob = Dispatch ( (lksprob, (IntType, FloatType)), )
+fprob = Dispatch ( (lfprob, (IntType, FloatType)), )
+betacf = Dispatch ( (lbetacf, (IntType, FloatType)), )
+betai = Dispatch ( (lbetai, (IntType, FloatType)), )
+erfcc = Dispatch ( (lerfcc, (IntType, FloatType)), )
+gammln = Dispatch ( (lgammln, (IntType, FloatType)), )
+
+## ANOVA FUNCTIONS:
+F_oneway = Dispatch ( (lF_oneway, (ListType, TupleType)), )
+F_value = Dispatch ( (lF_value, (ListType, TupleType)), )
+
+## SUPPORT FUNCTIONS:
+incr = Dispatch ( (lincr, (ListType, TupleType)), )
+sum = Dispatch ( (lsum, (ListType, TupleType)), )
+cumsum = Dispatch ( (lcumsum, (ListType, TupleType)), )
+ss = Dispatch ( (lss, (ListType, TupleType)), )
+summult = Dispatch ( (lsummult, (ListType, TupleType)), )
+square_of_sums = Dispatch ( (lsquare_of_sums, (ListType, TupleType)), )
+sumdiffsquared = Dispatch ( (lsumdiffsquared, (ListType, TupleType)), )
+shellsort = Dispatch ( (lshellsort, (ListType, TupleType)), )
+rankdata = Dispatch ( (lrankdata, (ListType, TupleType)), )
+findwithin = Dispatch ( (lfindwithin, (ListType, TupleType)), )
+
+
+#=============  THE ARRAY-VERSION OF THE STATS FUNCTIONS  ===============
+#=============  THE ARRAY-VERSION OF THE STATS FUNCTIONS  ===============
+#=============  THE ARRAY-VERSION OF THE STATS FUNCTIONS  ===============
+#=============  THE ARRAY-VERSION OF THE STATS FUNCTIONS  ===============
+#=============  THE ARRAY-VERSION OF THE STATS FUNCTIONS  ===============
+#=============  THE ARRAY-VERSION OF THE STATS FUNCTIONS  ===============
+#=============  THE ARRAY-VERSION OF THE STATS FUNCTIONS  ===============
+#=============  THE ARRAY-VERSION OF THE STATS FUNCTIONS  ===============
+#=============  THE ARRAY-VERSION OF THE STATS FUNCTIONS  ===============
+#=============  THE ARRAY-VERSION OF THE STATS FUNCTIONS  ===============
+#=============  THE ARRAY-VERSION OF THE STATS FUNCTIONS  ===============
+#=============  THE ARRAY-VERSION OF THE STATS FUNCTIONS  ===============
+#=============  THE ARRAY-VERSION OF THE STATS FUNCTIONS  ===============
+#=============  THE ARRAY-VERSION OF THE STATS FUNCTIONS  ===============
+#=============  THE ARRAY-VERSION OF THE STATS FUNCTIONS  ===============
+#=============  THE ARRAY-VERSION OF THE STATS FUNCTIONS  ===============
+#=============  THE ARRAY-VERSION OF THE STATS FUNCTIONS  ===============
+#=============  THE ARRAY-VERSION OF THE STATS FUNCTIONS  ===============
+#=============  THE ARRAY-VERSION OF THE STATS FUNCTIONS  ===============
+
+try:                         # DEFINE THESE *ONLY* IF NUMERIC IS AVAILABLE
+ import Numeric
+ N = Numeric
+ import LinearAlgebra
+ LA = LinearAlgebra
+
+
+#####################################
+########  ACENTRAL TENDENCY  ########
+#####################################
+
+ def ageometricmean (inarray,dimension=None,keepdims=0):
+    """
+Calculates the geometric mean of the values in the passed array.
+That is:  n-th root of (x1 * x2 * ... * xn).  Defaults to ALL values in
+the passed array.  Use dimension=None to flatten array first.  REMEMBER: if
+dimension=0, it collapses over dimension 0 ('rows' in a 2D array) only, and
+if dimension is a sequence, it collapses over all specified dimensions.  If
+keepdims is set to 1, the resulting array will have as many dimensions as
+inarray, with only 1 'level' per dim that was collapsed over.
+
+Usage:   ageometricmean(inarray,dimension=None,keepdims=0)
+Returns: geometric mean computed over dim(s) listed in dimension
+"""
+    inarray = N.array(inarray,N.Float)
+    if dimension == None:
+        inarray = N.ravel(inarray)
+        size = len(inarray)
+        mult = N.power(inarray,1.0/size)
+        mult = N.multiply.reduce(mult)
+    elif type(dimension) in [IntType,FloatType]:
+        size = inarray.shape[dimension]
+        mult = N.power(inarray,1.0/size)
+        mult = N.multiply.reduce(mult,dimension)
+        if keepdims == 1:
+            shp = list(inarray.shape)
+            shp[dimension] = 1
+            sum = N.reshape(sum,shp)
+    else: # must be a SEQUENCE of dims to average over
+        dims = list(dimension)
+        dims.sort()
+        dims.reverse()
+        size = N.array(N.multiply.reduce(N.take(inarray.shape,dims)),N.Float)
+        mult = N.power(inarray,1.0/size)
+        for dim in dims:
+            mult = N.multiply.reduce(mult,dim)
+        if keepdims == 1:
+            shp = list(inarray.shape)
+            for dim in dims:
+                shp[dim] = 1
+            mult = N.reshape(mult,shp)
+    return mult
+
+
+ def aharmonicmean (inarray,dimension=None,keepdims=0):
+    """
+Calculates the harmonic mean of the values in the passed array.
+That is:  n / (1/x1 + 1/x2 + ... + 1/xn).  Defaults to ALL values in
+the passed array.  Use dimension=None to flatten array first.  REMEMBER: if
+dimension=0, it collapses over dimension 0 ('rows' in a 2D array) only, and
+if dimension is a sequence, it collapses over all specified dimensions.  If
+keepdims is set to 1, the resulting array will have as many dimensions as
+inarray, with only 1 'level' per dim that was collapsed over.
+
+Usage:   aharmonicmean(inarray,dimension=None,keepdims=0)
+Returns: harmonic mean computed over dim(s) in dimension
+"""
+    inarray = inarray.astype(N.Float)
+    if dimension == None:
+        inarray = N.ravel(inarray)
+        size = len(inarray)
+        s = N.add.reduce(1.0 / inarray)
+    elif type(dimension) in [IntType,FloatType]:
+        size = float(inarray.shape[dimension])
+        s = N.add.reduce(1.0/inarray, dimension)
+        if keepdims == 1:
+            shp = list(inarray.shape)
+            shp[dimension] = 1
+            s = N.reshape(s,shp)
+    else: # must be a SEQUENCE of dims to average over
+        dims = list(dimension)
+        dims.sort()
+        nondims = []
+        for i in range(len(inarray.shape)):
+            if i not in dims:
+                nondims.append(i)
+        tinarray = N.transpose(inarray,nondims+dims) # put keep-dims first
+        idx = [0] *len(nondims)
+        if idx == []:
+            size = len(N.ravel(inarray))
+            s = asum(1.0 / inarray)
+            if keepdims == 1:
+                s = N.reshape([s],N.ones(len(inarray.shape)))
+        else:
+            idx[0] = -1
+            loopcap = N.array(tinarray.shape[0:len(nondims)]) -1
+            s = N.zeros(loopcap+1,N.Float)
+            while incr(idx,loopcap) <> -1:
+                s[idx] = asum(1.0/tinarray[idx])
+            size = N.multiply.reduce(N.take(inarray.shape,dims))
+            if keepdims == 1:
+                shp = list(inarray.shape)
+                for dim in dims:
+                    shp[dim] = 1
+                s = N.reshape(s,shp)
+    return size / s
+
+
+ def amean (inarray,dimension=None,keepdims=0):
+    """
+Calculates the arithmatic mean of the values in the passed array.
+That is:  1/n * (x1 + x2 + ... + xn).  Defaults to ALL values in the
+passed array.  Use dimension=None to flatten array first.  REMEMBER: if
+dimension=0, it collapses over dimension 0 ('rows' in a 2D array) only, and
+if dimension is a sequence, it collapses over all specified dimensions.  If
+keepdims is set to 1, the resulting array will have as many dimensions as
+inarray, with only 1 'level' per dim that was collapsed over.
+
+Usage:   amean(inarray,dimension=None,keepdims=0)
+Returns: arithematic mean calculated over dim(s) in dimension
+"""
+    if inarray.typecode() in ['l','s','b']:
+        inarray = inarray.astype(N.Float)
+    if dimension == None:
+        inarray = N.ravel(inarray)
+        sum = N.add.reduce(inarray)
+        denom = float(len(inarray))
+    elif type(dimension) in [IntType,FloatType]:
+        sum = asum(inarray,dimension)
+        denom = float(inarray.shape[dimension])
+        if keepdims == 1:
+            shp = list(inarray.shape)
+            shp[dimension] = 1
+            sum = N.reshape(sum,shp)
+    else: # must be a TUPLE of dims to average over
+        dims = list(dimension)
+        dims.sort()
+        dims.reverse()
+        sum = inarray *1.0
+        for dim in dims:
+            sum = N.add.reduce(sum,dim)
+        denom = N.array(N.multiply.reduce(N.take(inarray.shape,dims)),N.Float)
+        if keepdims == 1:
+            shp = list(inarray.shape)
+            for dim in dims:
+                shp[dim] = 1
+            sum = N.reshape(sum,shp)
+    return sum/denom
+
+
+ def amedian (inarray,numbins=1000):
+    """
+Calculates the COMPUTED median value of an array of numbers, given the
+number of bins to use for the histogram (more bins approaches finding the
+precise median value of the array; default number of bins = 1000).  From
+G.W. Heiman's Basic Stats, or CRC Probability & Statistics.
+NOTE:  THIS ROUTINE ALWAYS uses the entire passed array (flattens it first).
+
+Usage:   amedian(inarray,numbins=1000)
+Returns: median calculated over ALL values in inarray
+"""
+    inarray = N.ravel(inarray)
+    (hist, smallest, binsize, extras) = ahistogram(inarray,numbins)
+    cumhist = N.cumsum(hist)            # make cumulative histogram
+    otherbins = N.greater_equal(cumhist,len(inarray)/2.0)
+    otherbins = list(otherbins)         # list of 0/1s, 1s start at median bin
+    cfbin = otherbins.index(1)                # get 1st(!) index holding 50%ile score
+    LRL = smallest + binsize*cfbin        # get lower read limit of that bin
+    cfbelow = N.add.reduce(hist[0:cfbin])        # cum. freq. below bin
+    freq = hist[cfbin]                        # frequency IN the 50%ile bin
+    median = LRL + ((len(inarray)/2.0-cfbelow)/float(freq))*binsize # MEDIAN
+    return median
+
+
+ def amedianscore (inarray,dimension=None):
+    """
+Returns the 'middle' score of the passed array.  If there is an even
+number of scores, the mean of the 2 middle scores is returned.  Can function
+with 1D arrays, or on the FIRST dimension of 2D arrays (i.e., dimension can
+be None, to pre-flatten the array, or else dimension must equal 0).
+
+Usage:   amedianscore(inarray,dimension=None)
+Returns: 'middle' score of the array, or the mean of the 2 middle scores
+"""
+    if dimension == None:
+        inarray = N.ravel(inarray)
+        dimension = 0
+    inarray = N.sort(inarray,dimension)
+    if inarray.shape[dimension] % 2 == 0:   # if even number of elements
+        indx = inarray.shape[dimension]/2   # integer division correct
+        median = N.asarray(inarray[indx]+inarray[indx-1]) / 2.0
+    else:
+        indx = inarray.shape[dimension] / 2 # integer division correct
+        median = N.take(inarray,[indx],dimension)
+        if median.shape == (1,):
+            median = median[0]
+    return median
+
+
+ def amode(a, dimension=None):
+    """
+Returns an array of the modal (most common) score in the passed array.
+If there is more than one such score, ONLY THE FIRST is returned.
+The bin-count for the modal values is also returned.  Operates on whole
+array (dimension=None), or on a given dimension.
+
+Usage:   amode(a, dimension=None)
+Returns: array of bin-counts for mode(s), array of corresponding modal values
+"""
+
+    if dimension == None:
+        a = N.ravel(a)
+        dimension = 0
+    scores = pstat.aunique(N.ravel(a))       # get ALL unique values
+    testshape = list(a.shape)
+    testshape[dimension] = 1
+    oldmostfreq = N.zeros(testshape)
+    oldcounts = N.zeros(testshape)
+    for score in scores:
+        template = N.equal(a,score)
+        counts = asum(template,dimension,1)
+        mostfrequent = N.where(N.greater(counts,oldcounts),score,oldmostfreq)
+        oldcounts = N.where(N.greater(counts,oldcounts),counts,oldcounts)
+        oldmostfreq = mostfrequent
+    return oldcounts, mostfrequent
+
+
+ def atmean(a,limits=None,inclusive=(1,1)):
+     """
+Returns the arithmetic mean of all values in an array, ignoring values
+strictly outside the sequence passed to 'limits'.   Note: either limit
+in the sequence, or the value of limits itself, can be set to None.  The
+inclusive list/tuple determines whether the lower and upper limiting bounds
+(respectively) are open/exclusive (0) or closed/inclusive (1).
+
+Usage:   atmean(a,limits=None,inclusive=(1,1))
+"""
+     if a.typecode() in ['l','s','b']:
+         a = a.astype(N.Float)
+     if limits == None:
+         return mean(a)
+     assert type(limits) in [ListType,TupleType,N.ArrayType], "Wrong type for limits in atmean"
+     if inclusive[0]:         lowerfcn = N.greater_equal
+     else:               lowerfcn = N.greater
+     if inclusive[1]:         upperfcn = N.less_equal
+     else:               upperfcn = N.less
+     if limits[0] > N.maximum.reduce(N.ravel(a)) or limits[1] < N.minimum.reduce(N.ravel(a)):
+         raise ValueError, "No array values within given limits (atmean)."
+     elif limits[0]==None and limits[1]<>None:
+         mask = upperfcn(a,limits[1])
+     elif limits[0]<>None and limits[1]==None:
+         mask = lowerfcn(a,limits[0])
+     elif limits[0]<>None and limits[1]<>None:
+         mask = lowerfcn(a,limits[0])*upperfcn(a,limits[1])
+     s = float(N.add.reduce(N.ravel(a*mask)))
+     n = float(N.add.reduce(N.ravel(mask)))
+     return s/n
+
+
+ def atvar(a,limits=None,inclusive=(1,1)):
+     """
+Returns the sample variance of values in an array, (i.e., using N-1),
+ignoring values strictly outside the sequence passed to 'limits'.  
+Note: either limit in the sequence, or the value of limits itself,
+can be set to None.  The inclusive list/tuple determines whether the lower
+and upper limiting bounds (respectively) are open/exclusive (0) or
+closed/inclusive (1).
+
+Usage:   atvar(a,limits=None,inclusive=(1,1))
+"""
+     a = a.astype(N.Float)
+     if limits == None or limits == [None,None]:
+         term1 = N.add.reduce(N.ravel(a*a))
+         n = float(len(N.ravel(a))) - 1
+         term2 = N.add.reduce(N.ravel(a))**2 / n
+         print term1, term2, n
+         return (term1 - term2) / n
+     assert type(limits) in [ListType,TupleType,N.ArrayType], "Wrong type for limits in atvar"
+     if inclusive[0]:         lowerfcn = N.greater_equal
+     else:               lowerfcn = N.greater
+     if inclusive[1]:         upperfcn = N.less_equal
+     else:               upperfcn = N.less
+     if limits[0] > N.maximum.reduce(N.ravel(a)) or limits[1] < N.minimum.reduce(N.ravel(a)):
+         raise ValueError, "No array values within given limits (atvar)."
+     elif limits[0]==None and limits[1]<>None:
+         mask = upperfcn(a,limits[1])
+     elif limits[0]<>None and limits[1]==None:
+         mask = lowerfcn(a,limits[0])
+     elif limits[0]<>None and limits[1]<>None:
+         mask = lowerfcn(a,limits[0])*upperfcn(a,limits[1])
+     term1 = N.add.reduce(N.ravel(a*a*mask))
+     n = float(N.add.reduce(N.ravel(mask))) - 1
+     term2 = N.add.reduce(N.ravel(a*mask))**2 / n
+     print term1, term2, n
+     return (term1 - term2) / n
+
+
+ def atmin(a,lowerlimit=None,dimension=None,inclusive=1):
+     """
+Returns the minimum value of a, along dimension, including only values less
+than (or equal to, if inclusive=1) lowerlimit.  If the limit is set to None,
+all values in the array are used.
+
+Usage:   atmin(a,lowerlimit=None,dimension=None,inclusive=1)
+"""
+     if inclusive:         lowerfcn = N.greater
+     else:               lowerfcn = N.greater_equal
+     if dimension == None:
+         a = N.ravel(a)
+         dimension = 0
+     if lowerlimit == None:
+         lowerlimit = N.minimum.reduce(N.ravel(a))-11
+     biggest = N.maximum.reduce(N.ravel(a))
+     ta = N.where(lowerfcn(a,lowerlimit),a,biggest)
+     return N.minimum.reduce(ta,dimension)
+
+
+ def atmax(a,upperlimit,dimension=None,inclusive=1):
+     """
+Returns the maximum value of a, along dimension, including only values greater
+than (or equal to, if inclusive=1) upperlimit.  If the limit is set to None,
+a limit larger than the max value in the array is used.
+
+Usage:   atmax(a,upperlimit,dimension=None,inclusive=1)
+"""
+     if inclusive:         upperfcn = N.less
+     else:               upperfcn = N.less_equal
+     if dimension == None:
+         a = N.ravel(a)
+         dimension = 0
+     if upperlimit == None:
+         upperlimit = N.maximum.reduce(N.ravel(a))+1
+     smallest = N.minimum.reduce(N.ravel(a))
+     ta = N.where(upperfcn(a,upperlimit),a,smallest)
+     return N.maximum.reduce(ta,dimension)
+
+
+ def atstdev(a,limits=None,inclusive=(1,1)):
+     """
+Returns the standard deviation of all values in an array, ignoring values
+strictly outside the sequence passed to 'limits'.   Note: either limit
+in the sequence, or the value of limits itself, can be set to None.  The
+inclusive list/tuple determines whether the lower and upper limiting bounds
+(respectively) are open/exclusive (0) or closed/inclusive (1).
+
+Usage:   atstdev(a,limits=None,inclusive=(1,1))
+"""
+     return N.sqrt(tvar(a,limits,inclusive))
+
+
+ def atsem(a,limits=None,inclusive=(1,1)):
+     """
+Returns the standard error of the mean for the values in an array,
+(i.e., using N for the denominator), ignoring values strictly outside
+the sequence passed to 'limits'.   Note: either limit in the sequence,
+or the value of limits itself, can be set to None.  The inclusive list/tuple
+determines whether the lower and upper limiting bounds (respectively) are
+open/exclusive (0) or closed/inclusive (1).
+
+Usage:   atsem(a,limits=None,inclusive=(1,1))
+"""
+     sd = tstdev(a,limits,inclusive)
+     if limits == None or limits == [None,None]:
+         n = float(len(N.ravel(a)))
+     assert type(limits) in [ListType,TupleType,N.ArrayType], "Wrong type for limits in atsem"
+     if inclusive[0]:         lowerfcn = N.greater_equal
+     else:               lowerfcn = N.greater
+     if inclusive[1]:         upperfcn = N.less_equal
+     else:               upperfcn = N.less
+     if limits[0] > N.maximum.reduce(N.ravel(a)) or limits[1] < N.minimum.reduce(N.ravel(a)):
+         raise ValueError, "No array values within given limits (atsem)."
+     elif limits[0]==None and limits[1]<>None:
+         mask = upperfcn(a,limits[1])
+     elif limits[0]<>None and limits[1]==None:
+         mask = lowerfcn(a,limits[0])
+     elif limits[0]<>None and limits[1]<>None:
+         mask = lowerfcn(a,limits[0])*upperfcn(a,limits[1])
+     term1 = N.add.reduce(N.ravel(a*a*mask))
+     n = float(N.add.reduce(N.ravel(mask)))
+     return sd/math.sqrt(n)
+
+
+#####################################
+############  AMOMENTS  #############
+#####################################
+
+ def amoment(a,moment=1,dimension=None):
+    """
+Calculates the nth moment about the mean for a sample (defaults to the
+1st moment).  Generally used to calculate coefficients of skewness and
+kurtosis.  Dimension can equal None (ravel array first), an integer
+(the dimension over which to operate), or a sequence (operate over
+multiple dimensions).
+
+Usage:   amoment(a,moment=1,dimension=None)
+Returns: appropriate moment along given dimension
+"""
+    if dimension == None:
+        a = N.ravel(a)
+        dimension = 0
+    if moment == 1:
+        return 0.0
+    else:
+        mn = amean(a,dimension,1)  # 1=keepdims
+        s = N.power((a-mn),moment)
+        return amean(s,dimension)
+
+
+ def avariation(a,dimension=None):
+    """
+Returns the coefficient of variation, as defined in CRC Standard
+Probability and Statistics, p.6. Dimension can equal None (ravel array
+first), an integer (the dimension over which to operate), or a
+sequence (operate over multiple dimensions).
+
+Usage:   avariation(a,dimension=None)
+"""
+    return 100.0*asamplestdev(a,dimension)/amean(a,dimension)
+
+
+ def askew(a,dimension=None): 
+    """ 
+Returns the skewness of a distribution (normal ==> 0.0; >0 means extra
+weight in left tail).  Use askewtest() to see if it's close enough.
+Dimension can equal None (ravel array first), an integer (the
+dimension over which to operate), or a sequence (operate over multiple
+dimensions).
+
+Usage:   askew(a, dimension=None)
+Returns: skew of vals in a along dimension, returning ZERO where all vals equal
+"""
+    denom = N.power(amoment(a,2,dimension),1.5)
+    zero = N.equal(denom,0)
+    if type(denom) == N.ArrayType and asum(zero) <> 0:
+        print "Number of zeros in askew: ",asum(zero)
+    denom = denom + zero  # prevent divide-by-zero
+    return N.where(zero, 0, amoment(a,3,dimension)/denom)
+
+
+ def akurtosis(a,dimension=None):
+    """
+Returns the kurtosis of a distribution (normal ==> 3.0; >3 means
+heavier in the tails, and usually more peaked).  Use akurtosistest()
+to see if it's close enough.  Dimension can equal None (ravel array
+first), an integer (the dimension over which to operate), or a
+sequence (operate over multiple dimensions).
+
+Usage:   akurtosis(a,dimension=None)
+Returns: kurtosis of values in a along dimension, and ZERO where all vals equal
+"""
+    denom = N.power(amoment(a,2,dimension),2)
+    zero = N.equal(denom,0)
+    if type(denom) == N.ArrayType and asum(zero) <> 0:
+        print "Number of zeros in akurtosis: ",asum(zero)
+    denom = denom + zero  # prevent divide-by-zero
+    return N.where(zero,0,amoment(a,4,dimension)/denom)
+
+
+ def adescribe(inarray,dimension=None):
+     """
+Returns several descriptive statistics of the passed array.  Dimension
+can equal None (ravel array first), an integer (the dimension over
+which to operate), or a sequence (operate over multiple dimensions).
+
+Usage:   adescribe(inarray,dimension=None)
+Returns: n, (min,max), mean, standard deviation, skew, kurtosis
+"""
+     if dimension == None:
+         inarray = N.ravel(inarray)
+         dimension = 0
+     n = inarray.shape[dimension]
+     mm = (N.minimum.reduce(inarray),N.maximum.reduce(inarray))
+     m = amean(inarray,dimension)
+     sd = astdev(inarray,dimension)
+     skew = askew(inarray,dimension)
+     kurt = akurtosis(inarray,dimension)
+     return n, mm, m, sd, skew, kurt
+
+
+#####################################
+########  NORMALITY TESTS  ##########
+#####################################
+
+ def askewtest(a,dimension=None):
+    """
+Tests whether the skew is significantly different from a normal
+distribution.  Dimension can equal None (ravel array first), an
+integer (the dimension over which to operate), or a sequence (operate
+over multiple dimensions).
+
+Usage:   askewtest(a,dimension=None)
+Returns: z-score and 2-tail z-probability
+"""
+    if dimension == None:
+        a = N.ravel(a)
+        dimension = 0
+    b2 = askew(a,dimension)
+    n = float(a.shape[dimension])
+    y = b2 * N.sqrt(((n+1)*(n+3)) / (6.0*(n-2)) )
+    beta2 = ( 3.0*(n*n+27*n-70)*(n+1)*(n+3) ) / ( (n-2.0)*(n+5)*(n+7)*(n+9) )
+    W2 = -1 + N.sqrt(2*(beta2-1))
+    delta = 1/N.sqrt(N.log(N.sqrt(W2)))
+    alpha = N.sqrt(2/(W2-1))
+    y = N.where(N.equal(y,0),1,y)
+    Z = delta*N.log(y/alpha + N.sqrt((y/alpha)**2+1))
+    return Z, (1.0-zprob(Z))*2
+
+
+ def akurtosistest(a,dimension=None):
+    """
+Tests whether a dataset has normal kurtosis (i.e.,
+kurtosis=3(n-1)/(n+1)) Valid only for n>20.  Dimension can equal None
+(ravel array first), an integer (the dimension over which to operate),
+or a sequence (operate over multiple dimensions).
+
+Usage:   akurtosistest(a,dimension=None)
+Returns: z-score and 2-tail z-probability, returns 0 for bad pixels
+"""
+    if dimension == None:
+        a = N.ravel(a)
+        dimension = 0
+    n = float(a.shape[dimension])
+    if n<20:
+        print "akurtosistest only valid for n>=20 ... continuing anyway, n=",n
+    b2 = akurtosis(a,dimension)
+    E = 3.0*(n-1) /(n+1)
+    varb2 = 24.0*n*(n-2)*(n-3) / ((n+1)*(n+1)*(n+3)*(n+5))
+    x = (b2-E)/N.sqrt(varb2)
+    sqrtbeta1 = 6.0*(n*n-5*n+2)/((n+7)*(n+9)) * N.sqrt((6.0*(n+3)*(n+5))/
+                                                       (n*(n-2)*(n-3)))
+    A = 6.0 + 8.0/sqrtbeta1 *(2.0/sqrtbeta1 + N.sqrt(1+4.0/(sqrtbeta1**2)))
+    term1 = 1 -2/(9.0*A)
+    denom = 1 +x*N.sqrt(2/(A-4.0))
+    denom = N.where(N.less(denom,0), 99, denom)
+    term2 = N.where(N.equal(denom,0), term1, N.power((1-2.0/A)/denom,1/3.0))
+    Z = ( term1 - term2 ) / N.sqrt(2/(9.0*A))
+    Z = N.where(N.equal(denom,99), 0, Z)
+    return Z, (1.0-zprob(Z))*2
+
+
+ def anormaltest(a,dimension=None):
+    """
+Tests whether skew and/OR kurtosis of dataset differs from normal
+curve.  Can operate over multiple dimensions.  Dimension can equal
+None (ravel array first), an integer (the dimension over which to
+operate), or a sequence (operate over multiple dimensions).
+
+Usage:   anormaltest(a,dimension=None)
+Returns: z-score and 2-tail probability
+"""
+    if dimension == None:
+        a = N.ravel(a)
+        dimension = 0
+    s,p = askewtest(a,dimension)
+    k,p = akurtosistest(a,dimension)
+    k2 = N.power(s,2) + N.power(k,2)
+    return k2, achisqprob(k2,2)
+
+
+#####################################
+######  AFREQUENCY FUNCTIONS  #######
+#####################################
+
+ def aitemfreq(a):
+    """
+Returns a 2D array of item frequencies.  Column 1 contains item values,
+column 2 contains their respective counts.  Assumes a 1D array is passed.
+
+Usage:   aitemfreq(a)
+Returns: a 2D frequency table (col [0:n-1]=scores, col n=frequencies)
+"""
+    scores = pstat.aunique(a)
+    scores = N.sort(scores)
+    freq = N.zeros(len(scores))
+    for i in range(len(scores)):
+        freq[i] = N.add.reduce(N.equal(a,scores[i]))
+    return N.array(pstat.aabut(scores, freq))
+
+
+ def ascoreatpercentile (inarray, percent):
+    """
+Usage:   ascoreatpercentile(inarray,percent)   0<percent<100
+Returns: score at given percentile, relative to inarray distribution
+"""
+    percent = percent / 100.0
+    targetcf = percent*len(inarray)
+    h, lrl, binsize, extras = histogram(inarray)
+    cumhist = cumsum(h*1)
+    for i in range(len(cumhist)):
+        if cumhist[i] >= targetcf:
+            break
+    score = binsize * ((targetcf - cumhist[i-1]) / float(h[i])) + (lrl+binsize*i)
+    return score
+
+
+ def apercentileofscore (inarray,score,histbins=10,defaultlimits=None):
+    """
+Note: result of this function depends on the values used to histogram
+the data(!).
+
+Usage:   apercentileofscore(inarray,score,histbins=10,defaultlimits=None)
+Returns: percentile-position of score (0-100) relative to inarray
+"""
+    h, lrl, binsize, extras = histogram(inarray,histbins,defaultlimits)
+    cumhist = cumsum(h*1)
+    i = int((score - lrl)/float(binsize))
+    pct = (cumhist[i-1]+((score-(lrl+binsize*i))/float(binsize))*h[i])/float(len(inarray)) * 100
+    return pct
+
+
+ def ahistogram (inarray,numbins=10,defaultlimits=None,printextras=1):
+    """
+Returns (i) an array of histogram bin counts, (ii) the smallest value
+of the histogram binning, and (iii) the bin width (the last 2 are not
+necessarily integers).  Default number of bins is 10.  Defaultlimits
+can be None (the routine picks bins spanning all the numbers in the
+inarray) or a 2-sequence (lowerlimit, upperlimit).  Returns all of the
+following: array of bin values, lowerreallimit, binsize, extrapoints.
+
+Usage:   ahistogram(inarray,numbins=10,defaultlimits=None,printextras=1)
+Returns: (array of bin counts, bin-minimum, min-width, #-points-outside-range)
+"""
+    inarray = N.ravel(inarray)               # flatten any >1D arrays
+    if (defaultlimits <> None):
+        lowerreallimit = defaultlimits[0]
+        upperreallimit = defaultlimits[1]
+        binsize = (upperreallimit-lowerreallimit) / float(numbins)
+    else:
+        Min = N.minimum.reduce(inarray)
+        Max = N.maximum.reduce(inarray)
+        estbinwidth = float(Max - Min)/float(numbins) + 1
+        binsize = (Max-Min+estbinwidth)/float(numbins)
+        lowerreallimit = Min - binsize/2.0  #lower real limit,1st bin
+    bins = N.zeros(numbins)
+    extrapoints = 0
+    for num in inarray:
+        try:
+            if (num-lowerreallimit) < 0:
+                extrapoints = extrapoints + 1
+            else:
+                bintoincrement = int((num-lowerreallimit) / float(binsize))
+                bins[bintoincrement] = bins[bintoincrement] + 1
+        except:                           # point outside lower/upper limits
+            extrapoints = extrapoints + 1
+    if (extrapoints > 0 and printextras == 1):
+        print '\nPoints outside given histogram range =',extrapoints
+    return (bins, lowerreallimit, binsize, extrapoints)
+
+
+ def acumfreq(a,numbins=10,defaultreallimits=None):
+    """
+Returns a cumulative frequency histogram, using the histogram function.
+Defaultreallimits can be None (use all data), or a 2-sequence containing
+lower and upper limits on values to include.
+
+Usage:   acumfreq(a,numbins=10,defaultreallimits=None)
+Returns: array of cumfreq bin values, lowerreallimit, binsize, extrapoints
+"""
+    h,l,b,e = histogram(a,numbins,defaultreallimits)
+    cumhist = cumsum(h*1)
+    return cumhist,l,b,e
+
+
+ def arelfreq(a,numbins=10,defaultreallimits=None):
+    """
+Returns a relative frequency histogram, using the histogram function.
+Defaultreallimits can be None (use all data), or a 2-sequence containing
+lower and upper limits on values to include.
+
+Usage:   arelfreq(a,numbins=10,defaultreallimits=None)
+Returns: array of cumfreq bin values, lowerreallimit, binsize, extrapoints
+"""
+    h,l,b,e = histogram(a,numbins,defaultreallimits)
+    h = N.array(h/float(a.shape[0]))
+    return h,l,b,e
+
+
+#####################################
+######  AVARIABILITY FUNCTIONS  #####
+#####################################
+
+ def aobrientransform(*args):
+    """
+Computes a transform on input data (any number of columns).  Used to
+test for homogeneity of variance prior to running one-way stats.  Each
+array in *args is one level of a factor.  If an F_oneway() run on the
+transformed data and found significant, variances are unequal.   From
+Maxwell and Delaney, p.112.
+
+Usage:   aobrientransform(*args)    *args = 1D arrays, one per level of factor
+Returns: transformed data for use in an ANOVA
+"""
+    TINY = 1e-10
+    k = len(args)
+    n = N.zeros(k,N.Float)
+    v = N.zeros(k,N.Float)
+    m = N.zeros(k,N.Float)
+    nargs = []
+    for i in range(k):
+        nargs.append(args[i].astype(N.Float))
+        n[i] = float(len(nargs[i]))
+        v[i] = var(nargs[i])
+        m[i] = mean(nargs[i])
+    for j in range(k):
+        for i in range(n[j]):
+            t1 = (n[j]-1.5)*n[j]*(nargs[j][i]-m[j])**2
+            t2 = 0.5*v[j]*(n[j]-1.0)
+            t3 = (n[j]-1.0)*(n[j]-2.0)
+            nargs[j][i] = (t1-t2) / float(t3)
+    check = 1
+    for j in range(k):
+        if v[j] - mean(nargs[j]) > TINY:
+            check = 0
+    if check <> 1:
+        raise ValueError, 'Lack of convergence in obrientransform.'
+    else:
+        return N.array(nargs)
+
+
+ def asamplevar (inarray,dimension=None,keepdims=0):
+    """
+Returns the sample standard deviation of the values in the passed
+array (i.e., using N).  Dimension can equal None (ravel array first),
+an integer (the dimension over which to operate), or a sequence
+(operate over multiple dimensions).  Set keepdims=1 to return an array
+with the same number of dimensions as inarray.
+
+Usage:   asamplevar(inarray,dimension=None,keepdims=0)
+"""
+    if dimension == None:
+        inarray = N.ravel(inarray)
+        dimension = 0
+    if dimension == 1:
+        mn = amean(inarray,dimension)[:,N.NewAxis]
+    else:
+        mn = amean(inarray,dimension,keepdims=1)
+    deviations = inarray - mn 
+    if type(dimension) == ListType:
+        n = 1
+        for d in dimension:
+            n = n*inarray.shape[d]
+    else:
+        n = inarray.shape[dimension]
+    svar = ass(deviations,dimension,keepdims) / float(n)
+    return svar
+
+
+ def asamplestdev (inarray, dimension=None, keepdims=0):
+    """
+Returns the sample standard deviation of the values in the passed
+array (i.e., using N).  Dimension can equal None (ravel array first),
+an integer (the dimension over which to operate), or a sequence
+(operate over multiple dimensions).  Set keepdims=1 to return an array
+with the same number of dimensions as inarray.
+
+Usage:   asamplestdev(inarray,dimension=None,keepdims=0)
+"""
+    return N.sqrt(asamplevar(inarray,dimension,keepdims))
+
+
+ def asignaltonoise(instack,dimension=0):
+    """
+Calculates signal-to-noise.  Dimension can equal None (ravel array
+first), an integer (the dimension over which to operate), or a
+sequence (operate over multiple dimensions).
+
+Usage:   asignaltonoise(instack,dimension=0):
+Returns: array containing the value of (mean/stdev) along dimension,
+         or 0 when stdev=0
+"""
+    m = mean(instack,dimension)
+    sd = stdev(instack,dimension)
+    return N.where(N.equal(sd,0),0,m/sd)
+
+
+ def avar (inarray, dimension=None,keepdims=0):
+    """
+Returns the estimated population variance of the values in the passed
+array (i.e., N-1).  Dimension can equal None (ravel array first), an
+integer (the dimension over which to operate), or a sequence (operate
+over multiple dimensions).  Set keepdims=1 to return an array with the
+same number of dimensions as inarray.
+
+Usage:   avar(inarray,dimension=None,keepdims=0)
+"""
+    if dimension == None:
+        inarray = N.ravel(inarray)
+        dimension = 0
+    mn = amean(inarray,dimension,1)
+    deviations = inarray - mn
+    if type(dimension) == ListType:
+        n = 1
+        for d in dimension:
+            n = n*inarray.shape[d]
+    else:
+        n = inarray.shape[dimension]
+    var = ass(deviations,dimension,keepdims)/float(n-1)
+    return var
+
+
+ def astdev (inarray, dimension=None, keepdims=0):
+    """
+Returns the estimated population standard deviation of the values in
+the passed array (i.e., N-1).  Dimension can equal None (ravel array
+first), an integer (the dimension over which to operate), or a
+sequence (operate over multiple dimensions).  Set keepdims=1 to return
+an array with the same number of dimensions as inarray.
+
+Usage:   astdev(inarray,dimension=None,keepdims=0)
+"""
+    return N.sqrt(avar(inarray,dimension,keepdims))
+
+
+ def asterr (inarray, dimension=None, keepdims=0):
+    """
+Returns the estimated population standard error of the values in the
+passed array (i.e., N-1).  Dimension can equal None (ravel array
+first), an integer (the dimension over which to operate), or a
+sequence (operate over multiple dimensions).  Set keepdims=1 to return
+an array with the same number of dimensions as inarray.
+
+Usage:   asterr(inarray,dimension=None,keepdims=0)
+"""
+    if dimension == None:
+        inarray = N.ravel(inarray)
+        dimension = 0
+    return astdev(inarray,dimension,keepdims) / float(N.sqrt(inarray.shape[dimension]))
+
+
+ def asem (inarray, dimension=None, keepdims=0):
+    """
+Returns the standard error of the mean (i.e., using N) of the values
+in the passed array.  Dimension can equal None (ravel array first), an
+integer (the dimension over which to operate), or a sequence (operate
+over multiple dimensions).  Set keepdims=1 to return an array with the
+same number of dimensions as inarray.
+
+Usage:   asem(inarray,dimension=None, keepdims=0)
+"""
+    if dimension == None:
+        inarray = N.ravel(inarray)
+        dimension = 0
+    if type(dimension) == ListType:
+        n = 1
+        for d in dimension:
+            n = n*inarray.shape[d]
+    else:
+        n = inarray.shape[dimension]
+    s = asamplestdev(inarray,dimension,keepdims) / N.sqrt(n-1)
+    return s
+
+
+ def az (a, score):
+    """
+Returns the z-score of a given input score, given thearray from which
+that score came.  Not appropriate for population calculations, nor for
+arrays > 1D.
+
+Usage:   az(a, score)
+"""
+    z = (score-amean(a)) / asamplestdev(a)
+    return z
+
+
+ def azs (a):
+    """
+Returns a 1D array of z-scores, one for each score in the passed array,
+computed relative to the passed array.
+
+Usage:   azs(a)
+"""
+    zscores = []
+    for item in a:
+        zscores.append(z(a,item))
+    return N.array(zscores)
+
+
+ def azmap (scores, compare, dimension=0):
+    """
+Returns an array of z-scores the shape of scores (e.g., [x,y]), compared to
+array passed to compare (e.g., [time,x,y]).  Assumes collapsing over dim 0
+of the compare array.
+
+Usage:   azs(scores, compare, dimension=0)
+"""
+    mns = amean(compare,dimension)
+    sstd = asamplestdev(compare,0)
+    return (scores - mns) / sstd
+
+
+#####################################
+#######  ATRIMMING FUNCTIONS  #######
+#####################################
+
+ def around(a,digits=1):
+     """
+Rounds all values in array a to 'digits' decimal places.
+
+Usage:   around(a,digits)
+Returns: a, where each value is rounded to 'digits' decimals
+"""
+     def ar(x,d=digits):
+         return round(x,d)
+
+     if type(a) <> N.ArrayType:
+         try:
+             a = N.array(a)
+         except:
+             a = N.array(a,'O')
+     shp = a.shape
+     if a.typecode() in ['f','F','d','D']:
+         b = N.ravel(a)
+         b = N.array(map(ar,b))
+         b.shape = shp
+     elif a.typecode() in ['o','O']:
+         b = N.ravel(a)*1
+         for i in range(len(b)):
+             if type(b[i]) == FloatType:
+                 b[i] = round(b[i],digits)
+         b.shape = shp
+     else:  # not a float, double or Object array
+         b = a*1
+     return b
+
+
+ def athreshold(a,threshmin=None,threshmax=None,newval=0):
+    """
+Like Numeric.clip() except that values <threshmid or >threshmax are replaced
+by newval instead of by threshmin/threshmax (respectively).
+
+Usage:   athreshold(a,threshmin=None,threshmax=None,newval=0)
+Returns: a, with values <threshmin or >threshmax replaced with newval
+"""
+    mask = N.zeros(a.shape)
+    if threshmin <> None:
+        mask = mask + N.where(N.less(a,threshmin),1,0)
+    if threshmax <> None:
+        mask = mask + N.where(N.greater(a,threshmax),1,0)
+    mask = N.clip(mask,0,1)
+    return N.where(mask,newval,a)
+
+
+ def atrimboth (a,proportiontocut):
+    """
+Slices off the passed proportion of items from BOTH ends of the passed
+array (i.e., with proportiontocut=0.1, slices 'leftmost' 10% AND
+'rightmost' 10% of scores.  You must pre-sort the array if you want
+"proper" trimming.  Slices off LESS if proportion results in a
+non-integer slice index (i.e., conservatively slices off
+proportiontocut).
+
+Usage:   atrimboth (a,proportiontocut)
+Returns: trimmed version of array a
+"""
+    lowercut = int(proportiontocut*len(a))
+    uppercut = len(a) - lowercut
+    return a[lowercut:uppercut]
+
+
+ def atrim1 (a,proportiontocut,tail='right'):
+    """
+Slices off the passed proportion of items from ONE end of the passed
+array (i.e., if proportiontocut=0.1, slices off 'leftmost' or 'rightmost'
+10% of scores).  Slices off LESS if proportion results in a non-integer
+slice index (i.e., conservatively slices off proportiontocut).
+
+Usage:   atrim1(a,proportiontocut,tail='right')  or set tail='left'
+Returns: trimmed version of array a
+"""
+    if string.lower(tail) == 'right':
+        lowercut = 0
+        uppercut = len(a) - int(proportiontocut*len(a))
+    elif string.lower(tail) == 'left':
+        lowercut = int(proportiontocut*len(a))
+        uppercut = len(a)
+    return a[lowercut:uppercut]
+
+
+#####################################
+#####  ACORRELATION FUNCTIONS  ######
+#####################################
+
+ def acovariance(X):
+    """
+Computes the covariance matrix of a matrix X.  Requires a 2D matrix input.
+
+Usage:   acovariance(X)
+Returns: covariance matrix of X
+"""
+    if len(X.shape) <> 2:
+        raise TypeError, "acovariance requires 2D matrices"
+    n = X.shape[0]
+    mX = amean(X,0)
+    return N.dot(N.transpose(X),X) / float(n) - N.multiply.outer(mX,mX)
+
+
+ def acorrelation(X):
+    """
+Computes the correlation matrix of a matrix X.  Requires a 2D matrix input.
+
+Usage:   acorrelation(X)
+Returns: correlation matrix of X
+"""
+    C = acovariance(X)
+    V = N.diagonal(C)
+    return C / N.sqrt(N.multiply.outer(V,V))
+
+
+ def apaired(x,y):
+    """
+Interactively determines the type of data in x and y, and then runs the
+appropriated statistic for paired group data.
+
+Usage:   apaired(x,y)     x,y = the two arrays of values to be compared
+Returns: appropriate statistic name, value, and probability
+"""
+    samples = ''
+    while samples not in ['i','r','I','R','c','C']:
+        print '\nIndependent or related samples, or correlation (i,r,c): ',
+        samples = raw_input()
+
+    if samples in ['i','I','r','R']:
+        print '\nComparing variances ...',
+# USE O'BRIEN'S TEST FOR HOMOGENEITY OF VARIANCE, Maxwell & delaney, p.112
+        r = obrientransform(x,y)
+        f,p = F_oneway(pstat.colex(r,0),pstat.colex(r,1))
+        if p<0.05:
+            vartype='unequal, p='+str(round(p,4))
+        else:
+            vartype='equal'
+        print vartype
+        if samples in ['i','I']:
+            if vartype[0]=='e':
+                t,p = ttest_ind(x,y,None,0)
+                print '\nIndependent samples t-test:  ', round(t,4),round(p,4)
+            else:
+                if len(x)>20 or len(y)>20:
+                    z,p = ranksums(x,y)
+                    print '\nRank Sums test (NONparametric, n>20):  ', round(z,4),round(p,4)
+                else:
+                    u,p = mannwhitneyu(x,y)
+                    print '\nMann-Whitney U-test (NONparametric, ns<20):  ', round(u,4),round(p,4)
+
+        else:  # RELATED SAMPLES
+            if vartype[0]=='e':
+                t,p = ttest_rel(x,y,0)
+                print '\nRelated samples t-test:  ', round(t,4),round(p,4)
+            else:
+                t,p = ranksums(x,y)
+                print '\nWilcoxon T-test (NONparametric):  ', round(t,4),round(p,4)
+    else:  # CORRELATION ANALYSIS
+        corrtype = ''
+        while corrtype not in ['c','C','r','R','d','D']:
+            print '\nIs the data Continuous, Ranked, or Dichotomous (c,r,d): ',
+            corrtype = raw_input()
+        if corrtype in ['c','C']:
+            m,b,r,p,see = linregress(x,y)
+            print '\nLinear regression for continuous variables ...'
+            lol = [['Slope','Intercept','r','Prob','SEestimate'],[round(m,4),round(b,4),round(r,4),round(p,4),round(see,4)]]
+            pstat.printcc(lol)
+        elif corrtype in ['r','R']:
+            r,p = spearmanr(x,y)
+            print '\nCorrelation for ranked variables ...'
+            print "Spearman's r: ",round(r,4),round(p,4)
+        else: # DICHOTOMOUS
+            r,p = pointbiserialr(x,y)
+            print '\nAssuming x contains a dichotomous variable ...'
+            print 'Point Biserial r: ',round(r,4),round(p,4)
+    print '\n\n'
+    return None
+
+
+ def apearsonr(x,y,verbose=1):
+    """
+Calculates a Pearson correlation coefficient and returns p.  Taken
+from Heiman's Basic Statistics for the Behav. Sci (2nd), p.195.
+
+Usage:   apearsonr(x,y,verbose=1)      where x,y are equal length arrays
+Returns: Pearson's r, two-tailed p-value
+"""
+    TINY = 1.0e-20
+    n = len(x)
+    xmean = amean(x)
+    ymean = amean(y)
+    r_num = n*(N.add.reduce(x*y)) - N.add.reduce(x)*N.add.reduce(y)
+    r_den = math.sqrt((n*ass(x) - asquare_of_sums(x))*(n*ass(y)-asquare_of_sums(y)))
+    r = (r_num / r_den)
+    df = n-2
+    t = r*math.sqrt(df/((1.0-r+TINY)*(1.0+r+TINY)))
+    prob = abetai(0.5*df,0.5,df/(df+t*t),verbose)
+    return r,prob
+
+
+ def aspearmanr(x,y):
+    """
+Calculates a Spearman rank-order correlation coefficient.  Taken
+from Heiman's Basic Statistics for the Behav. Sci (1st), p.192.
+
+Usage:   aspearmanr(x,y)      where x,y are equal-length arrays
+Returns: Spearman's r, two-tailed p-value
+"""
+    TINY = 1e-30
+    n = len(x)
+    rankx = rankdata(x)
+    ranky = rankdata(y)
+    dsq = N.add.reduce((rankx-ranky)**2)
+    rs = 1 - 6*dsq / float(n*(n**2-1))
+    t = rs * math.sqrt((n-2) / ((rs+1.0)*(1.0-rs)))
+    df = n-2
+    probrs = abetai(0.5*df,0.5,df/(df+t*t))
+# probability values for rs are from part 2 of the spearman function in
+# Numerical Recipies, p.510.  They close to tables, but not exact.(?)
+    return rs, probrs
+
+
+ def apointbiserialr(x,y):
+    """
+Calculates a point-biserial correlation coefficient and the associated
+probability value.  Taken from Heiman's Basic Statistics for the Behav.
+Sci (1st), p.194.
+
+Usage:   apointbiserialr(x,y)      where x,y are equal length arrays
+Returns: Point-biserial r, two-tailed p-value
+"""
+    TINY = 1e-30
+    categories = pstat.aunique(x)
+    data = pstat.aabut(x,y)
+    if len(categories) <> 2:
+        raise ValueError, "Exactly 2 categories required (in x) for pointbiserialr()."
+    else:   # there are 2 categories, continue
+        codemap = pstat.aabut(categories,N.arange(2))
+        recoded = pstat.arecode(data,codemap,0)
+        x = pstat.alinexand(data,0,categories[0])
+        y = pstat.alinexand(data,0,categories[1])
+        xmean = amean(pstat.acolex(x,1))
+        ymean = amean(pstat.acolex(y,1))
+        n = len(data)
+        adjust = math.sqrt((len(x)/float(n))*(len(y)/float(n)))
+        rpb = (ymean - xmean)/asamplestdev(pstat.acolex(data,1))*adjust
+        df = n-2
+        t = rpb*math.sqrt(df/((1.0-rpb+TINY)*(1.0+rpb+TINY)))
+        prob = abetai(0.5*df,0.5,df/(df+t*t))
+        return rpb, prob
+
+
+ def akendalltau(x,y):
+    """
+Calculates Kendall's tau ... correlation of ordinal data.  Adapted
+from function kendl1 in Numerical Recipies.  Needs good test-cases.@@@
+
+Usage:   akendalltau(x,y)
+Returns: Kendall's tau, two-tailed p-value
+"""
+    n1 = 0
+    n2 = 0
+    iss = 0
+    for j in range(len(x)-1):
+        for k in range(j,len(y)):
+            a1 = x[j] - x[k]
+            a2 = y[j] - y[k]
+            aa = a1 * a2
+            if (aa):             # neither array has a tie
+                n1 = n1 + 1
+                n2 = n2 + 1
+                if aa > 0:
+                    iss = iss + 1
+                else:
+                    iss = iss -1
+            else:
+                if (a1):
+                    n1 = n1 + 1
+                else:
+                    n2 = n2 + 1
+    tau = iss / math.sqrt(n1*n2)
+    svar = (4.0*len(x)+10.0) / (9.0*len(x)*(len(x)-1))
+    z = tau / math.sqrt(svar)
+    prob = erfcc(abs(z)/1.4142136)
+    return tau, prob
+
+
+ def alinregress(*args):
+    """
+Calculates a regression line on two arrays, x and y, corresponding to x,y
+pairs.  If a single 2D array is passed, alinregress finds dim with 2 levels
+and splits data into x,y pairs along that dim.
+
+Usage:   alinregress(*args)    args=2 equal-length arrays, or one 2D array
+Returns: slope, intercept, r, two-tailed prob, sterr-of-the-estimate
+"""
+    TINY = 1.0e-20
+    if len(args) == 1:  # more than 1D array?
+        args = args[0]
+        if len(args) == 2:
+            x = args[0]
+            y = args[1]
+        else:
+            x = args[:,0]
+            y = args[:,1]
+    else:
+        x = args[0]
+        y = args[1]
+    n = len(x)
+    xmean = amean(x)
+    ymean = amean(y)
+    r_num = n*(N.add.reduce(x*y)) - N.add.reduce(x)*N.add.reduce(y)
+    r_den = math.sqrt((n*ass(x) - asquare_of_sums(x))*(n*ass(y)-asquare_of_sums(y)))
+    r = r_num / r_den
+    z = 0.5*math.log((1.0+r+TINY)/(1.0-r+TINY))
+    df = n-2
+    t = r*math.sqrt(df/((1.0-r+TINY)*(1.0+r+TINY)))
+    prob = abetai(0.5*df,0.5,df/(df+t*t))
+    slope = r_num / (float(n)*ass(x) - asquare_of_sums(x))
+    intercept = ymean - slope*xmean
+    sterrest = math.sqrt(1-r*r)*asamplestdev(y)
+    return slope, intercept, r, prob, sterrest
+
+
+#####################################
+#####  AINFERENTIAL STATISTICS  #####
+#####################################
+
+ def attest_1samp(a,popmean,printit=0,name='Sample',writemode='a'):
+    """
+Calculates the t-obtained for the independent samples T-test on ONE group
+of scores a, given a population mean.  If printit=1, results are printed
+to the screen.  If printit='filename', the results are output to 'filename'
+using the given writemode (default=append).  Returns t-value, and prob.
+
+Usage:   attest_1samp(a,popmean,Name='Sample',printit=0,writemode='a')
+Returns: t-value, two-tailed prob
+"""
+    if type(a) != N.ArrayType:
+        a = N.array(a)
+    x = amean(a)
+    v = avar(a)
+    n = len(a)
+    df = n-1
+    svar = ((n-1)*v) / float(df)
+    t = (x-popmean)/math.sqrt(svar*(1.0/n))
+    prob = abetai(0.5*df,0.5,df/(df+t*t))
+
+    if printit <> 0:
+        statname = 'Single-sample T-test.'
+        outputpairedstats(printit,writemode,
+                          'Population','--',popmean,0,0,0,
+                          name,n,x,v,N.minimum.reduce(N.ravel(a)),
+                          N.maximum.reduce(N.ravel(a)),
+                          statname,t,prob)
+    return t,prob
+
+
+ def attest_ind (a, b, dimension=None, printit=0, name1='Samp1', name2='Samp2',writemode='a'):
+    """
+Calculates the t-obtained T-test on TWO INDEPENDENT samples of scores
+a, and b.  From Numerical Recipies, p.483.  If printit=1, results are
+printed to the screen.  If printit='filename', the results are output
+to 'filename' using the given writemode (default=append).  Dimension
+can equal None (ravel array first), or an integer (the dimension over
+which to operate on a and b).
+
+Usage:   attest_ind (a,b,dimension=None,printit=0,
+                     Name1='Samp1',Name2='Samp2',writemode='a')
+Returns: t-value, two-tailed p-value
+"""
+    if dimension == None:
+        a = N.ravel(a)
+        b = N.ravel(b)
+        dimension = 0
+    x1 = amean(a,dimension)
+    x2 = amean(b,dimension)
+    v1 = avar(a,dimension)
+    v2 = avar(b,dimension)
+    n1 = a.shape[dimension]
+    n2 = b.shape[dimension]
+    df = n1+n2-2
+    svar = ((n1-1)*v1+(n2-1)*v2) / float(df)
+    zerodivproblem = N.equal(svar,0)
+    svar = N.where(zerodivproblem,1,svar)  # avoid zero-division in 1st place
+    t = (x1-x2)/N.sqrt(svar*(1.0/n1 + 1.0/n2))  # N-D COMPUTATION HERE!!!!!!
+    t = N.where(zerodivproblem,1.0,t)     # replace NaN/wrong t-values with 1.0
+    probs = abetai(0.5*df,0.5,float(df)/(df+t*t))
+
+    if type(t) == N.ArrayType:
+        probs = N.reshape(probs,t.shape)
+    if len(probs) == 1:
+        probs = probs[0]
+        
+    if printit <> 0:
+        if type(t) == N.ArrayType:
+            t = t[0]
+        if type(probs) == N.ArrayType:
+            probs = probs[0]
+        statname = 'Independent samples T-test.'
+        outputpairedstats(printit,writemode,
+                          name1,n1,x1,v1,N.minimum.reduce(N.ravel(a)),
+                          N.maximum.reduce(N.ravel(a)),
+                          name2,n2,x2,v2,N.minimum.reduce(N.ravel(b)),
+                          N.maximum.reduce(N.ravel(b)),
+                          statname,t,probs)
+        return
+    return t, probs
+
+
+ def attest_rel (a,b,dimension=None,printit=0,name1='Samp1',name2='Samp2',writemode='a'):
+    """
+Calculates the t-obtained T-test on TWO RELATED samples of scores, a
+and b.  From Numerical Recipies, p.483.  If printit=1, results are
+printed to the screen.  If printit='filename', the results are output
+to 'filename' using the given writemode (default=append).  Dimension
+can equal None (ravel array first), or an integer (the dimension over
+which to operate on a and b).
+
+Usage:   attest_rel(a,b,dimension=None,printit=0,
+                    name1='Samp1',name2='Samp2',writemode='a')
+Returns: t-value, two-tailed p-value
+"""
+    if dimension == None:
+        a = N.ravel(a)
+        b = N.ravel(b)
+        dimension = 0
+    if len(a)<>len(b):
+        raise ValueError, 'Unequal length arrays.'
+    x1 = amean(a,dimension)
+    x2 = amean(b,dimension)
+    v1 = avar(a,dimension)
+    v2 = avar(b,dimension)
+    n = a.shape[dimension]
+    df = float(n-1)
+    d = (a-b).astype('d')
+
+    denom = N.sqrt((n*N.add.reduce(d*d,dimension) - N.add.reduce(d,dimension)**2) /df)
+    zerodivproblem = N.equal(denom,0)
+    denom = N.where(zerodivproblem,1,denom)  # avoid zero-division in 1st place
+    t = N.add.reduce(d,dimension) / denom      # N-D COMPUTATION HERE!!!!!!
+    t = N.where(zerodivproblem,1.0,t)     # replace NaN/wrong t-values with 1.0
+    probs = abetai(0.5*df,0.5,float(df)/(df+t*t))
+    if type(t) == N.ArrayType:
+        probs = N.reshape(probs,t.shape)
+    if len(probs) == 1:
+        probs = probs[0]
+
+    if printit <> 0:
+        statname = 'Related samples T-test.'
+        outputpairedstats(printit,writemode,
+                          name1,n,x1,v1,N.minimum.reduce(N.ravel(a)),
+                          N.maximum.reduce(N.ravel(a)),
+                          name2,n,x2,v2,N.minimum.reduce(N.ravel(b)),
+                          N.maximum.reduce(N.ravel(b)),
+                          statname,t,probs)
+        return
+    return t, probs
+
+
+ def achisquare(f_obs,f_exp=None):
+    """
+Calculates a one-way chi square for array of observed frequencies and returns
+the result.  If no expected frequencies are given, the total N is assumed to
+be equally distributed across all groups.
+
+Usage:   achisquare(f_obs, f_exp=None)   f_obs = array of observed cell freq.
+Returns: chisquare-statistic, associated p-value
+"""
+
+    k = len(f_obs)
+    if f_exp == None:
+        f_exp = N.array([sum(f_obs)/float(k)] * len(f_obs),N.Float)
+    f_exp = f_exp.astype(N.Float)
+    chisq = N.add.reduce((f_obs-f_exp)**2 / f_exp)
+    return chisq, chisqprob(chisq, k-1)
+
+
+ def aks_2samp (data1,data2):
+    """
+Computes the Kolmogorov-Smirnof statistic on 2 samples.  Modified from
+Numerical Recipies in C, page 493.  Returns KS D-value, prob.  Not ufunc-
+like.
+
+Usage:   aks_2samp(data1,data2)  where data1 and data2 are 1D arrays
+Returns: KS D-value, p-value
+"""
+    j1 = 0    # N.zeros(data1.shape[1:]) TRIED TO MAKE THIS UFUNC-LIKE
+    j2 = 0    # N.zeros(data2.shape[1:])
+    fn1 = 0.0 # N.zeros(data1.shape[1:],N.Float)
+    fn2 = 0.0 # N.zeros(data2.shape[1:],N.Float)
+    n1 = data1.shape[0]
+    n2 = data2.shape[0]
+    en1 = n1*1
+    en2 = n2*1
+    d = N.zeros(data1.shape[1:],N.Float)
+    data1 = N.sort(data1,0)
+    data2 = N.sort(data2,0)
+    while j1 < n1 and j2 < n2:
+        d1=data1[j1]
+        d2=data2[j2]
+        if d1 <= d2:
+            fn1 = (j1)/float(en1)
+            j1 = j1 + 1
+        if d2 <= d1:
+            fn2 = (j2)/float(en2)
+            j2 = j2 + 1
+        dt = (fn2-fn1)
+        if abs(dt) > abs(d):
+            d = dt
+    try:
+        en = math.sqrt(en1*en2/float(en1+en2))
+        prob = aksprob((en+0.12+0.11/en)*N.fabs(d))
+    except:
+        prob = 1.0
+    return d, prob
+
+
+ def amannwhitneyu(x,y):
+    """
+Calculates a Mann-Whitney U statistic on the provided scores and
+returns the result.  Use only when the n in each condition is < 20 and
+you have 2 independent samples of ranks.  REMEMBER: Mann-Whitney U is
+significant if the u-obtained is LESS THAN or equal to the critical
+value of U.
+
+Usage:   amannwhitneyu(x,y)     where x,y are arrays of values for 2 conditions
+Returns: u-statistic, one-tailed p-value (i.e., p(z(U)))
+"""
+    n1 = len(x)
+    n2 = len(y)
+    ranked = rankdata(N.concatenate((x,y)))
+    rankx = ranked[0:n1]       # get the x-ranks
+    ranky = ranked[n1:]        # the rest are y-ranks
+    u1 = n1*n2 + (n1*(n1+1))/2.0 - sum(rankx)  # calc U for x
+    u2 = n1*n2 - u1                            # remainder is U for y
+    bigu = max(u1,u2)
+    smallu = min(u1,u2)
+    T = math.sqrt(tiecorrect(ranked))  # correction factor for tied scores
+    if T == 0:
+        raise ValueError, 'All numbers are identical in amannwhitneyu'
+    sd = math.sqrt(T*n1*n2*(n1+n2+1)/12.0)
+    z = abs((bigu-n1*n2/2.0) / sd)  # normal approximation for prob calc
+    return smallu, 1.0 - zprob(z)
+
+
+ def atiecorrect(rankvals):
+    """
+Tie-corrector for ties in Mann Whitney U and Kruskal Wallis H tests.
+See Siegel, S. (1956) Nonparametric Statistics for the Behavioral
+Sciences.  New York: McGraw-Hill.  Code adapted from |Stat rankind.c
+code.
+
+Usage:   atiecorrect(rankvals)
+Returns: T correction factor for U or H
+"""
+    sorted,posn = ashellsort(N.array(rankvals))
+    n = len(sorted)
+    T = 0.0
+    i = 0
+    while (i<n-1):
+        if sorted[i] == sorted[i+1]:
+            nties = 1
+            while (i<n-1) and (sorted[i] == sorted[i+1]):
+                nties = nties +1
+                i = i +1
+            T = T + nties**3 - nties
+        i = i+1
+    T = T / float(n**3-n)
+    return 1.0 - T
+
+
+ def aranksums(x,y):
+    """
+Calculates the rank sums statistic on the provided scores and returns
+the result.
+
+Usage:   aranksums(x,y)     where x,y are arrays of values for 2 conditions
+Returns: z-statistic, two-tailed p-value
+"""
+    n1 = len(x)
+    n2 = len(y)
+    alldata = N.concatenate((x,y))
+    ranked = arankdata(alldata)
+    x = ranked[:n1]
+    y = ranked[n1:]
+    s = sum(x)
+    expected = n1*(n1+n2+1) / 2.0
+    z = (s - expected) / math.sqrt(n1*n2*(n1+n2+1)/12.0)
+    prob = 2*(1.0 -zprob(abs(z)))
+    return z, prob
+
+
+ def awilcoxont(x,y):
+    """
+Calculates the Wilcoxon T-test for related samples and returns the
+result.  A non-parametric T-test.
+
+Usage:   awilcoxont(x,y)     where x,y are equal-length arrays for 2 conditions
+Returns: t-statistic, two-tailed p-value
+"""
+    if len(x) <> len(y):
+        raise ValueError, 'Unequal N in awilcoxont.  Aborting.'
+    d = x-y
+    d = N.compress(N.not_equal(d,0),d) # Keep all non-zero differences
+    count = len(d)
+    absd = abs(d)
+    absranked = arankdata(absd)
+    r_plus = 0.0
+    r_minus = 0.0
+    for i in range(len(absd)):
+        if d[i] < 0:
+            r_minus = r_minus + absranked[i]
+        else:
+            r_plus = r_plus + absranked[i]
+    wt = min(r_plus, r_minus)
+    mn = count * (count+1) * 0.25
+    se =  math.sqrt(count*(count+1)*(2.0*count+1.0)/24.0)
+    z = math.fabs(wt-mn) / se
+    z = math.fabs(wt-mn) / se
+    prob = 2*(1.0 -zprob(abs(z)))
+    return wt, prob
+
+
+ def akruskalwallish(*args):
+    """
+The Kruskal-Wallis H-test is a non-parametric ANOVA for 3 or more
+groups, requiring at least 5 subjects in each group.  This function
+calculates the Kruskal-Wallis H and associated p-value for 3 or more
+independent samples.
+
+Usage:   akruskalwallish(*args)     args are separate arrays for 3+ conditions
+Returns: H-statistic (corrected for ties), associated p-value
+"""
+    assert len(args) == 3, "Need at least 3 groups in stats.akruskalwallish()"
+    args = list(args)
+    n = [0]*len(args)
+    n = map(len,args)
+    all = []
+    for i in range(len(args)):
+        all = all + args[i].tolist()
+    ranked = rankdata(all)
+    T = tiecorrect(ranked)
+    for i in range(len(args)):
+        args[i] = ranked[0:n[i]]
+        del ranked[0:n[i]]
+    rsums = []
+    for i in range(len(args)):
+        rsums.append(sum(args[i])**2)
+        rsums[i] = rsums[i] / float(n[i])
+    ssbn = sum(rsums)
+    totaln = sum(n)
+    h = 12.0 / (totaln*(totaln+1)) * ssbn - 3*(totaln+1)
+    df = len(args) - 1
+    if T == 0:
+        raise ValueError, 'All numbers are identical in akruskalwallish'
+    h = h / float(T)
+    return h, chisqprob(h,df)
+
+
+ def afriedmanchisquare(*args):
+    """
+Friedman Chi-Square is a non-parametric, one-way within-subjects
+ANOVA.  This function calculates the Friedman Chi-square test for
+repeated measures and returns the result, along with the associated
+probability value.  It assumes 3 or more repeated measures.  Only 3
+levels requires a minimum of 10 subjects in the study.  Four levels
+requires 5 subjects per level(??).
+
+Usage:   afriedmanchisquare(*args)   args are separate arrays for 2+ conditions
+Returns: chi-square statistic, associated p-value
+"""
+    k = len(args)
+    if k < 3:
+        raise ValueError, '\nLess than 3 levels.  Friedman test not appropriate.\n'
+    n = len(args[0])
+    data = apply(pstat.aabut,args)
+    data = data.astype(N.Float)
+    for i in range(len(data)):
+        data[i] = arankdata(data[i])
+    ssbn = asum(asum(args,1)**2)
+    chisq = 12.0 / (k*n*(k+1)) * ssbn - 3*n*(k+1)
+    return chisq, chisqprob(chisq,k-1)
+
+
+#####################################
+####  APROBABILITY CALCULATIONS  ####
+#####################################
+
+ def achisqprob(chisq,df):
+    """
+Returns the (1-tail) probability value associated with the provided chi-square
+value and df.  Heavily modified from chisq.c in Gary Perlman's |Stat.  Can
+handle multiple dimensions.
+
+Usage:   achisqprob(chisq,df)    chisq=chisquare stat., df=degrees of freedom
+"""
+    BIG = 200.0
+    def ex(x):
+        BIG = 200.0
+        exponents = N.where(N.less(x,-BIG),-BIG,x)
+        return N.exp(exponents)
+
+    if type(chisq) == N.ArrayType:
+        arrayflag = 1
+    else:
+        arrayflag = 0
+        chisq = N.array([chisq])
+    if df < 1:
+        return N.ones(chisq.shape,N.float)
+    probs = N.zeros(chisq.shape,N.Float)
+    probs = N.where(N.less_equal(chisq,0),1.0,probs)  # set prob=1 for chisq<0
+    a = 0.5 * chisq
+    if df > 1:
+        y = ex(-a)
+    if df%2 == 0:
+        even = 1
+        s = y*1
+        s2 = s*1
+    else:
+        even = 0
+        s = 2.0 * azprob(-N.sqrt(chisq))
+        s2 = s*1
+    if (df > 2):
+        chisq = 0.5 * (df - 1.0)
+        if even:
+            z = N.ones(probs.shape,N.Float)
+        else:
+            z = 0.5 *N.ones(probs.shape,N.Float)
+        if even:
+            e = N.zeros(probs.shape,N.Float)
+        else:
+            e = N.log(N.sqrt(N.pi)) *N.ones(probs.shape,N.Float)
+        c = N.log(a)
+        mask = N.zeros(probs.shape)
+        a_big = N.greater(a,BIG)
+        a_big_frozen = -1 *N.ones(probs.shape,N.Float)
+        totalelements = N.multiply.reduce(N.array(probs.shape))
+        while asum(mask)<>totalelements:
+            e = N.log(z) + e
+            s = s + ex(c*z-a-e)
+            z = z + 1.0
+#            print z, e, s
+            newmask = N.greater(z,chisq)
+            a_big_frozen = N.where(newmask*N.equal(mask,0)*a_big, s, a_big_frozen)
+            mask = N.clip(newmask+mask,0,1)
+        if even:
+            z = N.ones(probs.shape,N.Float)
+            e = N.ones(probs.shape,N.Float)
+        else:
+            z = 0.5 *N.ones(probs.shape,N.Float)
+            e = 1.0 / N.sqrt(N.pi) / N.sqrt(a) * N.ones(probs.shape,N.Float)
+        c = 0.0
+        mask = N.zeros(probs.shape)
+        a_notbig_frozen = -1 *N.ones(probs.shape,N.Float)
+        while asum(mask)<>totalelements:
+            e = e * (a/z.astype(N.Float))
+            c = c + e
+            z = z + 1.0
+#            print '#2', z, e, c, s, c*y+s2
+            newmask = N.greater(z,chisq)
+            a_notbig_frozen = N.where(newmask*N.equal(mask,0)*(1-a_big),
+                                      c*y+s2, a_notbig_frozen)
+            mask = N.clip(newmask+mask,0,1)
+        probs = N.where(N.equal(probs,1),1,
+                        N.where(N.greater(a,BIG),a_big_frozen,a_notbig_frozen))
+        return probs
+    else:
+        return s
+
+
+ def aerfcc(x):
+    """
+Returns the complementary error function erfc(x) with fractional error
+everywhere less than 1.2e-7.  Adapted from Numerical Recipies.  Can
+handle multiple dimensions.
+
+Usage:   aerfcc(x)
+"""
+    z = abs(x)
+    t = 1.0 / (1.0+0.5*z)
+    ans = t * N.exp(-z*z-1.26551223 + t*(1.00002368+t*(0.37409196+t*(0.09678418+t*(-0.18628806+t*(0.27886807+t*(-1.13520398+t*(1.48851587+t*(-0.82215223+t*0.17087277)))))))))
+    return N.where(N.greater_equal(x,0), ans, 2.0-ans)
+
+
+ def azprob(z):
+    """
+Returns the area under the normal curve 'to the left of' the given z value.
+Thus, 
+    for z<0, zprob(z) = 1-tail probability
+    for z>0, 1.0-zprob(z) = 1-tail probability
+    for any z, 2.0*(1.0-zprob(abs(z))) = 2-tail probability
+Adapted from z.c in Gary Perlman's |Stat.  Can handle multiple dimensions.
+
+Usage:   azprob(z)    where z is a z-value
+"""
+    def yfunc(y):
+        x = (((((((((((((-0.000045255659 * y
+                         +0.000152529290) * y -0.000019538132) * y
+                       -0.000676904986) * y +0.001390604284) * y
+                     -0.000794620820) * y -0.002034254874) * y
+                   +0.006549791214) * y -0.010557625006) * y
+                 +0.011630447319) * y -0.009279453341) * y
+               +0.005353579108) * y -0.002141268741) * y
+             +0.000535310849) * y +0.999936657524
+        return x
+
+    def wfunc(w):
+        x = ((((((((0.000124818987 * w
+                    -0.001075204047) * w +0.005198775019) * w
+                  -0.019198292004) * w +0.059054035642) * w
+                -0.151968751364) * w +0.319152932694) * w
+              -0.531923007300) * w +0.797884560593) * N.sqrt(w) * 2.0
+        return x
+
+    Z_MAX = 6.0    # maximum meaningful z-value
+    x = N.zeros(z.shape,N.Float) # initialize
+    y = 0.5 * N.fabs(z)
+    x = N.where(N.less(y,1.0),wfunc(y*y),yfunc(y-2.0)) # get x's
+    x = N.where(N.greater(y,Z_MAX*0.5),1.0,x)          # kill those with big Z
+    prob = N.where(N.greater(z,0),(x+1)*0.5,(1-x)*0.5)
+    return prob
+
+
+ def aksprob(alam):
+     """
+Returns the probability value for a K-S statistic computed via ks_2samp.
+Adapted from Numerical Recipies.  Can handle multiple dimensions.
+
+Usage:   aksprob(alam)
+"""
+     if type(alam) == N.ArrayType:
+         frozen = -1 *N.ones(alam.shape,N.Float64)
+         alam = alam.astype(N.Float64)
+         arrayflag = 1
+     else:
+         frozen = N.array(-1.)
+         alam = N.array(alam,N.Float64)
+     mask = N.zeros(alam.shape)
+     fac = 2.0 *N.ones(alam.shape,N.Float)
+     sum = N.zeros(alam.shape,N.Float)
+     termbf = N.zeros(alam.shape,N.Float)
+     a2 = N.array(-2.0*alam*alam,N.Float64)
+     totalelements = N.multiply.reduce(N.array(mask.shape))
+     for j in range(1,201):
+         if asum(mask) == totalelements:
+             break
+         exponents = (a2*j*j)
+         overflowmask = N.less(exponents,-746)
+         frozen = N.where(overflowmask,0,frozen)
+         mask = mask+overflowmask
+         term = fac*N.exp(exponents)
+         sum = sum + term
+         newmask = N.where(N.less_equal(abs(term),(0.001*termbf)) +
+                           N.less(abs(term),1.0e-8*sum), 1, 0)
+         frozen = N.where(newmask*N.equal(mask,0), sum, frozen)
+         mask = N.clip(mask+newmask,0,1)
+         fac = -fac
+         termbf = abs(term)
+     if arrayflag:
+         return N.where(N.equal(frozen,-1), 1.0, frozen)  # 1.0 if doesn't converge
+     else:
+         return N.where(N.equal(frozen,-1), 1.0, frozen)[0]  # 1.0 if doesn't converge
+
+
+ def afprob (dfnum, dfden, F):
+    """
+Returns the 1-tailed significance level (p-value) of an F statistic
+given the degrees of freedom for the numerator (dfR-dfF) and the degrees
+of freedom for the denominator (dfF).  Can handle multiple dims for F.
+
+Usage:   afprob(dfnum, dfden, F)   where usually dfnum=dfbn, dfden=dfwn
+"""
+    if type(F) == N.ArrayType:
+        return abetai(0.5*dfden, 0.5*dfnum, dfden/(1.0*dfden+dfnum*F))
+    else:
+        return abetai(0.5*dfden, 0.5*dfnum, dfden/float(dfden+dfnum*F))
+
+
+ def abetacf(a,b,x,verbose=1):
+    """
+Evaluates the continued fraction form of the incomplete Beta function,
+betai.  (Adapted from: Numerical Recipies in C.)  Can handle multiple
+dimensions for x.
+
+Usage:   abetacf(a,b,x,verbose=1)
+"""
+    ITMAX = 200
+    EPS = 3.0e-7
+
+    arrayflag = 1
+    if type(x) == N.ArrayType:
+        frozen = N.ones(x.shape,N.Float) *-1  #start out w/ -1s, should replace all
+    else:
+        arrayflag = 0
+        frozen = N.array([-1])
+        x = N.array([x])
+    mask = N.zeros(x.shape)
+    bm = az = am = 1.0
+    qab = a+b
+    qap = a+1.0
+    qam = a-1.0
+    bz = 1.0-qab*x/qap
+    for i in range(ITMAX+1):
+        if N.sum(N.ravel(N.equal(frozen,-1)))==0:
+            break
+        em = float(i+1)
+        tem = em + em
+        d = em*(b-em)*x/((qam+tem)*(a+tem))
+        ap = az + d*am
+        bp = bz+d*bm
+        d = -(a+em)*(qab+em)*x/((qap+tem)*(a+tem))
+        app = ap+d*az
+        bpp = bp+d*bz
+        aold = az*1
+        am = ap/bpp
+        bm = bp/bpp
+        az = app/bpp
+        bz = 1.0
+        newmask = N.less(abs(az-aold),EPS*abs(az))
+        frozen = N.where(newmask*N.equal(mask,0), az, frozen)
+        mask = N.clip(mask+newmask,0,1)
+    noconverge = asum(N.equal(frozen,-1))
+    if noconverge <> 0 and verbose:
+        print 'a or b too big, or ITMAX too small in Betacf for ',noconverge,' elements'
+    if arrayflag:
+        return frozen
+    else:
+        return frozen[0]
+
+
+ def agammln(xx):
+    """
+Returns the gamma function of xx.
+    Gamma(z) = Integral(0,infinity) of t^(z-1)exp(-t) dt.
+Adapted from: Numerical Recipies in C.  Can handle multiple dims ... but
+probably doesn't normally have to.
+
+Usage:   agammln(xx)
+"""
+    coeff = [76.18009173, -86.50532033, 24.01409822, -1.231739516,
+             0.120858003e-2, -0.536382e-5]
+    x = xx - 1.0
+    tmp = x + 5.5
+    tmp = tmp - (x+0.5)*N.log(tmp)
+    ser = 1.0
+    for j in range(len(coeff)):
+        x = x + 1
+        ser = ser + coeff[j]/x
+    return -tmp + N.log(2.50662827465*ser)
+
+
+ def abetai(a,b,x,verbose=1):
+    """
+Returns the incomplete beta function:
+
+    I-sub-x(a,b) = 1/B(a,b)*(Integral(0,x) of t^(a-1)(1-t)^(b-1) dt)
+
+where a,b>0 and B(a,b) = G(a)*G(b)/(G(a+b)) where G(a) is the gamma
+function of a.  The continued fraction formulation is implemented
+here, using the betacf function.  (Adapted from: Numerical Recipies in
+C.)  Can handle multiple dimensions.
+
+Usage:   abetai(a,b,x,verbose=1)
+"""
+    TINY = 1e-15
+    if type(a) == N.ArrayType:
+        if asum(N.less(x,0)+N.greater(x,1)) <> 0:
+            raise ValueError, 'Bad x in abetai'
+    x = N.where(N.equal(x,0),TINY,x)
+    x = N.where(N.equal(x,1.0),1-TINY,x)
+
+    bt = N.where(N.equal(x,0)+N.equal(x,1), 0, -1)
+    exponents = ( gammln(a+b)-gammln(a)-gammln(b)+a*N.log(x)+b*
+                  N.log(1.0-x) )
+    # 746 (below) is the MAX POSSIBLE BEFORE OVERFLOW
+    exponents = N.where(N.less(exponents,-740),-740,exponents)
+    bt = N.exp(exponents)
+    if type(x) == N.ArrayType:
+        ans = N.where(N.less(x,(a+1)/(a+b+2.0)),
+                      bt*abetacf(a,b,x,verbose)/float(a),
+                      1.0-bt*abetacf(b,a,1.0-x,verbose)/float(b))
+    else:
+        if x<(a+1)/(a+b+2.0):
+            ans = bt*abetacf(a,b,x,verbose)/float(a)
+        else:
+            ans = 1.0-bt*abetacf(b,a,1.0-x,verbose)/float(b)
+    return ans
+
+
+#####################################
+#######  AANOVA CALCULATIONS  #######
+#####################################
+
+ import LinearAlgebra, operator
+ LA = LinearAlgebra
+
+ def aglm(data,para):
+    """
+Calculates a linear model fit ... anova/ancova/lin-regress/t-test/etc. Taken
+from:
+    Peterson et al. Statistical limitations in functional neuroimaging
+    I. Non-inferential methods and statistical models.  Phil Trans Royal Soc
+    Lond B 354: 1239-1260.
+
+Usage:   aglm(data,para)
+Returns: statistic, p-value ???
+"""
+    if len(para) <> len(data):
+        print "data and para must be same length in aglm"
+        return
+    n = len(para)
+    p = pstat.aunique(para)
+    x = N.zeros((n,len(p)))  # design matrix
+    for l in range(len(p)):
+        x[:,l] = N.equal(para,p[l])
+    b = N.dot(N.dot(LA.inverse(N.dot(N.transpose(x),x)),  # i.e., b=inv(X'X)X'Y
+                    N.transpose(x)),
+              data)
+    diffs = (data - N.dot(x,b))
+    s_sq = 1./(n-len(p)) * N.dot(N.transpose(diffs), diffs)
+
+    if len(p) == 2:  # ttest_ind
+        c = N.array([1,-1])
+        df = n-2
+        fact = asum(1.0/asum(x,0))  # i.e., 1/n1 + 1/n2 + 1/n3 ...
+        t = N.dot(c,b) / N.sqrt(s_sq*fact)
+        probs = abetai(0.5*df,0.5,float(df)/(df+t*t))
+        return t, probs
+
+
+ def aF_oneway(*args):
+    """
+Performs a 1-way ANOVA, returning an F-value and probability given
+any number of groups.  From Heiman, pp.394-7.
+
+Usage:   aF_oneway (*args)    where *args is 2 or more arrays, one per
+                                  treatment group
+Returns: f-value, probability
+"""
+    na = len(args)            # ANOVA on 'na' groups, each in it's own array
+    means = [0]*na
+    vars = [0]*na
+    ns = [0]*na
+    alldata = []
+    tmp = map(N.array,args)
+    means = map(amean,tmp)
+    vars = map(avar,tmp)
+    ns = map(len,args)
+    alldata = N.concatenate(args)
+    bign = len(alldata)
+    sstot = ass(alldata)-(asquare_of_sums(alldata)/float(bign))
+    ssbn = 0
+    for a in args:
+        ssbn = ssbn + asquare_of_sums(N.array(a))/float(len(a))
+    ssbn = ssbn - (asquare_of_sums(alldata)/float(bign))
+    sswn = sstot-ssbn
+    dfbn = na-1
+    dfwn = bign - na
+    msb = ssbn/float(dfbn)
+    msw = sswn/float(dfwn)
+    f = msb/msw
+    prob = fprob(dfbn,dfwn,f)
+    return f, prob
+
+
+ def aF_value (ER,EF,dfR,dfF):
+    """
+Returns an F-statistic given the following:
+        ER  = error associated with the null hypothesis (the Restricted model)
+        EF  = error associated with the alternate hypothesis (the Full model)
+        dfR = degrees of freedom the Restricted model
+        dfF = degrees of freedom associated with the Restricted model
+"""
+    return ((ER-EF)/float(dfR-dfF) / (EF/float(dfF)))
+
+
+ def outputfstats(Enum, Eden, dfnum, dfden, f, prob):
+     Enum = round(Enum,3)
+     Eden = round(Eden,3)
+     dfnum = round(Enum,3)
+     dfden = round(dfden,3)
+     f = round(f,3)
+     prob = round(prob,3)
+     suffix = ''                       # for *s after the p-value
+     if  prob < 0.001:  suffix = '  ***'
+     elif prob < 0.01:  suffix = '  **'
+     elif prob < 0.05:  suffix = '  *'
+     title = [['EF/ER','DF','Mean Square','F-value','prob','']]
+     lofl = title+[[Enum, dfnum, round(Enum/float(dfnum),3), f, prob, suffix],
+                   [Eden, dfden, round(Eden/float(dfden),3),'','','']]
+     pstat.printcc(lofl)
+     return
+
+
+ def F_value_multivariate(ER, EF, dfnum, dfden):
+     """
+Returns an F-statistic given the following:
+        ER  = error associated with the null hypothesis (the Restricted model)
+        EF  = error associated with the alternate hypothesis (the Full model)
+        dfR = degrees of freedom the Restricted model
+        dfF = degrees of freedom associated with the Restricted model
+where ER and EF are matrices from a multivariate F calculation.
+"""
+     if type(ER) in [IntType, FloatType]:
+         ER = N.array([[ER]])
+     if type(EF) in [IntType, FloatType]:
+         EF = N.array([[EF]])
+     n_um = (LA.determinant(ER) - LA.determinant(EF)) / float(dfnum)
+     d_en = LA.determinant(EF) / float(dfden)
+     return n_um / d_en
+
+
+#####################################
+#######  ASUPPORT FUNCTIONS  ########
+#####################################
+
+ def asign(a):
+    """
+Usage:   asign(a)
+Returns: array shape of a, with -1 where a<0 and +1 where a>=0
+"""
+    a = N.asarray(a)
+    if ((type(a) == type(1.4)) or (type(a) == type(1))):
+        return a-a-N.less(a,0)+N.greater(a,0)
+    else:
+        return N.zeros(N.shape(a))-N.less(a,0)+N.greater(a,0)
+
+
+ def asum (a, dimension=None,keepdims=0):
+     """
+An alternative to the Numeric.add.reduce function, which allows one to
+(1) collapse over multiple dimensions at once, and/or (2) to retain
+all dimensions in the original array (squashing one down to size.
+Dimension can equal None (ravel array first), an integer (the
+dimension over which to operate), or a sequence (operate over multiple
+dimensions).  If keepdims=1, the resulting array will have as many
+dimensions as the input array.
+
+Usage:   asum(a, dimension=None, keepdims=0)
+Returns: array summed along 'dimension'(s), same _number_ of dims if keepdims=1
+"""
+     if type(a) == N.ArrayType and a.typecode() in ['l','s','b']:
+         a = a.astype(N.Float)
+     if dimension == None:
+         s = N.sum(N.ravel(a))
+     elif type(dimension) in [IntType,FloatType]:
+         s = N.add.reduce(a, dimension)
+         if keepdims == 1:
+             shp = list(a.shape)
+             shp[dimension] = 1
+             s = N.reshape(s,shp)
+     else: # must be a SEQUENCE of dims to sum over
+        dims = list(dimension)
+        dims.sort()
+        dims.reverse()
+        s = a *1.0
+        for dim in dims:
+            s = N.add.reduce(s,dim)
+        if keepdims == 1:
+            shp = list(a.shape)
+            for dim in dims:
+                shp[dim] = 1
+            s = N.reshape(s,shp)
+     return s
+
+
+ def acumsum (a,dimension=None):
+    """
+Returns an array consisting of the cumulative sum of the items in the
+passed array.  Dimension can equal None (ravel array first), an
+integer (the dimension over which to operate), or a sequence (operate
+over multiple dimensions, but this last one just barely makes sense).
+
+Usage:   acumsum(a,dimension=None)
+"""
+    if dimension == None:
+        a = N.ravel(a)
+        dimension = 0
+    if type(dimension) in [ListType, TupleType, N.ArrayType]:
+        dimension = list(dimension)
+        dimension.sort()
+        dimension.reverse()
+        for d in dimension:
+            a = N.add.accumulate(a,d)
+        return a
+    else:
+        return N.add.accumulate(a,dimension)
+
+
+ def ass(inarray, dimension=None, keepdims=0):
+    """
+Squares each value in the passed array, adds these squares & returns
+the result.  Unfortunate function name. :-) Defaults to ALL values in
+the array.  Dimension can equal None (ravel array first), an integer
+(the dimension over which to operate), or a sequence (operate over
+multiple dimensions).  Set keepdims=1 to maintain the original number
+of dimensions.
+
+Usage:   ass(inarray, dimension=None, keepdims=0)
+Returns: sum-along-'dimension' for (inarray*inarray)
+"""
+    if dimension == None:
+        inarray = N.ravel(inarray)
+        dimension = 0
+    return asum(inarray*inarray,dimension,keepdims)
+
+
+ def asummult (array1,array2,dimension=None,keepdims=0):
+    """
+Multiplies elements in array1 and array2, element by element, and
+returns the sum (along 'dimension') of all resulting multiplications.
+Dimension can equal None (ravel array first), an integer (the
+dimension over which to operate), or a sequence (operate over multiple
+dimensions).  A trivial function, but included for completeness.
+
+Usage:   asummult(array1,array2,dimension=None,keepdims=0)
+"""
+    if dimension == None:
+        array1 = N.ravel(array1)
+        array2 = N.ravel(array2)
+        dimension = 0
+    return asum(array1*array2,dimension,keepdims)
+
+
+ def asquare_of_sums(inarray, dimension=None, keepdims=0):
+    """
+Adds the values in the passed array, squares that sum, and returns the
+result.  Dimension can equal None (ravel array first), an integer (the
+dimension over which to operate), or a sequence (operate over multiple
+dimensions).  If keepdims=1, the returned array will have the same
+NUMBER of dimensions as the original.
+
+Usage:   asquare_of_sums(inarray, dimension=None, keepdims=0)
+Returns: the square of the sum over dim(s) in dimension
+"""
+    if dimension == None:
+        inarray = N.ravel(inarray)
+        dimension = 0
+    s = asum(inarray,dimension,keepdims)
+    if type(s) == N.ArrayType:
+        return s.astype(N.Float)*s
+    else:
+        return float(s)*s
+
+
+ def asumdiffsquared(a,b, dimension=None, keepdims=0):
+    """
+Takes pairwise differences of the values in arrays a and b, squares
+these differences, and returns the sum of these squares.  Dimension
+can equal None (ravel array first), an integer (the dimension over
+which to operate), or a sequence (operate over multiple dimensions).
+keepdims=1 means the return shape = len(a.shape) = len(b.shape)
+
+Usage:   asumdiffsquared(a,b)
+Returns: sum[ravel(a-b)**2]
+"""
+    if dimension == None:
+        inarray = N.ravel(a)
+        dimension = 0
+    return asum((a-b)**2,dimension,keepdims)
+
+
+ def ashellsort(inarray):
+    """
+Shellsort algorithm.  Sorts a 1D-array.
+
+Usage:   ashellsort(inarray)
+Returns: sorted-inarray, sorting-index-vector (for original array)
+"""
+    n = len(inarray)
+    svec = inarray *1.0
+    ivec = range(n)
+    gap = n/2   # integer division needed
+    while gap >0:
+        for i in range(gap,n):
+            for j in range(i-gap,-1,-gap):
+                while j>=0 and svec[j]>svec[j+gap]:
+                    temp        = svec[j]
+                    svec[j]     = svec[j+gap]
+                    svec[j+gap] = temp
+                    itemp       = ivec[j]
+                    ivec[j]     = ivec[j+gap]
+                    ivec[j+gap] = itemp
+        gap = gap / 2  # integer division needed
+#    svec is now sorted input vector, ivec has the order svec[i] = vec[ivec[i]]
+    return svec, ivec
+
+
+ def arankdata(inarray):
+    """
+Ranks the data in inarray, dealing with ties appropritely.  Assumes
+a 1D inarray.  Adapted from Gary Perlman's |Stat ranksort.
+
+Usage:   arankdata(inarray)
+Returns: array of length equal to inarray, containing rank scores
+"""
+    n = len(inarray)
+    svec, ivec = ashellsort(inarray)
+    sumranks = 0
+    dupcount = 0
+    newarray = N.zeros(n,N.Float)
+    for i in range(n):
+        sumranks = sumranks + i
+        dupcount = dupcount + 1
+        if i==n-1 or svec[i] <> svec[i+1]:
+            averank = sumranks / float(dupcount) + 1
+            for j in range(i-dupcount+1,i+1):
+                newarray[ivec[j]] = averank
+            sumranks = 0
+            dupcount = 0
+    return newarray
+
+
+ def afindwithin(data):
+    """
+Returns a binary vector, 1=within-subject factor, 0=between.  Input
+equals the entire data array (i.e., column 1=random factor, last
+column = measured values.
+
+Usage:   afindwithin(data)     data in |Stat format
+"""
+    numfact = len(data[0])-2
+    withinvec = [0]*numfact
+    for col in range(1,numfact+1):
+        rows = pstat.linexand(data,col,pstat.unique(pstat.colex(data,1))[0])  # get 1 level of this factor
+        if len(pstat.unique(pstat.colex(rows,0))) < len(rows):   # if fewer subjects than scores on this factor
+            withinvec[col-1] = 1
+    return withinvec
+
+
+ #########################################################
+ #########################################################
+ ######  RE-DEFINE DISPATCHES TO INCLUDE ARRAYS  #########
+ #########################################################
+ #########################################################
+
+## CENTRAL TENDENCY:
+ geometricmean = Dispatch ( (lgeometricmean, (ListType, TupleType)),
+                            (ageometricmean, (N.ArrayType,)) )
+ harmonicmean = Dispatch ( (lharmonicmean, (ListType, TupleType)),
+                           (aharmonicmean, (N.ArrayType,)) )
+ mean = Dispatch ( (lmean, (ListType, TupleType)),
+                   (amean, (N.ArrayType,)) )
+ median = Dispatch ( (lmedian, (ListType, TupleType)),
+                     (amedian, (N.ArrayType,)) )
+ medianscore = Dispatch ( (lmedianscore, (ListType, TupleType)),
+                          (amedianscore, (N.ArrayType,)) )
+ mode = Dispatch ( (lmode, (ListType, TupleType)),
+                   (amode, (N.ArrayType,)) )
+ tmean = Dispatch ( (atmean, (N.ArrayType,)) )
+ tvar = Dispatch ( (atvar, (N.ArrayType,)) )
+ tstdev = Dispatch ( (atstdev, (N.ArrayType,)) )
+ tsem = Dispatch ( (atsem, (N.ArrayType,)) )
+
+## VARIATION:
+ moment = Dispatch ( (lmoment, (ListType, TupleType)),
+                     (amoment, (N.ArrayType,)) )
+ variation = Dispatch ( (lvariation, (ListType, TupleType)),
+                        (avariation, (N.ArrayType,)) )
+ skew = Dispatch ( (lskew, (ListType, TupleType)),
+                   (askew, (N.ArrayType,)) )
+ kurtosis = Dispatch ( (lkurtosis, (ListType, TupleType)),
+                       (akurtosis, (N.ArrayType,)) )
+ describe = Dispatch ( (ldescribe, (ListType, TupleType)),
+                       (adescribe, (N.ArrayType,)) )
+
+## DISTRIBUTION TESTS
+
+ skewtest = Dispatch ( (askewtest, (ListType, TupleType)),
+                       (askewtest, (N.ArrayType,)) )
+ kurtosistest = Dispatch ( (akurtosistest, (ListType, TupleType)),
+                           (akurtosistest, (N.ArrayType,)) )
+ normaltest = Dispatch ( (anormaltest, (ListType, TupleType)),
+                         (anormaltest, (N.ArrayType,)) )
+
+## FREQUENCY STATS:
+ itemfreq = Dispatch ( (litemfreq, (ListType, TupleType)),
+                       (aitemfreq, (N.ArrayType,)) )
+ scoreatpercentile = Dispatch ( (lscoreatpercentile, (ListType, TupleType)),
+                                (ascoreatpercentile, (N.ArrayType,)) )
+ percentileofscore = Dispatch ( (lpercentileofscore, (ListType, TupleType)),
+                                 (apercentileofscore, (N.ArrayType,)) )
+ histogram = Dispatch ( (lhistogram, (ListType, TupleType)),
+                        (ahistogram, (N.ArrayType,)) )
+ cumfreq = Dispatch ( (lcumfreq, (ListType, TupleType)),
+                      (acumfreq, (N.ArrayType,)) )
+ relfreq = Dispatch ( (lrelfreq, (ListType, TupleType)),
+                      (arelfreq, (N.ArrayType,)) )
+ 
+## VARIABILITY:
+ obrientransform = Dispatch ( (lobrientransform, (ListType, TupleType)),
+                              (aobrientransform, (N.ArrayType,)) )
+ samplevar = Dispatch ( (lsamplevar, (ListType, TupleType)),
+                        (asamplevar, (N.ArrayType,)) )
+ samplestdev = Dispatch ( (lsamplestdev, (ListType, TupleType)),
+                          (asamplestdev, (N.ArrayType,)) )
+ signaltonoise = Dispatch( (asignaltonoise, (N.ArrayType,)),)
+ var = Dispatch ( (lvar, (ListType, TupleType)),
+                  (avar, (N.ArrayType,)) )
+ stdev = Dispatch ( (lstdev, (ListType, TupleType)),
+                    (astdev, (N.ArrayType,)) )
+ sterr = Dispatch ( (lsterr, (ListType, TupleType)),
+                    (asterr, (N.ArrayType,)) )
+ sem = Dispatch ( (lsem, (ListType, TupleType)),
+                  (asem, (N.ArrayType,)) )
+ z = Dispatch ( (lz, (ListType, TupleType)),
+                (az, (N.ArrayType,)) )
+ zs = Dispatch ( (lzs, (ListType, TupleType)),
+                 (azs, (N.ArrayType,)) )
+ 
+## TRIMMING FCNS:
+ threshold = Dispatch( (athreshold, (N.ArrayType,)),)
+ trimboth = Dispatch ( (ltrimboth, (ListType, TupleType)),
+                       (atrimboth, (N.ArrayType,)) )
+ trim1 = Dispatch ( (ltrim1, (ListType, TupleType)),
+                    (atrim1, (N.ArrayType,)) )
+ 
+## CORRELATION FCNS:
+ paired = Dispatch ( (lpaired, (ListType, TupleType)),
+                     (apaired, (N.ArrayType,)) )
+ pearsonr = Dispatch ( (lpearsonr, (ListType, TupleType)),
+                       (apearsonr, (N.ArrayType,)) )
+ spearmanr = Dispatch ( (lspearmanr, (ListType, TupleType)),
+                        (aspearmanr, (N.ArrayType,)) )
+ pointbiserialr = Dispatch ( (lpointbiserialr, (ListType, TupleType)),
+                             (apointbiserialr, (N.ArrayType,)) )
+ kendalltau = Dispatch ( (lkendalltau, (ListType, TupleType)),
+                         (akendalltau, (N.ArrayType,)) )
+ linregress = Dispatch ( (llinregress, (ListType, TupleType)),
+                         (alinregress, (N.ArrayType,)) )
+ 
+## INFERENTIAL STATS:
+ ttest_1samp = Dispatch ( (lttest_1samp, (ListType, TupleType)),
+                          (attest_1samp, (N.ArrayType,)) )
+ ttest_ind = Dispatch ( (lttest_ind, (ListType, TupleType)),
+                        (attest_ind, (N.ArrayType,)) )
+ ttest_rel = Dispatch ( (lttest_rel, (ListType, TupleType)),
+                        (attest_rel, (N.ArrayType,)) )
+ chisquare = Dispatch ( (lchisquare, (ListType, TupleType)),
+                        (achisquare, (N.ArrayType,)) )
+ ks_2samp = Dispatch ( (lks_2samp, (ListType, TupleType)),
+                       (aks_2samp, (N.ArrayType,)) )
+ mannwhitneyu = Dispatch ( (lmannwhitneyu, (ListType, TupleType)),
+                           (amannwhitneyu, (N.ArrayType,)) )
+ tiecorrect = Dispatch ( (ltiecorrect, (ListType, TupleType)),
+                         (atiecorrect, (N.ArrayType,)) )
+ ranksums = Dispatch ( (lranksums, (ListType, TupleType)),
+                       (aranksums, (N.ArrayType,)) )
+ wilcoxont = Dispatch ( (lwilcoxont, (ListType, TupleType)),
+                        (awilcoxont, (N.ArrayType,)) )
+ kruskalwallish = Dispatch ( (lkruskalwallish, (ListType, TupleType)),
+                             (akruskalwallish, (N.ArrayType,)) )
+ friedmanchisquare = Dispatch ( (lfriedmanchisquare, (ListType, TupleType)),
+                                (afriedmanchisquare, (N.ArrayType,)) )
+ 
+## PROBABILITY CALCS:
+ chisqprob = Dispatch ( (lchisqprob, (IntType, FloatType)),
+                        (achisqprob, (N.ArrayType,)) )
+ zprob = Dispatch ( (lzprob, (IntType, FloatType)),
+                    (azprob, (N.ArrayType,)) )
+ ksprob = Dispatch ( (lksprob, (IntType, FloatType)),
+                     (aksprob, (N.ArrayType,)) )
+ fprob = Dispatch ( (lfprob, (IntType, FloatType)),
+                    (afprob, (N.ArrayType,)) )
+ betacf = Dispatch ( (lbetacf, (IntType, FloatType)),
+                     (abetacf, (N.ArrayType,)) )
+ betai = Dispatch ( (lbetai, (IntType, FloatType)),
+                    (abetai, (N.ArrayType,)) )
+ erfcc = Dispatch ( (lerfcc, (IntType, FloatType)),
+                    (aerfcc, (N.ArrayType,)) )
+ gammln = Dispatch ( (lgammln, (IntType, FloatType)),
+                     (agammln, (N.ArrayType,)) )
+ 
+## ANOVA FUNCTIONS:
+ F_oneway = Dispatch ( (lF_oneway, (ListType, TupleType)),
+                       (aF_oneway, (N.ArrayType,)) )
+ F_value = Dispatch ( (lF_value, (ListType, TupleType)),
+                      (aF_value, (N.ArrayType,)) )
+
+## SUPPORT FUNCTIONS:
+ incr = Dispatch ( (lincr, (ListType, TupleType, N.ArrayType)), )
+ sum = Dispatch ( (lsum, (ListType, TupleType)),
+                  (asum, (N.ArrayType,)) )
+ cumsum = Dispatch ( (lcumsum, (ListType, TupleType)),
+                     (acumsum, (N.ArrayType,)) )
+ ss = Dispatch ( (lss, (ListType, TupleType)),
+                 (ass, (N.ArrayType,)) )
+ summult = Dispatch ( (lsummult, (ListType, TupleType)),
+                      (asummult, (N.ArrayType,)) )
+ square_of_sums = Dispatch ( (lsquare_of_sums, (ListType, TupleType)),
+                             (asquare_of_sums, (N.ArrayType,)) )
+ sumdiffsquared = Dispatch ( (lsumdiffsquared, (ListType, TupleType)),
+                             (asumdiffsquared, (N.ArrayType,)) )
+ shellsort = Dispatch ( (lshellsort, (ListType, TupleType)),
+                        (ashellsort, (N.ArrayType,)) )
+ rankdata = Dispatch ( (lrankdata, (ListType, TupleType)),
+                       (arankdata, (N.ArrayType,)) )
+ findwithin = Dispatch ( (lfindwithin, (ListType, TupleType)),
+                         (afindwithin, (N.ArrayType,)) )
+
+######################  END OF NUMERIC FUNCTION BLOCK  #####################
+
+######################  END OF STATISTICAL FUNCTIONS  ######################
+
+except ImportError:
+ pass
diff --git a/lib/psyco_full.py b/lib/psyco_full.py
new file mode 100644
index 0000000..804bf33
--- /dev/null
+++ b/lib/psyco_full.py
@@ -0,0 +1,14 @@
+"""
+Attempt to call psyco.full, but ignore any errors.
+"""
+
+import sys
+
+try:
+    import psyco
+    psyco.full()
+except:
+	pass
+    #print >> sys.stderr, "Psyco not found, continuing without it"
+
+
diff --git a/script_tests/base/__init__.py b/script_tests/base/__init__.py
new file mode 100644
index 0000000..ab36d2a
--- /dev/null
+++ b/script_tests/base/__init__.py
@@ -0,0 +1,102 @@
+import tempfile
+import subprocess
+import filecmp
+import os
+import sys
+import string
+import StringIO
+import unittest
+
+class TestFile( object ):
+    def __init__( self, text=None, filename=None ):
+        assert text is None or filename is None, "Cannot specify both text and filename for input"
+        self.text = text
+        self.filename = filename
+        if self.filename is None:
+            _, tf_name = tempfile.mkstemp()
+            tf = open( tf_name, "w" )
+            sio = StringIO.StringIO( self.text )
+            for line in sio:
+                print >> tf, line.lstrip( " " ).rstrip( "\r\n" )
+            tf.close()
+            self.tempfile = True
+            self.filename = tf_name
+        else:
+            self.tempfile = False
+    def check( self, other_fname ):
+        assert filecmp.cmp( self.filename, other_fname ), "Files do not match (%s, %s)" % ( self.filename, other_fname )
+    def __del__( self ):
+        if self.tempfile:
+            os.remove( self.filename )
+
+class BaseScriptTest( object ):
+    """
+    Helper class for testing a command line tool
+    """
+    def test_script( self ):
+        # Accumulate parameters
+        input_files = dict()
+        output_files = dict()
+        stdin = stdout = stderr = None
+        for key in dir( self ):
+            if key == 'command_line':
+                command_line = getattr( self, key )
+            elif key.startswith( 'input_' ):
+                value = getattr( self, key )
+                assert isinstance( value, TestFile )
+                arg_name = key[6:]
+                input_files[ arg_name ] = value
+            elif key.startswith( 'output_' ):
+                value = getattr( self, key )
+                assert isinstance( value, TestFile )
+                arg_name = key[7:]
+                output_files[ arg_name ] = value
+        # Build the command line
+        input_fnames = dict()
+        output_fnames = dict()
+        all_fnames = dict()
+        for key, value in input_files.iteritems():
+            input_fnames[ key ] = value.filename
+            all_fnames[ key ] = input_fnames[ key ]
+            if key == 'stdin':
+                stdin = open( input_fnames[ key ], 'r' )
+        for key, value in output_files.iteritems():
+            _, tf_name = tempfile.mkstemp()
+            output_fnames[ key ] = tf_name
+            all_fnames[ key ] = output_fnames[ key ]
+            if key == 'stdout':
+                stdout = open( output_fnames[ key ], 'w' )
+                stdout.flush()
+            if key == 'stderr':
+                stderr = open( output_fnames[ key ], 'w' )
+                stdout.flush()
+        real_command = string.Template( command_line ).substitute( all_fnames )
+        # Augment PYTHONPATH, bit of a HACK here! need to suck this data from setuptools or something?
+        env = dict( os.environ )
+        if 'PYTHONPATH' in env:
+            env['PYTHONPATH'] = "./lib:" + env['PYTHONPATH']
+        else:
+            env['PYTHONPATH'] = "./lib"
+        # Run the command
+        assert subprocess.call( real_command, stdin=stdin, stdout=stdout, stderr=stderr, shell=True, env=env ) == 0
+        # Check the outputs
+        for key, value in output_files.iteritems():
+            value.check( output_fnames[key] )
+        # Cleanup
+        for value in output_fnames.values():
+            os.remove( value )
+        
+        
+class TestTest( BaseScriptTest, unittest.TestCase ):
+    input_in1 = TestFile( """Foo\nBar\nBaz""")
+    output_stdout = TestFile( """Foo""" )
+    command_line = "/usr/bin/head -1 ${in1}"
+    
+class TestTest2( BaseScriptTest, unittest.TestCase ):
+    input_in1 = TestFile( "/etc/passwd" )
+    output_stdout = TestFile( "/etc/passwd" )
+    command_line = "cat ${in1}" 
+    
+if __name__ == "__main__":
+    unittest.main()      
+    
\ No newline at end of file
diff --git a/script_tests/bnMapper_tests.py b/script_tests/bnMapper_tests.py
new file mode 100644
index 0000000..0865a7b
--- /dev/null
+++ b/script_tests/bnMapper_tests.py
@@ -0,0 +1,34 @@
+import base
+import unittest
+
+class Test1( base.BaseScriptTest, unittest.TestCase ):
+    command_line = "./scripts/out_to_chain.py ./test_data/epo_tests/epo_547_hs_mm_12way_mammals_65.out --chrsizes ./test_data/epo_tests/hg19.chrom.sizes ./test_data/epo_tests/mm9.chrom.sizes"
+    command_line = "./scripts/bnMapper.py ./test_data/epo_tests/hpeaks.bed ./test_data/epo_tests/epo_547_hs_mm_12way_mammals_65.chain"
+    output_stdout = base.TestFile( filename="./test_data/epo_tests/hpeaks.mapped.bed4" )
+
+class Test2( base.BaseScriptTest, unittest.TestCase ):
+    command_line = "./scripts/bnMapper.py -fBED12 ./test_data/epo_tests/hpeaks.bed ./test_data/epo_tests/epo_547_hs_mm_12way_mammals_65.chain"
+    output_stdout = base.TestFile( filename="./test_data/epo_tests/hpeaks.mapped.bed12" )
+
+class Test3( base.BaseScriptTest, unittest.TestCase ):
+    command_line = "./scripts/bnMapper.py -g9 ./test_data/epo_tests/hpeaks.bed ./test_data/epo_tests/epo_547_hs_mm_12way_mammals_65.chain"
+    output_stdout = base.TestFile( filename="./test_data/epo_tests/hpeaks.mapped.bed4" )
+
+class Test4( base.BaseScriptTest, unittest.TestCase ):
+    command_line = "./scripts/bnMapper.py -g3 ./test_data/epo_tests/hpeaks.bed ./test_data/epo_tests/epo_547_hs_mm_12way_mammals_65.chain"
+    output_stdout = base.TestFile( filename="./test_data/epo_tests/hpeaks.mapped.nopeak2.bed4" )
+
+class Test5( base.BaseScriptTest, unittest.TestCase ):
+    command_line = "./scripts/bnMapper.py -g9 -t0.67 ./test_data/epo_tests/hpeaks.bed ./test_data/epo_tests/epo_547_hs_mm_12way_mammals_65.chain"
+    output_stdout = base.TestFile( filename="./test_data/epo_tests/hpeaks.mapped.bed4" )
+
+class Test6( base.BaseScriptTest, unittest.TestCase ):
+    command_line = "./scripts/bnMapper.py -g9 -t0.7 ./test_data/epo_tests/hpeaks.bed ./test_data/epo_tests/epo_547_hs_mm_12way_mammals_65.chain"
+    output_stdout = base.TestFile( filename="./test_data/epo_tests/hpeaks.mapped.nopeak2.bed4" )
+
+class Test6( base.BaseScriptTest, unittest.TestCase ):
+    command_line = "./scripts/bnMapper.py ./test_data/epo_tests/hg19_one_peak.bed ./test_data/epo_tests/hg19.mm9.rBest.chain.gz"
+    output_stdout = base.TestFile( filename="./test_data/epo_tests/hg19_one_peak.mapped.bed" )
+
+unittest.main()
+
diff --git a/script_tests/line_select_tests.py b/script_tests/line_select_tests.py
new file mode 100644
index 0000000..948c2e1
--- /dev/null
+++ b/script_tests/line_select_tests.py
@@ -0,0 +1,20 @@
+import base
+import unittest
+
+class Test( base.BaseScriptTest, unittest.TestCase ):
+    command_line = "./scripts/line_select.py ${features}"
+    input_features = base.TestFile( """0
+                                       1
+                                       1
+                                       0
+                                       1
+                                       0""" )
+    input_stdin = base.TestFile( """a
+                                    b
+
+                                    d
+                                    e
+                                    f""" )
+    output_stdout = base.TestFile( """b
+
+                                      e""" )
diff --git a/script_tests/maf_extract_ranges_indexed_tests.py b/script_tests/maf_extract_ranges_indexed_tests.py
new file mode 100644
index 0000000..2b312ed
--- /dev/null
+++ b/script_tests/maf_extract_ranges_indexed_tests.py
@@ -0,0 +1,7 @@
+import base
+import unittest
+
+class Test( base.BaseScriptTest, unittest.TestCase ):
+    command_line = "./scripts/maf_extract_ranges_indexed.py ./test_data/maf_tests/mm8_chr7_tiny.maf -c -p mm8. < ${bed}" 
+    input_bed = base.TestFile( filename="./test_data/maf_tests/dcking_ghp074.bed" )
+    output_stdout = base.TestFile( filename="./test_data/maf_tests/dcking_ghp074.maf" )
diff --git a/script_tests/out_to_chain_tests.py b/script_tests/out_to_chain_tests.py
new file mode 100644
index 0000000..f05fbef
--- /dev/null
+++ b/script_tests/out_to_chain_tests.py
@@ -0,0 +1,8 @@
+import base
+import unittest
+
+class Test( base.BaseScriptTest, unittest.TestCase ):
+    command_line = "./scripts/out_to_chain.py ./test_data/epo_tests/epo_547_hs_mm_12way_mammals_65.out --chrsizes ./test_data/epo_tests/hg19.chrom.sizes ./test_data/epo_tests/mm9.chrom.sizes"
+    output_stdout = base.TestFile( filename="./test_data/epo_tests/epo_547_hs_mm_12way_mammals_65.chain" )
+
+unittest.main()
diff --git a/scripts/aggregate_scores_in_intervals.py b/scripts/aggregate_scores_in_intervals.py
new file mode 100755
index 0000000..3847d6d
--- /dev/null
+++ b/scripts/aggregate_scores_in_intervals.py
@@ -0,0 +1,126 @@
+#!/usr/bin/env python
+
+"""
+Given a list of intervals in BED format (`interval_file`) and a set of scores
+(`score_file`) print each interval plus the average, minimum, and maximum of
+the scores that fall in that interval. Scores can either be wiggle format
+data or a directory containing binned array files (named according to the
+sequence source / chromosome of the intervals).
+
+usage: %prog score_file interval_file [out_file] [options] 
+    -b, --binned: 'score_file' is actually a directory of binned array files
+    -m, --mask=FILE: bed file containing regions not to consider valid
+"""
+
+from __future__ import division
+
+import psyco_full
+import sys
+import os, os.path
+from UserDict import DictMixin
+import bx.wiggle
+from bx.binned_array import BinnedArray, FileBinnedArray
+from bx.bitset import *
+from bx.bitset_builders import *
+from bx_extras.fpconst import isNaN
+from bx.cookbook import doc_optparse
+from bx import misc
+
+class FileBinnedArrayDir( DictMixin ):
+    """
+    Adapter that makes a directory of FileBinnedArray files look like
+    a regular dict of BinnedArray objects. 
+    """
+    def __init__( self, dir ):
+        self.dir = dir
+        self.cache = dict()
+    def __getitem__( self, key ):
+        value = None
+        if key in self.cache:
+            value = self.cache[key]
+        else:
+            fname = os.path.join( self.dir, "%s.ba" % key )
+            if os.path.exists( fname ):
+                value = FileBinnedArray( open( fname ) )
+                self.cache[key] = value
+        if value is None:
+            raise KeyError( "File does not exist: " + fname )
+        return value
+
+def load_scores_wiggle( fname ):
+    """
+    Read a wiggle file and return a dict of BinnedArray objects keyed 
+    by chromosome.
+    """
+    scores_by_chrom = dict()
+    for chrom, pos, val in bx.wiggle.Reader( misc.open_compressed( fname ) ):
+        if chrom not in scores_by_chrom:
+            scores_by_chrom[chrom] = BinnedArray()
+        scores_by_chrom[chrom][pos] = val
+    return scores_by_chrom
+
+def load_scores_ba_dir( dir ):
+    """
+    Return a dict-like object (keyed by chromosome) that returns 
+    FileBinnedArray objects created from "key.ba" files in `dir`
+    """
+    return FileBinnedArrayDir( dir )
+    
+def main():
+
+    # Parse command line
+    options, args = doc_optparse.parse( __doc__ )
+    try:
+        score_fname = args[0]
+        interval_fname = args[1]
+        if len( args ) > 2:
+            out_file = open( args[2], 'w' )
+        else:
+            out_file = sys.stdout
+        binned = bool( options.binned )
+        mask_fname = options.mask
+    except:
+        doc_optparse.exit()
+
+    if binned:
+        scores_by_chrom = load_scores_ba_dir( score_fname )
+    else:
+        scores_by_chrom = load_scores_wiggle( score_fname )
+
+    if mask_fname:
+        masks = binned_bitsets_from_file( open( mask_fname ) )
+    else:
+        masks = None
+
+    for line in open( interval_fname ):
+        fields = line.split()
+        chrom, start, stop = fields[0], int( fields[1] ), int( fields[2] )
+        total = 0
+        count = 0
+        min_score = 100000000
+        max_score = -100000000
+        for i in range( start, stop ):
+            if chrom in scores_by_chrom and scores_by_chrom[chrom][i]:
+                # Skip if base is masked
+                if masks and chrom in masks:
+                    if masks[chrom][i]:
+                        continue
+                # Get the score, only count if not 'nan'
+                score = scores_by_chrom[chrom][i]
+                if not isNaN( score ):
+                    total += score
+                    count += 1
+                    max_score = max( score, max_score )
+                    min_score = min( score, min_score )
+        if count > 0:
+            avg = total/count
+        else:
+            avg = "nan"
+            min_score = "nan"
+            max_score = "nan"
+            
+        print >> out_file, "\t".join( map( str, [ chrom, start, stop, avg, min_score, max_score ] ) )
+
+    out_file.close()
+
+if __name__ == "__main__": main()
diff --git a/scripts/align_print_template.py b/scripts/align_print_template.py
new file mode 100755
index 0000000..2201571
--- /dev/null
+++ b/scripts/align_print_template.py
@@ -0,0 +1,47 @@
+#!/usr/bin/env python
+
+"""
+Read an alignment from stdin and for each block print the result of 
+evaluating `template_string` (in cheetah template format). The alignment
+block will be placed in the template context as `a` and the list of components
+as `c`.
+
+usage: %prog template [options]
+    -f, --format = maf: Input format, maf (default) or axt
+"""
+
+from __future__ import division
+
+import psyco_full
+
+import sys
+from bx.cookbook import doc_optparse
+from bx import align
+
+try:
+    from Cheetah.Template import Template
+except:
+    print >> sys.stderr, "This script requires the Cheetah template modules"
+    sys.exit( -1 )
+
+def main():
+
+    # Parse command line arguments
+    options, args = doc_optparse.parse( __doc__ )
+
+    try:
+        template = Template( args[0] )
+        format = options.format
+        if not format: format = "maf"
+    except:
+        doc_optparse.exception()
+
+    reader = align.get_reader( format, sys.stdin ) 
+
+    for a in reader: 
+        template.a = a
+        template.c = a.components
+        print template
+
+if __name__ == "__main__": 
+	main()
diff --git a/scripts/axt_extract_ranges.py b/scripts/axt_extract_ranges.py
new file mode 100755
index 0000000..b8b6976
--- /dev/null
+++ b/scripts/axt_extract_ranges.py
@@ -0,0 +1,68 @@
+#!/usr/bin/env python
+
+"""
+Reads a list of intervals and an axt. Produces a new axt containing the
+portions of the original that overlapped the intervals
+
+usage: %prog interval_file refindex [options] < axt_file
+   -m, --mincols=10: Minimum length (columns) required for alignment to be output
+"""
+
+import psyco_full
+
+from bx.cookbook import doc_optparse
+
+import bx.align.axt
+from bx import intervals
+import sys
+
+
+def __main__():
+
+	# Parse Command Line
+
+	options, args = doc_optparse.parse( __doc__ )
+
+	try:
+		range_filename = args[ 0 ]
+		refindex = int( args[ 1 ] )
+		if options.mincols: mincols = int( options.mincols )
+		else: mincols = 10
+	except:
+		doc_optparse.exit()
+
+	# Load Intervals
+
+	intersecter = intervals.Intersecter()
+	for line in file( range_filename ):
+		fields = line.split()
+		intersecter.add_interval( intervals.Interval( int( fields[0] ), int( fields[1] ) ) )
+
+	# Start axt on stdout
+
+	out = bx.align.axt.Writer( sys.stdout )
+
+	# Iterate over input axt
+
+	for axt in bx.align.axt.Reader( sys.stdin ):
+		ref_component = axt.components[ refindex ]
+		# Find overlap with reference component
+		intersections = intersecter.find( ref_component.start, ref_component.end )
+		# Keep output axt ordered
+		intersections.sort()
+		# Write each intersecting block
+		for interval in intersections: 
+			start = max( interval.start, ref_component.start )
+			end = min( interval.end, ref_component.end )
+			sliced = axt.slice_by_component( refindex, start, end ) 
+			good = True
+			for c in sliced.components: 
+				if c.size < 1: 
+					good = False
+			if good and sliced.text_size > mincols: out.write( sliced )
+		 
+	# Close output axt
+
+	out.close()
+
+if __name__ == "__main__": __main__()
diff --git a/scripts/axt_to_fasta.py b/scripts/axt_to_fasta.py
new file mode 100755
index 0000000..48a7a17
--- /dev/null
+++ b/scripts/axt_to_fasta.py
@@ -0,0 +1,53 @@
+#!/usr/bin/env python
+
+"""
+Application to convert AXT file to FASTA file. Reads an AXT file from standard 
+input and writes a FASTA file to standard out.
+
+usage: %prog < axt_file > fasta_file
+"""
+
+__author__ = "Bob Harris (rsharris at bx.psu.edu)"
+
+import sys
+import bx.align.axt
+
+def usage(s=None):
+	message = """
+axt_to_fasta < axt_file > fasta_file
+"""
+	if (s == None): sys.exit (message)
+	else:           sys.exit ("%s\n%s" % (s,message))
+
+
+def main():
+
+	# check the command line
+
+	if (len(sys.argv) > 1):
+		usage("give me no arguments")
+
+	# convert the alignment blocks
+
+	reader = bx.align.axt.Reader(sys.stdin,support_ids=True,\
+	                             species1="",species2="")
+
+	for a in reader:
+		if ("id" in a.attributes): id = a.attributes["id"]
+		else:                      id = None
+		print_component_as_fasta(a.components[0],id)
+		print_component_as_fasta(a.components[1],id)
+		print
+
+
+# $$$ this should be moved to a bx.align.fasta module
+
+def print_component_as_fasta(c,id=None):
+	header = ">%s_%s_%s" % (c.src,c.start,c.start+c.size)
+	if (id != None): header += " " + id
+	print header
+	print c.text
+
+
+if __name__ == "__main__": main()
+
diff --git a/scripts/axt_to_lav.py b/scripts/axt_to_lav.py
new file mode 100755
index 0000000..9abd311
--- /dev/null
+++ b/scripts/axt_to_lav.py
@@ -0,0 +1,158 @@
+#!/usr/bin/env python
+
+"""
+Application to convert AXT file to LAV file. Reads an AXT file from standard
+input and writes a LAV file to standard out; some statistics are written to
+standard error.
+
+usage: %prog primary_spec secondary_spec [--silent] < axt_file > lav_file
+
+Each spec is of the form seq_file[:species_name]:lengths_file.
+
+- seq_file should be a format string for the file names for the individual
+  sequences, with %s to be replaced by the alignment's src field.  For
+  example, "hg18/%s.nib" would prescribe files named "hg18/chr1.nib",
+  "hg18/chr2.nib", etc.
+
+- species_name is optional.  If present, it is prepended to the alignment's
+  src field.
+
+- Lengths files provide the length of each chromosome (lav format needs this
+  information but axt file does not contain it).  The format is a series of
+  lines of the form:
+
+  <chromosome name> <length>
+
+  The chromosome field in each axt block must match some <chromosome name> in
+  the lengths file.
+"""
+
+__author__ = "Bob Harris (rsharris at bx.psu.edu)"
+
+import sys
+import copy
+import bx.align.axt
+import bx.align.lav
+
+
+def usage(s=None):
+	message = __doc__
+	if (s == None): sys.exit (message)
+	else:           sys.exit ("%s\n%s" % (s,message))
+
+
+def main():
+	global debug
+
+	# parse the command line
+
+	primary   = None
+	secondary = None
+	silent    = False
+
+	# pick off options
+
+	args = sys.argv[1:]
+	while (len(args) > 0):
+		arg = args.pop(0)
+		val = None
+		fields = arg.split("=",1)
+		if (len(fields) == 2):
+			arg = fields[0]
+			val = fields[1]
+			if (val == ""):
+				usage("missing a value in %s=" % arg)
+
+		if (arg == "--silent") and (val == None):
+			silent = True
+		elif (primary == None) and (val == None):
+			primary = arg
+		elif (secondary == None) and (val == None):
+			secondary = arg
+		else:
+			usage("unknown argument: %s" % arg)
+
+	if (primary == None):
+		usage("missing primary file name and length")
+
+	if (secondary == None):
+		usage("missing secondary file name and length")
+
+	try:
+		(primaryFile,primary,primaryLengths) = parse_spec(primary)
+	except:
+		usage("bad primary spec (must be seq_file[:species_name]:lengths_file")
+
+	try:
+		(secondaryFile,secondary,secondaryLengths) = parse_spec(secondary)
+	except:
+		usage("bad secondary spec (must be seq_file[:species_name]:lengths_file")
+
+	# read the lengths
+
+	speciesToLengths = {}
+	speciesToLengths[primary]   = read_lengths (primaryLengths)
+	speciesToLengths[secondary] = read_lengths (secondaryLengths)
+
+	# read the alignments
+
+	out = bx.align.lav.Writer(sys.stdout, \
+			attributes = { "name_format_1" : primaryFile,
+			               "name_format_2" : secondaryFile })
+
+	axtsRead = 0
+	axtsWritten = 0
+	for axtBlock in bx.align.axt.Reader(sys.stdin, \
+			species_to_lengths = speciesToLengths,
+			species1           = primary,
+			species2           = secondary,
+			support_ids        = True):
+		axtsRead += 1
+		out.write (axtBlock)
+		axtsWritten += 1
+
+	out.close()
+
+	if (not silent):
+		sys.stderr.write ("%d blocks read, %d written\n" % (axtsRead,axtsWritten))
+
+def parse_spec(spec): # returns (seq_file,species_name,lengths_file)
+	fields = spec.split(":")
+	if   (len(fields) == 2): return (fields[0],"",fields[1])
+	elif (len(fields) == 3): return (fields[0],fields[1],fields[2])
+	else:                    raise ValueError
+
+def read_lengths (fileName):
+
+	chromToLength = {}
+
+	f = file (fileName, "r")
+
+	for lineNumber,line in enumerate(f):
+		line = line.strip()
+		if (line == ""): continue
+		if (line.startswith("#")): continue
+
+		fields = line.split ()
+		if (len(fields) != 2):
+			raise ValueError("bad lengths line (%s:%d): %s" % (fileName,lineNumber,line))
+
+		chrom = fields[0]
+		try:
+			length = int(fields[1])
+		except:
+			raise ValueError("bad lengths line (%s:%d): %s" % (fileName,lineNumber,line))
+
+		if (chrom in chromToLength):
+			raise ValueError("%s appears more than once (%s:%d): %s" \
+			    % (chrom,fileName,lineNumber))
+
+		chromToLength[chrom] = length
+
+	f.close ()
+
+	return chromToLength
+
+
+if __name__ == "__main__": main()
+
diff --git a/scripts/axt_to_maf.py b/scripts/axt_to_maf.py
new file mode 100755
index 0000000..8394e01
--- /dev/null
+++ b/scripts/axt_to_maf.py
@@ -0,0 +1,161 @@
+#!/usr/bin/env python
+
+"""
+Application to convert AXT file to MAF file. Reads an AXT file from standard
+input and writes a MAF file to standard out;  some statistics are written to
+standard error.
+
+axt_to_maf primary:lengths_file secondary:lengths_file < axt_file > maf_file
+  --silent: prevents stats report
+
+  Lengths files provide the length of each chromosome (maf format needs this
+  information but axt file does not contain it).  The format is a series of
+  lines of the form:
+
+    <chromosome name> <length>
+
+  The chromosome field in each axt block must match some <chromosome name> in
+  the lengths file.
+"""
+
+__author__ = "Bob Harris (rsharris at bx.psu.edu)"
+
+import sys
+import copy
+import bx.align.axt
+import bx.align.maf
+
+def usage(s=None):
+	message = __doc__
+	if (s == None): sys.exit (message)
+	else:           sys.exit ("%s\n%s" % (s,message))
+
+
+def main():
+	global debug
+
+	##########
+	# parse the command line
+	##########
+
+	primary   = None
+	secondary = None
+	silent    = False
+
+	# pick off options
+
+	args = sys.argv[1:]
+	while (len(args) > 0):
+		arg = args.pop(0)
+		val = None
+		fields = arg.split("=",1)
+		if (len(fields) == 2):
+			arg = fields[0]
+			val = fields[1]
+			if (val == ""):
+				usage("missing a value in %s=" % arg)
+
+		if (arg == "--silent") and (val == None):
+			silent = True
+		elif (primary == None) and (val == None):
+			primary = arg
+		elif (secondary == None) and (val == None):
+			secondary = arg
+		else:
+			usage("unknown argument: %s" % arg)
+
+	if (primary == None):
+		usage("missing primary species")
+
+	if (secondary == None):
+		usage("missing secondary species")
+
+	fields = primary.split(":")
+	if (len(fields) != 2):
+		usage("bad primary species (must be species:lengths_file")
+	primary = fields[0]
+	primaryLengths = fields[1]
+
+	fields = secondary.split(":")
+	if (len(fields) != 2):
+		usage("bad secondary species (must be species:lengths_file")
+	secondary = fields[0]
+	secondaryLengths = fields[1]
+
+	##########
+	# read the lengths
+	##########
+
+	speciesToLengths = {}
+	speciesToLengths[primary]   = read_lengths (primaryLengths)
+	speciesToLengths[secondary] = read_lengths (secondaryLengths)
+
+	##########
+	# read the alignments
+	##########
+
+	out = bx.align.maf.Writer(sys.stdout)
+
+	axtsRead = 0
+	axtsWritten = 0
+	for axtBlock in bx.align.axt.Reader(sys.stdin,\
+			species_to_lengths = speciesToLengths,
+			species1           = primary,
+			species2           = secondary):
+		axtsRead += 1
+
+		p = axtBlock.get_component_by_src_start(primary)
+		if (p == None): continue
+		s = axtBlock.get_component_by_src_start(secondary)
+		if (s == None): continue
+
+		mafBlock = bx.align.Alignment (axtBlock.score, axtBlock.attributes)
+		mafBlock.add_component (clone_component(p))
+		mafBlock.add_component (clone_component(s))
+
+		out.write (mafBlock)
+		axtsWritten += 1
+
+	if (not silent):
+		sys.stderr.write ("%d blocks read, %d written\n" % (axtsRead,axtsWritten))
+
+
+def clone_component(c):
+	return bx.align.Component (c.src, c.start, c.size, c.strand, c.src_size, \
+	                           copy.copy(c.text))
+
+
+def read_lengths (fileName):
+
+	chromToLength = {}
+
+	f = file (fileName, "r")
+
+	for lineNumber,line in enumerate(f):
+		line = line.strip()
+		if (line == ""): continue
+		if (line.startswith("#")): continue
+
+		fields = line.split ()
+		if (len(fields) != 2):
+			raise ValueError("bad lengths line (%s:%d): %s" % (fileName,lineNumber,line))
+
+		chrom = fields[0]
+		try:
+			length = int(fields[1])
+		except:
+			raise ValueError("bad lengths line (%s:%d): %s" % (fileName,lineNumber,line))
+
+		if (chrom in chromToLength):
+			raise ValueError("%s appears more than once (%s:%d): %s" \
+			    % (chrom,fileName,lineNumber))
+
+		chromToLength[chrom] = length
+
+	f.close ()
+
+	return chromToLength
+
+
+if __name__ == "__main__": main()
+
diff --git a/scripts/bed_bigwig_profile.py b/scripts/bed_bigwig_profile.py
new file mode 100755
index 0000000..954144d
--- /dev/null
+++ b/scripts/bed_bigwig_profile.py
@@ -0,0 +1,33 @@
+#!/usr/bin/env python
+
+"""
+Create a site profile vector showing the average signal accumulated from a
+bigwig file around the center of each interval from a BED file.
+
+Output is the average signal value at that relative position across the 
+intervals.
+
+usage: %prog bigwig_file.bw padding < bed_file.bed 
+"""
+
+import sys
+from numpy import *
+
+from bx.intervals.io import GenomicIntervalReader
+from bx.bbi.bigwig_file import BigWigFile
+
+bw = BigWigFile( open( sys.argv[1] ) )
+padding = int( sys.argv[2] )
+totals = zeros( padding*2, dtype=float64 )
+valid = zeros( padding*2, dtype=int32 )
+
+for interval in GenomicIntervalReader( sys.stdin ):
+    center = floor( ( interval.start + interval.end ) / 2 )
+    values = bw.get_as_array( interval.chrom, center - padding, center + padding )
+    # Determine which positions had data and mask the rest for totalling
+    invalid = isnan( values )
+    values[ invalid ] = 0
+    totals += values
+    valid += ( ~ invalid )
+
+savetxt( sys.stdout, totals/valid )
diff --git a/scripts/bed_build_windows.py b/scripts/bed_build_windows.py
new file mode 100755
index 0000000..a7752f1
--- /dev/null
+++ b/scripts/bed_build_windows.py
@@ -0,0 +1,54 @@
+#!/usr/bin/env python2.4
+
+"""
+Build windows of length `window_size` over the sequences defined by 
+`len_file` excluding regions in `gap_file`.
+
+After removing the gaps, windows of exactly `window_size` units will be
+placed in the remaining regions, with the extra space evenly placed
+between the windows.
+
+`len_file` is LEN format (name length) and `gap_file is BED (name start stop).
+
+usage: %prog len_file gap_file window_size
+"""
+
+import sys
+from bx.bitset_builders import binned_bitsets_from_file
+import random
+
+def main():
+    region_fname, exclude_fname, window_size = sys.argv[1], sys.argv[2], int( sys.argv[3] ) 
+    exclude_bitsets = binned_bitsets_from_file( open( exclude_fname ) )
+    for line in open( region_fname ):
+        fields = line.split()
+        chr, start, end = fields[0], 0, int( fields[1] )
+        if chr not in exclude_bitsets:
+            do_windows( chr, start, end, window_size )
+        else:
+            bits = exclude_bitsets[chr]
+            assert end < bits.size
+            e = 0
+            while 1:
+                s = bits.next_clear( e )
+                if s > end: break
+                e = bits.next_set( s )
+                do_windows( chr, s, min( e, end ), window_size )
+
+def do_windows( chr, start, end, window_size ):
+    length = end - start
+    window_count = length // window_size
+    if window_count == 0:
+        return
+    lost = length % window_size
+    skip_amount = lost // window_count
+    ## skip_amounts = [0] * ( window_count + 1 )
+    ## for i in range( 0, lost ): skip_amounts[ random.randrange( 0, window_count + 1 ) ] += 1
+    s = 0
+    for i in range( 0, window_count ):
+        s += skip_amount
+        print chr, start + s, start + s + window_size        
+        s += window_size
+        
+if __name__ == "__main__":
+    main()
\ No newline at end of file
diff --git a/scripts/bed_complement.py b/scripts/bed_complement.py
new file mode 100755
index 0000000..5eabd48
--- /dev/null
+++ b/scripts/bed_complement.py
@@ -0,0 +1,50 @@
+#!/usr/bin/env python2.4
+
+"""
+Complement the regions of a bed file. Requires a file that maps source names
+to sizes. This should be in the simple LEN file format (each line contains
+a source name followed by a size, separated by whitespace).
+
+usage: %prog bed_file chrom_length_file
+"""
+
+import sys
+
+from bx.bitset import *
+from bx.bitset_builders import *
+
+from bx.cookbook import doc_optparse
+
+def read_len( f ):
+    """Read a 'LEN' file and return a mapping from chromosome to length"""
+    mapping = dict()
+    for line in f:
+        fields = line.split()
+        mapping[ fields[0] ] = int( fields[1] )
+    return mapping
+
+options, args = doc_optparse.parse( __doc__ )
+try:
+    in_fname, len_fname = args
+except:
+    doc_optparse.exit()
+
+bitsets = binned_bitsets_from_file( open( in_fname ) )
+
+lens = read_len( open( len_fname ) )
+
+for chrom in lens:
+    if chrom in bitsets:
+        bits = bitsets[chrom]
+        bits.invert()
+        len = lens[chrom]
+        end = 0
+        while 1:
+            start = bits.next_set( end )
+            if start == bits.size: break
+            end = bits.next_clear( start )
+            if end > len: end = len
+            print "%s\t%d\t%d" % ( chrom, start, end )
+            if end == len: break
+    else:
+        print "%s\t%d\t%d" % ( chrom, 0, lens[chrom] )
diff --git a/scripts/bed_count_by_interval.py b/scripts/bed_count_by_interval.py
new file mode 100755
index 0000000..5aa3c92
--- /dev/null
+++ b/scripts/bed_count_by_interval.py
@@ -0,0 +1,29 @@
+#!/usr/bin/env python2.4
+"""
+For each interval in `bed1` count the number of intersecting regions in `bed2`.
+
+usage: %prog bed1 bed2 
+"""
+
+import sys
+from bx.intervals import *
+
+bed1,bed2 = sys.argv[1:3]
+
+ranges = {}
+for line in open( bed2 ):
+    fields = line.strip().split() 
+    chrom, start, end, = fields[0], int(fields[1]), int(fields[2])
+    if chrom not in ranges: ranges[chrom] = Intersecter()
+    ranges[chrom].add_interval( Interval( start, end ) )
+    
+for line in open( bed1 ):
+    fields = line.strip().split() 
+    chrom, start, end = fields[0], int(fields[1]), int(fields[2]) 
+    other = " ".join(fields[3:])
+    out = " ".join(fields[:3] +[other])
+    if chrom in ranges: 
+        print out, len( ranges[chrom].find( start, end ) )
+    else:
+        print out, 0
+
diff --git a/scripts/bed_count_overlapping.py b/scripts/bed_count_overlapping.py
new file mode 100755
index 0000000..5aa3c92
--- /dev/null
+++ b/scripts/bed_count_overlapping.py
@@ -0,0 +1,29 @@
+#!/usr/bin/env python2.4
+"""
+For each interval in `bed1` count the number of intersecting regions in `bed2`.
+
+usage: %prog bed1 bed2 
+"""
+
+import sys
+from bx.intervals import *
+
+bed1,bed2 = sys.argv[1:3]
+
+ranges = {}
+for line in open( bed2 ):
+    fields = line.strip().split() 
+    chrom, start, end, = fields[0], int(fields[1]), int(fields[2])
+    if chrom not in ranges: ranges[chrom] = Intersecter()
+    ranges[chrom].add_interval( Interval( start, end ) )
+    
+for line in open( bed1 ):
+    fields = line.strip().split() 
+    chrom, start, end = fields[0], int(fields[1]), int(fields[2]) 
+    other = " ".join(fields[3:])
+    out = " ".join(fields[:3] +[other])
+    if chrom in ranges: 
+        print out, len( ranges[chrom].find( start, end ) )
+    else:
+        print out, 0
+
diff --git a/scripts/bed_coverage.py b/scripts/bed_coverage.py
new file mode 100755
index 0000000..8e5366f
--- /dev/null
+++ b/scripts/bed_coverage.py
@@ -0,0 +1,29 @@
+#!/usr/bin/env python
+
+"""
+Print number of bases covered by all intervals in a bed file (bases covered by
+more than one interval are counted only once). Multiple bed files can be 
+provided on the command line or to stdin.
+
+usage: %prog bed files ...
+"""
+
+import psyco_full
+import sys
+from bx.bitset import BinnedBitSet
+from bx.bitset_builders import *
+from itertools import *
+
+bed_filenames = sys.argv[1:]
+if bed_filenames:
+    input = chain( * imap( open, bed_filenames ) )
+else:
+    input = sys.stdin
+
+bitsets = binned_bitsets_from_file( input )
+
+total = 0
+for chrom in bitsets:
+    total += bitsets[chrom].count_range( 0, bitsets[chrom].size )
+
+print total    
diff --git a/scripts/bed_coverage_by_interval.py b/scripts/bed_coverage_by_interval.py
new file mode 100755
index 0000000..9b2b4b2
--- /dev/null
+++ b/scripts/bed_coverage_by_interval.py
@@ -0,0 +1,55 @@
+#!/usr/bin/env python
+
+"""
+For each interval in `bed1` print the fraction of bases covered by `bed2`.
+
+usage: %prog bed1 bed2 [mask]
+"""
+
+from __future__ import division
+
+import psyco_full
+import sys
+from bx.bitset import BinnedBitSet
+from bx.bitset_builders import *
+from itertools import *
+
+bed1_fname, bed2_fname = sys.argv[1:3]
+
+bitsets = binned_bitsets_from_file( open( bed2_fname ) )
+
+def clone( bits ):
+    b = BinnedBitSet( bits.size )
+    b.ior( bits )
+    return b
+
+if len( sys.argv ) > 3:
+    mask_fname = sys.argv[3]
+    mask = binned_bitsets_from_file( open( mask_fname ) )
+    new_bitsets = dict()
+    for key in bitsets:
+        if key in mask:
+            b = clone( mask[key] )
+            b.invert()
+            b.iand( bitsets[key] )
+            new_bitsets[key] = b
+    bitsets = new_bitsets
+else:
+    mask = None
+
+for line in open( bed1_fname ):
+    fields = line.split()
+    chr, start, end = fields[0], int( fields[1] ), int( fields[2] )
+    bases_covered = 0
+    if chr in bitsets:
+         bases_covered = bitsets[ chr ].count_range( start, end-start )
+    length = end - start
+    if mask and chr in mask:
+        bases_masked = mask[ chr ].count_range( start, end-start )
+        length -= bases_masked
+    assert bases_covered <= length, "%r, %r, %r" % ( bases_covered, bases_masked, length )
+    if length == 0:
+        print 0.0
+    else:
+        print bases_covered / length
+
diff --git a/scripts/bed_diff_basewise_summary.py b/scripts/bed_diff_basewise_summary.py
new file mode 100755
index 0000000..07fecc0
--- /dev/null
+++ b/scripts/bed_diff_basewise_summary.py
@@ -0,0 +1,44 @@
+#!/usr/bin/env python
+
+"""
+Given two bed files print the number of bases covered 1) by both, 2) only by 
+the first, and 3) only by the second.
+
+usage: %prog bed_file_1 bed_file_2
+"""
+import sys
+from warnings import warn
+from bx.bitset import BinnedBitSet
+from bx.bitset_builders import *
+from bx.cookbook import doc_optparse
+
+def coverage( bitsets ):
+    total = 0
+    for chrom in bitsets:
+        total += bitsets[chrom].count_range( 0, bitsets[chrom].size )
+    return total    
+
+options, args = doc_optparse.parse( __doc__ )
+try:
+    in_fname, in2_fname = args
+except:
+    doc_optparse.exit()
+
+bits1 = binned_bitsets_from_file( open( in_fname ) )
+bits2 = binned_bitsets_from_file( open( in2_fname ) )
+
+bits1_covered = coverage( bits1 )
+bits2_covered = coverage( bits2 )
+
+bitsets = dict()
+
+for key in bits1:
+    if key in bits2:
+        bits1[key].iand( bits2[key] )
+        bitsets[key] = bits1[key]
+
+both_covered = coverage( bitsets )
+
+print "in both:  \t%d" % both_covered
+print "only in %s:\t%d" % ( in_fname, bits1_covered - both_covered )
+print "only in %s:\t%d" % ( in2_fname, bits2_covered - both_covered )
diff --git a/scripts/bed_extend_to.py b/scripts/bed_extend_to.py
new file mode 100755
index 0000000..ec7c749
--- /dev/null
+++ b/scripts/bed_extend_to.py
@@ -0,0 +1,36 @@
+#!/usr/bin/env python
+
+"""
+Read BED file and extend each record to the specified minimum length. If chromosome 
+size information is provided trim extended intervals.
+
+usage: %prog amount [ chrom_file ] < bed_file
+"""
+
+import sys
+from bx.intervals.io import GenomicIntervalReader
+
+length = int( sys.argv[1] )
+chrom_len = None
+if len( sys.argv ) > 2:
+    chrom_len = dict( ( fields[0], int( fields[1] ) ) for fields in map( str.split, open( sys.argv[2] ) ) )
+
+for interval in GenomicIntervalReader( sys.stdin ):
+    if interval.end - interval.start < length:
+        start = interval.start
+        end = interval.end
+        # Extend in positive direction on strand
+        if interval.strand == "+":
+            end = start + length
+        else:
+            start = end - length
+        # Trim 
+        if start < 0:
+            start = 0
+        if chrom_len and end > chrom_len[interval.chrom]:
+            end = chrom_len[interval.chrom]
+        # Set new start and end
+        interval.start = start
+        interval.end = end
+    # Output possibly adjusted interval
+    print interval
diff --git a/scripts/bed_intersect.py b/scripts/bed_intersect.py
new file mode 100755
index 0000000..a0a5958
--- /dev/null
+++ b/scripts/bed_intersect.py
@@ -0,0 +1,68 @@
+#!/usr/bin/env python
+
+"""
+Find regions of first bed file that overlap regions in a second bed file. The
+output preserves all fields from the input. 
+
+NOTE: -u and -d options are currently not functional!
+
+usage: %prog bed_file_1 bed_file_2
+    -m, --mincols=N: Require this much overlap (default 1bp)
+    -u, --upstream_pad=N: upstream interval padding (default 0bp)
+    -d, --downstream_pad=N: downstream interval padding (default 0bp)
+    -v, --reverse: Print regions that DO NOT overlap
+    -b, --booleans: Just print '1' if interval overlaps or '0' otherwise
+"""
+
+import sys
+from warnings import warn
+
+from bx.bitset import *
+from bx.bitset_builders import *
+
+from bx.cookbook import doc_optparse
+
+mincols = 1
+upstream_pad = 0
+downstream_pad = 0
+
+options, args = doc_optparse.parse( __doc__ )
+try:
+    if options.mincols: mincols = int( options.mincols )
+    if options.upstream_pad: upstream_pad = int( options.upstream_pad )
+    if options.downstream_pad: downstream_pad = int( options.downstream_pad )
+    reverse = bool( options.reverse )
+    booleans = bool( options.booleans )
+    in_fname, in2_fname = args
+except:
+    doc_optparse.exit()
+
+# Read first bed into some bitsets
+
+bitsets = binned_bitsets_from_file( open( in2_fname ) )
+
+# Read second BED and intersect
+
+for line in open( in_fname ):
+    if line.startswith("#") or line.isspace(): 
+        continue
+    fields = line.split()
+    start, end = int( fields[1] ), int( fields[2] )
+    if start > end: 
+        warn( "Bed interval start after end!" )
+    if fields[0] in bitsets and bitsets[fields[0]].count_range( start, end-start ) >= mincols:
+        if booleans:
+            if reverse: 
+                print 0
+            else:
+                print 1
+        elif not reverse:
+            print line,
+    else:
+        if booleans:
+            if reverse:
+                print 1
+            else:
+                print 0
+        elif reverse:
+            print line,
diff --git a/scripts/bed_intersect_basewise.py b/scripts/bed_intersect_basewise.py
new file mode 100755
index 0000000..0acfd9f
--- /dev/null
+++ b/scripts/bed_intersect_basewise.py
@@ -0,0 +1,40 @@
+#!/usr/bin/env python
+
+"""
+Find regions of first bed file that overlap regions in a second bed file. This
+program performs a base-by-base intersection, so only runs of bases that are
+covered in both of the inputs will be output.
+
+usage: %prog bed_file_1 bed_file_2
+"""
+
+import sys
+from warnings import warn
+from bx.bitset import *
+from bx.bitset_builders import *
+from bx.cookbook import doc_optparse
+
+options, args = doc_optparse.parse( __doc__ )
+try:
+    in_fname, in2_fname = args
+except:
+    doc_optparse.exit()
+
+bits1 = binned_bitsets_from_file( open( in_fname ) )
+bits2 = binned_bitsets_from_file( open( in2_fname ) )
+
+bitsets = dict()
+
+for key in bits1:
+    if key in bits2:
+        bits1[key].iand( bits2[key] )
+        bitsets[key] = bits1[key]
+
+for chrom in bitsets:
+    bits = bitsets[chrom]
+    end = 0
+    while 1:
+        start = bits.next_set( end )
+        if start == bits.size: break
+        end = bits.next_clear( start )
+        print "%s\t%d\t%d" % ( chrom, start, end )
diff --git a/scripts/bed_merge_overlapping.py b/scripts/bed_merge_overlapping.py
new file mode 100755
index 0000000..1fbd944
--- /dev/null
+++ b/scripts/bed_merge_overlapping.py
@@ -0,0 +1,33 @@
+#!/usr/bin/env python
+
+"""
+Merge any overlapping regions of bed files. Bed files can be provided on the
+command line or on stdin. Merged regions are always reported on the '+' 
+strand, and any fields beyond chrom/start/stop are lost. 
+
+usage: %prog bed files ...
+"""
+
+import psyco_full
+import sys
+
+from bx.bitset import *
+from bx.bitset_builders import *
+from itertools import *
+
+bed_filenames = sys.argv[1:]
+if bed_filenames:
+    input = chain( * imap( open, bed_filenames ) )
+else:
+    input = sys.stdin
+
+bitsets = binned_bitsets_from_bed_file( input )
+
+for chrom in bitsets:
+    bits = bitsets[chrom]
+    end = 0
+    while 1:
+        start = bits.next_set( end )
+        if start == bits.size: break
+        end = bits.next_clear( start )
+        print "%s\t%d\t%d" % ( chrom, start, end )
diff --git a/scripts/bed_rand_intersect.py b/scripts/bed_rand_intersect.py
new file mode 100755
index 0000000..7ae69d7
--- /dev/null
+++ b/scripts/bed_rand_intersect.py
@@ -0,0 +1,160 @@
+#!/usr/bin/env python2.4
+
+"""
+From a set of regions and two sets of intervals inside those regions
+compute (for each region separately) the overlap between the two sets
+of intervals and the overlap in `nsamples` random coverings of the 
+regions with intervals having the same lengths. Prints the z-score relative
+to the mean and sample stdev of the random coverings.
+
+Currently intervals must be in bed 3+ format.
+
+TODO: There are a few versions of this floating around, including a 
+      better/faster one using gap lists instead of bitsets. Need to track 
+      that down and merge as necessary.
+
+usage: %prog bounding_region_file intervals1 intervals2 nsamples
+"""
+
+from __future__ import division 
+
+import sys, random
+import bisect
+from bx_extras import stats
+from Numeric import *
+from bx.bitset import *
+from bx.intervals.random_intervals import *
+
+maxtries = 10
+
+class MaxtriesException( Exception ):
+    pass
+
+def bit_clone( bits ):
+    """
+    Clone a bitset
+    """
+    new = BitSet( bits.size )
+    new.ior( bits )
+    return new
+
+def throw_random( lengths, mask ):
+    """
+    Try multiple times to run 'throw_random'
+    """
+    saved = None
+    for i in range( maxtries ):
+        try:
+            return throw_random_bits( lengths, mask )
+        except MaxtriesException, e:
+            saved = e
+            continue
+    raise e
+    
+def as_bits( region_start, region_length, intervals ):
+    """
+    Convert a set of intervals overlapping a region of a chromosome into 
+    a bitset for just that region with the bits covered by the intervals 
+    set.
+    """
+    bits = BitSet( region_length )
+    for chr, start, stop in intervals:
+        bits.set_range( start - region_start, stop - start )
+    return bits
+
+def interval_lengths( bits ):
+    """
+    Get the length distribution of all contiguous runs of set bits from
+    """
+    end = 0
+    while 1:
+        start = bits.next_set( end )
+        if start == bits.size: break
+        end = bits.next_clear( start )
+        yield end - start
+
+def count_overlap( bits1, bits2 ):
+    """
+    Count the number of bits that overlap between two sets
+    """
+    b = BitSet( bits1.size )
+    b |= bits1
+    b &= bits2
+    return b.count_range( 0, b.size )
+    
+def overlapping_in_bed( fname, r_chr, r_start, r_stop ):
+    """
+    Get from a bed all intervals that overlap the region defined by
+    r_chr, r_start, r_stop.
+    """
+    rval = []
+    for line in open( fname ):
+        if line.startswith( "#" ) or line.startswith( "track" ):
+            continue
+        fields = line.split()
+        chr, start, stop = fields[0], int( fields[1] ), int( fields[2] )
+        if chr == r_chr and start < r_stop and stop >= r_start:
+            rval.append( ( chr, max( start, r_start ), min( stop, r_stop ) ) )
+    return rval        
+
+def main():
+    region_fname = sys.argv[1]
+    mask_fname = sys.argv[2]       
+    nsamples = int( sys.argv[3] )
+    intervals1_fname = sys.argv[4]       
+    intervals2_fnames = sys.argv[5:]       
+    nfeatures = len( intervals2_fnames )
+    total_actual = zeros( nfeatures )
+    # total_lengths1 = 0
+    total_lengths2 = zeros( nfeatures )
+    total_samples = zeros( ( nsamples, nfeatures ) )
+    for line in open( region_fname ):
+        # Load lengths for all intervals overlapping region
+        fields = line.split()
+        print >>sys.stderr, "Processing region:", fields[3]
+        r_chr, r_start, r_stop = fields[0], int( fields[1] ), int( fields[2] )
+        r_length = r_stop - r_start
+        # Load the mask
+        mask = overlapping_in_bed( mask_fname, r_chr, r_start, r_stop )
+        bits_mask = as_bits( r_start, r_length, mask )
+        bits_not_masked = bit_clone( bits_mask ); bits_not_masked.invert()
+        # Load the first set
+        intervals1 = overlapping_in_bed( intervals1_fname, r_chr, r_start, r_stop )
+        bits1 = as_bits( r_start, r_length, intervals1 )
+        # Intersect it with the mask 
+        bits1.iand( bits_not_masked )
+        # Sanity checks
+        assert count_overlap( bits1, bits_mask ) == 0
+        # For each data set
+        for featnum, intervals2_fname in enumerate( intervals2_fnames ):
+            print >>sys.stderr, intervals2_fname
+            intervals2 = overlapping_in_bed( intervals2_fname, r_chr, r_start, r_stop )
+            bits2 = as_bits( r_start, r_length, intervals2 )
+            bits2.iand( bits_not_masked )
+            assert count_overlap( bits2, bits_mask ) == 0
+            # Observed values
+            actual_overlap = count_overlap( bits1, bits2 )
+            total_actual[featnum] += actual_overlap
+            # Sample 
+            lengths2 = list( interval_lengths( bits2 ) )
+            total_lengths2[ featnum ] += sum( lengths2 )
+            for i in range( nsamples ):
+                # Build randomly covered bitmask for second set
+                random2 = throw_random( lengths2, bits_mask )
+                # Find intersection
+                random2 &= bits1
+                # Print amount intersecting
+                total_samples[ i, featnum ] += random2.count_range( 0, random2.size )
+                print >>sys.stderr, total_samples[ i, featnum ]
+    fraction_overlap = total_samples / total_lengths2
+    print "\t".join( intervals2_fnames )
+    print "\t".join( map( str, total_actual/total_lengths2 ) )
+    for row in fraction_overlap:
+        print "\t".join( map( str, row ) )
+    #print "total covered by first: %d, second: %d, overlap: %d" % ( total_lengths1, total_lengths2, total_actual )
+    print "observed overlap: %d, sample mean: %d, sample stdev: %d" % ( total_actual, stats.amean( total_samples ), stats.asamplestdev( total_samples ) )
+    print "z-score:", ( total_actual - stats.amean( total_samples ) ) / stats.asamplestdev( total_samples )
+    print "percentile:", sum( total_actual > total_samples ) / nsamples
+    
+if __name__ == "__main__": 
+    main()
diff --git a/scripts/bed_subtract_basewise.py b/scripts/bed_subtract_basewise.py
new file mode 100755
index 0000000..e6f2315
--- /dev/null
+++ b/scripts/bed_subtract_basewise.py
@@ -0,0 +1,43 @@
+#!/usr/bin/env python
+
+"""
+Find continuous regions that are covered by the first bed file (`bed_file_1`)
+but not by the second bed file (`bed_file_2`)
+
+usage: %prog bed_file_1 bed_file_2
+"""
+
+import sys
+from warnings import warn
+from bx.bitset_builders import binned_bitsets_from_file
+from bx.cookbook import doc_optparse
+
+def print_bits_as_bed( bits ):
+    end = 0
+    while 1:
+        start = bits.next_set( end )
+        if start == bits.size: break
+        end = bits.next_clear( start )
+        print "%s\t%d\t%d" % ( chrom, start, end )
+
+options, args = doc_optparse.parse( __doc__ )
+try:
+    in_fname, in2_fname = args
+except:
+    doc_optparse.exit()
+
+# Read first bed into some bitsets
+
+bitsets1 = binned_bitsets_from_file( open( in_fname ) )
+bitsets2 = binned_bitsets_from_file( open( in2_fname ) )
+
+for chrom in bitsets1:  
+    if chrom not in bitsets1:
+        continue
+    bits1 = bitsets1[chrom]
+    if chrom in bitsets2:
+        bits2 = bitsets2[chrom]
+        bits2.invert()
+        bits1.iand( bits2 )
+    print_bits_as_bed( bits1 )
+    
diff --git a/scripts/bnMapper.py b/scripts/bnMapper.py
new file mode 100755
index 0000000..54884c1
--- /dev/null
+++ b/scripts/bnMapper.py
@@ -0,0 +1,262 @@
+#!/usr/bin/env python -O
+
+"""Map features from the target species to the query species of a chain alignment file.
+This is intended for mapping relatively short features such as Chip-Seq
+peaks on TF binding events. Features that when mapped
+span multiple chains or multiple chromosomes are silently filtered out. TODO:
+(1)for narrowPeak input, map the predicted peak position.
+"""
+
+from __future__ import with_statement
+
+import sys, os, logging, pdb
+import numpy as np
+from operator import concat, attrgetter, itemgetter
+from itertools import groupby
+from bx.intervals.intersection import IntervalTree, Interval
+from bx.cookbook import argparse
+from bx.align import epo
+from bx.align.epo import bed_union as elem_u
+
+
+elem_t = np.dtype([('chrom', np.str_, 30), ('start', np.int64), ('end', np.int64), ('id', np.str_, 100)])
+LOG_LEVELS = {"info" : logging.INFO, "debug" : logging.DEBUG, "silent" : logging.ERROR}
+
+logging.basicConfig()
+log = logging.getLogger()
+
+class GIntervalTree( IntervalTree ):
+    """a set of IntervalTrees that is indexed by chromosomes"""
+
+    def __init__(self, data=[]):
+        self._trees = {}
+
+    def add(self, chrom, element):
+        """insert an element. use this method as the IntervalTree one.
+        this will simply call the IntervalTree.add method on the right tree
+
+        :param chrom: chromosome
+        :param element: the argument of IntervalTree.insert_interval
+        :return: None
+        """
+
+        self._trees.setdefault(chrom, IntervalTree()).insert_interval( element )
+
+    def find(self, chrom, start, end):
+        """find the intersecting elements
+
+        :param chrom: chromosome
+        :param start: start
+        :param end: end
+        :return: a list of intersecting elements"""
+
+        tree = self._trees.get( chrom, None )
+        if tree:
+            return tree.find( start, end )
+        #return always a list
+        return []
+
+def transform(elem, (chain, CT, CQ), max_gap):
+    """transform the coordinates of this elem into the other species.
+
+    elem intersects this chain's ginterval.
+    :return: a list of the type [(to_chr, start, end, elem[id]) ... ]"""
+
+    start, end = max(elem['start'], chain.tStart) - chain.tStart, min(elem['end'], chain.tEnd) - chain.tStart
+
+    assert np.all( (CT[:,1] - CT[:,0]) == (CQ[:,1] - CQ[:,0]) )
+    to_chrom = chain.qName
+    to_gab_start = chain.qStart
+
+    start_idx = np.where( CT[:,1] > start )[0][0]
+    end_idx = np.where( CT[:,0] < end )[0][-1]
+
+    if start_idx > end_idx: #maps to a gap region on the other species
+        return []
+
+    ## apply the gap threshold
+    if max_gap >= 0 and start_idx < end_idx - 1:
+        if np.max(CT[(start_idx+1):end_idx,0] - CT[start_idx:(end_idx-1),1]) > max_gap or np.max(CQ[(start_idx+1):end_idx,0] - CQ[start_idx:(end_idx-1),1]) > max_gap:
+            return []
+
+    assert start < CT[start_idx, 1]
+    assert  CT[end_idx, 0] < end
+    to_start = CQ[start_idx, 0] + max(0, start - CT[start_idx,0]) # correct if on middle of interval
+    to_end = CQ[end_idx, 1] - max(0, CT[end_idx, 1] - end)        # idem
+
+    if start_idx == end_idx: #elem falls in a single run of matches
+        slices = [(to_start, to_end)]
+    else:
+        slices = [(to_start, CQ[start_idx,1])]
+        slices += map(lambda i: (CQ[i,0], CQ[i,1]), range(start_idx+1, end_idx))
+        slices.append( (CQ[end_idx,0], to_end) )
+    if chain.qStrand == '-':
+        Sz = chain.qEnd - chain.qStart
+        slices =  map(lambda t: (Sz-t[1], Sz-t[0]), slices)
+    return map(lambda t: (to_chrom, to_gab_start + t[0], to_gab_start + t[1], elem['id']), slices)
+
+def union_elements(elements):
+    """elements = [(chr, s, e, id), ...], this is to join elements that have a
+    deletion in the 'to' species
+    """
+
+    if len(elements) < 2: return elements
+    assert set( map(lambda e: e[3], elements) ) == set( [elements[0][3]] ), "more than one id"
+    el_id = elements[0][3]
+
+    unioned_elements = []
+    for ch, chgrp in groupby(elements, key=itemgetter(0)):
+        for (s,e) in elem_u( np.array(map(itemgetter(1,2), chgrp), dtype=np.uint) ):
+            if (s < e):
+                unioned_elements.append( (ch, s, e, el_id) )
+    assert len(unioned_elements) <= len(elements)
+    return unioned_elements
+
+def transform_by_chrom(all_epo, from_elem_list, tree, chrom, opt, out_fd):
+    BED4_FRM = "%s\t%d\t%d\t%s\n"
+    BED12_FRM = "%s\t%d\t%d\t%s\t1000\t+\t%d\t%d\t0,0,0\t%d\t%s\t%s\n"
+    assert len( set(from_elem_list['chrom']) ) <= 1
+
+    mapped_elem_count = 0
+    for from_elem in from_elem_list:
+        matching_block_ids = map(attrgetter("value"), tree.find(chrom, from_elem['start'], from_elem['end']))
+
+        # do the actual mapping
+        to_elem_slices = filter(bool, map(lambda i: transform(from_elem, all_epo[i], opt.gap), matching_block_ids))
+        if len(to_elem_slices) > 1 or len(to_elem_slices) == 0:
+            log.debug("%s no match or in different chain/chromosomes" % (str(from_elem)))
+            continue
+        to_elem_slices = to_elem_slices[0]
+
+        # apply threshold
+        if (from_elem[2] - from_elem[1]) * opt.threshold > reduce(lambda b,a: a[2]-a[1] + b, to_elem_slices, 0):
+            log.debug("%s did not pass threshold" % (str(from_elem)))
+            continue
+
+        # if to_species had insertions you can join elements
+        to_elem_list = sorted(union_elements(to_elem_slices), key=lambda a: a[1])
+        if to_elem_list:
+            mapped_elem_count += 1
+            log.debug("\tjoined to %d elements" % (len(to_elem_list)))
+            if opt.format == "BED4":
+                map(lambda tel: out_fd.write(BED4_FRM % tel), to_elem_list)
+            else:
+                start = to_elem_list[0][1]
+                end = to_elem_list[-1][2]
+                out_fd.write(BED12_FRM % (to_elem_list[0][0], start, end, from_elem['id'],
+                        start, end, len(to_elem_list),
+                        ",".join( map(lambda e: "%d" % (e[2]-e[1]), to_elem_list) ),
+                        ",".join( map(lambda e: "%d" % (e[1]-start), to_elem_list) ) )
+                        )
+    log.info("%s %d of %d elements mapped" % (chrom, mapped_elem_count, from_elem_list.shape[0]))
+
+def transform_file(ELEMS, ofname, EPO, TREE, opt):
+    "transform/map the elements of this file and dump the output on 'ofname'"
+
+    BED4_FRM = "%s\t%d\t%d\t%s\n"
+    log.info("%s (%d) elements ..." % (opt.screen and "screening" or "transforming", ELEMS.shape[0]))
+    with open(ofname, 'w') as out_fd:
+        if opt.screen:
+            for elem in ELEMS.flat:
+                matching_blocks = map(attrgetter("value"),
+                        TREE.find(elem['chrom'], elem['start'], elem['end']))
+                assert set( matching_blocks ) <= set( EPO.keys() )
+                if matching_blocks:
+                    out_fd.write(BED4_FRM % elem)
+        else:
+            for chrom in set( ELEMS['chrom'] ):
+                transform_by_chrom(EPO,
+                        ELEMS[ELEMS['chrom'] == chrom],
+                        TREE, chrom, opt, out_fd)
+    log.info("DONE!")
+
+def loadChains(path):
+    "name says it."
+
+    EPO = epo.Chain._parse_file(path, True)
+    ## convert coordinates w.r.t the forward strand (into slices)
+    ## compute cummulative intervals
+    for i in range( len(EPO) ):
+        ch, S, T, Q = EPO[i]
+        if ch.tStrand == '-':
+            ch = ch._replace(tEnd = ch.tSize - ch.tStart,
+                    tStart = ch.tSize - ch.tEnd)
+        if ch.qStrand == '-':
+            ch = ch._replace(qEnd = ch.qSize - ch.qStart,
+                    qStart = ch.qSize - ch.qEnd)
+        EPO[i] = (ch,
+                epo.cummulative_intervals(S, T),
+                epo.cummulative_intervals(S, Q)
+                )
+    ##now each element of epo is (chain_header, target_intervals, query_intervals)
+    assert all( map(lambda t: t[0].tStrand == '+', EPO) ), "all target strands should be +"
+    return EPO
+
+def loadFeatures(path):
+    "load BED4 features (all other columns are ignored)"
+
+    log.info("loading from %s ..." % path)
+    data = []
+    with open(path) as fd:
+        for line in fd:
+            cols = line.split()
+            data.append( (cols[0], int(cols[1]), int(cols[2]), cols[3]) )
+    return np.array(data, dtype=elem_t)
+
+if __name__ == "__main__":
+    parser = argparse.ArgumentParser(description=__doc__, epilog="Olgert Denas (Taylor Lab)",
+            formatter_class=argparse.ArgumentDefaultsHelpFormatter)
+
+    parser.add_argument("input", nargs='+',
+            help="Input to process. If more than a file is specified, all files will be mapped and placed on --output, which should be a directory.")
+    parser.add_argument("alignment", help="Alignment file (.chain or .pkl)")
+
+    parser.add_argument("-f", '--format', choices=("BED4", "BED12"), default="BED4",
+            help="Output format.")
+    parser.add_argument("-o", '--output', metavar="FILE", default='stdout',
+            type=lambda s: ((s in ('stdout', '-') and "/dev/stdout") or s),
+            help="Output file. Mandatory if more than on file in input.")
+    parser.add_argument("-t", '--threshold', metavar="FLOAT", default=0., type=float,
+            help="Mapping threshold i.e., |elem| * threshold <= |mapped_elem|")
+    parser.add_argument("-s", '--screen', default=False, action='store_true',
+            help="Only report elements in the alignment (without mapping). -t has not effect here (TODO)")
+    parser.add_argument('-g', '--gap', type=int, default=-1,
+            help="Ignore elements with an insertion/deletion of this or bigger size.")
+    parser.add_argument('-v', '--verbose', type=str, choices=LOG_LEVELS.keys(), default='info',
+            help='Verbosity level')
+
+
+    opt = parser.parse_args()
+    log.setLevel(LOG_LEVELS[opt.verbose])
+
+    #check for output if input is a directory arguments
+    if len(opt.input) > 1 and (not os.path.isdir(opt.output)):
+        parser.error("For multiple inputs, output is mandatory and should be a dir.")
+
+
+    #loading alignments from opt.alignment
+    EPO = dict( map(lambda ch: (ch[0].id, ch), loadChains(opt.alignment)) )
+
+    ## create an interval tree based on chain headers (from_species side)
+    ## for fast feature-to-chain_header searching
+    log.info("indexing %d chains ..." % (len(EPO),))
+    TREE = GIntervalTree()
+    for gabid in EPO:
+        chain, t, q = EPO[gabid]
+        TREE.add(chain.tName, Interval(chain.tStart, chain.tEnd, chain.id))
+
+    # transform elements
+    if len(opt.input) > 1:
+        for inpath in opt.input:
+            if not os.path.isfile(inpath):
+                log.warning("skipping %s (not a file) ..." % inpath)
+                continue
+            outpath = os.path.join(opt.output, os.path.basename(inpath))
+            if os.path.isfile(outpath):
+                log.warning("overwriting %s ..." % outpath)
+            transform_file(loadFeatures(inpath), outpath, EPO, TREE, opt)
+    else:
+        transform_file(loadFeatures( opt.input[0] ), opt.output, EPO, TREE, opt)
+
+
+
diff --git a/scripts/div_snp_table_chr.py b/scripts/div_snp_table_chr.py
new file mode 100755
index 0000000..c886877
--- /dev/null
+++ b/scripts/div_snp_table_chr.py
@@ -0,0 +1,146 @@
+#!/usr/bin/env python2.4
+
+"""
+FIXME!
+
+usage: %prog feature.bed ar.bed snp.bed div_directory [options]
+    -m, --mask=M: Mask AR and features with this file
+    -s, --suffix=S: append suffix to chromosomes to get filenames from div_directory
+    -l, --lens=l: Set chromosome ends using LEN file
+"""
+
+import sys
+import bx.bitset
+from bx.bitset_builders import *
+from bx.cookbook import doc_optparse
+
+def main():
+
+    options, args = doc_optparse.parse( __doc__ )
+    try:
+        lens = {}
+        if options.lens:
+            for line in open( options.lens ):
+                chrom, length = line.split()
+                lens[chrom] = int( length )
+
+        if options.suffix: suffix = options.suffix
+        else: suffix = ""
+
+        print >>sys.stderr, "\nReading feature",
+        interval_file = open(args[0])
+        feature = binned_bitsets_from_file(interval_file, lens=lens)
+        interval_file.close()
+        # reuse interval file 
+        intervals = {}
+        interval_file = open(args[0])
+        for line in interval_file:
+            fields = line.split()
+            chrom, start, end = fields[0], int(fields[1]), int(fields[2])
+            if chrom not in intervals: intervals[chrom] = []
+            intervals[chrom].append( [start,end] )
+        interval_file.close()
+
+        print >>sys.stderr, "\nReading ar",
+        ar = binned_bitsets_from_file(open( args[1] ), lens=lens)
+
+        print >>sys.stderr, "\nReading snps",
+        snp = binned_bitsets_from_file(open( args[2] ), lens=lens)
+        snp_mask = clone_inverted( snp )
+        snp_copy = clone( snp )
+
+        print >>sys.stderr, "\nMasking AR",
+        ar_mask = clone_inverted( ar )
+        print >>sys.stderr
+
+        dirname = args[3]
+
+
+        if options.mask: mask = binned_bitsets_from_file(open(options.mask), lens=lens)
+        else: mask = None
+    except:
+        doc_optparse.exit()
+    
+    if mask:
+        for chrom in mask.keys():
+            if chrom in feature: feature[chrom].iand( mask[chrom] )
+            if chrom in ar: ar[chrom].iand( mask[chrom] )
+
+
+    # divergence and snp counts for all features
+    feature_div_count = 0
+    feature_snp_count = 0
+    ar_div_count = 0
+    ar_snp_count = 0
+
+    # collect snp and div
+    for chr in feature.keys():
+
+        if chr not in snp: continue
+        if chr not in ar: continue
+
+        print >>sys.stderr, "reading %s ..." % chr,
+        try:
+            div = binned_bitsets_from_file( open( dirname + "/%s.bed" % (chr+suffix) ), lens=lens)
+        except:
+            print >>sys.stderr,"%s.bed not found" % chr
+            continue
+
+        div[chr].iand( snp_mask[chr] ) # div/snp sites count snp-only
+        div_copy = clone( div )
+
+        print >>sys.stderr, "AR:", chr,
+        snp[chr].iand( ar[chr] )
+        div[chr].iand( ar[chr] )
+        snp_count = snp[chr].count_range(0,snp[chr].size)
+        ar_snp_count += snp_count
+        print >>sys.stderr, snp_count,
+        try:
+            div_count = div[chr].count_range(0,div[chr].size)
+            ar_div_count += div_count
+            print >>sys.stderr, div_count
+        except:
+            print >>sys.stderr, chr, "failed"
+    
+        div = div_copy
+        snp[chr] = snp_copy[chr]
+        print >>sys.stderr, "feature:", chr,
+        feature[chr].iand( ar_mask[chr] ) # clip to non-AR only
+        snp[chr].iand( feature[chr] )
+        div[chr].iand( feature[chr] )
+        feature_snp_count += snp[chr].count_range(0,snp[chr].size)
+        print >>sys.stderr, snp[chr].count_range(0,snp[chr].size), div[chr].count_range(0,div[chr].size)
+        feature_div_count += div[chr].count_range(0,div[chr].size)
+        print >>sys.stderr, snp[chr].count_range(0,snp[chr].size), div[chr].count_range(0,div[chr].size)
+
+        # Note: can loop over feature intervals here for individual counts
+        if chr in intervals:
+            for start,end in intervals[chr]:
+                ind_div_count = div[chr].count_range(start,end-start)
+                ind_snp_count = snp[chr].count_range(start,end-start)
+                print chr, start, end, ind_div_count, ind_snp_count
+    
+    print "feature snp\t%d" %feature_snp_count
+    print "feature div\t%d" %feature_div_count
+    print "ar snp\t%d" %ar_snp_count
+    print "ar div\t%d" %ar_div_count
+
+# copies a dictionary of bitsets
+def copybits( binnedbits ):
+    bitset = BinnedBitSet( binnedbits.size )
+    bitset.ior( binnedbits )
+    return bitset
+
+def clone( bitsets ):
+    r = {}
+    for k,b in bitsets.items(): r[ k ] = copybits( b )
+    return r
+
+def clone_inverted( bitsets ):
+    r = {}
+    for k,b in bitsets.items(): 
+        r[ k ] = copybits( b )
+        r[ k ].invert()
+    return r
+
+main()
diff --git a/scripts/find_in_sorted_file.py b/scripts/find_in_sorted_file.py
new file mode 100755
index 0000000..6f8997b
--- /dev/null
+++ b/scripts/find_in_sorted_file.py
@@ -0,0 +1,77 @@
+#!/usr/bin/env python
+
+"""
+Extract ranges of scores from a sorted file in which each line contains a
+position followed by a score. 
+
+TODO: The finder class might actually be useful, it strides through a file
+      and builds an index based on the first line. Maybe move it into the
+      library and get rid of this very specific script?
+      
+usage: %prog start_pos stop_pos
+"""
+
+import sys
+
+max_cats = 1000
+
+class Finder:
+    def __init__( self, file, segments ):
+        self.file = file
+        self.segments = segments
+        self.make_index()
+    def make_index( self ):
+        self.values = []
+        self.positions = []
+        
+        file.seek( 0, 2 )
+        end = file.tell()
+
+        step = end / ( self.segments - 1 )
+
+        for i in range( 0, self.segments - 1 ):
+            file.seek( i * step, 0 )
+            file.readline()
+            position = file.tell()
+            fields = file.readline().split()
+            self.values.append( int( fields[ 0 ] ) )
+            self.positions.append( position )
+
+    def scores_in_range( self, start, end ):
+        position = self.positions[ -1 ]
+        for i in range( 1, len( self.values ) ):
+            if self.values[ i ] > start:
+                position = self.positions[ i - 1 ]
+                break
+        self.file.seek( position, 0 )
+        result = []
+        while 1:
+            line = file.readline()
+            if line == "": break
+            fields = line.split()
+
+            pos = int( fields[ 0 ] )
+
+            if pos < start: continue
+            if pos > end: break
+
+            result.append( ( pos, fields[1] ) )
+
+        return result
+
+file = open( sys.argv[ 1 ] )
+
+finder = Finder( file, 100 )
+
+scores = finder.scores_in_range( int( sys.argv[2] ), int( sys.argv[3] ) )
+
+rng = scores[-1][0] - scores[0][0]
+
+if rng > max_cats:
+    stride = rng // max_cats
+else:
+    stride = 1
+
+for score in scores:
+    if score[0] % stride == 0:
+        print score[0], score[1]
diff --git a/scripts/gene_fourfold_sites.py b/scripts/gene_fourfold_sites.py
new file mode 100755
index 0000000..88c40bb
--- /dev/null
+++ b/scripts/gene_fourfold_sites.py
@@ -0,0 +1,236 @@
+#!/usr/bin/python
+
+"""
+Returns a bed-like translation of a CDS in which each record corresponds to
+a single site in the CDS and includes additional fields for site degenaracy, 
+position ind CDS, and amino acid encoded.
+
+usage: %prog nibdir genefile [options]
+    -o, --outfile=o:      output file
+    -f, --format=f:       format bed (default), or gtf|gff
+    -a, --allpositions: 1st, 2nd and 3rd positions are evaluated for degeneracy given the sequence at the other two positions.  Many 1d sites in 1st codon positions become 2d sites when considered this way.
+    -n, --include_name: include the 'name' or 'id' field from the source file on every line of output
+"""
+
+import re
+import sys
+import os
+import string
+from bx.seq import nib
+from bx.bitset import *
+from bx.bitset_builders import *
+from bx.bitset_utils import *
+from bx.gene_reader import *
+from bx.cookbook import doc_optparse
+
+GENETIC_CODE = """
+TTT (Phe/F)Phenylalanine
+TTC (Phe/F)Phenylalanine
+TTA (Leu/L)Leucine
+TTG (Leu/L)Leucine, Start
+TCT (Ser/S)Serine
+TCC (Ser/S)Serine
+TCA (Ser/S)Serine
+TCG (Ser/S)Serine
+TAT (Tyr/Y)Tyrosine
+TAC (Tyr/Y)Tyrosine
+TAA Ochre (Stop)
+TAG Amber (Stop)
+TGT (Cys/C)Cysteine
+TGC (Cys/C)Cysteine
+TGA Opal (Stop)
+TGG (Trp/W)Tryptophan
+CTT (Leu/L)Leucine
+CTC (Leu/L)Leucine
+CTA (Leu/L)Leucine
+CTG (Leu/L)Leucine, Start
+CCT (Pro/P)Proline
+CCC (Pro/P)Proline
+CCA (Pro/P)Proline
+CCG (Pro/P)Proline
+CAT (His/H)Histidine
+CAC (His/H)Histidine
+CAA (Gln/Q)Glutamine
+CAG (Gln/Q)Glutamine
+CGT (Arg/R)Arginine
+CGC (Arg/R)Arginine
+CGA (Arg/R)Arginine
+CGG (Arg/R)Arginine
+ATT (Ile/I)Isoleucine, Start2
+ATC (Ile/I)Isoleucine
+ATA (Ile/I)Isoleucine
+ATG (Met/M)Methionine, Start1
+ACT (Thr/T)Threonine
+ACC (Thr/T)Threonine
+ACA (Thr/T)Threonine
+ACG (Thr/T)Threonine
+AAT (Asn/N)Asparagine
+AAC (Asn/N)Asparagine
+AAA (Lys/K)Lysine
+AAG (Lys/K)Lysine
+AGT (Ser/S)Serine
+AGC (Ser/S)Serine
+AGA (Arg/R)Arginine
+AGG (Arg/R)Arginine
+GTT (Val/V)Valine
+GTC (Val/V)Valine
+GTA (Val/V)Valine
+GTG (Val/V)Valine, Start2
+GCT (Ala/A)Alanine
+GCC (Ala/A)Alanine
+GCA (Ala/A)Alanine
+GCG (Ala/A)Alanine
+GAT (Asp/D)Aspartic acid
+GAC (Asp/D)Aspartic acid
+GAA (Glu/E)Glutamic acid
+GAG (Glu/E)Glutamic acid
+GGT (Gly/G)Glycine
+GGC (Gly/G)Glycine
+GGA (Gly/G)Glycine
+GGG (Gly/G)Glycine
+"""
+
+def translate( codon, genetic_code):
+    c1,c2,c3 = codon
+    return genetic_code[c1][c2][c3]
+
+""" parse the doc string to hash the genetic code"""
+GEN_CODE = {}
+for line in GENETIC_CODE.split('\n'):
+    if line.strip() == '': continue
+    f = re.split('\s|\(|\)|\/',line)
+    codon = f[0]
+    c1,c2,c3 = codon
+    aminoacid = f[3]
+    if c1 not in GEN_CODE: GEN_CODE[c1] = {}
+    if c2 not in GEN_CODE[c1]: GEN_CODE[c1][c2] = {}
+
+    GEN_CODE[c1][c2][c3] = aminoacid
+
+def getnib( nibdir ):
+    seqs = {}
+    for nibf in os.listdir( nibdir ):
+        if not nibf.endswith('.nib'): continue
+        chr = nibf.replace('.nib','')
+        file = os.path.join( nibdir, nibf )
+        seqs[chr] = nib.NibFile( open(file) )
+
+    return seqs
+
+REVMAP = string.maketrans("ACGTacgt","TGCAtgca")
+def revComp(seq):
+    return seq[::-1].translate(REVMAP)
+
+def Comp(seq):
+    return seq.translate(REVMAP)
+
+def codon_degeneracy( codon, position=3 ):
+    aa = translate( codon, GEN_CODE )
+    if position==1:
+        degeneracy1 = [GEN_CODE[ k ][ codon[1] ][ codon[2] ] for k in all].count(aa) 
+    elif position==2:
+        degeneracy2 = [GEN_CODE[ codon[0] ][ k ][ codon[2] ] for k in all].count(aa)
+    elif position==3:
+        degeneracy = GEN_CODE[ codon[0] ][ codon[1] ].values().count(aa)
+    return degeneracy
+
+def main():
+
+    options, args = doc_optparse.parse( __doc__ )
+    try:
+        if options.outfile: 
+            out = open( options.outfile, "w")
+        else:
+            out = sys.stdout
+        if options.format:
+            format = options.format
+        else:
+            format = 'bed'
+
+        allpositions = bool( options.allpositions )
+        include_name = bool( options.include_name )
+        nibdir = args[0]
+        bedfile = args[1]
+    except:
+        doc_optparse.exit()
+
+    nibs = getnib(nibdir)
+
+    for chrom, strand, cds_exons, name in CDSReader( open(bedfile), format=format):
+
+        cds_seq = ''
+
+        # genome_seq_index maps the position in CDS to position on the genome
+        genome_seq_index = []
+        for (c_start, c_end) in cds_exons:
+            cds_seq += nibs[chrom].get( c_start, c_end-c_start )
+            for i in range(c_start,c_end):
+                genome_seq_index.append(i)
+
+        cds_seq = cds_seq.upper()
+
+        if strand == '+': 
+            frsts = range( 0, len(cds_seq), 3)
+            offsign = 1
+        else: 
+            cds_seq = Comp( cds_seq )
+            frsts = range( 2, len(cds_seq), 3)
+            offsign = -1
+
+        offone = 1 * offsign
+        offtwo = 2 * offsign
+
+        all = ['A','C','G','T']
+
+        for first_pos in frsts:
+            c1 = first_pos
+            c2 = first_pos + offone
+            c3 = first_pos + offtwo
+            try:
+                assert c3 < len(cds_seq)
+            except AssertionError:
+                print >>sys.stderr, "out of sequence at %d for %s, %d" % (c3, chrom, genome_seq_index[ first_pos ])
+                continue
+            codon = cds_seq[c1], cds_seq[c2], cds_seq[c3]
+            aa = translate( codon, GEN_CODE )
+            degeneracy3 = str(GEN_CODE[ codon[0] ][ codon[1] ].values().count(aa)) + "d"
+
+            if not include_name: name_text = ''
+            else: 
+                name_text = name.replace(' ','_')
+
+            if allpositions:
+                try:
+                    degeneracy1 = str([GEN_CODE[ k ][ codon[1] ][ codon[2] ] for k in all].count(aa)) + "d"
+                    degeneracy2 = str([GEN_CODE[ codon[0] ][ k ][ codon[2] ] for k in all].count(aa)) + "d"
+                except TypeError, s:
+                    print >>sys.stderr, GEN_CODE.values()
+                    raise TypeError, s
+
+                if strand == '+':
+                    print >>out, chrom, genome_seq_index[c1], genome_seq_index[c1] + 1, cds_seq[c1], degeneracy1, aa, name_text
+                    print >>out, chrom, genome_seq_index[c2], genome_seq_index[c2] + 1, cds_seq[c2], degeneracy2, aa, name_text
+                    print >>out, chrom, genome_seq_index[c3], genome_seq_index[c3] + 1, cds_seq[c3], degeneracy3, aa, name_text
+                else:
+                    print >>out, chrom, genome_seq_index[c3], genome_seq_index[c3] + 1, cds_seq[c3], degeneracy3, aa, name_text
+                    print >>out, chrom, genome_seq_index[c2], genome_seq_index[c2] + 1, cds_seq[c2], degeneracy2, aa, name_text
+                    print >>out, chrom, genome_seq_index[c1], genome_seq_index[c1] + 1, cds_seq[c1], degeneracy1, aa, name_text
+            else:
+                if strand == '+':
+                    for b in c1,c2:
+                        print >>out, chrom, genome_seq_index[b], genome_seq_index[b] + 1, cds_seq[b], "1d", aa, name_text
+                    print >>out, chrom, genome_seq_index[c3], genome_seq_index[c3] + 1, cds_seq[c3], degeneracy3, aa, name_text
+                else:
+                    print >>out, chrom, genome_seq_index[c3], genome_seq_index[c3] + 1, cds_seq[c3], degeneracy3, aa, name_text
+                    for b in c2,c1:
+                        print >>out, chrom, genome_seq_index[b], genome_seq_index[b] + 1, cds_seq[b], "1d", aa, name_text
+    out.close()
+
+if __name__ == '__main__': 
+    main()
+    #format = sys.argv[1]
+    #file = sys.argv[2]
+    #for chr, strand, cds_exons in CDSReader( open(file), format=format):
+    #    s_points = [ "%d,%d" % (a[0],a[1]) for a in cds_exons ]
+    #    print chr, strand, len(cds_exons), "\t".join(s_points)
+
diff --git a/scripts/get_scores_in_intervals.py b/scripts/get_scores_in_intervals.py
new file mode 100755
index 0000000..7fa33f5
--- /dev/null
+++ b/scripts/get_scores_in_intervals.py
@@ -0,0 +1,59 @@
+#!/usr/bin/env python
+
+"""
+Read scores in "wiggle" format from `score_file` and intervals in "bed" format
+from `interval_file` and print all scores overlapping intervals.
+
+TODO: Support binned array format scores also.
+
+usage: %prog score_file interval_file [out_file] 
+"""
+
+from __future__ import division
+
+import sys
+import psyco_full
+import bx.wiggle
+from bx.binned_array import BinnedArray
+from fpconst import isNaN
+from bx.cookbook import doc_optparse
+from bx import misc
+
+def read_scores( f ):
+    scores_by_chrom = dict()
+    for chrom, pos, val in bx.wiggle.Reader( f ):
+        if chrom not in scores_by_chrom:
+            scores_by_chrom[chrom] = BinnedArray()
+        scores_by_chrom[chrom][pos] = val
+    return scores_by_chrom
+
+def main():
+
+    # Parse command line
+    options, args = doc_optparse.parse( __doc__ )
+    try:
+        score_file = open( args[0] )
+        interval_file = open( args[1] )
+        if len( args ) > 2:
+            out_file = open( args[2], 'w' )
+        else:
+            out_file = sys.stdout
+    except:
+        doc_optparse.exit()
+
+    scores_by_chrom = read_scores( misc.open_compressed( sys.argv[1] ) )
+    for line in open( sys.argv[2] ):
+        fields = line.split()
+        chrom, start, stop = fields[0], int( fields[1] ), int( fields[2] )
+        if chrom in scores_by_chrom:
+            ba = scores_by_chrom[chrom]
+            scores = [ ba[i] for i in range( start, stop ) ]
+        else:
+            scores = []
+        print >> out_file, " ".join( fields ), " ".join( map( str, scores ) )
+
+    score_file.close()
+    interval_file.close()
+    out_file.close()
+
+if __name__ == "__main__": main()
diff --git a/scripts/int_seqs_to_char_strings.py b/scripts/int_seqs_to_char_strings.py
new file mode 100755
index 0000000..9087800
--- /dev/null
+++ b/scripts/int_seqs_to_char_strings.py
@@ -0,0 +1,24 @@
+#!/usr/bin/env python
+
+"""
+Translate lists of space separated integers (magnitude less than 62) and print 
+as strings of alphanumeric characters. This is useful mainly for some machine
+learning algorithms that only take string input.
+
+usage: %prog < int_seqs > strings
+"""
+
+from itertools import *
+
+import sys
+
+table = "012345678ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
+
+def main():
+    for line in sys.stdin:
+        ints = [ int( f ) for f in line.split() ]
+        if max( ints ) > len( table ):
+            raise ValueError("Alphabet size too large!")
+        print str.join( '', [ table[i] for i in ints ] )
+
+if __name__ == "__main__": main()
diff --git a/scripts/interval_count_intersections.py b/scripts/interval_count_intersections.py
new file mode 100755
index 0000000..1b1c8e8
--- /dev/null
+++ b/scripts/interval_count_intersections.py
@@ -0,0 +1,50 @@
+#!/usr/bin/env python
+
+"""
+Read two lists of intervals (with chromosomes) and count the number of entries
+in the second set that intersect any entry in the first set.
+
+TODO: This could use bitsets rather than the intervals package, would it be
+      faster?
+
+usage: %prog bed1 bed2 > out
+"""
+
+from __future__ import division
+
+import psyco_full
+
+from bx import intervals
+from bx import misc
+import string
+import sys
+
+def main():
+
+    intersecters = {}
+
+    # Read ranges
+
+    for chr, start, end in read_intervals( misc.open_compressed( sys.argv[1] ) ):
+        if not intersecters.has_key( chr ): intersecters[ chr ] = intervals.Intersecter()
+        intersecters[ chr ].add_interval( intervals.Interval( start, end ) )
+
+    # Count intersection
+
+    total = 0
+
+    for chr, start, end in read_intervals( misc.open_compressed( sys.argv[2] ) ):
+        if intersecters.has_key( chr ):
+            intersection = intersecters[ chr ].find( start, end )
+            if intersection: 
+                #print chr, intersection
+                total += 1
+
+    print total
+
+def read_intervals( input ):
+    for line in input:
+        fields = line.split()
+        yield fields[0], int( fields[1] ), int( fields[2] )
+
+main()
diff --git a/scripts/interval_join.py b/scripts/interval_join.py
new file mode 100755
index 0000000..6e31293
--- /dev/null
+++ b/scripts/interval_join.py
@@ -0,0 +1,39 @@
+#!/usr/bin/env python2.4
+
+"""
+Match up intersecting intervals from two files. This performs a "full join", 
+any pair of intervals with any basewise overlap will be printed side-by-side.
+
+usage: %prog bed1 bed2
+"""
+
+from __future__ import division
+
+import psyco_full
+
+import string
+import sys
+
+import bx.intervals.io
+import bx.intervals.intersection
+
+def main():
+
+    intersecters = {}
+
+    # Read second set into intersecter
+    for interval in bx.intervals.io.GenomicIntervalReader( open( sys.argv[2] ) ):
+        if not intersecters.has_key( interval.chrom ): 
+            intersecters[ interval.chrom ] = bx.intervals.Intersecter()
+        intersecters[ interval.chrom ].add_interval( interval )
+
+    # Join with first set    
+    for interval in bx.intervals.io.GenomicIntervalReader( open( sys.argv[1] ) ):
+        if intersecters.has_key( interval.chrom ):
+            intersection = intersecters[ interval.chrom ].find( interval.start, interval.end )
+            for interval2 in intersection:
+                print "\t".join( [ str( interval ), str( interval2 ) ] )
+
+
+if __name__ == "__main__":
+    main()
\ No newline at end of file
diff --git a/scripts/lav_to_axt.py b/scripts/lav_to_axt.py
new file mode 100755
index 0000000..7a434b7
--- /dev/null
+++ b/scripts/lav_to_axt.py
@@ -0,0 +1,55 @@
+#!/usr/bin/env python
+"""
+Application to convert LAV file to AXT file. Reads a LAV file from standard 
+input and writes a AXT file to standard out;  some statistics are written 
+to standard error.
+
+usage: lav_to_axt [--silent] [path=replacement] < lav_file > axt_file
+"""
+
+__author__ = "Bob Harris (rsharris at bx.psu.edu)"
+
+import sys
+import copy
+import bx.align.lav
+import bx.align.axt
+
+def usage(s=None):
+	message = __doc__
+	if (s == None): sys.exit (message)
+	else:           sys.exit ("%s\n%s" % (s,message))
+
+
+def main():
+
+	# parse the command line
+
+	silent = False
+	pathSubs = []
+
+	for arg in sys.argv[1:]:
+		if ("=" in arg):
+			ix = arg.find("=")
+			pathSubs.append((arg[:ix],arg[ix+1:]))
+		elif (arg == "--silent"):
+			silent = True
+		else:
+			usage("unrecognized argument: " + arg)
+
+	# read the alignments and other info
+
+	out = bx.align.axt.Writer(sys.stdout)
+
+	lavsRead = axtsWritten = 0
+	for lavBlock in bx.align.lav.Reader(sys.stdin,path_subs=pathSubs):
+		lavsRead += 1
+
+		out.write (lavBlock)
+		axtsWritten += 1
+
+	if (not silent):
+		sys.stderr.write ("%d blocks read, %d written\n" % (lavsRead,axtsWritten))
+
+
+if __name__ == "__main__": main()
+
diff --git a/scripts/lav_to_maf.py b/scripts/lav_to_maf.py
new file mode 100755
index 0000000..1a918df
--- /dev/null
+++ b/scripts/lav_to_maf.py
@@ -0,0 +1,53 @@
+#!/usr/bin/env python
+"""
+Application to convert LAV file to MAF file. Reads a LAV file from standard 
+input and writes a MAF file to standard out; some statistics are written to 
+standard error.
+
+usage: lav_to_maf [--silent] [path=replacement] < lav_file > maf_file
+"""
+
+import sys
+import copy
+import bx.align.lav
+import bx.align.maf
+
+def usage(s=None):
+	message = __doc__
+	if (s == None): sys.exit (message)
+	else:           sys.exit ("%s\n%s" % (s,message))
+
+
+def main():
+
+	# parse the command line
+
+	silent = False
+	pathSubs = []
+
+	for arg in sys.argv[1:]:
+		if ("=" in arg):
+			ix = arg.find("=")
+			pathSubs.append((arg[:ix],arg[ix+1:]))
+		elif (arg == "--silent"):
+			silent = True
+		else:
+			usage("unrecognized argument: " + arg)
+
+	# read the alignments and other info
+
+	out = bx.align.maf.Writer(sys.stdout)
+
+	lavsRead = mafsWritten = 0
+	for lavBlock in bx.align.lav.Reader(sys.stdin,path_subs=pathSubs):
+		lavsRead += 1
+
+		out.write (lavBlock)
+		mafsWritten += 1
+
+	if (not silent):
+		sys.stderr.write ("%d blocks read, %d written\n" % (lavsRead,mafsWritten))
+
+
+if __name__ == "__main__": main()
+
diff --git a/scripts/line_select.py b/scripts/line_select.py
new file mode 100755
index 0000000..a470a3e
--- /dev/null
+++ b/scripts/line_select.py
@@ -0,0 +1,31 @@
+#!/usr/bin/env python
+
+"""
+Read a file containing a 0 or 1 on each line (`feature_file`), output 
+all lines from stdin for which that value was 1
+
+TODO: no need to read the feature_file into memory here, just iterate in
+      parallel.
+
+usage: %prog feature_file < ...
+"""
+
+import psyco_full
+
+import sys
+
+def __main__():
+
+    feature_file = sys.argv[1]
+
+    if len( sys.argv ) > 2:
+        match = int( sys.argv[2] )
+    else:
+        match = 1
+    
+    feature_vector = [ int( line ) for line in file( feature_file ) ]
+
+    for index, line in enumerate( sys.stdin ):
+        if feature_vector[ index ] == match: print line,
+
+if __name__ == "__main__": __main__()
diff --git a/scripts/lzop_build_offset_table.py b/scripts/lzop_build_offset_table.py
new file mode 100755
index 0000000..9995bf6
--- /dev/null
+++ b/scripts/lzop_build_offset_table.py
@@ -0,0 +1,90 @@
+#!/usr/bin/env python2.4
+
+"""
+Read a compressed file as created by 'lzop' from stdin and write a table to 
+stdout containing the blocksize and the start offset (in bytes) of each 
+compressed block. 
+
+usage: %prog < FILENAME.lzo > FILENAME.lzot
+"""
+
+import struct, sys
+
+MAGIC="\x89\x4c\x5a\x4f\x00\x0d\x0a\x1a\x0a"
+
+F_ADLER32_D     = 0x00000001L
+F_ADLER32_C     = 0x00000002L
+F_H_EXTRA_FIELD = 0x00000040L
+F_H_GMTDIFF     = 0x00000080L
+F_CRC32_D       = 0x00000100L
+F_CRC32_C       = 0x00000200L
+F_MULTIPART     = 0x00000400L
+F_H_FILTER      = 0x00000800L
+F_H_CRC32       = 0x00001000L
+
+assert struct.calcsize( "!H" ) == 2
+assert struct.calcsize( "!I" ) == 4
+
+class UnpackWrapper( object ):
+    def __init__( self, file ):
+        self.file = file
+    def read( self, amt ):
+        return self.file.read( amt )
+    def get( self, fmt ):
+        t = struct.unpack( fmt, self.file.read( struct.calcsize( fmt ) ) )
+        return t[0]
+
+def main():
+    f = UnpackWrapper( sys.stdin )
+    # Read header
+    magic = f.read(9)
+    assert magic == MAGIC, "Not LZOP file"
+    version = f.get( "!H" )
+    lib_version = f.get( "!H" )
+    if version >= 0x0940:
+        extract_version = f.get( "!H" )
+    method = f.get( "!B" )
+    assert 1 <= method <= 3, "Only LZO compression is currently supported"
+    level = f.get( "!B" )
+    flags = f.get( "!I" )
+    assert not( flags & F_H_FILTER ), "LZOP filters not supported"
+    has_compressed_crc = ( flags & F_CRC32_C or flags & F_ADLER32_C )
+    has_uncompressed_crc = ( flags & F_CRC32_D or flags & F_ADLER32_D )
+    mode = f.get( "!I" )
+    time = f.get( "!I" )
+    time_offset = f.get( "!I" )
+    fname_len = f.get( "!B" )
+    fname = f.read( fname_len )
+    assert len( fname ) == fname_len, "EOF reading filename"
+    header_crc = f.get( "!I" )
+    if ( flags & F_H_EXTRA_FIELD ):
+        extra_len = f.get( "!I" )
+        extra = f.read( extra_len )
+        assert len( extra ) == extra_len, "EOF reading extra field"
+    # Done with header
+    block_size = None
+    expect_no_more = False
+    # Read blocks
+    while 1:
+        size = f.get( "!I" )
+        if size == 0: break
+        assert not( expect_no_more ), \
+            "Encountered an undersized block that was not the last block"
+        if block_size is None:
+            print "s", size
+            block_size = size
+        else:
+            if size < block_size:
+                expect_no_more = True
+        compressed_size = f.get( "!I" )
+        if has_uncompressed_crc:
+            crc = f.get( "!I" )
+        if has_compressed_crc:
+            compressed_crc = f.get( "!I" )
+        print "o", f.file.tell(), compressed_size, size
+        compressed_data = f.read( compressed_size )
+        assert len( compressed_data ) == compressed_size, \
+            "EOF reading compressed data"
+
+if __name__ == "__main__":
+    main()
diff --git a/scripts/mMK_bitset.py b/scripts/mMK_bitset.py
new file mode 100644
index 0000000..4f5cc94
--- /dev/null
+++ b/scripts/mMK_bitset.py
@@ -0,0 +1,150 @@
+#!/usr/bin/env python2.4
+
+import sys
+
+import bx.align.maf
+import bx.bitset
+from bx.bitset_builders import *
+from itertools import *
+from optparse import OptionParser
+from rpy import *
+
+def main():
+
+	# Parse the command line
+	parser = OptionParser(usage = "usage: %prog [options] maf_file snp_file neutral_file window_size step_size") 
+	
+	parser.add_option("-o", "--outfile", help = "Specify file for output")
+	
+	parser.add_option("-s", "--species", type = "string", default = "panTro2")
+	
+	parser.add_option("-b", "--build", type = "string", default = "hg18")
+	
+	(options, args) = parser.parse_args()
+
+	if len(args) != 5:
+		parser.error("Incorrect number of arguments")
+	else:
+		maf_filename = args[0]
+		snp_filename = args[1]
+		neutral_filename = args[2]
+		window_size = int(args[3])
+		step_size = int(args[4])
+		
+	if options.outfile != None:
+		out_file = open(options.outfile, 'w')
+		
+	#Generate snp and neutral bitsets
+	AR_snp_bitsets = binned_bitsets_from_file(open(snp_filename))
+	neutral_bitsets = binned_bitsets_from_file(open(neutral_filename))
+
+	# Generate divergence bitset from maf file
+	AR_div_bitsets = dict()
+	chr_lens = dict()
+	reader = bx.align.maf.Reader( open (maf_filename) )
+	
+	for block in reader:
+		comp1 = block.get_component_by_src_start( options.build )
+		comp2 = block.get_component_by_src_start( options.species )
+		
+		if comp1 is None or comp2 is None:
+			continue
+			
+		# Chromosome, start, and stop of reference species alignment
+		chr = comp1.src.split( '.' )[1]
+		start = comp1.start
+		end = comp1.end
+		
+		# Get or create bitset for this chromosome
+		if chr in AR_div_bitsets:
+			bitset = AR_div_bitsets[chr]
+		else:
+			bitset = AR_div_bitsets[chr] = bx.bitset.BinnedBitSet()
+			chr_lens[chr] = comp1.get_src_size()
+			
+		# Iterate over text and set diverged bit
+		pos = start
+		for ch1, ch2 in izip( comp1.text.upper(), comp2.text.upper() ):
+			if ch1 == '-': continue
+			if ch2 == '-':
+				pos += 1
+				continue
+			
+			if ch1 != ch2 and not AR_snp_bitsets[chr][pos]:
+				bitset.set( pos )
+			pos += 1
+			
+	# Debugging Code
+# 	for chr in AR_div_bitsets:
+# 		for pos in range(0, AR_div_bitsets[chr].size):
+# 			if AR_div_bitsets[pos]:
+# 				print >> sys.stderr, chr, pos, pos+1
+	
+	# Copy div and snp bitsets
+	nonAR_snp_bitsets = dict()
+	for chr in AR_snp_bitsets:
+		nonAR_snp_bitsets[chr] = bx.bitset.BinnedBitSet()
+		nonAR_snp_bitsets[chr].ior(AR_snp_bitsets[chr])
+		
+	nonAR_div_bitsets = dict()
+	for chr in AR_div_bitsets:
+		nonAR_div_bitsets[chr] = bx.bitset.BinnedBitSet()
+		nonAR_div_bitsets[chr].ior(AR_div_bitsets[chr])
+	
+	# Generates AR snps by intersecting with neutral intervals
+	for chr in AR_snp_bitsets:
+		AR_snp_bitsets[chr].iand(neutral_bitsets[chr])
+	
+	# Generates AR divs by intersecting with neutral intervals	
+	for chr in AR_div_bitsets:
+		AR_div_bitsets[chr].iand(neutral_bitsets[chr])
+
+	# Inverts the neutral intervals so now represents nonAR
+	for chr in neutral_bitsets:
+		neutral_bitsets[chr].invert()
+	
+	# Generates nonAR snps by intersecting with masked neutral intervals	
+	for chr in nonAR_snp_bitsets:
+		nonAR_snp_bitsets[chr].iand(neutral_bitsets[chr])
+	# Generates nonAR divs by intersecting with masked neutral intervals		
+	for chr in nonAR_div_bitsets:
+		nonAR_div_bitsets[chr].iand(neutral_bitsets[chr])
+
+	for chr in AR_div_bitsets:
+		for window in range(0, chr_lens[chr] - window_size, step_size):
+# 			neutral_size = neutral_bitsets[chr].count_range(window, window_size)
+# 			if neutral_size < 9200: continue
+			AR_snp = AR_snp_bitsets[chr].count_range(window, window_size)
+			AR_div = AR_div_bitsets[chr].count_range(window, window_size)
+			nonAR_snp = nonAR_snp_bitsets[chr].count_range(window, window_size)
+			nonAR_div = nonAR_div_bitsets[chr].count_range(window, window_size)
+			
+			if nonAR_snp >= 6 and nonAR_div >= 6 and AR_snp >= 6 and AR_div >= 6:
+				MK_pval = MK_chi_pvalue(nonAR_snp, nonAR_div, AR_snp, AR_div)
+			else:
+				MK_pval = MK_fisher_pvalue(nonAR_snp, nonAR_div, AR_snp, AR_div)
+				
+			if options.outfile != None:
+				out_file.write("%s\t%d\t%d\t%d\t%d\t%d\t%d\t%1.15f\n" % (chr, window, window+window_size, nonAR_snp, nonAR_div, AR_snp, AR_div, MK_pval))
+			else:
+				print "%s\t%d\t%d\t%d\t%d\t%d\t%d\t%1.15f" % (chr, window, window+window_size, nonAR_snp, nonAR_div, AR_snp, AR_div, MK_pval)
+	
+	if options.outfile != None:
+		out_file.close()
+			
+def MK_fisher_pvalue(win_snp, win_div, AR_snp, AR_div):
+
+	if win_snp == 0 and win_div == 0 and AR_snp == 0 and AR_div == 0:
+		return 1.0
+	
+	fisher_result = r.fisher_test(r.matrix(r.c([win_snp, win_div, AR_snp, AR_div]), nr = 2))
+	
+	return fisher_result['p.value']
+
+def MK_chi_pvalue(win_snp, win_div, AR_snp, AR_div):
+	
+	chi_result = r.chisq_test(r.matrix(r.c([win_snp, win_div, AR_snp, AR_div]), nr = 2))
+	
+	return chi_result['p.value']
+
+main() 
\ No newline at end of file
diff --git a/scripts/maf_build_index.py b/scripts/maf_build_index.py
new file mode 100755
index 0000000..6b9c9e6
--- /dev/null
+++ b/scripts/maf_build_index.py
@@ -0,0 +1,83 @@
+#!/usr/bin/env python
+
+"""
+Build an index file for a set of MAF alignment blocks.
+
+If index_file is not provided maf_file.index is used.
+
+usage: %prog maf_file index_file
+    -s, --species=a,b,c: only index the position of the block in the listed species
+"""
+
+import psyco_full
+
+from bx.cookbook import doc_optparse
+
+import sys
+import os.path
+
+from bx import interval_index_file
+import bx.align.maf
+from bx.misc.seekbzip2 import SeekableBzip2File
+
+def main():
+
+    # Parse command line
+
+    options, args = doc_optparse.parse( __doc__ )
+
+    try:
+        maf_file = args[0]
+        # If it appears to be a bz2 file, attempt to open with table
+        if maf_file.endswith( ".bz2" ):
+            table_file = maf_file + "t"
+            if not os.path.exists( table_file ):
+                doc_optparse.exit( "To index bz2 compressed files first "
+                                   "create a bz2t file with bzip-table." )
+            # Open with SeekableBzip2File so we have tell support
+            maf_in = SeekableBzip2File( maf_file, table_file )
+            # Strip .bz2 from the filename before adding ".index"
+            maf_file = maf_file[:-4]
+        elif maf_file.endswith( ".lzo" ):
+            from bx.misc.seeklzop import SeekableLzopFile
+            table_file = maf_file + "t"
+            if not os.path.exists( table_file ):
+                doc_optparse.exit( "To index lzo compressed files first "
+                                   "create a lzot file with lzop_build_offset_table." )
+            # Open with SeekableBzip2File so we have tell support
+            maf_in = SeekableLzopFile( maf_file, table_file )
+            # Strip .lzo from the filename before adding ".index"
+            maf_file = maf_file[:-4]
+        else:
+            maf_in = open( maf_file )
+        # Determine the name of the index file
+        if len( args ) > 1: 
+            index_file = args[1]
+        else: 
+            index_file = maf_file + ".index" 
+        if options.species:
+            species = options.species.split( "," )
+        else:
+            species = None
+    except:
+        doc_optparse.exception()
+
+    maf_reader = bx.align.maf.Reader( maf_in )
+
+    indexes = interval_index_file.Indexes()
+
+    # Need to be a bit tricky in our iteration here to get the 'tells' right
+    while 1:
+        pos = maf_reader.file.tell()
+        block = maf_reader.next()
+        if block is None: break
+        for c in block.components:
+            if species is not None and c.src.split('.')[0] not in species:
+                continue
+            indexes.add( c.src, c.forward_strand_start, c.forward_strand_end, pos, max=c.src_size )
+
+    out = open( index_file, 'w' )
+    indexes.write( out )
+    out.close()
+
+if __name__ == "__main__": main()
diff --git a/scripts/maf_chop.py b/scripts/maf_chop.py
new file mode 100755
index 0000000..5b49fa4
--- /dev/null
+++ b/scripts/maf_chop.py
@@ -0,0 +1,55 @@
+#!/usr/bin/env python
+
+"""
+Chops alignments in a MAF file to piece of a specified length. A random set of
+non overlapping chunks of exactly the specified chop length will be produced
+
+usage: %prog [options] < maf > maf
+  -l, --length: Chop to exactly this length in columns (default 100)
+"""
+
+import sys
+
+import sys, random
+import bx.align.maf
+from optparse import OptionParser
+
+def main():
+
+    # Parse command line arguments
+
+    parser = OptionParser()
+    parser.add_option( "-l", "--length", action="store", type="int", default=100, help="" )
+
+    ( options, args ) = parser.parse_args()
+
+    length = options.length
+    maf_reader = bx.align.maf.Reader( sys.stdin )
+    maf_writer = bx.align.maf.Writer( sys.stdout )
+
+    for m in maf_reader:
+        for chopped in chop( m, length ):
+            maf_writer.write( chopped )
+
+def chop( m, length ):
+    maf_length = m.text_size
+    chunk_count = maf_length // length
+    lost_bases = maf_length % length
+    skip_amounts = [0] * ( chunk_count + 1 )
+    for i in range( 0, lost_bases ): skip_amounts[ random.randrange( 0, chunk_count + 1 ) ] += 1
+    start = 0
+    rval = []
+    for i in range( 0, chunk_count ):
+        start += skip_amounts[ i ]
+        n = m.slice( start, start + length )
+        if check_len( n ): rval.append( m.slice( start, start + length ) )
+        start += length
+    return rval
+
+def check_len( a ):
+    for c in a.components:
+        if c.size == 0: return False
+    return True 
+    
+
+if __name__ == "__main__": main()
diff --git a/scripts/maf_chunk.py b/scripts/maf_chunk.py
new file mode 100755
index 0000000..df25a46
--- /dev/null
+++ b/scripts/maf_chunk.py
@@ -0,0 +1,80 @@
+#!/usr/bin/env python
+
+"""
+Read a MAF from stdin and break into several new mafs containing no more than
+`chunk_size` columns. The new mafs will be written to `out_dir` along with a
+file "intervals.txt" specifying the range covered by each new maf file. A
+probability for writing each chunk can optionally be specified, resulting in
+a random fraction of chunks from the input MAF being produced.
+
+usage: %prog [options] chunk_size out_dir < maf
+  --prob: probability of writing versus skipping each chunk.
+"""
+
+usage = "usage: %prog chunk_size out_dir"
+
+import sys
+from optparse import OptionParser
+import bx.align.maf
+import psyco_full
+import random
+
+INF="inf"
+
+def __main__():
+
+    # Parse command line arguments
+
+    parser = OptionParser( "usage: %prog chunk_size out_dir" )
+    parser.add_option( "--prob", action="store", default=None, type="float", 
+                       help="Probability of writing a given chunk" )
+    
+    ( options, args ) = parser.parse_args()
+
+    chunk_size = int( args[0] )
+    out_dir = args[1]
+    prob = options.prob
+
+    maf_reader = bx.align.maf.Reader( sys.stdin )
+
+    maf_writer = None
+
+    count = 0
+    current_chunk = -1
+
+    chunk_min = INF
+    chunk_max = 0
+
+    write_current_chunk = True
+
+    interval_file = file( "%s/intervals.txt" % out_dir, "w" )	
+
+    for m in maf_reader:
+        chunk_min = min( chunk_min, m.components[0].start )
+        chunk_max = max( chunk_max, m.components[0].end )
+        if not maf_writer or count + m.text_size > chunk_size:
+            current_chunk += 1
+            # Finish the last chunk            
+            if maf_writer: 
+                maf_writer.close()
+                interval_file.write( "%s %s\n" % ( chunk_min, chunk_max ) )
+                chunk_min = INF
+                chunk_max = 0
+            # Decide if the new chunk will be written     
+            if prob: write_current_chunk = bool( random.random() <= prob )
+            else: write_current_chunk = True
+            if write_current_chunk:
+                maf_writer = bx.align.maf.Writer( file( "%s/%09d.maf" % ( out_dir, current_chunk ), "w" ) )
+            else:
+                maf_writer = None
+            count = 0
+        if maf_writer: maf_writer.write( m )
+        #count += m.text_size
+        count += m.components[0].size
+    
+    if maf_writer:
+        maf_writer.close()
+        interval_file.write( "%s %s\n" % ( chunk_min, chunk_max ) )
+        interval_file.close()
+
+if __name__ == "__main__": __main__()
diff --git a/scripts/maf_col_counts.py b/scripts/maf_col_counts.py
new file mode 100755
index 0000000..adac82d
--- /dev/null
+++ b/scripts/maf_col_counts.py
@@ -0,0 +1,38 @@
+#!/usr/bin/env python
+
+"""
+For every column that occurs in a multiple alignment print the column
+and the number of times it occurs (one column/count per line, tab
+separated), sorted by count descending.
+
+Note: all blocks must have exactly the same number of species.
+
+usage: %prog < maf > column_counts
+"""
+
+import bx.align.maf
+import sys
+
+from itertools import *
+
+counts = {}
+
+nspecies = None
+
+for block in bx.align.maf.Reader( sys.stdin ):
+    # Ensure all blocks have the same number of rows
+    if nspecies: assert len( block.components ) == nspecies
+    else: nspecies = len( block.components )
+    # Increment count for each column
+    for col in izip( * [ iter( comp.text.upper() ) for comp in block.components ] ):
+        try: counts[ col ] += 1
+        except: counts[ col ] = 1
+
+counts = [ ( value, key ) for key, value in counts.iteritems() ]
+counts.sort()
+counts.reverse()
+
+# print len( counts )
+
+for count, col in counts:
+    print "".join(col), count
diff --git a/scripts/maf_col_counts_all.py b/scripts/maf_col_counts_all.py
new file mode 100755
index 0000000..8992414
--- /dev/null
+++ b/scripts/maf_col_counts_all.py
@@ -0,0 +1,64 @@
+#!/usr/bin/env python
+
+"""
+For every column that occurs in a multiple alignment print the column
+and the number of times it occurs (one column/count per line, tab
+separated), sorted by count descending.
+
+This version allows special handling of the 'wildcard' symbol in alignments.
+
+Note: all blocks must have exactly the same number of species.
+
+usage: %prog [options] < maf > column_counts
+    -w, --wildcard: include wildcards
+    -m, --maxwildcards=N: only allow N missing species
+"""
+
+import bx.align.maf
+import sys
+from bx.cookbook import doc_optparse, cross_lists
+
+from itertools import *
+
+counts = {}
+
+nspecies = None
+
+for block in bx.align.maf.Reader( sys.stdin ):
+    # Ensure all blocks have the same number of rows
+    if nspecies: assert len( block.components ) == nspecies
+    else: nspecies = len( block.components )
+    # Increment count for each column
+    for col in izip( * [ iter( comp.text.upper() ) for comp in block.components ] ):
+        col = ''.join( col )
+        try: counts[ col ] += 1
+        except: counts[ col ] = 1
+
+# counts = [ ( value, key ) for key, value in counts.iteritems() ]
+# counts.sort()
+# counts.reverse()
+
+## for count, col in counts:
+##     print "".join(col), count
+
+options, args = doc_optparse.parse( __doc__ )
+
+wildcard = False
+if options.wildcard: 
+    wildcard = True
+    max_wildcard = nspecies - 1
+if options.maxwildcards:
+    wildcard = True
+    max_wildcard = int( options.maxwildcards ) 
+
+nucs = "ACGT-"
+if wildcard:
+    nucs += "*"
+
+for col in cross_lists( *( [ nucs ] * nspecies ) ):
+    col = ''.join( col )
+    if wildcard and col.count( "*" ) > max_wildcard:
+        continue
+    if col.count( "-" ) == nspecies:
+        continue
+    print col, counts.get( col, 0 )
diff --git a/scripts/maf_count.py b/scripts/maf_count.py
new file mode 100755
index 0000000..4d42215
--- /dev/null
+++ b/scripts/maf_count.py
@@ -0,0 +1,58 @@
+#!/usr/bin/env python2.3
+
+"""
+Read a MAF from standard input and print counts of alignments, bases, or 
+columns. 
+
+usage: %prog [options]
+   -c, --cols: count alignment columns rather than number of alignments
+   -b, --bases: count bases in first species rather than number of alignments
+   -s, --skip=N: when counting bases, skip this base
+   -e, --each: print a count for each alignment rather than whole file
+   -r, --ref=N: reference sequence (first by default, 0..n)
+"""
+
+from bx.cookbook import doc_optparse
+import sys
+
+import bx.align.maf
+
+def __main__():
+
+    options, args = doc_optparse.parse( __doc__ )
+
+    try:
+        if options.cols: action = "cols"
+        elif options.bases: action = "bases"
+        else: action = "aligns"
+        print_each = bool( options.each )
+        if options.ref: ref = int( options.ref )
+        else: ref = 0
+        if options.skip: skip = options.skip
+        else: skip = None
+    except:
+        doc_optparse.exit()
+
+    maf_reader = bx.align.maf.Reader( sys.stdin )
+
+    count = 0
+
+    for m in maf_reader:
+        
+        if action == "aligns": 
+            count += 1
+        elif action == "cols": 
+            count += m.text_size
+        elif action == "bases":
+            if skip:
+                count += ( m.components[ref].size - m.components[ref].text.count( skip ) )
+            else:
+                count += m.components[ref].size
+
+        if print_each: 
+            print count
+            count = 0
+
+    if not print_each: print count
+
+if __name__ == "__main__": __main__()
diff --git a/scripts/maf_covered_ranges.py b/scripts/maf_covered_ranges.py
new file mode 100755
index 0000000..ab04c49
--- /dev/null
+++ b/scripts/maf_covered_ranges.py
@@ -0,0 +1,53 @@
+#!/usr/bin/env python2.3
+
+"""
+usage: %prog species1,species2,... nrequired < maf 
+"""
+
+import psyco_full
+
+import bx.align.maf
+import copy
+import sys
+
+from itertools import *
+from bx.cookbook import doc_optparse
+
+SPAN = 100
+MIN = 100
+
+def main():
+
+    options, args = doc_optparse.parse( __doc__ )
+
+    try:
+        species = args[0].split(',')
+        nrequired = int( args[1] )
+    except:
+        doc_optparse.exit()
+
+    maf_reader = bx.align.maf.Reader( sys.stdin )
+    
+    interval_start = None
+    interval_end = None   
+
+    for m in maf_reader:            
+        ref = m.components[0]
+        # Does this alignment have enough of the required species        
+        if nrequired <= len( [ comp for comp in m.components if comp.src.split('.')[0] in species ] ):
+            if interval_start is None:
+                interval_start = ref.start
+                interval_end = ref.end
+            else:
+                if ref.start - interval_end < SPAN:
+                    interval_end = ref.end
+                else:
+                    if interval_end - interval_start >= MIN: print ref.src.split('.')[1], interval_start, interval_end
+                    interval_start = ref.start
+                    interval_end = ref.end    
+        else:
+            if interval_start != None and interval_end - interval_start >= MIN: print ref.src.split('.')[1],interval_start,interval_end
+            interval_start = None
+            interval_end = None
+
+if __name__ == "__main__": main()
diff --git a/scripts/maf_covered_regions.py b/scripts/maf_covered_regions.py
new file mode 100755
index 0000000..4d40f68
--- /dev/null
+++ b/scripts/maf_covered_regions.py
@@ -0,0 +1,56 @@
+#!/usr/bin/env python
+
+"""
+Read a maf file and print the regions covered to a set of bed files (one for 
+each sequence source referenced in the maf). Only blocks with a positive 
+percent identity are written out. 
+
+TODO: Can this be generalized to be made more useful?
+
+usage: %prog bed_outfile_prefix < maf
+"""
+
+from __future__ import division
+
+import psyco_full
+import bx.align.maf
+import sys
+
+def block_pid( comp1, comp2 ):
+    match = 0
+    total = 0
+    t1 = comp1.text.lower()
+    t2 = comp2.text.lower()
+    for i in range( 0, len(t1) ):
+        a, b = t1[i], t2[i]
+        if a == '-' or b == '-': 
+            continue
+        elif a == b:
+            match += 1
+        total += 1
+    if total == 0: return None
+    return ( match / total )
+
+def main():
+    out_prefix = sys.argv[1]
+    print out_prefix
+    out_files = dict()
+    for block in bx.align.maf.Reader( sys.stdin ):
+        ref_comp = block.components[0]
+        ref_chrom = ref_comp.src.split('.')[1]
+        for comp in block.components[1:]:
+            comp_species, comp_chrom = comp.src.split('.')[:2]
+            if comp_species not in out_files:
+                f = open( "%s%s.bed" % ( out_prefix, comp_species ), "w" )
+                out_files[comp_species] = f
+            pid = block_pid( ref_comp, comp )
+            if pid:
+                out_files[comp_species].write( "%s\t%d\t%d\t%s:%d-%d,%s\t%f\n" %
+                                 ( ref_chrom, ref_comp.forward_strand_start, ref_comp.forward_strand_end, \
+                                   comp_chrom, comp.start, comp.end, comp.strand, pid ) )
+
+    for f in out_files.values():
+        f.close()
+    
+
+if __name__ == "__main__": main()
diff --git a/scripts/maf_div_sites.py b/scripts/maf_div_sites.py
new file mode 100755
index 0000000..85904b6
--- /dev/null
+++ b/scripts/maf_div_sites.py
@@ -0,0 +1,55 @@
+#!/usr/bin/env python2.4
+"""
+Create a bed file listing all the divergent sites between two specific species 
+in a maf.
+
+usage: %prog maf_file reference_species_name other_species_name
+"""
+
+import sys
+import bx.align.maf
+import bx.bitset
+from bx.bitset_builders import *
+from itertools import *
+
+def main():
+	bitsets = {}
+	maf = sys.argv[1]
+	reference_sp, other_sp = sys.argv[2], sys.argv[3]
+
+	for block in bx.align.maf.Reader( open(maf) ):
+		ref = block.get_component_by_src_start( reference_sp )
+		other = block.get_component_by_src_start( other_sp )
+
+		if not ref or not other: continue
+		ref_chrom = ref.src.split( '.' )[1]
+		ref_start = ref.start
+		ref_end = ref.end
+		chrom_size = ref.get_src_size()
+
+		if ref_chrom not in bitsets: bitsets[ ref_chrom ] = bx.bitset.BinnedBitSet( chrom_size )
+
+		pos = ref_start
+		for i,j in izip( ref.text.upper(), other.text.upper() ):
+			if i != '-':
+				if i != j: # mismatch
+					if i != 'N' and j != 'N' and j != '-': 
+						# set if all valid chars
+						bitsets[ ref_chrom ].set( pos )
+				pos += 1
+
+	
+	# bits --> bed file
+	for chrom in bitsets:
+		bits = bitsets[chrom]
+		end = 0
+		while 1:
+			start = bits.next_set( end )
+			if start == bits.size: break
+			end = bits.next_clear( start )
+			print "%s\t%d\t%d" % ( chrom, start, end )
+
+
+main()
+
+
diff --git a/scripts/maf_drop_overlapping.py b/scripts/maf_drop_overlapping.py
new file mode 100755
index 0000000..ba4620c
--- /dev/null
+++ b/scripts/maf_drop_overlapping.py
@@ -0,0 +1,56 @@
+#!/usr/bin/env python
+
+"""
+Remove any blocks from a maf that overlap any of a set of intervals.
+
+usage: %prog interval files... < maf
+"""
+
+import psyco_full
+
+from bx.cookbook import doc_optparse
+
+import bx.align.maf
+from bx import intervals
+import sys
+
+
+def __main__():
+
+    # Parse Command Line
+
+    options, args = doc_optparse.parse( __doc__ )
+
+    try:
+        assert len( args ) > 0
+    except:
+        doc_optparse.exit()
+
+    # Load Intervals
+
+    intersector = intervals.Intersecter()
+
+    for f in args:
+        for line in file( f ):
+            if line.startswith( "#" ) or line.isspace(): continue
+            fields = line.split()
+            intersector.add_interval( intervals.Interval( int( fields[0] ), int( fields[1] ) ) )
+
+    # Start MAF on stdout
+
+    out = bx.align.maf.Writer( sys.stdout )
+
+    # Iterate over input MAF
+
+    for maf in bx.align.maf.Reader( sys.stdin ):
+        # Find overlap with reference component
+        intersections = intersector.find( maf.components[0].start, maf.components[0].end )
+        # Write only if no overlap
+        if len( intersections ) == 0:
+            out.write( maf )
+         
+    # Close output MAF
+
+    out.close()
+
+if __name__ == "__main__": __main__()
diff --git a/scripts/maf_extract_chrom_ranges.py b/scripts/maf_extract_chrom_ranges.py
new file mode 100755
index 0000000..698b3a7
--- /dev/null
+++ b/scripts/maf_extract_chrom_ranges.py
@@ -0,0 +1,91 @@
+#!/usr/bin/env python
+
+"""
+Reads a list of intervals and a maf. Produces a new maf containing the
+portions of the original that overlapped the intervals
+
+NOTE: See maf_extract_ranges_indexed.py which works better / faster for many
+      use cases.
+
+TODO: Combine with maf_extract_ranges, and possibly share some code with 
+      maf_extract_ranges_indexed.
+
+usage: %prog interval_file refname|refindex [options] < maf_file
+   -m, --mincols=10: Minimum length (columns) required for alignment to be output
+   -p, --prefix=PREFIX: Prefix
+"""
+
+import psyco_full
+
+from bx.cookbook import doc_optparse
+
+import bx.align.maf
+from bx import intervals
+import sys
+
+
+def __main__():
+
+    # Parse Command Line
+
+    options, args = doc_optparse.parse( __doc__ )
+
+    try:
+        range_filename = args[ 0 ]
+        try: 
+            refindex = int( args[ 1 ] )
+            refname = None
+        except: 
+            refindex = None
+            refname = args[ 1 ]
+        if options.mincols: mincols = int( options.mincols )
+        else: mincols = 10
+        if options.prefix: prefix = options.prefix
+        else: prefix = ""
+    except:
+        doc_optparse.exit()
+
+    # Load Intervals
+
+    intersecters = dict()    
+    for line in file( range_filename ):
+        fields = line.split()
+        src = prefix + fields[0]
+        if not src in intersecters: intersecters[src] = intervals.Intersecter()
+        intersecters[src].add_interval( intervals.Interval( int( fields[1] ), int( fields[2] ) ) )
+
+    # Start MAF on stdout
+
+    out = bx.align.maf.Writer( sys.stdout )
+
+    # Iterate over input MAF
+
+    for maf in bx.align.maf.Reader( sys.stdin ):
+        if refname: 
+            sourcenames = [ cmp.src.split('.')[0] for cmp in maf.components ]
+            try: refindex = sourcenames.index( refname )
+            except:
+                continue
+
+        ref_component = maf.components[ refindex ]
+        # Find overlap with reference component
+        if not ( ref_component.src in intersecters ): continue
+        intersections = intersecters[ ref_component.src ].find( ref_component.start, ref_component.end )
+        # Keep output maf ordered
+        intersections.sort()
+        # Write each intersecting block
+        for interval in intersections: 
+            start = max( interval.start, ref_component.start )
+            end = min( interval.end, ref_component.end )
+            sliced = maf.slice_by_component( refindex, start, end ) 
+            good = True
+            for c in sliced.components: 
+                if c.size < 1: 
+                    good = False
+            if good and sliced.text_size > mincols: out.write( sliced )
+         
+    # Close output MAF
+
+    out.close()
+
+if __name__ == "__main__": __main__()
diff --git a/scripts/maf_extract_ranges.py b/scripts/maf_extract_ranges.py
new file mode 100755
index 0000000..b9a55ea
--- /dev/null
+++ b/scripts/maf_extract_ranges.py
@@ -0,0 +1,73 @@
+#!/usr/bin/env python
+
+"""
+Reads a list of intervals (start, stop) and a maf. Produces a new maf
+containing the blocks from the original that overlapped the intervals.
+
+NOTE: See maf_extract_ranges_indexed.py which works better / faster for many
+      use cases.
+
+NOTE: chromosome/src information in the MAF is ignored by this variant.
+
+usage: %prog interval_file refindex [options] < maf_file
+   -m, --mincols=10: Minimum length (columns) required for alignment to be output
+"""
+
+import psyco_full
+
+from bx.cookbook import doc_optparse
+
+import bx.align.maf
+from bx import intervals
+import sys
+
+
+def __main__():
+
+    # Parse Command Line
+
+    options, args = doc_optparse.parse( __doc__ )
+
+    try:
+        range_filename = args[ 0 ]
+        refindex = int( args[ 1 ] )
+        if options.mincols: mincols = int( options.mincols )
+        else: mincols = 10
+    except:
+        doc_optparse.exit()
+
+    # Load Intervals
+
+    intersecter = intervals.Intersecter()
+    for line in file( range_filename ):
+        fields = line.split()
+        intersecter.add_interval( intervals.Interval( int( fields[0] ), int( fields[1] ) ) )
+
+    # Start MAF on stdout
+
+    out = bx.align.maf.Writer( sys.stdout )
+
+    # Iterate over input MAF
+
+    for maf in bx.align.maf.Reader( sys.stdin ):
+        ref = maf.components[ refindex ]
+        # Find overlap with reference component
+        intersections = intersecter.find( ref.get_forward_strand_start(), ref.get_forward_strand_end() )
+        # Keep output maf ordered
+        intersections.sort()
+        # Write each intersecting block
+        for interval in intersections: 
+            start = max( interval.start, ref.get_forward_strand_start() )
+            end = min( interval.end, ref.get_forward_strand_end() )
+            sliced = maf.slice_by_component( refindex, start, end ) 
+            good = True
+            for c in sliced.components: 
+                if c.size < 1: 
+                    good = False
+            if good and sliced.text_size > mincols: out.write( sliced )
+         
+    # Close output MAF
+
+    out.close()
+
+if __name__ == "__main__": __main__()
diff --git a/scripts/maf_extract_ranges_indexed.py b/scripts/maf_extract_ranges_indexed.py
new file mode 100755
index 0000000..407d246
--- /dev/null
+++ b/scripts/maf_extract_ranges_indexed.py
@@ -0,0 +1,114 @@
+#!/usr/bin/env python
+
+"""
+Reads a list of intervals and a maf. Produces a new maf containing the
+blocks or parts of blocks in the original that overlapped the intervals.
+
+It is assumed that each file `maf_fname` has a corresponding `maf_fname`.index 
+file.
+
+NOTE: If two intervals overlap the same block it will be written twice. With
+      non-overlapping intervals and --chop this is never a problem. 
+      
+NOTE: Intervals are origin-zero, half-open.  For example, the interval 100,150
+      is 50 bases long, and there are 100 bases to its left in the sequence.
+      
+NOTE: Intervals are relative to the + strand, regardless of the strands in
+      the alignments.
+
+      
+WARNING: bz2/bz2t support and file cache support are new and not as well
+         tested. 
+
+usage: %prog maf_fname1 maf_fname2 ... [options] < interval_file
+   -m, --mincols=0: Minimum length (columns) required for alignment to be output
+   -c, --chop:       Should blocks be chopped to only portion overlapping (no by default)
+   -s, --src=s:      Use this src for all intervals
+   -p, --prefix=p:   Prepend this to each src before lookup
+   -d, --dir=d:      Write each interval as a separate file in this directory
+   -S, --strand:     Strand is included as an additional column, and the blocks are reverse complemented (if necessary) so that they are always on that strand w/r/t the src species.
+   -C, --usecache:   Use a cache that keeps blocks of the MAF files in memory (requires ~20MB per MAF)
+"""
+
+import psyco_full
+
+from bx.cookbook import doc_optparse
+
+import bx.align.maf
+from bx import misc
+import os
+import sys
+
+def main():
+    # Parse Command Line
+    options, args = doc_optparse.parse( __doc__ )
+    try:
+        maf_files = args
+        if options.mincols: mincols = int( options.mincols )
+        else: mincols = 0
+        if options.src: fixed_src = options.src
+        else: fixed_src = None
+        if options.prefix: prefix = options.prefix
+        else: prefix = None
+        if options.dir: dir = options.dir
+        else: dir = None
+        chop = bool( options.chop )
+        do_strand = bool( options.strand )
+        use_cache = bool( options.usecache )
+    except:
+        doc_optparse.exit()
+    # Open indexed access to mafs
+    index = bx.align.maf.MultiIndexed( maf_files, keep_open=True,
+                                                  parse_e_rows=True,
+                                                  use_cache=use_cache )
+    # Start MAF on stdout
+    if dir is None: 
+        out = bx.align.maf.Writer( sys.stdout )
+    # Iterate over input ranges 
+    for line in sys.stdin:
+        strand = None
+        fields = line.split()
+        if fixed_src:
+            src, start, end = fixed_src, int( fields[0] ), int( fields[1] )
+            if do_strand: strand = fields[2]
+        else:
+            src, start, end = fields[0], int( fields[1] ), int( fields[2] )
+            if do_strand: strand = fields[3]
+        if prefix: src = prefix + src
+        # Find overlap with reference component
+        blocks = index.get( src, start, end )
+        # Open file if needed
+        if dir:
+            out = bx.align.maf.Writer( open( os.path.join( dir, "%s:%09d-%09d.maf" % ( src, start, end ) ), 'w' ) )
+        # Write each intersecting block
+        if chop:
+            for block in blocks: 
+                for ref in block.get_components_by_src( src ):
+                    slice_start = max( start, ref.get_forward_strand_start() )
+                    slice_end = min( end, ref.get_forward_strand_end() )
+                    if (slice_end <= slice_start): continue
+                    sliced = block.slice_by_component( ref, slice_start, slice_end ) 
+                    # If the block is shorter than the minimum allowed size, stop
+                    if mincols and ( sliced.text_size < mincols ):
+                        continue
+                    # If the reference component is empty, don't write the block
+                    if sliced.get_component_by_src( src ).size < 1:
+                        continue
+                    # Keep only components that are not empty
+                    sliced.components = [ c for c in sliced.components if c.size > 0 ]
+                    # Reverse complement if needed
+                    if ( strand != None ) and ( ref.strand != strand ): 
+                        sliced = sliced.reverse_complement()
+                    # Write the block
+                    out.write( sliced )
+        else:
+            for block in blocks:
+                out.write( block )
+        if dir:
+            out.close()
+    # Close output MAF
+    out.close()
+    index.close()
+
+if __name__ == "__main__": 
+    main()
diff --git a/scripts/maf_filter.py b/scripts/maf_filter.py
new file mode 100755
index 0000000..375c5bd
--- /dev/null
+++ b/scripts/maf_filter.py
@@ -0,0 +1,52 @@
+#!/usr/bin/env python
+
+"""
+Filter each block in a maf file. Can filter blocks for a minimum number of
+components (rows), a minimum length in columns, or an arbitrary python 
+expression (which will be evaluated for each block with the variable 'm'
+containing that block).
+
+usage: %prog [options] < maf > maf
+    --component_count=N: Minimum number of components (rows)
+    --min_cols=N: Minimum number of columns
+    -e, --expr=EXPR: Python expression that must evaulate to true
+"""
+
+import psyco_full
+
+import sys
+
+import sys
+from bx.align import maf
+from optparse import OptionParser
+
+def __main__():
+
+    # Parse command line arguments
+
+    parser = OptionParser()
+    parser.add_option( "--component_count", action="store", default=None, type="int", help="" )
+    parser.add_option( "--min_cols", action="store", default=None, type="int", help="" )
+    parser.add_option( "-e", "--expr", action="store", default=None )
+
+    ( options, args ) = parser.parse_args()
+
+    component_count = options.component_count
+    min_cols = options.min_cols
+    expr = options.expr
+
+    # Compile expression for SPEED
+    if expr: expr = compile( expr, '<expr arg>', 'eval' )
+
+    maf_reader = maf.Reader( sys.stdin )
+    maf_writer = maf.Writer( sys.stdout )
+
+    for m in maf_reader:
+
+        if component_count and len( m.components ) != component_count: continue
+        if min_cols and m.text_size < min_cols: continue
+        if expr and not bool( eval( expr, { "m": m, "maf": m } ) ): continue
+
+        maf_writer.write( m )
+
+if __name__ == "__main__": __main__()
diff --git a/scripts/maf_filter_max_wc.py b/scripts/maf_filter_max_wc.py
new file mode 100755
index 0000000..b86db1d
--- /dev/null
+++ b/scripts/maf_filter_max_wc.py
@@ -0,0 +1,40 @@
+#!/usr/bin/env python
+
+"""
+Filter maf blocks for presence of wildcard columns. Blocks must meet the 
+criteria of having at least `min_good` columns, each of which has more than
+`min_species` rows that are NOT wildcard bases ('*').
+
+TODO: Allow specifying the character of the wildcard base.
+
+usage: %prog min_good min_species < maf > maf
+"""
+
+from __future__ import division
+
+import psyco_full
+
+import sys
+
+import sys
+from bx.align import maf
+from optparse import OptionParser
+
+def main():
+
+    min_good = int( sys.argv[1] )
+    min_species = int( sys.argv[2] )
+
+    maf_reader = maf.Reader( sys.stdin )
+    maf_writer = maf.Writer( sys.stdout )
+
+    for m in maf_reader:
+        good = 0
+        for col in m.column_iter():
+            if col.count( '*' ) <= min_species:
+                good += 1   
+        if good >= min_good: 
+            maf_writer.write( m )
+
+if __name__ == "__main__": 
+    main()
diff --git a/scripts/maf_gap_frequency.py b/scripts/maf_gap_frequency.py
new file mode 100755
index 0000000..2a01cb0
--- /dev/null
+++ b/scripts/maf_gap_frequency.py
@@ -0,0 +1,23 @@
+#!/usr/bin/env python
+
+"""
+Read a MAF from standard input and print the fraction of gap columns in 
+each block.
+
+usage: %prog < maf > out
+"""
+
+from __future__ import division
+
+import sys
+import bx.align.maf
+
+
+def main():    
+    for m in bx.align.maf.Reader( sys.stdin ):  
+        gaps = 0        
+        for col in m.column_iter():
+            if ( '-' in col ): gaps += 1          
+        print gaps / m.text_size
+
+if __name__ == "__main__": main()
diff --git a/scripts/maf_gc_content.py b/scripts/maf_gc_content.py
new file mode 100755
index 0000000..8aa512b
--- /dev/null
+++ b/scripts/maf_gc_content.py
@@ -0,0 +1,32 @@
+#!/usr/bin/env python2.3
+
+"""
+Read a MAF from standard input and print average GC content of each alignment
+
+usage: %prog < maf > out
+"""
+
+from __future__ import division
+
+import sys
+
+from bx.align import maf
+
+
+def __main__():
+    
+    maf_reader = maf.Reader( sys.stdin )
+
+    for m in maf_reader:
+        gc = 0
+        bases = 0
+        for c in m.components:
+          gc += c.text.count( 'G' )
+          gc += c.text.count( 'C' )
+          gc += c.text.count( 'g' )
+          gc += c.text.count( 'c' )
+          bases += ( len( c.text ) - c.text.count( '-' ) )
+
+        print gc / bases
+
+if __name__ == "__main__": __main__()
diff --git a/scripts/maf_interval_alignibility.py b/scripts/maf_interval_alignibility.py
new file mode 100755
index 0000000..7135e7d
--- /dev/null
+++ b/scripts/maf_interval_alignibility.py
@@ -0,0 +1,111 @@
+#!/usr/bin/env python2.4
+
+"""
+WARNING: bz2/bz2t support and file cache support are new and not as well
+         tested. 
+
+usage: %prog maf_files [options] < interval_file
+    -s, --species=SPECIES: Comma separated list of species to include
+    -p, --prefix=PREFIX: Prefix to add to each interval chrom (usually reference species)
+   -C, --usecache:   Use a cache that keeps blocks of the MAF files in memory (requires ~20MB per MAF)
+"""
+
+from __future__ import division
+
+import psyco_full
+
+from bx.cookbook import doc_optparse
+
+import bx.align.maf
+from bx import misc
+import os
+import sys
+
+from numpy import *
+
+def main():
+    # Parse Command Line
+    options, args = doc_optparse.parse( __doc__ )
+    try:
+        maf_files = args
+        species = options.species.split( "," )
+        prefix = options.prefix
+        use_cache = bool( options.usecache )
+        if not prefix:
+            prefix = ""
+    except:
+        doc_optparse.exit()
+    # Open indexed access to mafs
+    index = bx.align.maf.MultiIndexed( maf_files, 
+                                      parse_e_rows=True,
+                                      use_cache=use_cache )
+    # Print header
+    print "#chr", "start", "end",
+    for s in species:
+        print s,
+    print
+    # Iterate over input ranges 
+    for line in sys.stdin:
+        fields = line.split()
+        # Input is BED3+
+        chr, start, end = fields[0], int( fields[1] ), int( fields[2] )
+        length = end - start
+        assert length > 0, "Interval has length less than one"
+        # Prepend prefix if specified
+        src = prefix + chr    
+        # Keep a bitset for each species noting covered pieces
+        aligned_bits = []
+        missing_bits = []
+        for s in species:
+            aligned_bits.append( zeros( length, dtype=bool ) )
+            missing_bits.append( zeros( length, dtype=bool ) )
+        # Find overlap with reference component
+        blocks = index.get( src, start, end )
+        # Determine alignability for each position
+        for block in blocks:
+            # Determine the piece of the human interval this block covers, 
+            # relative to the start of the interval of interest
+            ref = block.get_component_by_src( src )
+            assert ref.strand == "+", \
+                "Reference species blocks must be on '+' strand"
+            rel_start = max( start, ref.start ) - start
+            rel_end = min( end, ref.end ) - start
+            # Check alignability for each species
+            for i, s in enumerate( species ):
+                other = block.get_component_by_src_start( s )
+                # Species does not appear at all indicates unaligned (best we
+                # can do here?)
+                if other is None:
+                    continue
+                # An empty component might indicate missing data, all other
+                # cases (even contiguous) we count as not aligned
+                if other.empty:
+                    if other.synteny_empty == bx.align.maf.MAF_MISSING_STATUS:
+                        missing_bits[i][rel_start:rel_end] = True
+                # Otherwise we have a local alignment with some text, call
+                # it aligned
+                else:
+                    aligned_bits[i][rel_start:rel_end] = True
+        # Now determine the total alignment coverage of each interval
+        print chr, start, end,
+        for i, s in enumerate( species ):
+            aligned = sum( aligned_bits[i] )
+            missing = sum( missing_bits[i] )
+            # An interval will be called missing if it is < 100bp and <50% 
+            # present, or more than 100bp and less that 50bp present (yes,
+            # arbitrary)
+            is_missing = False
+            if length < 100 and missing > ( length / 2 ):
+                print "NA",
+            elif length >= 100 and missing > 50:
+                print "NA",
+            else:
+                print aligned / ( length - missing ),
+                
+        print
+         
+    # Close MAF files
+    index.close()
+
+if __name__ == "__main__": 
+    main()
diff --git a/scripts/maf_limit_to_species.py b/scripts/maf_limit_to_species.py
new file mode 100755
index 0000000..f3e2127
--- /dev/null
+++ b/scripts/maf_limit_to_species.py
@@ -0,0 +1,40 @@
+#!/usr/bin/env python2.3
+
+"""
+Read a maf file from stdin and write out a new maf with only blocks having all
+of the required in species, after dropping any other species and removing
+columns containing only gaps.
+
+usage: %prog species,species2,... < maf
+"""
+
+import psyco_full
+
+import bx.align.maf
+import copy
+import sys
+
+from itertools import *
+
+def main():
+
+    species = sys.argv[1].split( ',' )
+
+    maf_reader = bx.align.maf.Reader( sys.stdin )
+    maf_writer = bx.align.maf.Writer( sys.stdout )
+
+    for m in maf_reader:        
+        new_components = []    
+        for comp in m.components:
+            if comp.src.split( '.' )[0] in species:
+                new_components.append( comp )
+        m.components = new_components
+        m.remove_all_gap_columns()
+        if len( m.components ) > 1:
+            maf_writer.write( m )
+        
+    maf_reader.close()
+    maf_writer.close()
+
+if __name__ == "__main__": 
+    main()
diff --git a/scripts/maf_mapping_word_frequency.py b/scripts/maf_mapping_word_frequency.py
new file mode 100755
index 0000000..6262156
--- /dev/null
+++ b/scripts/maf_mapping_word_frequency.py
@@ -0,0 +1,58 @@
+#!/usr/bin/env python2.3
+
+"""
+
+Reads a maf file from stdin and applies the mapping file specified by
+`mapping_file` to produce a sequence of integers. Then for each possible word
+of length `motif_len` in this integer alphabet print the number of times
+that word occurs in the block. 
+
+usage: %prog motif_len mapping_file < maf_file > counts
+"""
+
+from __future__ import division
+
+import psyco_full
+
+import bx.align.maf
+from bx import seqmapping
+import string
+import sys
+from Numeric import *
+
+def main():
+
+    word_length = int( sys.argv[1] )
+    align_count, alpha_map = seqmapping.alignment_mapping_from_file( file( sys.argv[2] ) )
+
+    for maf in bx.align.maf.Reader( sys.stdin ):
+        assert len( maf.components ) == align_count
+        # Translate alignment to ints
+        ints = seqmapping.DNA.translate_list( [ c.text for c in maf.components ] )
+        # Apply mapping 
+        ints = alpha_map.translate( ints )
+        # Count words
+        radix = alpha_map.get_out_size()
+        counts = zeros( radix ** word_length, Int ) 
+        total = 0
+        for i in range( word_length, len( ints ) ):
+            index = 0
+            factor = 1
+            skip = False
+            for j in range( word_length ):
+                assert 0 < i-j < len( ints )
+                letter = ints[i-j]
+                if letter < 0:
+                    skip = True
+                    break
+                index += letter * factor
+                factor *= radix
+            if skip: 
+                continue        
+            else:
+                counts[ index ] += 1
+                total += 1
+        # Write ints separated by tabs
+        print '\t'.join( [ str( total ) ] + map( str, counts ) )
+
+if __name__ == "__main__": main()
diff --git a/scripts/maf_mask_cpg.py b/scripts/maf_mask_cpg.py
new file mode 100644
index 0000000..01f91c9
--- /dev/null
+++ b/scripts/maf_mask_cpg.py
@@ -0,0 +1,40 @@
+#!/usr/bin/env python
+
+"""
+Mask out potential CpG sites from a maf. Restricted or inclusive definition
+of CpG sites can be used. The total fraction masked is printed to stderr.
+
+usage: %prog < input > output
+    -m, --mask=N: Character to use as mask ('?' is default)
+    -r, --restricted: Use restricted definition of CpGs
+"""
+
+import bx.align
+import bx.align.maf
+from bx.cookbook import doc_optparse
+import sys
+import bx.align.sitemask.cpg
+
+def main():
+    options, args = doc_optparse.parse( __doc__ )
+    try:
+        if options.mask:
+            mask = options.mask
+        else:
+            mask = "?"
+    except:
+        doc_optparse.exception()
+
+    reader = bx.align.maf.Reader( sys.stdin )
+    writer = bx.align.maf.Writer( sys.stdout )
+
+    if options.restricted:
+        cpgfilter = bx.align.sitemask.cpg.Restricted( mask=mask )
+    else:
+        cpgfilter = bx.align.sitemask.cpg.Inclusive( mask=mask )
+    cpgfilter.run( reader, writer.write )
+
+    print >> sys.stderr, str( float(cpgfilter.masked)/float(cpgfilter.total) * 100 ) + "% bases masked."
+
+if __name__ == "__main__":
+    main()
diff --git a/scripts/maf_mean_length_ungapped_piece.py b/scripts/maf_mean_length_ungapped_piece.py
new file mode 100755
index 0000000..ed47142
--- /dev/null
+++ b/scripts/maf_mean_length_ungapped_piece.py
@@ -0,0 +1,34 @@
+#!/usr/bin/env python2.3
+
+"""
+Read a MAF from standard input and determine the mean length of ungapped pieces
+in each block.
+
+usage: %prog < maf > out
+"""
+
+from __future__ import division
+
+import sys
+import bx.align.maf
+
+def main():
+    
+    for m in bx.align.maf.Reader( sys.stdin ):  
+    
+        ungapped_columns = 0
+        ungapped_runs = 0
+        in_ungapped = False
+        
+        for col in m.column_iter():
+            is_gap = ( '-' in col )
+            if not is_gap: ungapped_columns += 1
+            if in_ungapped and is_gap:
+                ungapped_runs += 1
+            in_ungapped = not is_gap
+        if in_ungapped: ungapped_runs += 1
+
+        print ungapped_columns / ungapped_runs
+
+
+if __name__ == "__main__": main()
diff --git a/scripts/maf_percent_columns_matching.py b/scripts/maf_percent_columns_matching.py
new file mode 100755
index 0000000..14aacd2
--- /dev/null
+++ b/scripts/maf_percent_columns_matching.py
@@ -0,0 +1,38 @@
+#!/usr/bin/env python2.3
+
+"""
+Read a PAIRWISE maf from stdin and print the fraction of columns whose bases 
+match for each alignment.
+
+TODO: generalize for more than two speceis.
+
+usage: %prog < maf > out
+"""
+
+from __future__ import division
+
+import sys
+
+import psyco_full
+
+from bx.align import maf
+
+
+def __main__():
+    
+    maf_reader = maf.Reader( sys.stdin )
+
+    for m in maf_reader:
+        match = 0
+        total = 0
+        for i in range( 0, m.text_size ):
+            a = m.components[0].text[i].lower() 
+            b = m.components[1].text[i].lower()            
+            if a == b:
+                match += 1
+            total += 1
+
+        print match / total
+
+
+if __name__ == "__main__": __main__()
diff --git a/scripts/maf_percent_identity.py b/scripts/maf_percent_identity.py
new file mode 100755
index 0000000..e2633ec
--- /dev/null
+++ b/scripts/maf_percent_identity.py
@@ -0,0 +1,41 @@
+#!/usr/bin/env python2.3
+
+"""
+Read a PAIRWISE maf from stdin and print the percent identity of each
+alignment, where percent identity is defined as the number of matching columns
+over the number of aligned (non-gap) columns.
+
+TODO: Generalize for more than two species
+
+usage: %prog < maf > out
+"""
+
+from __future__ import division
+
+import sys
+
+import psyco_full
+
+from bx.align import maf
+
+
+def __main__():
+
+    maf_reader = maf.Reader( sys.stdin )
+
+    for m in maf_reader:
+        match = 0
+        total = 0
+        for i in range( 0, m.text_size ):
+            a = m.components[0].text[i].lower() 
+            b = m.components[1].text[i].lower()            
+            if a == '-' or b == '-': 
+                continue
+            elif a == b:
+                match += 1
+            total += 1
+
+        print match / total
+
+
+if __name__ == "__main__": __main__()
diff --git a/scripts/maf_print_chroms.py b/scripts/maf_print_chroms.py
new file mode 100755
index 0000000..9d88595
--- /dev/null
+++ b/scripts/maf_print_chroms.py
@@ -0,0 +1,37 @@
+#!/usr/bin/env python2.3
+
+"""
+Read a maf from stdin and print the chromosome number for each alignment. It
+searches for 'chr' in each alignment block src, and may not be robust if other
+src formats are used. 
+
+NOTE: See 'align_print_template.py' for a more general variation of this
+      program.
+
+usage: %prog refindex [options]
+"""
+
+from __future__ import division
+
+import sys
+from bx.cookbook import doc_optparse
+from bx.align import maf
+from optparse import OptionParser
+
+def __main__():
+
+    # Parse command line arguments
+    options, args = doc_optparse.parse( __doc__ )
+
+    try:
+        refindex = int( args[0] )
+    except:
+        doc_optparse.exit()
+
+    maf_reader = maf.Reader( sys.stdin )
+
+    for m in maf_reader: 
+		c = m.components[ refindex ].src
+		print c[ c.rfind( "chr" ) + 3 : ]
+
+if __name__ == "__main__": __main__()
diff --git a/scripts/maf_print_scores.py b/scripts/maf_print_scores.py
new file mode 100755
index 0000000..1f0091e
--- /dev/null
+++ b/scripts/maf_print_scores.py
@@ -0,0 +1,57 @@
+#!/usr/bin/env python
+
+"""
+Read a MAF from standard input and print the score of each block. It can 
+optionally recalculate each score using the hox70 matrix, and normalize the 
+score by the number of columns in the alignment.
+
+TODO: Should be able to read an arbitrary scoring matrix.
+
+usage: %prog [options]
+   -r, --recalculate: don't use the score from the maf, recalculate (using hox70 matrix)
+   -l, --lnorm: divide (normalize) score by alignment text length
+"""
+
+from __future__ import division
+
+import sys
+from bx.cookbook import doc_optparse
+from bx.align import maf
+from bx.align import score
+from optparse import OptionParser
+
+def main():
+
+    # Parse command line arguments
+    options, args = doc_optparse.parse( __doc__ )
+
+    try:
+        lnorm = bool( options.lnorm )
+        recalculate = bool( options.recalculate )
+    except:
+        doc_optparse.exit()
+
+    hox70 = score.build_scoring_scheme( """  A    C    G    T
+                                      91 -114  -31 -123
+                                    -114  100 -125  -31
+                                     -31 -125  100 -114
+                                    -123  -31 -114   91 """, 400, 30, default=0 )
+
+    maf_reader = maf.Reader( sys.stdin )
+
+    for m in maf_reader: 
+        if m.text_size == 0:
+            print "NA"
+            continue
+        s = m.score
+        # Recalculate?
+        if recalculate:
+            s = hox70.score_alignment( m )
+        # Normalize?
+        if lnorm:
+            s = s / m.text_size
+        # Print
+        print s
+
+if __name__ == "__main__": 
+    main()
diff --git a/scripts/maf_randomize.py b/scripts/maf_randomize.py
new file mode 100755
index 0000000..5986d23
--- /dev/null
+++ b/scripts/maf_randomize.py
@@ -0,0 +1,35 @@
+#!/usr/bin/env python
+
+"""
+Randomize the order of blocks in a MAF file. If `sample_size` is specified,
+that many random blocks will be kept from the original maf
+
+usage: %prog [sample_size] < maf > maf
+"""
+
+import sys
+
+import sys, random
+from bx.align import maf
+from math import *
+from optparse import OptionParser
+
+def __main__():
+
+    #if len( sys.argv ) > 1: fraction = float( sys.argv[1] )
+    if len( sys.argv ) > 1: sample_size = int( sys.argv[1] )
+
+    maf_reader = maf.Reader( sys.stdin )
+    maf_writer = maf.Writer( sys.stdout )
+
+    mafs = list( maf_reader )
+
+    # for m in maf_reader: mafs.append( m )
+
+    random.shuffle( mafs )
+
+    if not sample_size: sample_size = len( mafs )
+
+    for i in range( 0, sample_size ): maf_writer.write( mafs[ i ] )
+    
+if __name__ == "__main__": __main__()
diff --git a/scripts/maf_region_coverage_by_src.py b/scripts/maf_region_coverage_by_src.py
new file mode 100755
index 0000000..6b3b070
--- /dev/null
+++ b/scripts/maf_region_coverage_by_src.py
@@ -0,0 +1,68 @@
+#!/usr/bin/env python
+
+"""
+Reads a list of intervals and a set of indexed mafs. For each interval print
+the amount covered by each species other than the reference.
+
+usage: %prog maf_files  [options] < interval_file
+   -s, --src=s:      Use this src for all intervals
+   -p, --prefix=p:   Prepend this to each src before lookup
+"""
+
+from __future__ import division
+
+import psyco_full
+
+from bx.cookbook import doc_optparse
+
+import bx.align.maf
+from bx import intervals
+from bx import misc
+import sys
+
+def __main__():
+
+    # Parse Command Line
+
+    options, args = doc_optparse.parse( __doc__ )
+
+    try:
+        maf_files = args
+        if options.prefix: prefix = options.prefix
+        else: prefix = None
+    except:
+        doc_optparse.exit()
+
+    # Open indexed access to mafs
+    indexes = [ bx.align.maf.Indexed( maf_file, maf_file + ".index" ) for maf_file in maf_files ]
+
+    # Iterate over input ranges 
+
+    for line in sys.stdin:
+        fields = line.split()
+        src, start, end = fields[0], int( fields[1] ), int( fields[2] )
+        if prefix: src = prefix + src
+
+        total_length = end - start
+
+        # Find overlap with reference component
+        blocks = []
+        for index in indexes: blocks += index.get( src, start, end )
+
+        coverage = dict()
+        for block in blocks:
+            overlap_start = max( start, block.components[0].start )
+            overlap_end = min( end, block.components[0].end )
+            length = overlap_end - overlap_start
+            assert length > 0
+            for c in block.components[1:]:
+                species = c.src.split( '.' )[0]
+                try: coverage[ species ] += length
+                except: coverage[ species ] = length
+
+        print line,
+        for key, value in coverage.iteritems():
+            print "   ", key.ljust(10), "%0.2f" % ( value / total_length )
+
+
+if __name__ == "__main__": __main__()
diff --git a/scripts/maf_select.py b/scripts/maf_select.py
new file mode 100755
index 0000000..c862bdb
--- /dev/null
+++ b/scripts/maf_select.py
@@ -0,0 +1,35 @@
+#!/usr/bin/env python
+
+"""
+Read a feature file containing a 0 or 1 on each line, output 
+all mafs whose index in maf_file corresponds to a row having a 1
+
+usage: %prog feature_file < maf_file
+"""
+
+import psyco_full
+
+import sys
+import bx.align.maf
+
+def __main__():
+
+    feature_file = sys.argv[1]
+
+    if len( sys.argv ) > 2:
+        match = int( sys.argv[2] )
+    else:
+        match = 1
+    
+    feature_vector = [ int( line ) for line in file( feature_file ) ]
+
+    maf_reader = bx.align.maf.Reader( sys.stdin )
+    maf_writer = bx.align.maf.Writer( sys.stdout )
+
+    index = 0
+
+    for m in maf_reader:
+        if feature_vector[ index ] == match: maf_writer.write( m )
+        index += 1
+
+if __name__ == "__main__": __main__()
diff --git a/scripts/maf_shuffle_columns.py b/scripts/maf_shuffle_columns.py
new file mode 100755
index 0000000..333b9aa
--- /dev/null
+++ b/scripts/maf_shuffle_columns.py
@@ -0,0 +1,29 @@
+#!/usr/bin/env python
+
+"""
+Randomly shuffle the columns of each block of a maf file. Note that this does
+not change any other features of the maf block, thus the text of each row no
+longer will match the sequence refered to by the other row attributes!
+
+usage: %prog < maf > maf
+"""
+
+import psyco_full
+
+import sys
+
+import sys
+from bx import align
+
+def __main__():
+
+    maf_reader = align.maf.Reader( sys.stdin )
+    maf_writer = align.maf.Writer( sys.stdout )
+
+    for m in maf_reader:
+    
+        align.shuffle_columns( m )
+
+        maf_writer.write( m )
+
+if __name__ == "__main__": __main__()
diff --git a/scripts/maf_species_in_all_files.py b/scripts/maf_species_in_all_files.py
new file mode 100755
index 0000000..4e4a1ae
--- /dev/null
+++ b/scripts/maf_species_in_all_files.py
@@ -0,0 +1,26 @@
+#!/usr/bin/env python2.4
+
+"""
+Takes a list of maf filenames on the command line and prints a comma separated
+list of the species that occur in all of the mafs. 
+
+usage %prog maf1 maf2 ...
+"""
+
+import operator
+import sys
+import bx.align.maf
+
+files = sys.argv[1:]
+sets = []
+
+for file in files:
+    sys.stderr.write( "." )
+    s = set()
+    for block in bx.align.maf.Reader( open( file ) ):
+        for comp in block.components:
+            s.add( comp.src.split( '.' )[0] )
+    sets.append( s )
+
+inter = reduce( operator.and_, sets )
+print ",".join( inter )
diff --git a/scripts/maf_split_by_src.py b/scripts/maf_split_by_src.py
new file mode 100755
index 0000000..d208bd9
--- /dev/null
+++ b/scripts/maf_split_by_src.py
@@ -0,0 +1,60 @@
+#!/usr/bin/env python2.3
+
+"""
+Read a MAF from stdin and break into several mafs based on the source of 
+each block. If the `component` option is provided then only that component
+will be used to determine the new file for each block, otherwise the src
+for *all* components will be used.
+
+TODO: Should be able to specify component by species/prefix?
+
+usage: %prog [options] < maf
+    -o, --outprefix: prepend this to the name of each generate maf
+    -c, --component: use only this component (by index!) to split
+"""
+
+import sys, string
+import bx.align.maf
+from optparse import OptionParser
+
+import psyco_full
+
+INF="inf"
+
+def __main__():
+
+    # Parse command line arguments
+
+    parser = OptionParser()
+    parser.add_option( "-o", "--outprefix", action="store", default="" )
+    parser.add_option( "-c", "--component", action="store", default=None )
+    ( options, args ) = parser.parse_args()
+
+    out_prefix = options.outprefix
+    comp = options.component
+    if comp is not None:
+       comp = int( comp )
+
+    maf_reader = bx.align.maf.Reader( sys.stdin )
+
+    writers = {}
+
+    for m in maf_reader:
+       
+        if comp is None: 
+            writer_key = string.join( [ c.src for c in m.components ], '_' )
+        else:
+            writer_key = m.components[ comp ].src
+
+        if not writers.has_key( writer_key ):
+            writer = bx.align.maf.Writer( file( "%s%s.maf" % ( out_prefix, writer_key ), "w" ) )
+            writers[ writer_key ] = writer
+        else:
+            writer = writers[ writer_key ] 
+
+        writer.write( m )
+
+    for key in writers:
+        writers[ key ].close()
+
+if __name__ == "__main__": __main__()
diff --git a/scripts/maf_thread_for_species.py b/scripts/maf_thread_for_species.py
new file mode 100755
index 0000000..53b362d
--- /dev/null
+++ b/scripts/maf_thread_for_species.py
@@ -0,0 +1,55 @@
+#!/usr/bin/env python
+
+"""
+Read a maf file from stdin and write out a new maf with only blocks having all of
+the passed in species, after dropping any other species and removing columns 
+containing only gaps. By default this will attempt to fuse together any blocks
+which are adjacent after the unwanted species have been dropped. 
+
+usage: %prog species1 species2 ... < maf 
+    -n, --nofuse: Don't attempt to join blocks, just remove rows.
+"""
+
+import psyco_full
+
+import bx.align.maf
+import copy
+import sys
+
+from bx.align.tools.thread import *
+from bx.align.tools.fuse import *
+
+from itertools import *
+
+from bx.cookbook import doc_optparse
+
+def main():
+
+    options, args = doc_optparse.parse( __doc__ )
+
+    try:
+        species = args
+        # Allow a comma separated list, TODO: allow a newick format tree
+        if len( species ) == 1 and ',' in species[0]: species = species[0].split( ',' )
+        fuse = not( bool( options.nofuse ) ) 
+    except:
+        doc_optparse.exit()
+
+    maf_reader = bx.align.maf.Reader( sys.stdin )
+    maf_writer = bx.align.maf.Writer( sys.stdout )
+
+    if fuse: 
+        maf_writer = FusingAlignmentWriter( maf_writer )
+   
+    for m in maf_reader:            
+        new_components = get_components_for_species( m, species )	
+        if new_components: 
+            remove_all_gap_columns( new_components )          
+            m.components = new_components
+            m.score = 0.0 
+            maf_writer.write( m )
+
+    maf_reader.close()
+    maf_writer.close()
+    
+if __name__ == "__main__": main()
diff --git a/scripts/maf_tile.py b/scripts/maf_tile.py
new file mode 100755
index 0000000..4ab1ffa
--- /dev/null
+++ b/scripts/maf_tile.py
@@ -0,0 +1,138 @@
+#!/usr/bin/env python
+
+"""
+'Tile' the blocks of a maf file over each of a set of intervals. The
+highest scoring block that covers any part of a region will be used, and 
+pieces not covered by any block filled with "-" or optionally "*". The list
+of species to tile is specified by `tree` (either a tree or just a comma
+separated list). The `seq_db` is a lookup table mapping chromosome names
+to nib file for filling in the reference species. Maf files must be indexed.
+
+NOTE: See maf_tile_2.py for a more sophisticated version of this program, I
+      think this one will be eliminated in the future. 
+
+usage: %prog tree maf_files...
+    -m, --missingData: Inserts wildcards for missing block rows instead of '-'
+"""
+
+import psyco_full
+
+from bx.cookbook import doc_optparse
+
+import bx.align.maf
+import bx.align as align
+from bx import misc
+import bx.seq.nib
+import os
+import string
+import sys
+
+tree_tx = string.maketrans( "(),", "   " )
+
+def main():
+
+    options, args = doc_optparse.parse( __doc__ )
+    try:
+        sources = args[0].translate( tree_tx ).split()
+        seq_db = load_seq_db( args[1] )
+        index = bx.align.maf.MultiIndexed( args[2:] )
+
+        out = bx.align.maf.Writer( sys.stdout )
+        missing_data = bool(options.missingData)
+    except:
+        doc_optparse.exception()
+
+    for line in sys.stdin:
+        ref_src, start, end = line.split()[0:3]
+        do_interval( sources, index, out, ref_src, int( start ), int( end ), seq_db, missing_data )
+
+    out.close()
+
+def load_seq_db( fname ):
+    db = {}
+    for line in open( fname ):
+        fields = line.split(',')
+        src = fields[1] + "." + fields[2]
+        seq = fields[4]
+        db[src]=seq.strip()
+    return db
+
+def do_interval( sources, index, out, ref_src, start, end, seq_db, missing_data ):
+
+    assert sources[0].split('.')[0] == ref_src.split('.')[0], "%s != %s" % ( sources[0].split('.')[0], ref_src.split('.')[0] )
+
+    base_len = end - start
+        
+    blocks = index.get( ref_src, start, end )
+    # From low to high score
+    blocks.sort( lambda a, b: cmp( a.score, b.score ) )
+
+    mask = [ -1 ] * base_len
+
+    # print len( blocks )
+    # print blocks[0]
+    
+    ref_src_size = None
+    for i, block in enumerate( blocks ):
+        ref = block.get_component_by_src_start( ref_src )
+        ref_src_size = ref.src_size
+        assert ref.strand == "+"
+        slice_start = max( start, ref.start )
+        slice_end = min( end, ref.end )
+        for j in range( slice_start, slice_end ):
+            mask[j-start] = i
+
+    #print >>sys.stderr, mask
+
+    tiled = []
+    for i in range( len( sources ) ): tiled.append( [] )
+
+    for ss, ee, index in intervals_from_mask( mask ):
+        if index < 0:
+            tiled[0].append( bx.seq.nib.NibFile( open( seq_db[ ref_src ] ) ).get( start+ss, ee-ss ) )
+            for row in tiled[1:]:
+                if missing_data: 
+                    row.append( "*" * ( ee - ss ) )
+                else: 
+                    row.append( "-" * ( ee - ss ) )
+        else:
+            slice_start = start + ss
+            slice_end = start + ee
+            block = blocks[index]
+            ref = block.get_component_by_src_start( ref_src )
+            sliced = block.slice_by_component( ref, slice_start, slice_end ) 
+            sliced = sliced.limit_to_species( sources )
+            sliced.remove_all_gap_columns()
+            for i, src in enumerate( sources ):
+                comp = sliced.get_component_by_src_start( src )
+                if comp:
+                    tiled[i].append( comp.text )
+                else:
+                    if missing_data: tiled[i].append( "*" * sliced.text_size )
+                    else: tiled[i].append( "-" * sliced.text_size )
+        
+    a = align.Alignment()
+    for i, name in enumerate( sources ):
+        text = "".join( tiled[i] )
+        size = len( text ) - text.count( "-" )
+        if i == 0:
+            if ref_src_size is None: ref_src_size = bx.seq.nib.NibFile( open( seq_db[ ref_src ] ) ).length
+            c = align.Component( ref_src, start, end-start, "+", ref_src_size, text )
+        else:
+            c = align.Component( name + ".fake", 0, size, "?", size, text )
+        a.add_component( c )
+
+    out.write( a )
+
+
+def intervals_from_mask( mask ):
+    start = 0
+    last = mask[0]
+    for i in range( 1, len( mask ) ):
+        if mask[i] != last:
+            yield start, i, last
+            start = i
+            last = mask[i]
+    yield start, len(mask), last
+
+main()
diff --git a/scripts/maf_tile_2.py b/scripts/maf_tile_2.py
new file mode 100755
index 0000000..c40f31f
--- /dev/null
+++ b/scripts/maf_tile_2.py
@@ -0,0 +1,274 @@
+#!/usr/bin/env python
+
+"""
+'Tile' the blocks of a maf file over each of a set of intervals. The
+highest scoring block that covers any part of a region will be used, and 
+pieces not covered by any block filled with "-" or optionally "*". 
+
+This version uses synteny annotation if found on the alignment blocks, and
+will attempt to fill gaps with special characters depending on the type of
+gap, similar to the projected alignment display of the UCSC genome browser: 
+'*' for new, '=' for inverse/inset, '#' for contig, 'X' for missing. 
+
+- The list of species to tile is specified by the first argument (either a 
+  newick tree or just a comma separated list). 
+  
+- The `seq_db` is a lookup table mapping species and chromosome names
+  to nib file for filling in the reference species sequence. In this file
+  column 1 contains the species, column 2 the chromomsome or contig, and
+  column 4 the directory containing the sequences in nib format.
+  
+- The remaining arguments are a list of maf files which must have 
+  corresponding ".index" files.
+
+TODO: The seq_db format is specific to something old and obsure at PSU, 
+      need to standardize.
+
+usage: %prog list,of,species,to,keep seq_db_file indexed_maf_files ...
+    -m, --missingData: Inserts wildcards for missing block rows instead of '-'
+    -s, --strand:      Use strand information for intervals, reveres complement if '-'
+"""
+
+import psyco_full
+
+from cookbook import doc_optparse
+
+import operator
+
+import bx.align.maf as maf
+import bx.align as align
+from bx import misc
+import bx.seq.nib
+import os
+import string
+import sys
+
+tree_tx = string.maketrans( "(),", "   " )
+
+def main():
+
+    options, args = doc_optparse.parse( __doc__ )
+    try:
+        sources = args[0].translate( tree_tx ).split()
+        seq_db = load_seq_db( args[1] )
+        index = maf.MultiIndexed( args[2:] )
+
+        out = maf.Writer( sys.stdout )
+        missing_data = bool(options.missingData)
+        use_strand = bool(options.strand)
+    except:
+        doc_optparse.exception()
+
+    for line in sys.stdin:
+        fields = line.split()
+        ref_src, start, end = fields[0:3]
+        if use_strand and len( fields ) > 5:
+            strand = fields[5]
+        else:
+            strand = '+'
+        do_interval( sources, index, out, ref_src, int( start ), int( end ), seq_db, missing_data, strand )
+
+    out.close()
+
+def load_seq_db( fname ):
+    db = {}
+    for line in open( fname ):
+        fields = line.split(',')
+        src = fields[1] + "." + fields[2]
+        seq = fields[4]
+        db[src]=seq.strip()
+    return db
+    
+def get_fill_char( maf_status ):
+    """
+    Return the character that should be used to fill between blocks
+    having a given status
+    """
+    ## assert maf_status not in ( maf.MAF_CONTIG_NESTED_STATUS, maf.MAF_NEW_NESTED_STATUS, 
+    ##                            maf.MAF_MAYBE_NEW_NESTED_STATUS ), \
+    ##     "Nested rows do not make sense in a single coverage MAF (or do they?)"
+    if maf_status in ( maf.MAF_NEW_STATUS, maf.MAF_MAYBE_NEW_STATUS, 
+                       maf.MAF_NEW_NESTED_STATUS, maf.MAF_MAYBE_NEW_NESTED_STATUS ):
+        return "*"
+    elif maf_status in ( maf.MAF_INVERSE_STATUS, maf.MAF_INSERT_STATUS ):
+        return "="
+    elif maf_status in ( maf.MAF_CONTIG_STATUS, maf.MAF_CONTIG_NESTED_STATUS ):
+        return "#"
+    elif maf_status == maf.MAF_MISSING_STATUS:
+        return "X"
+    else:
+        raise ValueError("Unknwon maf status")
+
+def guess_fill_char( left_comp, right_comp ):
+    """
+    For the case where there is no annotated synteny we will try to guess it
+    """
+    # No left component, obiously new
+    return "*"
+    # First check that the blocks have the same src (not just species) and 
+    # orientation
+    if ( left_comp.src == right_comp.src and left_comp.strand != right_comp.strand ): 
+        # Are they completely contiguous? Easy to call that a gap
+        if left_comp.end == right_comp.start: 
+            return "-"
+        # TODO: should be able to make some guesses about short insertions
+        # here
+    # All other cases we have no clue about
+    return "*" 
+        
+def remove_all_gap_columns( texts ):
+    """
+    Remove any columns containing only gaps from alignment texts
+    """
+    seqs = [ list( t ) for t in texts ]
+    i = 0
+    text_size = len( texts[0] )
+    while i < text_size:
+        all_gap = True
+        for seq in seqs:
+            if seq[i] not in ( '-', '#', '*', '=', 'X', '@' ): 
+                all_gap = False
+        if all_gap:
+            for seq in seqs: 
+                del seq[i]
+            text_size -= 1
+        else:
+            i += 1
+    return [ ''.join( s ) for s in seqs ]
+
+def do_interval( sources, index, out, ref_src, start, end, seq_db, missing_data, strand ):
+    """
+    Join together alignment blocks to create a semi human projected local 
+    alignment (small reference sequence deletions are kept as supported by 
+    the local alignment).
+    """
+    ref_src_size = None
+    # Make sure the reference component is also the first in the source list
+    assert sources[0].split('.')[0] == ref_src.split('.')[0], "%s != %s" \
+        % ( sources[0].split('.')[0], ref_src.split('.')[0] )
+    # Determine the overall length of the interval
+    base_len = end - start
+    # Counter for the last reference species base we have processed
+    last_stop = start
+    # Rows in maf blocks come in in arbitrary order, we'll convert things
+    # to the destred order of the tiled block
+    source_to_index = dict( ( name, i ) for ( i, name ) in enumerate( sources ) )
+    # This gets all the maf blocks overlapping our interval of interest
+    # NOTE: Unlike maf_tile we're expecting 
+    # things to be single coverage in the reference species, so we won't 
+    # sort by score and lay down.
+    blocks = index.get( ref_src, start, end )
+    # The last component seen for each species onto which we are tiling
+    last_components = [ None ] * len( sources )
+    last_status = [ None ] * len( sources )
+    cols_needing_fill = [ 0 ] * len( sources )
+    # The list of strings in which we build up the tiled alignment
+    tiled_rows = [ "" for i in range( len( sources ) ) ]
+    # Enumerate the (ordered) list of blocks
+    for i, block in enumerate( blocks ):
+        # Check for overlap in reference species
+        ref = block.get_component_by_src_start( ref_src )
+        if ref.start < last_stop:
+            if ref.end < last_stop: 
+                continue
+            block = block.slice_by_component( ref, last_stop, min( end, ref.end ) )
+            ref = block.get_component_by_src_start( ref_src )
+        block = block.slice_by_component( ref, max( start, ref.start ), min( end, ref.end ) )
+        ref = block.get_component_by_src_start( ref_src )
+        # print block
+        assert last_components[0] is None or ref.start >= last_components[0].end, \
+            "MAF must be sorted and single coverage in reference species!"
+        assert ref.strand == "+", \
+            "MAF must have all reference species blocks on the plus strand"
+        # Store the size of the reference sequence for building fake block   
+        if ref_src_size is None:
+            ref_src_size = ref.src_size
+        # Handle the reference component seperately, it has no synteny status
+        # but we will try to fill in missing sequence
+        if ref.start > last_stop:
+            # Need to fill in some reference sequence
+            chunk_len = ref.start - last_stop
+            text = bx.seq.nib.NibFile( open( seq_db[ ref_src ] ) ).get( last_stop, chunk_len ) 
+            tiled_rows[0] += text
+            for source in sources[1:]:
+                cols_needing_fill[ source_to_index[ source ] ] += chunk_len
+        # Do reference component
+        chunk_len = len( ref.text )
+        tiled_rows[0] += ref.text
+        # Do each other component
+        for source in sources[1:]:
+            source_index = source_to_index[ source ]
+            comp = block.get_component_by_src_start( source )
+            if comp:
+                if comp.synteny_left is None:
+                    left_status, left_length = None, -1
+                else:
+                    left_status, left_length = comp.synteny_left
+                if comp.synteny_right is None:
+                    right_status, right_length = None, -1
+                else:
+                    right_status, right_length = comp.synteny_right
+                # We have a component, do we need to do some filling?
+                cols_to_fill = cols_needing_fill[ source_index ]
+                if cols_to_fill > 0:
+                    # Adjacent components should have matching status
+                    ## assert last_status[ source_index ] is None or last_status[ source_index ] == left_status, \
+                    ##     "left status (%s) does not match right status (%s) of last component for %s" \
+                    ##         % ( left_status, last_status[ source_index ], source )
+                    if left_status is None:
+                        fill_char = guess_fill_char( last_components[source_index], comp )
+                    else:
+                        fill_char = get_fill_char( left_status )
+                    tiled_rows[ source_index ] += ( fill_char * cols_to_fill )
+                    cols_needing_fill[ source_index ] = 0
+                # Okay, filled up to current position, now append the text
+                tiled_rows[ source_index ] += comp.text
+                assert len( tiled_rows[ source_index ] ) == len( tiled_rows[ 0 ] ), \
+                    "length of tiled row should match reference row"
+                last_components[ source_index ] = comp
+                last_status[ source_index ] = right_status
+            else:
+                # No component, we'll have to fill this region when we know
+                # the status
+                cols_needing_fill[ source_index ] += chunk_len
+        last_stop = ref.end
+    # No more components, clean up the ends
+    if last_stop < end:
+        # Need to fill in some reference sequence
+        chunk_len = end - last_stop
+        tiled_rows[0] += bx.seq.nib.NibFile( open( seq_db[ ref_src ] ) ).get( last_stop, chunk_len ) 
+        for source in sources[1:]:
+            cols_needing_fill[ source_to_index[ source ] ] += chunk_len
+    # Any final filling that needs to be done?
+    for source in sources[1:]:
+        source_index = source_to_index[ source ]
+        fill_needed = cols_needing_fill[ source_index ]
+        if fill_needed > 0:
+            if last_components[ source_index ] is None:
+                # print >>sys.stderr, "Never saw any components for %s, filling with @" % source
+                fill_char = '@'
+            else:
+                if last_status[ source_index ] is None:
+                    fill_char = '*'
+                else:
+                    fill_char = get_fill_char( last_status[ source_index ] )
+            tiled_rows[ source_index ] += fill_char * fill_needed
+        assert len( tiled_rows[ source_index ] ) == len( tiled_rows[ 0 ] ), \
+            "length of tiled row should match reference row"
+    # Okay, now make up the fake alignment from the tiled rows.
+    tiled_rows = remove_all_gap_columns( tiled_rows )
+    a = align.Alignment()
+    for i, name in enumerate( sources ):
+        text = "".join( tiled_rows[i] )
+        size = len( text ) - text.count( "-" )
+        if i == 0:
+            if ref_src_size is None: ref_src_size = bx.seq.nib.NibFile( open( seq_db[ ref_src ] ) ).length
+            c = align.Component( ref_src, start, end-start, "+", ref_src_size, text )
+        else:
+            c = align.Component( name + ".fake", 0, size, "?", size, text )
+        a.add_component( c )
+    if strand == '-':
+        a = a.reverse_complement()
+    out.write( a )
+    
+main()
diff --git a/scripts/maf_tile_2bit.py b/scripts/maf_tile_2bit.py
new file mode 100755
index 0000000..615978e
--- /dev/null
+++ b/scripts/maf_tile_2bit.py
@@ -0,0 +1,268 @@
+#!/usr/bin/env python
+
+"""
+'Tile' the blocks of a maf file over each of a set of intervals. The
+highest scoring block that covers any part of a region will be used, and 
+pieces not covered by any block filled with "-" or optionally "*". 
+
+This version uses synteny annotation if found on the alignment blocks, and
+will attempt to fill gaps with special characters depending on the type of
+gap, similar to the projected alignment display of the UCSC genome browser: 
+'*' for new, '=' for inverse/inset, '#' for contig, 'X' for missing. 
+
+- The list of species to tile is specified by the first argument (either a 
+  newick tree or just a comma separated list). 
+  
+- a 2bit file is expected for the reference species to fill in missing
+  sequence
+
+- The remaining arguments are a list of maf files which must have 
+  corresponding ".index" files.
+
+TODO: The seq_db format is specific to something old and obsure at PSU, 
+      need to standardize.
+
+usage: %prog list,of,species,to,keep ref.2bit indexed_maf_files ...
+    -m, --missingData: Inserts wildcards for missing block rows instead of '-'
+    -s, --strand:      Use strand information for intervals, reveres complement if '-'
+"""
+
+import psyco_full
+
+from bx.cookbook import doc_optparse
+
+import operator
+
+import bx.align.maf as maf
+import bx.align as align
+import bx.seq.twobit
+from bx import misc
+import bx.seq.nib
+import os
+import string
+import sys
+
+tree_tx = string.maketrans( "(),", "   " )
+
+def main():
+
+    options, args = doc_optparse.parse( __doc__ )
+    try:
+        sources = args[0].translate( tree_tx ).split()
+        ref_2bit = bx.seq.twobit.TwoBitFile( open( args[1] ) )
+        index = maf.MultiIndexed( args[2:] )
+
+        out = maf.Writer( sys.stdout )
+        missing_data = bool(options.missingData)
+        use_strand = bool(options.strand)
+    except:
+        doc_optparse.exception()
+
+    for line in sys.stdin:
+        fields = line.split()
+        ref_src, start, end = fields[0:3]
+        if use_strand and len( fields ) > 5:
+            strand = fields[5]
+        else:
+            strand = '+'
+        do_interval( sources, index, out, ref_src, int( start ), int( end ), ref_2bit, missing_data, strand )
+
+    out.close()
+
+def get_fill_char( maf_status ):
+    """
+    Return the character that should be used to fill between blocks
+    having a given status
+    """
+    ## assert maf_status not in ( maf.MAF_CONTIG_NESTED_STATUS, maf.MAF_NEW_NESTED_STATUS, 
+    ##                            maf.MAF_MAYBE_NEW_NESTED_STATUS ), \
+    ##     "Nested rows do not make sense in a single coverage MAF (or do they?)"
+    if maf_status in ( maf.MAF_NEW_STATUS, maf.MAF_MAYBE_NEW_STATUS, 
+                       maf.MAF_NEW_NESTED_STATUS, maf.MAF_MAYBE_NEW_NESTED_STATUS ):
+        return "*"
+    elif maf_status in ( maf.MAF_INVERSE_STATUS, maf.MAF_INSERT_STATUS ):
+        return "="
+    elif maf_status in ( maf.MAF_CONTIG_STATUS, maf.MAF_CONTIG_NESTED_STATUS ):
+        return "#"
+    elif maf_status == maf.MAF_MISSING_STATUS:
+        return "X"
+    else:
+        raise ValueError("Unknwon maf status")
+
+def guess_fill_char( left_comp, right_comp ):
+    """
+    For the case where there is no annotated synteny we will try to guess it
+    """
+    # No left component, obiously new
+    return "*"
+    # First check that the blocks have the same src (not just species) and 
+    # orientation
+    if ( left_comp.src == right_comp.src and left_comp.strand != right_comp.strand ): 
+        # Are they completely contiguous? Easy to call that a gap
+        if left_comp.end == right_comp.start: 
+            return "-"
+        # TODO: should be able to make some guesses about short insertions
+        # here
+    # All other cases we have no clue about
+    return "*" 
+        
+def remove_all_gap_columns( texts ):
+    """
+    Remove any columns containing only gaps from alignment texts
+    """
+    seqs = [ list( t ) for t in texts ]
+    i = 0
+    text_size = len( texts[0] )
+    while i < text_size:
+        all_gap = True
+        for seq in seqs:
+            if seq[i] not in ( '-', '#', '*', '=', 'X', '@' ): 
+                all_gap = False
+        if all_gap:
+            for seq in seqs: 
+                del seq[i]
+            text_size -= 1
+        else:
+            i += 1
+    return [ ''.join( s ) for s in seqs ]
+
+def do_interval( sources, index, out, ref_src, start, end, ref_2bit, missing_data, strand ):
+    """
+    Join together alignment blocks to create a semi human projected local 
+    alignment (small reference sequence deletions are kept as supported by 
+    the local alignment).
+    """
+    ref_src_size = None
+    # Make sure the reference component is also the first in the source list
+    assert sources[0].split('.')[0] == ref_src.split('.')[0], "%s != %s" \
+        % ( sources[0].split('.')[0], ref_src.split('.')[0] )
+    # Extract non-species part from ref_src for grabbing sequence
+    ref_chr = ref_src
+    if "." in ref_src:
+        ref_chr = ref_src[ref_src.index(".")+1:]
+    # Determine the overall length of the interval
+    base_len = end - start
+    # Counter for the last reference species base we have processed
+    last_stop = start
+    # Rows in maf blocks come in in arbitrary order, we'll convert things
+    # to the destred order of the tiled block
+    source_to_index = dict( ( name, i ) for ( i, name ) in enumerate( sources ) )
+    # This gets all the maf blocks overlapping our interval of interest
+    # NOTE: Unlike maf_tile we're expecting 
+    # things to be single coverage in the reference species, so we won't 
+    # sort by score and lay down.
+    blocks = index.get( ref_src, start, end )
+    # The last component seen for each species onto which we are tiling
+    last_components = [ None ] * len( sources )
+    last_status = [ None ] * len( sources )
+    cols_needing_fill = [ 0 ] * len( sources )
+    # The list of strings in which we build up the tiled alignment
+    tiled_rows = [ "" for i in range( len( sources ) ) ]
+    # Enumerate the (ordered) list of blocks
+    for i, block in enumerate( blocks ):
+        # Check for overlap in reference species
+        ref = block.get_component_by_src_start( ref_src )
+        if ref.start < last_stop:
+            if ref.end < last_stop: 
+                continue
+            block = block.slice_by_component( ref, last_stop, min( end, ref.end ) )
+            ref = block.get_component_by_src_start( ref_src )
+        block = block.slice_by_component( ref, max( start, ref.start ), min( end, ref.end ) )
+        ref = block.get_component_by_src_start( ref_src )
+        # print block
+        assert last_components[0] is None or ref.start >= last_components[0].end, \
+            "MAF must be sorted and single coverage in reference species!"
+        assert ref.strand == "+", \
+            "MAF must have all reference species blocks on the plus strand"
+        # Store the size of the reference sequence for building fake block   
+        if ref_src_size is None:
+            ref_src_size = ref.src_size
+        # Handle the reference component seperately, it has no synteny status
+        # but we will try to fill in missing sequence
+        if ref.start > last_stop:
+            # Need to fill in some reference sequence
+            chunk_len = ref.start - last_stop
+            text = ref_2bit[ ref_chr ].get( last_stop, last_stop + chunk_len ) 
+            tiled_rows[0] += text
+            for source in sources[1:]:
+                cols_needing_fill[ source_to_index[ source ] ] += chunk_len
+        # Do reference component
+        chunk_len = len( ref.text )
+        tiled_rows[0] += ref.text
+        # Do each other component
+        for source in sources[1:]:
+            source_index = source_to_index[ source ]
+            comp = block.get_component_by_src_start( source )
+            if comp:
+                if comp.synteny_left is None:
+                    left_status, left_length = None, -1
+                else:
+                    left_status, left_length = comp.synteny_left
+                if comp.synteny_right is None:
+                    right_status, right_length = None, -1
+                else:
+                    right_status, right_length = comp.synteny_right
+                # We have a component, do we need to do some filling?
+                cols_to_fill = cols_needing_fill[ source_index ]
+                if cols_to_fill > 0:
+                    # Adjacent components should have matching status
+                    ## assert last_status[ source_index ] is None or last_status[ source_index ] == left_status, \
+                    ##     "left status (%s) does not match right status (%s) of last component for %s" \
+                    ##         % ( left_status, last_status[ source_index ], source )
+                    if left_status is None:
+                        fill_char = guess_fill_char( last_components[source_index], comp )
+                    else:
+                        fill_char = get_fill_char( left_status )
+                    tiled_rows[ source_index ] += ( fill_char * cols_to_fill )
+                    cols_needing_fill[ source_index ] = 0
+                # Okay, filled up to current position, now append the text
+                tiled_rows[ source_index ] += comp.text
+                assert len( tiled_rows[ source_index ] ) == len( tiled_rows[ 0 ] ), \
+                    "length of tiled row should match reference row"
+                last_components[ source_index ] = comp
+                last_status[ source_index ] = right_status
+            else:
+                # No component, we'll have to fill this region when we know
+                # the status
+                cols_needing_fill[ source_index ] += chunk_len
+        last_stop = ref.end
+    # No more components, clean up the ends
+    if last_stop < end:
+        # Need to fill in some reference sequence
+        chunk_len = end - last_stop
+        tiled_rows[0] += ref_2bit[ ref_chr ].get( last_stop, last_stop + chunk_len ) 
+        for source in sources[1:]:
+            cols_needing_fill[ source_to_index[ source ] ] += chunk_len
+    # Any final filling that needs to be done?
+    for source in sources[1:]:
+        source_index = source_to_index[ source ]
+        fill_needed = cols_needing_fill[ source_index ]
+        if fill_needed > 0:
+            if last_components[ source_index ] is None:
+                # print >>sys.stderr, "Never saw any components for %s, filling with @" % source
+                fill_char = '@'
+            else:
+                if last_status[ source_index ] is None:
+                    fill_char = '*'
+                else:
+                    fill_char = get_fill_char( last_status[ source_index ] )
+            tiled_rows[ source_index ] += fill_char * fill_needed
+        assert len( tiled_rows[ source_index ] ) == len( tiled_rows[ 0 ] ), \
+            "length of tiled row should match reference row"
+    # Okay, now make up the fake alignment from the tiled rows.
+    tiled_rows = remove_all_gap_columns( tiled_rows )
+    a = align.Alignment()
+    for i, name in enumerate( sources ):
+        text = "".join( tiled_rows[i] )
+        size = len( text ) - text.count( "-" )
+        if i == 0:
+            if ref_src_size is None: ref_src_size = ref_2bit[ ref_chr ].length
+            c = align.Component( ref_src, start, end-start, "+", ref_src_size, text )
+        else:
+            c = align.Component( name + ".fake", 0, size, "?", size, text )
+        a.add_component( c )
+    if strand == '-':
+        a = a.reverse_complement()
+    out.write( a )
+    
+main()
diff --git a/scripts/maf_to_axt.py b/scripts/maf_to_axt.py
new file mode 100755
index 0000000..3c5aa3d
--- /dev/null
+++ b/scripts/maf_to_axt.py
@@ -0,0 +1,110 @@
+#!/usr/bin/env python
+"""
+Application to convert MAF file to AXT file, projecting to any two species. 
+Reads a MAF file from standard input and writes an AXT file to standard out;  
+some statistics are written to standard error.  The user must specify the 
+two species of interest.
+
+usage: %prog primary_species secondary_species < maf_file > axt_file
+"""
+
+__author__ = "Bob Harris (rsharris at bx.psu.edu)"
+
+import sys
+import copy
+import bx.align.maf
+import bx.align.axt
+
+def usage(s=None):
+	message = """
+maf_to_axt primary_species secondary_species < maf_file > axt_file
+"""
+	if (s == None): sys.exit (message)
+	else:           sys.exit ("%s\n%s" % (s,message))
+
+
+def main():
+
+	# parse the command line
+
+	primary   = None
+	secondary = None
+
+	args = sys.argv[1:]
+	while (len(args) > 0):
+		arg = args.pop(0)
+		val = None
+		fields = arg.split("=",1)
+		if (len(fields) == 2):
+			arg = fields[0]
+			val = fields[1]
+			if (val == ""):
+				usage("missing a value in %s=" % arg)
+
+		if (primary == None) and (val == None):
+			primary = arg
+		elif (secondary == None) and (val == None):
+			secondary = arg
+		else:
+			usage("unknown argument: %s" % arg)
+
+	if (primary == None):
+		usage("missing primary species")
+
+	if (secondary == None):
+		usage("missing secondary species")
+
+	# read the alignments and other info
+
+	out = bx.align.axt.Writer(sys.stdout)
+
+	axtsRead = 0
+	mafsWritten = 0
+	for mafBlock in bx.align.maf.Reader(sys.stdin):
+		axtsRead += 1
+
+		p = mafBlock.get_component_by_src_start(primary)
+		if (p == None): continue
+		s = mafBlock.get_component_by_src_start(secondary)
+		if (s == None): continue
+
+		axtBlock = bx.align.Alignment (mafBlock.score, mafBlock.attributes)
+		axtBlock.add_component (clone_component(p))
+		axtBlock.add_component (clone_component(s))
+
+		remove_mutual_gaps (axtBlock)
+		if (axtBlock.text_size == 0):
+			continue
+
+		out.write (axtBlock)
+		mafsWritten += 1
+
+	sys.stderr.write ("%d blocks read, %d written\n" % (axtsRead,mafsWritten))
+
+
+def clone_component(c):
+	return bx.align.Component (c.src, c.start, c.size, c.strand, c.src_size, \
+	                           copy.copy(c.text))
+
+
+def remove_mutual_gaps (block):
+
+	if (len(block.components) == 0): return
+
+	nonGaps = []
+
+	for c in block.components:
+		for ix in range(0,block.text_size):
+			if (ix not in nonGaps) and (c.text[ix] != "-"):
+				nonGaps.append(ix)
+
+	nonGaps.sort()
+
+	for c in block.components:
+		c.text = "".join([c.text[ix] for ix in nonGaps])
+
+	block.text_size = len(nonGaps)
+
+
+if __name__ == "__main__": main()
+
diff --git a/scripts/maf_to_concat_fasta.py b/scripts/maf_to_concat_fasta.py
new file mode 100755
index 0000000..d60f3ab
--- /dev/null
+++ b/scripts/maf_to_concat_fasta.py
@@ -0,0 +1,61 @@
+#!/usr/bin/env python
+
+"""
+Read a maf and print the text as a fasta file, concatenating blocks. A 
+specific subset of species can be chosen. 
+
+usage %prog [options] species1,species2,... < maf_file > fasta_file
+    --fill="expression": Insert this between blocks
+    --wrap=columns: Wrap FASTA to this many columns
+"""
+
+from optparse import OptionParser
+
+import textwrap
+import sys
+from bx.align import maf
+
+def __main__():
+    # Parse command line arguments
+
+    parser = OptionParser()
+    parser.add_option( "--fill", action="store", default=None, type="string", help="" )
+    parser.add_option( "--wrap", action="store", default=None, type="int", help="" )
+    parser.add_option( "--nowrap", action="store_true", default=False, dest="nowrap", help="" )
+
+    ( options, args ) = parser.parse_args()
+
+    species = []
+    for arg in args: species.extend(arg.split(','))
+
+    fill = ""
+    if options.fill: fill = eval( options.fill )
+
+    wrap = 50
+    if   (options.wrap != None): wrap = options.wrap
+    elif (options.nowrap):       wrap = 0
+
+    # create the concatenated sequences
+
+    texts = {}
+    for s in species: texts[s] = []
+    maf_reader = maf.Reader( sys.stdin )
+    for m in maf_reader:
+        for s in species:
+            c = m.get_component_by_src_start( s ) 
+            if c: texts[s].append( c.text )
+            else: texts[s].append( "-" * m.text_size )
+    for s in species:
+        print ">" + s
+        print_n( fill.join( texts[s] ), wrap )
+
+def print_n( s, n, f = sys.stdout ):
+    if (n <= 0):
+        print >> f, s
+    else:
+        p = 0
+        while p < len( s ):
+            print >> f, s[p:min(p+n,len(s))]
+            p += n
+
+if __name__ == "__main__": __main__()
diff --git a/scripts/maf_to_fasta.py b/scripts/maf_to_fasta.py
new file mode 100755
index 0000000..86b60fe
--- /dev/null
+++ b/scripts/maf_to_fasta.py
@@ -0,0 +1,42 @@
+#!/usr/bin/env python.
+
+"""
+Read a maf and print the text as a fasta file.
+
+usage: %prog < maf > fasta
+"""
+
+from __future__ import division
+
+import textwrap
+import sys
+from bx.align import maf
+
+def __main__():
+
+    maf_reader = maf.Reader( sys.stdin )
+
+    # Confusing since maf_to_concat_fasta takes names.
+
+    # if len( sys.argv ) > 1:
+    #     comps = map( int, sys.argv[1:] )
+    # else:
+    #     comps = None    
+
+    comps = None
+
+    for i, m in enumerate( maf_reader ):
+        if comps: l = [ m.components[i] for i in comps ]
+        else: l = m.components
+        for c in l:
+            print ">%s:%d-%d" % ( c.src, c.start, c.end )
+            print c.text
+            #print_n( c.text, 50 )
+
+def print_n( s, n, f = sys.stdout ):
+    p = 0
+    while p < len( s ):
+        print >> f, s[p:min(p+n,len(s))]
+        p += n
+
+if __name__ == "__main__": __main__()
diff --git a/scripts/maf_to_int_seqs.py b/scripts/maf_to_int_seqs.py
new file mode 100755
index 0000000..dbe45aa
--- /dev/null
+++ b/scripts/maf_to_int_seqs.py
@@ -0,0 +1,40 @@
+#!/usr/bin/env python
+
+"""
+For each block in a maf file (read from stdin) write a sequence of ints 
+corresponding to the columns of the block after applying the provided sequence
+mapping.
+
+The 'correct' number of species is determined by the mapping file, blocks not having
+this number of species will be ignored.
+
+usage: %prog mapping_file
+"""
+
+from __future__ import division
+
+import psyco_full
+
+import bx.align.maf
+from bx import seqmapping
+import string
+import sys
+
+def main():
+
+    if len( sys.argv ) > 1:
+        _, alpha_map = seqmapping.alignment_mapping_from_file( file( sys.argv[1] ) )
+    else:
+        alpha_map = None
+
+    for maf in bx.align.maf.Reader( sys.stdin ):
+        # Translate alignment to ints
+        int_seq = seqmapping.DNA.translate_list( [ c.text for c in maf.components ] )
+        # Apply mapping 
+        if alpha_map:
+            int_seq = alpha_map.translate( int_seq )
+        # Write ints separated by spaces
+        for i in int_seq: print i,
+        print
+
+if __name__ == "__main__": main()
diff --git a/scripts/maf_translate_chars.py b/scripts/maf_translate_chars.py
new file mode 100755
index 0000000..7b70522
--- /dev/null
+++ b/scripts/maf_translate_chars.py
@@ -0,0 +1,39 @@
+#!/usr/bin/env python
+
+"""
+Translate a maf file containing gap ambiguity characters as produced by 
+'maf_tile_2.py' to a new file in which "#" (contiguous) is replaced by "-" and
+all other types are replaces by "*".
+
+TODO: This could be much more general, should just take the translation table
+      from the command line.
+      
+usage: %prog < maf > maf
+"""
+
+from __future__ import division
+
+import psyco_full
+
+import sys
+
+import sys
+from bx.align import maf
+import string
+
+table = string.maketrans( "#=X@", "-***")
+
+def main():
+
+    maf_reader = maf.Reader( sys.stdin )
+    maf_writer = maf.Writer( sys.stdout )
+
+    for m in maf_reader:
+        for c in m.components:
+            c.text = c.text.translate( table )
+        maf_writer.write( m )    
+    
+    maf_writer.close()
+    
+if __name__ == "__main__": 
+    main()
diff --git a/scripts/maf_truncate.py b/scripts/maf_truncate.py
new file mode 100755
index 0000000..b1c5f80
--- /dev/null
+++ b/scripts/maf_truncate.py
@@ -0,0 +1,40 @@
+#!/usr/bin/env python
+
+"""
+Pass through blocks from a maf file until a certain number of columns
+have been passed.
+
+usage: %prog -c cols < maf > maf
+"""
+
+import sys
+
+from bx.align import maf
+from optparse import OptionParser
+
+def __main__():
+
+    # Parse command line arguments
+
+    parser = OptionParser()
+    parser.add_option( "-c", "--cols",  action="store" )
+
+    ( options, args ) = parser.parse_args()
+
+    maf_reader = maf.Reader( sys.stdin )
+    maf_writer = maf.Writer( sys.stdout )
+
+    if not options.cols: raise Exception("Cols argument is required")
+    cols = int( options.cols )
+
+    count = 0
+
+    for m in maf_reader:
+
+        maf_writer.write( m )
+
+        count += m.text_size
+
+        if count >= cols: return        
+
+if __name__ == "__main__": __main__()
diff --git a/scripts/maf_word_frequency.py b/scripts/maf_word_frequency.py
new file mode 100755
index 0000000..94f6ad7
--- /dev/null
+++ b/scripts/maf_word_frequency.py
@@ -0,0 +1,47 @@
+#!/usr/bin/env python2.3
+
+"""
+Read a MAF and print counts and frequencies of all n-mers
+(words composed on n consecutive alignment columns)
+
+TODO: reconcile this and maf_mapping_word_frequency.py
+
+usage: %prog n < maf_file
+"""
+
+from __future__ import division
+
+import psyco; psyco.profile()
+
+from bx.cookbook import doc_optparse
+import string
+import sys
+
+from align import maf
+
+
+def __main__():
+
+    motif_len = int( sys.argv[1] )
+
+    big_map = {}
+    total = 0
+    
+    maf_reader = maf.Reader( sys.stdin )
+
+    for m in maf_reader:
+        texts = [ c.text.upper() for c in m.components ]
+        for i in range( m.text_size - motif_len ):
+            motif = string.join( [ text[ i : i + motif_len ] for text in texts ] )
+            if big_map.has_key( motif ): big_map[ motif ] += 1
+            else: big_map[ motif ] = 1
+            total += 1
+
+    items = zip( big_map.values(), big_map.keys() )
+    items.sort()
+    items.reverse()
+
+    for count, motif in items: 
+        print "%d\t%0.10f\t%s" % ( count, count / total, motif )
+
+if __name__ == "__main__": __main__()
diff --git a/scripts/mask_quality.py b/scripts/mask_quality.py
new file mode 100644
index 0000000..0856e47
--- /dev/null
+++ b/scripts/mask_quality.py
@@ -0,0 +1,98 @@
+#!/usr/bin/env python
+
+"""
+Masks an AXT or MAF file based on quality (from a binned_array) and
+outputs AXT or MAF.
+
+Binned array form of quality scores can be generated with `qv_to_bqv.py`.
+
+usage: %prog input output
+    -i, --input=N: Format of input (axt or maf)
+    -o, --output=N: Format of output (axt or maf)
+    -m, --mask=N: Character to use as mask character
+    -q, --quality=N: Min quality allowed
+    -t, --type=N: base_pair or nqs
+    -l, --list=N: colon seperated list of species,len_file[,qualityfile].
+"""
+
+import sys
+import bx.align.axt
+import bx.align.maf
+import bx.binned_array
+from bx.cookbook import doc_optparse
+import fileinput
+from bx.align.sitemask.quality import *
+
+def main():
+    
+    options, args = doc_optparse.parse( __doc__ )
+    try:
+        inputformat = options.input
+        outputformat = options.output
+        mask = options.mask
+        minqual = int(options.quality)
+        qtype = options.type
+        speciesAndLens = options.list
+        inputfile = args[0]
+        outputfile = args[1]
+    except:
+        doc_optparse.exception()
+
+    outstream = open( outputfile, "w" )
+    instream = open( inputfile, "r" )
+
+    qualfiles = {}
+
+    # read lens
+    specieslist = speciesAndLens.split(":")
+    species_to_lengths = {}
+    
+    for entry in specieslist:
+        fields = entry.split(",")
+        lenstream = fileinput.FileInput( fields[1] )
+        lendict = dict()
+        for line in lenstream:
+            region = line.split()
+            lendict[region[0]] = int(region[1])
+        species_to_lengths[fields[0]] = lendict
+        if len(fields) >= 3:
+            qualfiles[fields[0]] = fields[2]
+
+    specieslist = map( lambda(a): a.split(":")[0], specieslist )
+    
+    # open quality binned_arrays
+    reader = None
+    writer = None
+    
+    if inputformat == "axt":
+        # load axt
+        if len(specieslist) != 2:
+            print "AXT is pairwise only."
+            sys.exit()
+        reader = bx.align.axt.Reader(instream, species1=specieslist[0], \
+                                     species2=specieslist[1], \
+                                     species_to_lengths = species_to_lengths)
+    elif outputformat == "maf":
+        # load maf
+        reader = bx.align.maf.Reader(instream, species_to_lengths=species_to_lengths)
+
+    if outputformat == "axt":
+        # setup axt
+        if len(specieslist) != 2:
+            print "AXT is pairwise only."
+            sys.exit()
+        writer = bx.align.axt.Writer(outstream, attributes=reader.attributes)
+    elif outputformat == "maf":
+        # setup maf
+        writer = bx.align.maf.Writer(outstream, attributes=reader.attributes)
+
+    qualfilter = Simple( mask=mask, qualspecies = species_to_lengths, \
+                         qualfiles = qualfiles, minqual = minqual, cache=50 )
+
+    qualfilter.run( reader, writer.write )
+
+    print "For "+str(qualfilter.total)+" base pairs, "+str(qualfilter.masked)+" base pairs were masked."
+    print str(float(qualfilter.masked)/float(qualfilter.total) * 100)+"%"
+    
+if __name__ == "__main__":
+    main()
diff --git a/scripts/nib_chrom_intervals_to_fasta.py b/scripts/nib_chrom_intervals_to_fasta.py
new file mode 100755
index 0000000..875e343
--- /dev/null
+++ b/scripts/nib_chrom_intervals_to_fasta.py
@@ -0,0 +1,47 @@
+#!/usr/bin/env python
+
+"""
+Read a set of ranges and a nib file, print portions of nib overlapping
+those ranges to stdout
+
+TODO: General sequence handling would be nice, as well as merging with
+      'nib_intervals_to_fasta.py'.
+
+usage: %prog nib_dir < range_file
+"""
+
+from bx.cookbook import doc_optparse
+import bx.seq.nib
+import string
+import sys
+
+def __main__():
+
+    options, args = doc_optparse.parse( __doc__ )
+
+    try:
+        nib_dir = args[0] 
+    except:
+        doc_optparse.exit()
+
+    nibs = {}
+
+    for line in sys.stdin: 
+        fields = line.split()
+        chrom, start, end = fields[0], int( fields[1] ), int( fields[2] ) 
+        print ">", chrom, start, end 
+        if chrom in nibs:
+            nib = nibs[chrom]
+        else:
+            nibs[chrom] = nib = bx.seq.nib.NibFile( file( "%s/%s.nib" % ( nib_dir, chrom ) ) )
+        print_wrapped( nib.get( start, end - start ) )
+
+def print_wrapped( s ):
+    l = len( s )        
+    c = 0
+    while c < l:
+        b = min( c + 50, l )
+        print s[c:b]
+        c = b
+
+if __name__ == "__main__": __main__()
diff --git a/scripts/nib_intervals_to_fasta.py b/scripts/nib_intervals_to_fasta.py
new file mode 100755
index 0000000..9a8b801
--- /dev/null
+++ b/scripts/nib_intervals_to_fasta.py
@@ -0,0 +1,41 @@
+#!/usr/bin/env python
+
+"""
+Read a set of ranges and a nib file, print portions of nib overlapping
+those ranges to stdout
+
+usage: %prog range_file nib_file
+"""
+
+from bx.cookbook import doc_optparse
+import bx.seq.nib
+import string
+import sys
+
+def __main__():
+
+    options, args = doc_optparse.parse( __doc__ )
+
+    try:
+        range_file = file( args[0] )
+        nib_file = file( args[1] )
+    except:
+        doc_optparse.exit()
+
+    nib = bx.seq.nib.NibFile( nib_file )
+
+    for line in range_file: 
+        fields = line.split()
+        start, end = int( fields[0] ), int( fields[1] ) 
+        print ">", start, end 
+        print_wrapped( nib.get( start, end - start ) )
+
+def print_wrapped( s ):
+    l = len( s )        
+    c = 0
+    while c < l:
+        b = min( c + 50, l )
+        print s[c:b]
+        c = b
+
+if __name__ == "__main__": __main__()
diff --git a/scripts/nib_length.py b/scripts/nib_length.py
new file mode 100755
index 0000000..9e0b71f
--- /dev/null
+++ b/scripts/nib_length.py
@@ -0,0 +1,13 @@
+#!/usr/bin/env python
+
+"""
+Print the number of bases in a nib file.
+
+usage: %prog nib_file
+"""
+
+from bx.seq import nib as seq_nib
+import sys
+
+nib = seq_nib.NibFile( file( sys.argv[1] ) )
+print nib.length
diff --git a/scripts/one_field_per_line.py b/scripts/one_field_per_line.py
new file mode 100755
index 0000000..4df27d5
--- /dev/null
+++ b/scripts/one_field_per_line.py
@@ -0,0 +1,14 @@
+#!/usr/bin/env python
+
+"""
+Read a file from stdin, split each line and write fields one per line to 
+stdout.
+
+TODO: is this really that useful?
+"""
+
+import sys
+
+for line in sys.stdin:
+    for field in line.split():
+        print field
\ No newline at end of file
diff --git a/scripts/out_to_chain.py b/scripts/out_to_chain.py
new file mode 100755
index 0000000..a6bbd4c
--- /dev/null
+++ b/scripts/out_to_chain.py
@@ -0,0 +1,70 @@
+#!/usr/bin/env python
+
+from __future__ import with_statement
+
+import sys, os, logging, pdb
+from itertools import product, izip, imap
+from bx.align.epo import Chain, EPOitem
+from bx.cookbook import argparse
+import numpy as np
+
+logging.basicConfig(level=logging.INFO)
+log = logging.getLogger()
+
+def outFile(s):
+    if (s in ('-', 'stdout')) or (s is None):
+        return sys.stdout
+    return open(s, 'w')
+
+def loadChrSizes(path):
+    data = {}
+    with open(path) as fd:
+        for ch,s in imap(lambda l: l.split(), fd):
+            data[ch] = int(s)
+    return data
+
+def convert_action(trg_comp, qr_comp, ts, qs, opt):
+    for i, (a,b) in enumerate(product(trg_comp, qr_comp)):
+        try:
+            ch, S, T, Q = Chain._make_from_epo(a, b, ts, qs)
+            if np.sum(S) == 0:
+                log.info("insignificant genomic alignment block %s ..." % ch.id)
+                continue
+            new_id = "%si%d" % (ch.id, i)
+            print >>opt.output, str(ch._replace(id=new_id))
+            map(lambda tup: opt.output.write("%d %d %d\n" % tup), izip(S,T,Q))
+            print >>opt.output, "%d\n" % S[-1]
+        except KeyError:
+            log.warning("skipping chromosome/contig (%s, %s)" % (a.chrom, b.chrom))
+
+if __name__ == '__main__':
+    parser = argparse.ArgumentParser(description="""EPO alignments (.out) to .chain converter.""",
+            epilog="Olgert Denas (Taylor Lab)",
+            formatter_class=argparse.ArgumentDefaultsHelpFormatter)
+
+    parser.add_argument("input", help="File to process.")
+    parser.add_argument("--species", nargs=2, default=["homo_sapiens", "mus_musculus"],
+            help="Names of target and query species (respectively) in the alignment.")
+    parser.add_argument("--chrsizes", nargs=2, required=True,
+            help="Chromosome sizes for the given species.")
+    parser.add_argument("-o", '--output', metavar="FILE", default='stdout', type=outFile, help="Output file")
+
+    opt = parser.parse_args()
+
+    log.info("loading sizes ...")
+    tsizes = loadChrSizes(opt.chrsizes[0])
+    qsizes = loadChrSizes(opt.chrsizes[1])
+
+    log.info("loading alignments ...")
+    data = EPOitem._parse_epo(opt.input)
+
+    log.info("dumping ...")
+    for k in data:
+        components = data[k]
+        trg_comp = filter(lambda c: c.species == opt.species[0], components)
+        qr_comp = filter(lambda c: c.species == opt.species[1], components)
+
+        convert_action(trg_comp, qr_comp, tsizes, qsizes, opt)
+
+
+
diff --git a/scripts/prefix_lines.py b/scripts/prefix_lines.py
new file mode 100755
index 0000000..2a14dd3
--- /dev/null
+++ b/scripts/prefix_lines.py
@@ -0,0 +1,9 @@
+#!/usr/bin/env python
+
+"""
+Simple script to add a prefix to every line in a file.
+"""
+
+import sys
+
+for line in sys.stdin: print sys.argv[1] + line,
diff --git a/scripts/pretty_table.py b/scripts/pretty_table.py
new file mode 100755
index 0000000..c1c3c9d
--- /dev/null
+++ b/scripts/pretty_table.py
@@ -0,0 +1,44 @@
+#!/usr/bin/env python
+
+"""
+Read some whitespace separated data from stdin and pretty print it so that
+the columns line up.
+"""
+
+import sys
+
+def main():
+    pad = "\t"
+    align = None
+    if len( sys.argv ) > 1:
+        pad = " " * int( sys.argv[1] )
+    if len( sys.argv ) > 2:
+        align = sys.argv[2]
+    rows = [ line.split() for line in sys.stdin ]
+    print_tabular( rows, pad, align )
+
+def print_tabular( rows, pad, align=None ):
+    if len( rows ) == 0: return ""
+    lengths = [ len( col ) for col in rows[ 0 ] ]
+    for row in rows[1:]:
+        for i in range( 0, len( row ) ):
+            lengths[ i ] = max( lengths[ i ], len( row[ i ] ) )
+    rval = ""
+    #for i in range( len( rows[0] ) ):
+    #    if align and align[ i ] == "l":
+    #        rval += str( i ).ljust( lengths[ i ] )
+    #    else:
+    #        rval += str( i ).rjust( lengths[ i ] )
+    #    rval += pad 
+    #print rval   
+    for row in rows:
+        rval = ""
+        for i in range( 0, len( row ) ):
+            if align and align[ i ] == "l":
+                rval += row[ i ].ljust( lengths[ i ] )
+            else:
+                rval += row[ i ].rjust( lengths[ i ] )
+            rval += pad
+        print rval
+
+main()
diff --git a/scripts/qv_to_bqv.py b/scripts/qv_to_bqv.py
new file mode 100644
index 0000000..d8b6af0
--- /dev/null
+++ b/scripts/qv_to_bqv.py
@@ -0,0 +1,69 @@
+#!/usr/bin/env python
+
+"""
+Convert a qual (qv) file to several BinnedArray files for fast seek.
+This script takes approximately 4 seconds per 1 million base pairs.
+
+The input format is fasta style quality -- fasta headers followed by 
+whitespace separated integers.
+
+usage: %prog qual_file output_file
+"""
+
+import string
+import psyco_full
+import sys
+from binned_array import *
+from bx.cookbook import *
+import fileinput
+
+def main():
+    args = sys.argv[1:]
+    try:
+        qual_file = args[ 0 ]
+        output_file = args[ 1 ]
+    except:
+        print "usage: qual_file output_file"
+        sys.exit()
+
+    qual = fileinput.FileInput( qual_file )
+    outfile = None
+    outbin = None
+    base_count = 0
+    mega_count = 0
+
+    for line in qual:
+        line = line.rstrip("\r\n")
+        if line.startswith(">"):
+            # close old
+            if outbin and outfile:
+                print "\nFinished region " + region + " at " + str(base_count) + " base pairs."
+                outbin.finish()
+                outfile.close()
+            # start new file
+            region = line.lstrip(">")
+            outfname = output_file + "." + region + ".bqv"
+            print "Writing region " + region + " to file " + outfname
+            outfile = open( outfname , "wb")
+            outbin = BinnedArrayWriter(outfile, typecode='b', default=0)
+            base_count = 0
+            mega_count = 0
+        else:
+            if outfile and outbin:
+                nums = line.split()
+                for val in nums:
+                    outval = int(val)
+                    assert outval <= 255 and outval >= 0
+                    outbin.write(outval)
+                    base_count += 1
+                if (mega_count * 1000000) <= base_count:
+                    sys.stdout.write(str(mega_count)+" ")
+                    sys.stdout.flush()
+                    mega_count = base_count // 1000000 + 1
+    if outbin and outfile:
+        print "\nFinished region " + region + " at " + str(base_count) + " base pairs."
+        outbin.finish()
+        outfile.close()
+
+if __name__ == "__main__":
+    main()
diff --git a/scripts/random_lines.py b/scripts/random_lines.py
new file mode 100755
index 0000000..3f21374
--- /dev/null
+++ b/scripts/random_lines.py
@@ -0,0 +1,16 @@
+#!/usr/bin/env python
+
+"""
+Script to select random lines from a file. Reads entire file into
+memory!
+
+TODO: Replace this with a more elegant implementation.
+"""
+
+import sys
+import random
+
+ndesired = int( sys.argv[1] )
+
+for line in random.sample( sys.stdin.readlines(), ndesired ):
+    print line,
diff --git a/scripts/table_add_column.py b/scripts/table_add_column.py
new file mode 100755
index 0000000..5691215
--- /dev/null
+++ b/scripts/table_add_column.py
@@ -0,0 +1,46 @@
+#!/usr/bin/env python
+
+"""
+Tool for adding a column to a table. Expressions for the column are similar
+to those supported by table_filter.py
+
+usage: %prog expression colname < table 
+    -H, --header:    keep header in output
+    -C, --comments:  keep comments in output
+"""
+
+import psyco_full
+
+import sys
+
+import sys
+import bx.tabular.io
+from bx.cookbook import doc_optparse
+
+def __main__():
+
+    # Parse command line arguments
+    options, args = doc_optparse.parse( __doc__ )
+    try:
+        keep_header = bool( options.header )
+        keep_comments = bool( options.comments )
+        expr = args[0]
+        colname = args[1]
+    except:
+        doc_optparse.exception()
+
+    # Compile expression for SPEED
+    if expr: expr = compile( expr, '<expr arg>', 'eval' )
+
+    for element in bx.tabular.io.Reader( sys.stdin ):
+        if type( element ) is bx.tabular.io.Header:
+            if keep_header: 
+                print str( element ) + "\t" + colname
+        elif type( element ) is bx.tabular.io.Comment:
+            if keep_comments: 
+                print element
+        else:
+            val = eval( expr, dict( row=element ) )
+            print str( element ) + "\t" + str( val )
+
+if __name__ == "__main__": __main__()
diff --git a/scripts/table_filter.py b/scripts/table_filter.py
new file mode 100755
index 0000000..968f48d
--- /dev/null
+++ b/scripts/table_filter.py
@@ -0,0 +1,72 @@
+#!/usr/bin/env python
+
+"""
+Tool for filtering a tabular data file. Fields are separated by tabs, the 
+header line is denoted by a '#' in the first byte, comments are denoted by
+a '#' at the start of any subsequent line.
+
+Expressions can use column names as well as numbers. The -c options allows
+cutting, again using field name or numbers.
+
+usage: %prog expression < table 
+    -H, --header:       keep header in output
+    -C, --comments:     keep comments in output
+    --force-header:     assume the first line is a header even if it does not start with "#"
+    -c, --cols=1,2:     names or indexes of columns to keep
+"""
+
+import psyco_full
+
+import sys
+
+import sys
+import bx.tabular.io
+from bx.cookbook import doc_optparse
+
+def __main__():
+
+    # Parse command line arguments
+    options, args = doc_optparse.parse( __doc__ )
+    try:
+        keep_header = bool( options.header )
+        keep_comments = bool( options.comments )
+        cols = []
+        if options.cols:
+            for c in options.cols.split( ',' ):
+                try:
+                    v = int( c )
+                except:
+                    v = c
+                cols.append( c )
+        if len( args ) > 0:
+            expr = args[0]
+        else:
+            expr = None
+        if options.force_header:
+            force_header = bx.tabular.io.FIRST_LINE_IS_HEADER
+        else:
+            force_header = None
+    except:
+        doc_optparse.exception()
+
+    # Compile expression for SPEED
+    if expr: expr = compile( expr, '<expr arg>', 'eval' )
+
+    for element in bx.tabular.io.TableReader( sys.stdin, force_header=force_header ):
+        if type( element ) is bx.tabular.io.Header:
+            if keep_header: 
+                if cols:
+                    print "#" + "\t".join( element[c] for c in cols )
+                else:
+                    print element
+        elif type( element ) is bx.tabular.io.Comment:
+            if keep_comments: 
+                print element
+        else:
+            if expr is None or bool( eval( expr, dict( row=element ) ) ):
+                if cols:
+                    print "\t".join( [ element[c] for c in cols ] )
+                else:
+                    print element
+
+if __name__ == "__main__": __main__()
diff --git a/scripts/tfloc_summary.py b/scripts/tfloc_summary.py
new file mode 100755
index 0000000..c7fe80e
--- /dev/null
+++ b/scripts/tfloc_summary.py
@@ -0,0 +1,27 @@
+#!/usr/bin/env python2.3
+
+"""
+Read TFLOC output from stdin and write out a summary in which the nth line
+contains the number of sites found in the nth alignment of the input.
+
+TODO: This is very special case, should it be here?
+"""
+
+import sys
+
+counts = dict()
+
+max_index = -1
+
+for line in sys.stdin:
+    if line[0].isdigit():
+        current_index = int( line )
+        max_index = max( current_index, max_index )
+    elif line[0] == "'":
+        try: counts[ current_index ] += 1
+        except: counts[ current_index ] = 1
+    else:
+        raise ValueError("Invalid input line " + line)
+
+for i in range( max_index + 1 ):
+    print counts.get( i, 0 )
diff --git a/scripts/ucsc_gene_table_to_intervals.py b/scripts/ucsc_gene_table_to_intervals.py
new file mode 100755
index 0000000..c45c72a
--- /dev/null
+++ b/scripts/ucsc_gene_table_to_intervals.py
@@ -0,0 +1,76 @@
+#!/usr/bin/env python
+
+"""
+Read a table dump in the UCSC gene table format and print a tab separated
+list of intervals corresponding to requested features of each gene.
+
+usage: ucsc_gene_table_to_intervals.py [options] < gene_table.txt
+
+options:
+  -h, --help            show this help message and exit
+  -rREGION, --region=REGION
+                        Limit to region: one of coding, utr3, utr5, transcribed [default]
+  -e, --exons           Only print intervals overlapping an exon
+"""
+
+import optparse, string, sys
+
+def main():
+    # Parse command line    
+    parser = optparse.OptionParser( usage="%prog [options] < gene_table.txt" )
+    parser.add_option( "-r", "--region", dest="region", default="transcribed",
+                       help="Limit to region: one of coding, utr3, utr5, transcribed [default]" )
+    parser.add_option( "-e", "--exons",  action="store_true", dest="exons",
+                       help="Only print intervals overlapping an exon" )
+    parser.add_option( "-s", "--strand",  action="store_true", dest="strand",
+                       help="Print strand after interval" )
+    parser.add_option( "-b", "--nobin",  action="store_false", dest="discard_first_column", default=True,
+                       help="file doesn't contain a 'bin' column (use this for pre-hg18 files)" )
+    options, args = parser.parse_args()
+    assert options.region in ( 'coding', 'utr3', 'utr5', 'transcribed' ), "Invalid region argument"
+
+    # Read table from stdin and handle each gene
+    for line in sys.stdin:
+
+        # Parse fields from gene tabls
+        fields = line.split( '\t' )
+        if (options.discard_first_column): fields.pop(0)
+        chrom = fields[1]
+        strand = fields[2]
+        tx_start = int( fields[3] )
+        tx_end = int( fields[4] )
+        cds_start = int( fields[5] )
+        cds_end = int( fields[6] )
+
+        # Determine the subset of the transcribed region we are interested in
+        if options.region == 'utr3':
+            if strand == '-': region_start, region_end = tx_start, cds_start
+            else: region_start, region_end = cds_end, tx_end 
+        elif options.region == 'utr5':
+            if strand == '-': region_start, region_end = cds_end, tx_end
+            else: region_start, region_end = tx_start, cds_start
+        elif options.region == 'coding':
+            region_start, region_end = cds_start, cds_end
+        else:
+            region_start, region_end = tx_start, tx_end
+
+        # If only interested in exons, print the portion of each exon overlapping
+        # the region of interest, otherwise print the span of the region
+        if options.exons:
+            exon_starts = map( int, fields[8].rstrip( ',\n' ).split( ',' ) )
+            exon_ends = map( int, fields[9].rstrip( ',\n' ).split( ',' ) )
+            for start, end in zip( exon_starts, exon_ends ):
+                start = max( start, region_start )
+                end = min( end, region_end )
+                if start < end:
+                    if strand: print_tab_sep( chrom, start, end, strand )
+                    else: print_tab_sep( chrom, start, end )
+        else:
+            if strand: print_tab_sep( chrom, region_start, region_end, strand )
+            else: print_tab_sep( chrom, region_start, region_end )
+
+def print_tab_sep( *args ):
+    """Print items in `l` to stdout separated by tabs"""
+    print string.join( [ str( f ) for f in args ], '\t' )
+
+if __name__ == "__main__": main()
diff --git a/scripts/wiggle_to_array_tree.py b/scripts/wiggle_to_array_tree.py
new file mode 100755
index 0000000..3cb43b0
--- /dev/null
+++ b/scripts/wiggle_to_array_tree.py
@@ -0,0 +1,37 @@
+#!/usr/bin/env python
+
+"""
+Read data in UCSC wiggle format and write it to an "array tree" file.
+
+usage: %prog array_length output.array_tree < input.wig
+"""
+
+from __future__ import division
+
+import sys
+
+from bx.arrays.array_tree import *
+from bx.arrays.wiggle import WiggleReader
+
+def main():
+   
+    sizes_fname = sys.argv[1]
+    out_fname = sys.argv[2]
+    
+    sizes = {}
+    for line in open( sizes_fname ):
+        fields = line.split()
+        sizes[ fields[0] ] = int( fields[1] )
+    
+    # Fill array from wiggle
+    d = array_tree_dict_from_reader( WiggleReader( sys.stdin ), sizes )
+    
+    for value in d.itervalues():
+        value.root.build_summary()
+    
+    f = open( out_fname, "w" )
+    FileArrayTreeDict.dict_to_file( d, f )
+    f.close()
+
+if __name__ == "__main__": 
+    main()
diff --git a/scripts/wiggle_to_binned_array.py b/scripts/wiggle_to_binned_array.py
new file mode 100755
index 0000000..b9cf021
--- /dev/null
+++ b/scripts/wiggle_to_binned_array.py
@@ -0,0 +1,54 @@
+#!/usr/bin/env python
+
+"""
+Convert wiggle data to a binned array. This assumes the input data is on a
+single chromosome and does no sanity checks!
+
+usage: %prog score_file out_file < wiggle_data
+    -c, --comp=type: compression type (none, zlib, lzo)
+"""
+
+from __future__ import division
+
+import sys
+import psyco_full
+import bx.wiggle
+from bx.binned_array import BinnedArray
+from bx_extras.fpconst import isNaN
+from bx.cookbook import doc_optparse
+from bx import misc
+
+def main():
+    
+    # Parse command line
+    options, args = doc_optparse.parse( __doc__ )
+    try:
+        if options.comp:
+            comp_type = options.comp
+        else:
+            comp_type = None
+        score_fname = args[0]
+        out_fname = args[1]
+    except:
+        doc_optparse.exit()
+
+    scores = BinnedArray()
+
+    ## last_chrom = None
+    for i, ( chrom, pos, val ) in enumerate( bx.wiggle.Reader( misc.open_compressed( score_fname ) ) ):
+        #if last_chrom is None: 
+        #    last_chrom = chrom
+        #else: 
+        #    assert chrom == last_chrom, "This script expects a 'wiggle' input on only one chromosome"
+        scores[pos] = val
+        # Status
+        if i % 10000 == 0: print i, "scores processed"
+
+    out = open( out_fname, "w" )
+    if comp_type:
+        scores.to_file( out, comp_type=comp_type )
+    else:    
+        scores.to_file( out )
+    out.close()
+
+if __name__ == "__main__": main()
diff --git a/scripts/wiggle_to_chr_binned_array.py b/scripts/wiggle_to_chr_binned_array.py
new file mode 100755
index 0000000..47b583d
--- /dev/null
+++ b/scripts/wiggle_to_chr_binned_array.py
@@ -0,0 +1,42 @@
+#!/usr/bin/env python
+
+"""
+Writes compressed data from a wiggle file by chromosome.
+
+usage: %prog score_file < wiggle_data
+"""
+
+from __future__ import division
+
+import sys
+import psyco_full
+import bx.wiggle
+from bx.binned_array import BinnedArray
+from fpconst import isNaN
+from bx.cookbook import doc_optparse
+from bx import misc
+
+
+def main():
+    
+    # Parse command line
+    options, args = doc_optparse.parse( __doc__ )
+    try:
+        score_fname = args[0]
+    except:
+        doc_optparse.exit()
+
+    scores = {}
+    for i, ( chrom, pos, val ) in enumerate( bx.wiggle.Reader( open(sys.argv[1]) ) ):
+        if not chrom in scores: scores[ chrom ] = BinnedArray()
+        scores[chrom][pos] = val
+
+        # Status
+        if i % 10000 == 0: print i, "scores processed"
+
+    for chr in scores.keys():
+        out = open( chr, "w" )
+        scores[chr].to_file( out )
+        out.close()
+
+if __name__ == "__main__": main()
diff --git a/scripts/wiggle_to_simple.py b/scripts/wiggle_to_simple.py
new file mode 100755
index 0000000..87d1e8c
--- /dev/null
+++ b/scripts/wiggle_to_simple.py
@@ -0,0 +1,24 @@
+#!/usr/bin/env python
+
+"""
+Read a wiggle track and print out a series of lines containing
+"chrom position score". Ignores track lines, handles bed, variableStep
+and fixedStep wiggle lines.
+"""
+
+import psyco_full
+
+import sys
+import bx.wiggle
+
+if len( sys.argv ) > 1: in_file = open( sys.argv[1] )
+else: in_file = sys.stdin
+
+if len( sys.argv ) > 2: out_file = open( sys.argv[2], "w" )
+else: out_file = sys.stdout
+
+for fields in bx.wiggle.Reader( in_file ):
+    print " ".join( map( str, fields ) )
+
+in_file.close()
+out_file.close()
diff --git a/setup.cfg b/setup.cfg
new file mode 100644
index 0000000..ef577b5
--- /dev/null
+++ b/setup.cfg
@@ -0,0 +1,17 @@
+[aliases]
+snapshot = egg_info -rb_DEV bdist_egg rotate -m.egg -k1
+test = nosetests
+build_docs = build_sphinx build_apidocs
+
+[nosetests]
+#tests=script_tests/
+#tests=lib/bx/
+verbosity=2
+#detailed-errors=0
+#with-doctest=1
+#doctest-extension=pyx
+
+[build_sphinx]
+source-dir = doc/source
+build-dir  = doc/docbuild
+all_files  = 1
diff --git a/setup.py b/setup.py
new file mode 100644
index 0000000..f5a3c86
--- /dev/null
+++ b/setup.py
@@ -0,0 +1,231 @@
+import sys, platform
+
+if sys.version_info < (2, 4):
+    print >> sys.stderr, "ERROR: bx-python requires python 2.4 or greater"
+    sys.exit()
+
+# Automatically download setuptools if not available
+from distribute_setup import use_setuptools
+use_setuptools()
+
+from setuptools import *
+from glob import glob
+
+try:
+    import numpy
+    have_numpy = True
+except:
+    have_numpy = False
+       
+def main():
+    setup(  name = "bx-python",
+            version = "0.7.2",
+            py_modules = [ 'psyco_full' ],
+            packages = find_packages( 'lib' ),
+            package_dir = { '': 'lib' },
+            package_data = { '': ['*.ps'] },
+            scripts = glob( "scripts/*.py" ),
+            ext_modules = get_extension_modules(),
+            test_suite = 'nose.collector',
+            setup_requires = ['nose>=0.10.4'],
+            author = "James Taylor, Bob Harris, David King, Brent Pedersen, Kanwei Li, and others",
+            author_email = "james at jamestaylor.org",
+            description = "Tools for manipulating biological data, particularly multiple sequence alignments",
+            url = "http://bitbucket.org/james_taylor/bx-python/wiki/Home",
+            license = "MIT",
+            classifiers = [
+                "Development Status :: 5 - Production/Stable",
+                "Intended Audience :: Developers",
+                "Intended Audience :: Science/Research",
+                "License :: OSI Approved :: MIT License",
+                "Operating System :: POSIX",
+                "Programming Language :: Python :: 2",
+                "Topic :: Scientific/Engineering :: Bio-Informatics",
+                "Topic :: Software Development :: Libraries :: Python Modules"
+            ],
+            zip_safe = False,
+            dependency_links = [],
+            cmdclass=command_classes )
+
+# ---- Commands -------------------------------------------------------------
+
+from distutils.core import Command
+
+# Use build_ext from Cython
+command_classes = {}
+
+# Use build_ext from Cython if found
+try:
+    import Cython.Distutils
+    command_classes['build_ext'] = Cython.Distutils.build_ext
+except:
+    pass
+
+# Run 2to3 builder if we're on Python 3.x, from
+#   http://wiki.python.org/moin/PortingPythonToPy3k
+try:
+    from distutils.command.build_py import build_py_2to3 as build_py
+except ImportError:
+    # 2.x
+    from distutils.command.build_py import build_py
+command_classes['build_py'] = build_py
+
+# Use epydoc if found
+try:
+    import pkg_resources
+    pkg_resources.require( "epydoc" )
+    import epydoc.cli, sys, os, os.path
+    # Create command class to build API documentation
+    class BuildAPIDocs( Command ):
+        user_options = []
+        def initialize_options( self ):
+            pass
+        def finalize_options( self ):
+            pass
+        def run( self ):
+            # Save working directory and args
+            old_argv = sys.argv
+            old_cwd = os.getcwd()
+            # Build command line for Epydoc
+            sys.argv = """epydoc.py bx --verbose --html --simple-term
+                                       --exclude=._
+                                       --exclude=_tests
+                                       --docformat=reStructuredText
+                                       --output=../doc/docbuild/html/apidoc""".split()
+            # Make output directory
+            if not os.path.exists( "./doc/docbuild/html/apidoc" ):
+                os.mkdir( "./doc/docbuild/html/apidoc" )
+            # Move to lib directory (so bx package is in current directory)
+            os.chdir( "./lib" )
+            # Invoke epydoc
+            epydoc.cli.cli()
+            # Restore args and working directory
+            sys.argv = old_argv
+            os.chdir( old_cwd )
+    # Add to extra_commands    
+    command_classes['build_apidocs'] = BuildAPIDocs
+except:
+    pass
+
+# ---- Extension Modules ----------------------------------------------------
+
+def get_extension_modules():
+    extensions = []
+    # Bitsets
+    extensions.append( Extension( "bx.bitset",
+                                  [ "lib/bx/bitset.pyx", 
+                                    "src/binBits.c",
+                                    "src/kent/bits.c",
+                                    "src/kent/common.c" ],
+                                  include_dirs=[ "src/kent", "src"] ) )
+    # Interval intersection
+    extensions.append( Extension( "bx.intervals.intersection", [ "lib/bx/intervals/intersection.pyx" ] ) )
+    # Alignment object speedups
+    extensions.append( Extension( "bx.align._core", [ "lib/bx/align/_core.pyx" ] ) )
+    # NIB reading speedups
+    extensions.append( Extension( "bx.seq._nib", [ "lib/bx/seq/_nib.pyx" ] ) )
+    # 2bit reading speedups
+    extensions.append( Extension( "bx.seq._twobit", [ "lib/bx/seq/_twobit.pyx" ] ) )
+    # Translation if character / integer strings 
+    extensions.append( Extension( "bx._seqmapping", [ "lib/bx/_seqmapping.pyx" ] ) )
+    # BGZF
+    extensions.append( Extension( "bx.misc.bgzf",
+                                  [ "lib/bx/misc/bgzf.pyx", "src/samtools/bgzf.c" ],
+                                  include_dirs=[ "src/samtools"],
+                                  libraries=['z'] ) )
+
+    
+    # The following extensions won't (currently) compile on windows
+    if platform.system() not in ( 'Microsoft', 'Windows' ):
+        
+        # Interval clustering                
+        extensions.append( Extension( "bx.intervals.cluster",
+                                  [ "lib/bx/intervals/cluster.pyx", 
+                                    "src/cluster.c"],
+                                  include_dirs=["src"] ) )
+        # Position weight matrices
+        extensions.append( Extension( "bx.pwm._position_weight_matrix",
+                                  [ "lib/bx/pwm/_position_weight_matrix.pyx", "src/pwm_utils.c" ],
+                                  include_dirs=["src"]  ) )
+ 
+        if have_numpy:
+            extensions.append( Extension( "bx.motif._pwm", [ "lib/bx/motif/_pwm.pyx" ], 
+                                          include_dirs=[numpy.get_include()] ) )
+            
+            # Sparse arrays with summaries organized as trees on disk
+            extensions.append( Extension( "bx.arrays.array_tree", [ "lib/bx/arrays/array_tree.pyx" ], include_dirs=[numpy.get_include()] ) )  
+        
+            # Reading UCSC "big binary index" files
+            extensions.append( Extension( "bx.bbi.bpt_file", [ "lib/bx/bbi/bpt_file.pyx" ] ) )
+            extensions.append( Extension( "bx.bbi.cirtree_file", [ "lib/bx/bbi/cirtree_file.pyx" ] ) )
+            extensions.append( Extension( "bx.bbi.bbi_file", [ "lib/bx/bbi/bbi_file.pyx" ], include_dirs=[numpy.get_include()] ) )
+            extensions.append( Extension( "bx.bbi.bigwig_file", [ "lib/bx/bbi/bigwig_file.pyx" ], include_dirs=[numpy.get_include()] ) )
+            extensions.append( Extension( "bx.bbi.bigbed_file", [ "lib/bx/bbi/bigbed_file.pyx" ], include_dirs=[numpy.get_include()] ) )
+            # EPO and Chain arithmetics and IO speedups
+            extensions.append( Extension( "bx.align._epo", [ "lib/bx/align/_epo.pyx" ], include_dirs=[numpy.get_include()] ) )
+
+        # Reading UCSC bed and wiggle formats
+        extensions.append( Extension( "bx.arrays.bed", [ "lib/bx/arrays/bed.pyx" ] ) )
+        extensions.append( Extension( "bx.arrays.wiggle", [ "lib/bx/arrays/wiggle.pyx" ] ) )
+
+
+        # CpG masking
+        extensions.append( Extension( "bx.align.sitemask._cpg", \
+                                      [ "lib/bx/align/sitemask/_cpg.pyx", 
+                                        "lib/bx/align/sitemask/find_cpg.c" ] ) )
+        
+        # Counting n-grams in integer strings
+        extensions.append( Extension( "bx.intseq.ngramcount", [ "lib/bx/intseq/ngramcount.pyx" ] ) )
+
+        # Seekable access to bzip2 files
+        extensions.append( Extension( "bx.misc._seekbzip2", 
+                                      [ "lib/bx/misc/_seekbzip2.pyx",
+                                        "src/bunzip/micro-bunzip.c" ],
+                                      include_dirs=[ "src/bunzip" ] ) )   
+    return extensions     
+     
+# ---- Monkey patches -------------------------------------------------------
+
+def monkey_patch_doctest():
+    #
+    # Doctest and coverage don't get along, so we need to create
+    # a monkeypatch that will replace the part of doctest that
+    # interferes with coverage reports.
+    #
+    # The monkeypatch is based on this zope patch:
+    # http://svn.zope.org/Zope3/trunk/src/zope/testing/doctest.py?rev=28679&r1=28703&r2=28705
+    #
+    try:
+        import doctest
+        _orp = doctest._OutputRedirectingPdb
+        class NoseOutputRedirectingPdb(_orp):
+            def __init__(self, out):
+                self.__debugger_used = False
+                _orp.__init__(self, out)
+
+            def set_trace(self):
+                self.__debugger_used = True
+                _orp.set_trace(self)
+
+            def set_continue(self):
+                # Calling set_continue unconditionally would break unit test coverage
+                # reporting, as Bdb.set_continue calls sys.settrace(None).
+                if self.__debugger_used:
+                    _orp.set_continue(self)
+        doctest._OutputRedirectingPdb = NoseOutputRedirectingPdb
+    except:
+        pass
+
+def monkey_patch_numpy():
+    # Numpy pushes its tests into every importers namespace, yeccch.
+    try:
+        import numpy
+        numpy.test = None
+    except:
+        pass
+        
+if __name__ == "__main__":
+    monkey_patch_doctest()
+    if have_numpy:
+        monkey_patch_numpy()
+    main()
diff --git a/src/binBits.c b/src/binBits.c
new file mode 100644
index 0000000..1c91938
--- /dev/null
+++ b/src/binBits.c
@@ -0,0 +1,317 @@
+#include "common.h"
+#include "bits.h"
+#include "binBits.h"
+
+static Bits * ALL_ZERO = NULL;
+static Bits * ALL_ONE = ( Bits * ) &"ONE";
+
+struct BinBits* binBitsAlloc( int size, int granularity )
+{
+    struct BinBits * bb;
+    AllocVar(bb);
+    bb->size = size;
+    bb->bin_size = (int) ceil( size / (float) granularity );
+    bb->nbins = (int) ceil( size / (float) bb->bin_size );
+    AllocArray( bb->bins, bb->nbins );
+    return bb;
+}
+
+void binBitsFree( struct BinBits *bb )
+{
+    int i;
+    for ( i = 0; i < bb->nbins; i++ )
+    {
+        if ( ( bb->bins[i] != ALL_ZERO ) && ( bb->bins[i] != ALL_ONE ) )
+        {
+            bitFree( &(bb->bins[i]) );
+        }
+    }
+    freeMem( bb->bins );
+    freeMem( bb );
+}
+
+#ifdef _MSC_VER
+    #define INLINE static __inline
+#else
+    #define INLINE static inline
+#endif
+
+INLINE int binBitsGetBin( struct BinBits * bb, int pos )
+{
+    return pos / bb->bin_size;
+}
+
+INLINE int binBitsGetOffset( struct BinBits * bb, int pos )
+{
+    return pos % bb->bin_size;
+}
+
+boolean binBitsReadOne( struct BinBits * bb, int pos )
+{
+    int bin = binBitsGetBin( bb, pos );
+    
+    if ( bb->bins[bin] == ALL_ZERO )
+    {
+        return 0;
+    }
+    else if ( bb->bins[bin] == ALL_ONE )
+    {
+        return 1;
+    }
+    else
+    {
+        return bitReadOne( bb->bins[bin], binBitsGetOffset( bb, pos ) );
+    }
+}
+
+void binBitsSetOne( struct BinBits * bb, int pos )
+{
+    int bin = binBitsGetBin( bb, pos );  
+    int offset = binBitsGetOffset( bb, pos );
+    if ( bb->bins[bin] == ALL_ONE )
+    {
+        return;
+    }
+    if ( bb->bins[bin] == ALL_ZERO )
+    {
+        bb->bins[bin] = bitAlloc( bb->bin_size );
+    }
+    bitSetOne( bb->bins[bin], offset );
+}
+
+void binBitsClearOne( struct BinBits * bb, int pos )
+{
+    int bin = binBitsGetBin( bb, pos );  
+    int offset = binBitsGetOffset( bb, pos );
+    if ( bb->bins[bin] == ALL_ZERO )
+    {
+        return;
+    }
+    if ( bb->bins[bin] == ALL_ONE )
+    {
+        bb->bins[bin] = bitAlloc( bb->bin_size );
+        bitSetRange( bb->bins[bin], 0, bb->bin_size );
+    }
+    bitClearOne( bb->bins[bin], offset );
+}
+
+void binBitsSetRange( struct BinBits *bb, int start, int size )
+{
+    int bin, offset, delta;
+    while ( size > 0 )
+    {
+        bin = binBitsGetBin( bb, start );  
+        offset = binBitsGetOffset( bb, start );
+        delta = bb->bin_size - offset;
+        if ( bb->bins[bin] == ALL_ZERO )
+        {
+            bb->bins[bin] = bitAlloc( bb->bin_size );   
+        }
+        if ( delta < size )
+        {
+            if ( bb->bins[bin] != ALL_ONE )
+            {
+                bitSetRange( bb->bins[bin], offset, delta );
+            }
+            size -= delta;
+            start += delta;
+        }
+        else
+        {
+            if ( bb->bins[bin] != ALL_ONE )
+            {
+                bitSetRange( bb->bins[bin], offset, size );
+            }
+            size = 0;
+        }
+    }
+}
+
+int binBitsCountRange( struct BinBits *bb, int start, int size )
+{
+    int delta;
+    int count = 0;
+    while ( size > 0 )
+    {
+        int bin = binBitsGetBin( bb, start );  
+        int offset = binBitsGetOffset( bb, start );
+        delta = bb->bin_size - offset;
+        if ( bb->bins[bin] == ALL_ZERO )
+        {
+            if ( delta < size )
+            {
+                size -= delta;
+                start += delta;
+            }
+            else
+            {
+                size = 0;
+            }
+        }
+        else if ( bb->bins[bin] == ALL_ONE )
+        {
+            if ( delta < size )
+            {
+                count += ( delta - offset );
+                size -= delta;
+                start += delta;
+            }
+            else
+            {
+                count += ( size - offset );
+                size = 0;
+            }
+        }
+        else if ( delta < size )
+        {
+            count += bitCountRange( bb->bins[bin], offset, delta );
+            size -= delta;
+            start += delta;
+        }
+        else
+        {
+            count += bitCountRange( bb->bins[bin], offset, size );
+            size = 0;
+        } 
+    }
+    return count;
+}
+
+int binBitsFindSet( struct BinBits *bb, int start )
+{
+    int ns;
+    int bin = binBitsGetBin( bb, start );  
+    int offset = binBitsGetOffset( bb, start );
+    while ( bin < bb->nbins )
+    {
+        if ( bb->bins[bin] == ALL_ONE )
+        {
+            return bin * bb->bin_size + offset;
+        }
+        else if ( bb->bins[bin] != ALL_ZERO )
+        {
+            ns = bitFindSet( bb->bins[bin], offset, bb->bin_size );
+            if ( ns < bb->bin_size )
+            {
+                return bin * bb->bin_size + ns;
+            }
+        }
+        bin += 1;
+        offset = 0;
+    }
+    return bb->size;
+}
+
+int binBitsFindClear( struct BinBits *bb, int start )
+{
+    int ns;
+    int bin = binBitsGetBin( bb, start );  
+    int offset = binBitsGetOffset( bb, start );
+    while ( bin < bb->nbins )
+    {
+        if ( bb->bins[bin] == ALL_ZERO )
+        {
+            return bin*bb->bin_size + offset;
+        }
+        else if ( bb->bins[bin] != ALL_ONE )
+        {
+            ns = bitFindClear( bb->bins[bin], offset, bb->bin_size );
+            if ( ns < bb->bin_size )
+            {
+                return bin*bb->bin_size + ns;
+            }
+        }
+        bin += 1;
+        offset = 0;
+    }
+    return bb->size;
+}
+
+void binBitsAnd( struct BinBits *bb1, struct BinBits *bb2 )
+{
+    int i;    
+    assert( bb1->bin_size == bb2->bin_size && bb1->nbins == bb2->nbins && bb1->size == bb2->size );
+
+    for ( i = 0; i < bb1->nbins; i++ )
+    {
+        if ( bb1->bins[i] == ALL_ZERO )
+        {
+            // Do nothing
+        }
+        else if ( bb2->bins[i] == ALL_ZERO )
+        {
+            if ( bb1->bins[i] != ALL_ONE )
+            {
+                bitFree( &bb1->bins[i] );
+            }
+            bb1->bins[i] = ALL_ZERO;
+        }
+        else if ( bb2->bins[i] == ALL_ONE )
+        {
+            // Do nothing
+        }
+        else if ( bb1->bins[i] == ALL_ONE )
+        {
+            bb1->bins[i] = bitClone( bb2->bins[i], bb1->bin_size );
+        }
+        else
+        {            
+            bitAnd( bb1->bins[i], bb2->bins[i], bb1->bin_size );
+        }
+    }
+}
+
+void binBitsOr( struct BinBits *bb1, struct BinBits *bb2 )
+{
+    int i;    
+    assert( bb1->bin_size == bb2->bin_size && bb1->nbins == bb2->nbins && bb1->size == bb2->size );
+
+    for ( i = 0; i < bb1->nbins; i++ )
+    {
+        if ( bb1->bins[i] == ALL_ONE )
+        {
+            // Do nothing
+        }
+        else if ( bb2->bins[i] == ALL_ONE )
+        {
+            if ( bb1->bins[i] != ALL_ZERO )
+            {
+                bitFree( &bb1->bins[i] );
+            }
+            bb1->bins[i] = ALL_ONE;
+        }
+        else if ( bb2->bins[i] == ALL_ZERO )
+        {
+            // Do nothing
+        }
+        else if ( bb1->bins[i] == ALL_ZERO )
+        {
+            bb1->bins[i] = bitClone( bb2->bins[i], bb1->bin_size );
+        }
+        else
+        {
+            bitOr( bb1->bins[i], bb2->bins[i], bb1->bin_size );
+        }
+    }
+}
+
+void binBitsNot( struct BinBits *bb )
+{
+    int i;    
+
+    for ( i = 0; i < bb->nbins; i++ )
+    {
+        if ( bb->bins[i] == ALL_ONE )
+        {
+            bb->bins[i] = ALL_ZERO;
+        }
+        else if ( bb->bins[i] == ALL_ZERO )
+        {
+            bb->bins[i] = ALL_ONE;
+        }
+        else
+        {
+            bitNot( bb->bins[i], bb->bin_size );
+        }
+    }
+}
diff --git a/src/binBits.h b/src/binBits.h
new file mode 100644
index 0000000..4db89f3
--- /dev/null
+++ b/src/binBits.h
@@ -0,0 +1,28 @@
+#ifndef BINBITS_H
+#define BINBITS_H
+
+#include "common.h"
+#include "bits.h"
+
+struct BinBits
+{
+    int size;
+    int bin_size;
+    int nbins;
+    Bits ** bins;
+};
+
+struct BinBits* binBitsAlloc( int size, int granularity );
+void binBitsFree( struct BinBits *bb );
+boolean binBitsReadOne( struct BinBits * bb, int pos );
+void binBitsSetOne( struct BinBits * bb, int pos );
+void binBitsClearOne( struct BinBits * bb, int pos );
+void binBitsSetRange( struct BinBits *bb, int start, int size );
+int binBitsCountRange( struct BinBits *bb, int start, int size );
+int binBitsFindSet( struct BinBits *bb, int start );
+int binBitsFindClear( struct BinBits *bb, int start );
+void binBitsAnd( struct BinBits *bb1, struct BinBits *bb2 );
+void binBitsOr( struct BinBits *bb1, struct BinBits *bb2 );
+void binBitsNot( struct BinBits *bb );
+
+#endif
diff --git a/src/bunzip/micro-bunzip.c b/src/bunzip/micro-bunzip.c
new file mode 100644
index 0000000..d3ceaca
--- /dev/null
+++ b/src/bunzip/micro-bunzip.c
@@ -0,0 +1,705 @@
+/* vi: set sw=4 ts=4: */
+/*	Small bzip2 deflate implementation, by Rob Landley (rob at landley.net).
+
+	Based on bzip2 decompression code by Julian R Seward (jseward at acm.org),
+	which also acknowledges contributions by Mike Burrows, David Wheeler,
+	Peter Fenwick, Alistair Moffat, Radford Neal, Ian H. Witten,
+	Robert Sedgewick, and Jon L. Bentley.
+
+	This code is licensed under the LGPLv2:
+		LGPL (http://www.gnu.org/copyleft/lgpl.html
+*/
+
+/*
+	Size and speed optimizations by Manuel Novoa III  (mjn3 at codepoet.org).
+
+	More efficient reading of huffman codes, a streamlined read_bunzip()
+	function, and various other tweaks.  In (limited) tests, approximately
+	20% faster than bzcat on x86 and about 10% faster on arm.
+
+	Note that about 2/3 of the time is spent in read_unzip() reversing
+	the Burrows-Wheeler transformation.  Much of that time is delay
+	resulting from cache misses.
+
+	I would ask that anyone benefiting from this work, especially those
+	using it in commercial products, consider making a donation to my local
+	non-profit hospice organization (see www.hospiceacadiana.com) in the
+    name of the woman I loved, Toni W. Hagan, who passed away Feb. 12, 2003.
+
+	Manuel
+ */
+
+#include <setjmp.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <limits.h>
+
+/* Constants for huffman coding */
+#define MAX_GROUPS			6
+#define GROUP_SIZE   		50		/* 64 would have been more efficient */
+#define MAX_HUFCODE_BITS 	20		/* Longest huffman code allowed */
+#define MAX_SYMBOLS 		258		/* 256 literals + RUNA + RUNB */
+#define SYMBOL_RUNA			0
+#define SYMBOL_RUNB			1
+
+/* Status return values */
+#define RETVAL_OK						0
+#define RETVAL_LAST_BLOCK				(-1)
+#define RETVAL_NOT_BZIP_DATA			(-2)
+#define RETVAL_UNEXPECTED_INPUT_EOF		(-3)
+#define RETVAL_UNEXPECTED_OUTPUT_EOF	(-4)
+#define RETVAL_DATA_ERROR				(-5)
+#define RETVAL_OUT_OF_MEMORY			(-6)
+#define RETVAL_OBSOLETE_INPUT			(-7)
+
+#define RETVAL_END_OF_BLOCK             (-8)
+#define RETVAL_STOPCHAR                 (-9)
+#define RETVAL_BUFFER_FULL              (-10)
+
+/* Other housekeeping constants */
+#define IOBUF_SIZE			4096
+
+/* This is what we know about each huffman coding group */
+struct group_data {
+	/* We have an extra slot at the end of limit[] for a sentinal value. */
+	int limit[MAX_HUFCODE_BITS+1],base[MAX_HUFCODE_BITS],permute[MAX_SYMBOLS];
+	int minLen, maxLen;
+};
+
+/* Structure holding all the housekeeping data, including IO buffers and
+   memory that persists between calls to bunzip */
+typedef struct {
+	/* State for interrupting output loop */
+	int writeCopies,writePos,writeRunCountdown,writeCount,writeCurrent;
+	/* I/O tracking data (file handles, buffers, positions, etc.) */
+	int in_fd,out_fd,inbufCount,inbufPos /*,outbufPos*/;
+	unsigned char *inbuf /*,*outbuf*/;
+	unsigned int inbufBitCount, inbufBits;
+	/* The CRC values stored in the block header and calculated from the data */
+	unsigned int crc32Table[256],headerCRC, totalCRC, writeCRC;
+	/* Intermediate buffer and its size (in bytes) */
+	unsigned int *dbuf, dbufSize;
+	/* These things are a bit too big to go on the stack */
+	unsigned char selectors[32768];			/* nSelectors=15 bits */
+	struct group_data groups[MAX_GROUPS];	/* huffman coding tables */
+	/* For I/O error handling */
+	jmp_buf jmpbuf;
+} bunzip_data;
+
+/* Return the next nnn bits of input.  All reads from the compressed input
+   are done through this function.  All reads are big endian */
+unsigned int get_bits(bunzip_data *bd, char bits_wanted)
+{
+	unsigned int bits=0;
+
+	/* If we need to get more data from the byte buffer, do so.  (Loop getting
+	   one byte at a time to enforce endianness and avoid unaligned access.) */
+	while (bd->inbufBitCount<bits_wanted) {
+		/* If we need to read more data from file into byte buffer, do so */
+		if(bd->inbufPos==bd->inbufCount) {
+			if((bd->inbufCount = read(bd->in_fd, bd->inbuf, IOBUF_SIZE)) <= 0)
+				longjmp(bd->jmpbuf,RETVAL_UNEXPECTED_INPUT_EOF);
+			bd->inbufPos=0;
+		}
+		/* Avoid 32-bit overflow (dump bit buffer to top of output) */
+		if(bd->inbufBitCount>=24) {
+			bits=bd->inbufBits&((1<<bd->inbufBitCount)-1);
+			bits_wanted-=bd->inbufBitCount;
+			bits<<=bits_wanted;
+			bd->inbufBitCount=0;
+		}
+		/* Grab next 8 bits of input from buffer. */
+		bd->inbufBits=(bd->inbufBits<<8)|bd->inbuf[bd->inbufPos++];
+		bd->inbufBitCount+=8;
+	}
+	/* Calculate result */
+	bd->inbufBitCount-=bits_wanted;
+	bits|=(bd->inbufBits>>bd->inbufBitCount)&((1<<bits_wanted)-1);
+
+	return bits;
+}
+
+/* Unpacks the next block and sets up for the inverse burrows-wheeler step. */
+
+int get_next_block(bunzip_data *bd)
+{
+	struct group_data *hufGroup;
+	int dbufCount,nextSym,dbufSize,groupCount,*base,*limit,selector,
+		i,j,k,t,runPos,symCount,symTotal,nSelectors,byteCount[256];
+	unsigned char uc, symToByte[256], mtfSymbol[256], *selectors;
+	unsigned int *dbuf,origPtr;
+
+	dbuf=bd->dbuf;
+	dbufSize=bd->dbufSize;
+	selectors=bd->selectors;
+	/* Reset longjmp I/O error handling */
+	i=setjmp(bd->jmpbuf);
+	if(i) return i;
+	/* Read in header signature and CRC, then validate signature.
+	   (last block signature means CRC is for whole file, return now) */
+	i = get_bits(bd,24);
+	j = get_bits(bd,24);
+	bd->headerCRC=get_bits(bd,32);
+	if ((i == 0x177245) && (j == 0x385090)) return RETVAL_LAST_BLOCK;
+	if ((i != 0x314159) || (j != 0x265359)) return RETVAL_NOT_BZIP_DATA;
+	/* We can add support for blockRandomised if anybody complains.  There was
+	   some code for this in busybox 1.0.0-pre3, but nobody ever noticed that
+	   it didn't actually work. */
+	if(get_bits(bd,1)) return RETVAL_OBSOLETE_INPUT;
+	if((origPtr=get_bits(bd,24)) > dbufSize) return RETVAL_DATA_ERROR;
+	/* mapping table: if some byte values are never used (encoding things
+	   like ascii text), the compression code removes the gaps to have fewer
+	   symbols to deal with, and writes a sparse bitfield indicating which
+	   values were present.  We make a translation table to convert the symbols
+	   back to the corresponding bytes. */
+	t=get_bits(bd, 16);
+	symTotal=0;
+	for (i=0;i<16;i++) {
+		if(t&(1<<(15-i))) {
+			k=get_bits(bd,16);
+			for(j=0;j<16;j++)
+				if(k&(1<<(15-j))) symToByte[symTotal++]=(16*i)+j;
+		}
+	}
+	/* How many different huffman coding groups does this block use? */
+	groupCount=get_bits(bd,3);
+	if (groupCount<2 || groupCount>MAX_GROUPS) return RETVAL_DATA_ERROR;
+	/* nSelectors: Every GROUP_SIZE many symbols we select a new huffman coding
+	   group.  Read in the group selector list, which is stored as MTF encoded
+	   bit runs.  (MTF=Move To Front, as each value is used it's moved to the
+	   start of the list.) */
+	if(!(nSelectors=get_bits(bd, 15))) return RETVAL_DATA_ERROR;
+	for(i=0; i<groupCount; i++) mtfSymbol[i] = i;
+	for(i=0; i<nSelectors; i++) {
+		/* Get next value */
+		for(j=0;get_bits(bd,1);j++) if (j>=groupCount) return RETVAL_DATA_ERROR;
+		/* Decode MTF to get the next selector */
+		uc = mtfSymbol[j];
+		for(;j;j--) mtfSymbol[j] = mtfSymbol[j-1];
+		mtfSymbol[0]=selectors[i]=uc;
+	}
+	/* Read the huffman coding tables for each group, which code for symTotal
+	   literal symbols, plus two run symbols (RUNA, RUNB) */
+	symCount=symTotal+2;
+	for (j=0; j<groupCount; j++) {
+		unsigned char length[MAX_SYMBOLS],temp[MAX_HUFCODE_BITS+1];
+		int	minLen,	maxLen, pp;
+		/* Read huffman code lengths for each symbol.  They're stored in
+		   a way similar to mtf; record a starting value for the first symbol,
+		   and an offset from the previous value for everys symbol after that.
+		   (Subtracting 1 before the loop and then adding it back at the end is
+		   an optimization that makes the test inside the loop simpler: symbol
+		   length 0 becomes negative, so an unsigned inequality catches it.) */
+		t=get_bits(bd, 5)-1;
+		for (i = 0; i < symCount; i++) {
+			for(;;) {
+				if (((unsigned)t) > (MAX_HUFCODE_BITS-1))
+					return RETVAL_DATA_ERROR;
+				/* If first bit is 0, stop.  Else second bit indicates whether
+				   to increment or decrement the value.  Optimization: grab 2
+				   bits and unget the second if the first was 0. */
+				k = get_bits(bd,2);
+				if (k < 2) {
+					bd->inbufBitCount++;
+					break;
+				}
+				/* Add one if second bit 1, else subtract 1.  Avoids if/else */
+				t+=(((k+1)&2)-1);
+			}
+			/* Correct for the initial -1, to get the final symbol length */
+			length[i]=t+1;
+		}
+		/* Find largest and smallest lengths in this group */
+		minLen=maxLen=length[0];
+		for(i = 1; i < symCount; i++) {
+			if(length[i] > maxLen) maxLen = length[i];
+			else if(length[i] < minLen) minLen = length[i];
+		}
+		/* Calculate permute[], base[], and limit[] tables from length[].
+		 *
+		 * permute[] is the lookup table for converting huffman coded symbols
+		 * into decoded symbols.  base[] is the amount to subtract from the
+		 * value of a huffman symbol of a given length when using permute[].
+		 *
+		 * limit[] indicates the largest numerical value a symbol with a given
+		 * number of bits can have.  This is how the huffman codes can vary in
+		 * length: each code with a value>limit[length] needs another bit.
+		 */
+		hufGroup=bd->groups+j;
+		hufGroup->minLen = minLen;
+		hufGroup->maxLen = maxLen;
+		/* Note that minLen can't be smaller than 1, so we adjust the base
+		   and limit array pointers so we're not always wasting the first
+		   entry.  We do this again when using them (during symbol decoding).*/
+		base=hufGroup->base-1;
+		limit=hufGroup->limit-1;
+		/* Calculate permute[].  Concurently, initialize temp[] and limit[]. */
+		pp=0;
+		for(i=minLen;i<=maxLen;i++) {
+			temp[i]=limit[i]=0;
+			for(t=0;t<symCount;t++) 
+				if(length[t]==i) hufGroup->permute[pp++] = t;
+		}
+		/* Count symbols coded for at each bit length */
+		for (i=0;i<symCount;i++) temp[length[i]]++;
+		/* Calculate limit[] (the largest symbol-coding value at each bit
+		 * length, which is (previous limit<<1)+symbols at this level), and
+		 * base[] (number of symbols to ignore at each bit length, which is
+		 * limit minus the cumulative count of symbols coded for already). */
+		pp=t=0;
+		for (i=minLen; i<maxLen; i++) {
+			pp+=temp[i];
+			/* We read the largest possible symbol size and then unget bits
+			   after determining how many we need, and those extra bits could
+			   be set to anything.  (They're noise from future symbols.)  At
+			   each level we're really only interested in the first few bits,
+			   so here we set all the trailing to-be-ignored bits to 1 so they
+			   don't affect the value>limit[length] comparison. */
+			limit[i]= (pp << (maxLen - i)) - 1;
+			pp<<=1;
+			base[i+1]=pp-(t+=temp[i]);
+		}
+		limit[maxLen+1] = INT_MAX; /* Sentinal value for reading next sym. */
+		limit[maxLen]=pp+temp[maxLen]-1;
+		base[minLen]=0;
+	}
+	/* We've finished reading and digesting the block header.  Now read this
+	   block's huffman coded symbols from the file and undo the huffman coding
+	   and run length encoding, saving the result into dbuf[dbufCount++]=uc */
+
+	/* Initialize symbol occurrence counters and symbol Move To Front table */
+	for(i=0;i<256;i++) {
+		byteCount[i] = 0;
+		mtfSymbol[i]=(unsigned char)i;
+	}
+	/* Loop through compressed symbols. */
+	runPos=dbufCount=symCount=selector=0;
+	for(;;) {
+		/* Determine which huffman coding group to use. */
+		if(!(symCount--)) {
+			symCount=GROUP_SIZE-1;
+			if(selector>=nSelectors) return RETVAL_DATA_ERROR;
+			hufGroup=bd->groups+selectors[selector++];
+			base=hufGroup->base-1;
+			limit=hufGroup->limit-1;
+		}
+		/* Read next huffman-coded symbol. */
+		/* Note: It is far cheaper to read maxLen bits and back up than it is
+		   to read minLen bits and then an additional bit at a time, testing
+		   as we go.  Because there is a trailing last block (with file CRC),
+		   there is no danger of the overread causing an unexpected EOF for a
+		   valid compressed file.  As a further optimization, we do the read
+		   inline (falling back to a call to get_bits if the buffer runs
+		   dry).  The following (up to got_huff_bits:) is equivalent to
+		   j=get_bits(bd,hufGroup->maxLen);
+		 */
+		while (bd->inbufBitCount<hufGroup->maxLen) {
+			if(bd->inbufPos==bd->inbufCount) {
+				j = get_bits(bd,hufGroup->maxLen);
+				goto got_huff_bits;
+			}
+			bd->inbufBits=(bd->inbufBits<<8)|bd->inbuf[bd->inbufPos++];
+			bd->inbufBitCount+=8;
+		};
+		bd->inbufBitCount-=hufGroup->maxLen;
+		j = (bd->inbufBits>>bd->inbufBitCount)&((1<<hufGroup->maxLen)-1);
+got_huff_bits:
+		/* Figure how how many bits are in next symbol and unget extras */
+		i=hufGroup->minLen;
+		while(j>limit[i]) ++i;
+		bd->inbufBitCount += (hufGroup->maxLen - i);
+		/* Huffman decode value to get nextSym (with bounds checking) */
+		if ((i > hufGroup->maxLen)
+			|| (((unsigned)(j=(j>>(hufGroup->maxLen-i))-base[i]))
+				>= MAX_SYMBOLS))
+			return RETVAL_DATA_ERROR;
+		nextSym = hufGroup->permute[j];
+		/* We have now decoded the symbol, which indicates either a new literal
+		   byte, or a repeated run of the most recent literal byte.  First,
+		   check if nextSym indicates a repeated run, and if so loop collecting
+		   how many times to repeat the last literal. */
+		if (((unsigned)nextSym) <= SYMBOL_RUNB) { /* RUNA or RUNB */
+			/* If this is the start of a new run, zero out counter */
+			if(!runPos) {
+				runPos = 1;
+				t = 0;
+			}
+			/* Neat trick that saves 1 symbol: instead of or-ing 0 or 1 at
+			   each bit position, add 1 or 2 instead.  For example,
+			   1011 is 1<<0 + 1<<1 + 2<<2.  1010 is 2<<0 + 2<<1 + 1<<2.
+			   You can make any bit pattern that way using 1 less symbol than
+			   the basic or 0/1 method (except all bits 0, which would use no
+			   symbols, but a run of length 0 doesn't mean anything in this
+			   context).  Thus space is saved. */
+			t += (runPos << nextSym); /* +runPos if RUNA; +2*runPos if RUNB */
+			runPos <<= 1;
+			continue;
+		}
+		/* When we hit the first non-run symbol after a run, we now know
+		   how many times to repeat the last literal, so append that many
+		   copies to our buffer of decoded symbols (dbuf) now.  (The last
+		   literal used is the one at the head of the mtfSymbol array.) */
+		if(runPos) {
+			runPos=0;
+			if(dbufCount+t>=dbufSize) return RETVAL_DATA_ERROR;
+
+			uc = symToByte[mtfSymbol[0]];
+			byteCount[uc] += t;
+			while(t--) dbuf[dbufCount++]=uc;
+		}
+		/* Is this the terminating symbol? */
+		if(nextSym>symTotal) break;
+		/* At this point, nextSym indicates a new literal character.  Subtract
+		   one to get the position in the MTF array at which this literal is
+		   currently to be found.  (Note that the result can't be -1 or 0,
+		   because 0 and 1 are RUNA and RUNB.  But another instance of the
+		   first symbol in the mtf array, position 0, would have been handled
+		   as part of a run above.  Therefore 1 unused mtf position minus
+		   2 non-literal nextSym values equals -1.) */
+		if(dbufCount>=dbufSize) return RETVAL_DATA_ERROR;
+		i = nextSym - 1;
+		uc = mtfSymbol[i];
+		/* Adjust the MTF array.  Since we typically expect to move only a
+		 * small number of symbols, and are bound by 256 in any case, using
+		 * memmove here would typically be bigger and slower due to function
+		 * call overhead and other assorted setup costs. */
+		do {
+			mtfSymbol[i] = mtfSymbol[i-1];
+		} while (--i);
+		mtfSymbol[0] = uc;
+		uc=symToByte[uc];
+		/* We have our literal byte.  Save it into dbuf. */
+		byteCount[uc]++;
+		dbuf[dbufCount++] = (unsigned int)uc;
+	}
+	/* At this point, we've read all the huffman-coded symbols (and repeated
+       runs) for this block from the input stream, and decoded them into the
+	   intermediate buffer.  There are dbufCount many decoded bytes in dbuf[].
+	   Now undo the Burrows-Wheeler transform on dbuf.
+	   See http://dogma.net/markn/articles/bwt/bwt.htm
+	 */
+	/* Turn byteCount into cumulative occurrence counts of 0 to n-1. */
+	j=0;
+	for(i=0;i<256;i++) {
+		k=j+byteCount[i];
+		byteCount[i] = j;
+		j=k;
+	}
+	/* Figure out what order dbuf would be in if we sorted it. */
+	for (i=0;i<dbufCount;i++) {
+		uc=(unsigned char)(dbuf[i] & 0xff);
+		dbuf[byteCount[uc]] |= (i << 8);
+		byteCount[uc]++;
+	}
+	/* Decode first byte by hand to initialize "previous" byte.  Note that it
+	   doesn't get output, and if the first three characters are identical
+	   it doesn't qualify as a run (hence writeRunCountdown=5). */
+	if(dbufCount) {
+		if(origPtr>=dbufCount) return RETVAL_DATA_ERROR;
+		bd->writePos=dbuf[origPtr];
+	    bd->writeCurrent=(unsigned char)(bd->writePos&0xff);
+		bd->writePos>>=8;
+		bd->writeRunCountdown=5;
+	}
+	bd->writeCount=dbufCount;
+
+	return RETVAL_OK;
+}
+
+/* Undo burrows-wheeler transform on intermediate buffer to produce output.
+   If start_bunzip was initialized with out_fd=-1, then up to len bytes of
+   data are written to outbuf.  Return value is number of bytes written or
+   error (all errors are negative numbers).  If out_fd!=-1, outbuf and len
+   are ignored, data is written to out_fd and return is RETVAL_OK or error.
+*/
+
+int read_bunzip(bunzip_data *bd, char *outbuf, int len)
+{
+	const unsigned int *dbuf;
+	int pos,current,previous,gotcount;
+
+	/* If last read was short due to end of file, return last block now */
+	/* if(bd->writeCount<0) return bd->writeCount; */
+	
+	/* james at bx.psu.edu: writeCount goes to -1 when the buffer is fully
+	   decoded, which results in this returning RETVAL_LAST_BLOCK, also
+	   equal to -1... Confusing, I'm returning 0 here to indicate no 
+	   bytes written into the buffer */
+    if(bd->writeCount<0) return 0;
+
+	gotcount = 0;
+	dbuf=bd->dbuf;
+	pos=bd->writePos;
+	current=bd->writeCurrent;
+
+	/* We will always have pending decoded data to write into the output
+	   buffer unless this is the very first call (in which case we haven't
+	   huffman-decoded a block into the intermediate buffer yet). */
+
+	if (bd->writeCopies) {
+		/* Inside the loop, writeCopies means extra copies (beyond 1) */
+		--bd->writeCopies;
+		/* Loop outputting bytes */
+		for(;;) {
+			/* Write next byte into output buffer, updating CRC */
+			/* If the output buffer is full, snapshot state and return */
+			if(gotcount >= len) {
+				bd->writePos=pos;
+				bd->writeCurrent=current;
+				bd->writeCopies++;
+				return len;
+			}
+			outbuf[gotcount++] = current;
+			bd->writeCRC=(((bd->writeCRC)<<8)
+						  ^bd->crc32Table[((bd->writeCRC)>>24)^current]);
+			/* Loop now if we're outputting multiple copies of this byte */
+			if (bd->writeCopies) {
+				--bd->writeCopies;
+				continue;
+			}
+decode_next_byte:
+            if (!bd->writeCount--) break;
+			/* Follow sequence vector to undo Burrows-Wheeler transform */
+			previous=current;
+			pos=dbuf[pos];
+			current=pos&0xff;
+			pos>>=8;
+			/* After 3 consecutive copies of the same byte, the 4th is a repeat
+			   count.  We count down from 4 instead
+			 * of counting up because testing for non-zero is faster */
+			if(--bd->writeRunCountdown) {
+				if(current!=previous) bd->writeRunCountdown=4;
+			} else {
+				/* We have a repeated run, this byte indicates the count */
+				bd->writeCopies=current;
+				current=previous;
+				bd->writeRunCountdown=5;
+				/* Sometimes there are just 3 bytes (run length 0) */
+				if(!bd->writeCopies) goto decode_next_byte;
+				/* Subtract the 1 copy we'd output anyway to get extras */
+				--bd->writeCopies;
+			}
+		}
+		/* Decompression of this block completed successfully */
+		bd->writeCRC=~bd->writeCRC;
+		bd->totalCRC=((bd->totalCRC<<1) | (bd->totalCRC>>31)) ^ bd->writeCRC;
+		/* If this block had a CRC error, force file level CRC error. */
+		if(bd->writeCRC!=bd->headerCRC) {
+            // fprintf( stderr, "CRC ERROR\n" ); fflush( stderr );
+			bd->totalCRC=bd->headerCRC+1;
+			return RETVAL_LAST_BLOCK;
+		}
+		/* james at bx.psu.edu -- rather than falling through we return here */
+        return gotcount;
+	}
+	
+    goto decode_next_byte;
+}
+
+/**
+ * Same as read_bunzip, but will stop if it encounters `stop_char`. 
+ */
+int read_bunzip_to_char(bunzip_data *bd, char *outbuf, int len, int* gotcount_out, char stopchar )
+{
+	const unsigned int *dbuf;
+	int pos,current,previous,gotcount;
+
+	/* If last read was short due to end of file, return last block now */
+	/* if(bd->writeCount<0) return bd->writeCount; */
+	
+	/* james at bx.psu.edu: writeCount goes to -1 when the buffer is fully
+	   decoded, which results in this returning RETVAL_LAST_BLOCK, also
+	   equal to -1... Confusing, I'm returning 0 here to indicate no 
+	   bytes written into the buffer */
+    if(bd->writeCount<0) return RETVAL_END_OF_BLOCK;
+
+	gotcount = 0;
+	dbuf=bd->dbuf;
+	pos=bd->writePos;
+	current=bd->writeCurrent;
+
+	/* We will always have pending decoded data to write into the output
+	   buffer unless this is the very first call (in which case we haven't
+	   huffman-decoded a block into the intermediate buffer yet). */
+
+	if (bd->writeCopies) {
+		/* Inside the loop, writeCopies means extra copies (beyond 1) */
+		--bd->writeCopies;
+		/* Loop outputting bytes */
+		for(;;) {
+			/* Write next byte into output buffer, updating CRC */
+			/* If the output buffer is full, snapshot state and return */
+			if(gotcount >= len) {
+				bd->writePos=pos;
+				bd->writeCurrent=current;
+				bd->writeCopies++;
+                *gotcount_out = gotcount;
+				return RETVAL_BUFFER_FULL;
+			}
+			/* Also stop if we hit stop char (this could be faster) */
+			if( gotcount && outbuf[gotcount-1] == stopchar ) {
+				bd->writePos=pos;
+				bd->writeCurrent=current;
+				bd->writeCopies++;
+                *gotcount_out = gotcount;
+				return RETVAL_STOPCHAR;
+			}
+			outbuf[gotcount++] = current;
+			bd->writeCRC=(((bd->writeCRC)<<8)
+						  ^bd->crc32Table[((bd->writeCRC)>>24)^current]);
+			/* Loop now if we're outputting multiple copies of this byte */
+			if (bd->writeCopies) {
+				--bd->writeCopies;
+				continue;
+			}
+decode_next_byte:
+            if (!bd->writeCount--) break;
+			/* Follow sequence vector to undo Burrows-Wheeler transform */
+			previous=current;
+			pos=dbuf[pos];
+			current=pos&0xff;
+			pos>>=8;
+			/* After 3 consecutive copies of the same byte, the 4th is a repeat
+			   count.  We count down from 4 instead
+			 * of counting up because testing for non-zero is faster */
+			if(--bd->writeRunCountdown) {
+				if(current!=previous) bd->writeRunCountdown=4;
+			} else {
+				/* We have a repeated run, this byte indicates the count */
+				bd->writeCopies=current;
+				current=previous;
+				bd->writeRunCountdown=5;
+				/* Sometimes there are just 3 bytes (run length 0) */
+				if(!bd->writeCopies) goto decode_next_byte;
+				/* Subtract the 1 copy we'd output anyway to get extras */
+				--bd->writeCopies;
+			}
+		}
+		/* Decompression of this block completed successfully */
+		bd->writeCRC=~bd->writeCRC;
+		bd->totalCRC=((bd->totalCRC<<1) | (bd->totalCRC>>31)) ^ bd->writeCRC;
+		/* If this block had a CRC error, force file level CRC error. */
+		if(bd->writeCRC!=bd->headerCRC) {
+            // fprintf( stderr, "CRC ERROR\n" ); fflush( stderr );
+			bd->totalCRC=bd->headerCRC+1;
+			return RETVAL_LAST_BLOCK;
+		}
+		/* james at bx.psu.edu -- rather than falling through we return here */
+        *gotcount_out = gotcount;
+        return RETVAL_END_OF_BLOCK;
+	}
+	
+    goto decode_next_byte;
+}
+
+int init_block( bunzip_data *bd )
+{
+    int status;
+    /* Refill the intermediate buffer by huffman-decoding next block of input */
+	/* (previous is just a convenient unused temp variable here) */
+	status=get_next_block(bd);
+	if(status) {
+		bd->writeCount=status;
+        return status;
+	}
+	bd->writeCRC=0xffffffffUL;
+    return RETVAL_OK;
+}
+
+/* Allocate the structure, read file header.  If in_fd==-1, inbuf must contain
+   a complete bunzip file (len bytes long).  If in_fd!=-1, inbuf and len are
+   ignored, and data is read from file handle into temporary buffer. */
+int start_bunzip(bunzip_data **bdp, int in_fd, char *inbuf, int len)
+{
+	bunzip_data *bd;
+	unsigned int i,j,c;
+	const unsigned int BZh0=(((unsigned int)'B')<<24)+(((unsigned int)'Z')<<16)
+							+(((unsigned int)'h')<<8)+(unsigned int)'0';
+
+	/* Figure out how much data to allocate */
+	i=sizeof(bunzip_data);
+	if(in_fd!=-1) i+=IOBUF_SIZE;
+	/* Allocate bunzip_data.  Most fields initialize to zero. */
+	if(!(bd=*bdp=malloc(i))) return RETVAL_OUT_OF_MEMORY;
+	memset(bd,0,sizeof(bunzip_data));
+	/* Setup input buffer */
+	if(-1==(bd->in_fd=in_fd)) {
+		bd->inbuf=inbuf;
+		bd->inbufCount=len;
+	} else bd->inbuf=(unsigned char *)(bd+1);
+	/* Init the CRC32 table (big endian) */
+	for(i=0;i<256;i++) {
+		c=i<<24;
+		for(j=8;j;j--)
+			c=c&0x80000000 ? (c<<1)^0x04c11db7 : (c<<1);
+		bd->crc32Table[i]=c;
+	}
+	/* Setup for I/O error handling via longjmp */
+	i=setjmp(bd->jmpbuf);
+	if(i) return i;
+
+	/* Ensure that file starts with "BZh['1'-'9']." */
+	i = get_bits(bd,32);
+	if (((unsigned int)(i-BZh0-1)) >= 9) return RETVAL_NOT_BZIP_DATA;
+
+	/* Fourth byte (ascii '1'-'9'), indicates block size in units of 100k of
+	   uncompressed data.  Allocate intermediate buffer for block. */
+	bd->dbufSize=100000*(i-BZh0);
+
+	if(!(bd->dbuf=malloc(bd->dbufSize * sizeof(int))))
+		return RETVAL_OUT_OF_MEMORY;
+	return RETVAL_OK;
+}
+
+/* Example usage: decompress src_fd to dst_fd.  (Stops at end of bzip data,
+   not end of file.) */
+extern int uncompressStream(int src_fd, int dst_fd)
+{
+	char *outbuf;
+	bunzip_data *bd;
+	int i;
+
+	if(!(outbuf=malloc(IOBUF_SIZE))) return RETVAL_OUT_OF_MEMORY;
+	if(!(i=start_bunzip(&bd,src_fd,0,0))) {
+		for(;;) {
+            if (((i=init_block(bd)) < 0)) break;
+            // fprintf( stderr, "init: %d\n", i );
+            for(;;)
+            {
+			    if((i=read_bunzip(bd,outbuf,IOBUF_SIZE)) <= 0) break;
+                // fprintf( stderr, "read: %d\n", i );
+			    if(i!=write(dst_fd,outbuf,i)) {
+				    i=RETVAL_UNEXPECTED_OUTPUT_EOF;
+				    break;
+			    }
+			}
+		}
+	}
+	/* Check CRC and release memory */
+	if(i==RETVAL_LAST_BLOCK && bd->headerCRC==bd->totalCRC) i=RETVAL_OK;
+	if(bd->dbuf) free(bd->dbuf);
+	free(bd);
+	free(outbuf);
+	return i;
+}
+
+#ifdef MICRO_BUNZIP_MAIN
+
+static char * const bunzip_errors[]={NULL,"Bad file checksum","Not bzip data",
+		"Unexpected input EOF","Unexpected output EOF","Data error",
+		 "Out of memory","Obsolete (pre 0.9.5) bzip format not supported."};
+
+/* Dumb little test thing, decompress stdin to stdout */
+int main(int argc, char *argv[])
+{
+	int i=uncompressStream(0,1);
+	char c;
+
+	if(i) fprintf(stderr,"%d: %s\n", i, bunzip_errors[-i]);
+    else if(read(0,&c,1)) fprintf(stderr,"Trailing garbage ignored\n");
+	return -i;
+}
+
+#endif
\ No newline at end of file
diff --git a/src/bunzip/micro-bunzip.h b/src/bunzip/micro-bunzip.h
new file mode 100644
index 0000000..317992c
--- /dev/null
+++ b/src/bunzip/micro-bunzip.h
@@ -0,0 +1,77 @@
+#ifndef __MICRO_BUNZIP_H__
+#define __MICRO_BUNZIP_H__
+
+/* ---- Duplicated from micro-bzip.c -------------------------------------- */
+
+#include <setjmp.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <limits.h>
+
+/* Constants for huffman coding */
+#define MAX_GROUPS			6
+#define GROUP_SIZE   		50		/* 64 would have been more efficient */
+#define MAX_HUFCODE_BITS 	20		/* Longest huffman code allowed */
+#define MAX_SYMBOLS 		258		/* 256 literals + RUNA + RUNB */
+#define SYMBOL_RUNA			0
+#define SYMBOL_RUNB			1
+
+/* Status return values */
+#define RETVAL_OK						0
+#define RETVAL_LAST_BLOCK				(-1)
+#define RETVAL_NOT_BZIP_DATA			(-2)
+#define RETVAL_UNEXPECTED_INPUT_EOF		(-3)
+#define RETVAL_UNEXPECTED_OUTPUT_EOF	(-4)
+#define RETVAL_DATA_ERROR				(-5)
+#define RETVAL_OUT_OF_MEMORY			(-6)
+#define RETVAL_OBSOLETE_INPUT			(-7)
+
+#define RETVAL_END_OF_BLOCK             (-8)
+#define RETVAL_STOPCHAR                 (-9)
+#define RETVAL_BUFFER_FULL              (-10)
+
+/* Other housekeeping constants */
+#define IOBUF_SIZE			4096
+
+/* This is what we know about each huffman coding group */
+struct group_data {
+	/* We have an extra slot at the end of limit[] for a sentinal value. */
+	int limit[MAX_HUFCODE_BITS+1],base[MAX_HUFCODE_BITS],permute[MAX_SYMBOLS];
+	int minLen, maxLen;
+};
+
+/* Structure holding all the housekeeping data, including IO buffers and
+   memory that persists between calls to bunzip */
+typedef struct {
+	/* State for interrupting output loop */
+	int writeCopies,writePos,writeRunCountdown,writeCount,writeCurrent;
+	/* I/O tracking data (file handles, buffers, positions, etc.) */
+	int in_fd,out_fd,inbufCount,inbufPos /*,outbufPos*/;
+	unsigned char *inbuf /*,*outbuf*/;
+	unsigned int inbufBitCount, inbufBits;
+	/* The CRC values stored in the block header and calculated from the data */
+	unsigned int crc32Table[256],headerCRC, totalCRC, writeCRC;
+	/* Intermediate buffer and its size (in bytes) */
+	unsigned int *dbuf, dbufSize;
+	/* These things are a bit too big to go on the stack */
+	unsigned char selectors[32768];			/* nSelectors=15 bits */
+	struct group_data groups[MAX_GROUPS];	/* huffman coding tables */
+	/* For I/O error handling */
+	jmp_buf jmpbuf;
+} bunzip_data;
+
+static char * const bunzip_errors[]={NULL,"Bad file checksum","Not bzip data",
+		"Unexpected input EOF","Unexpected output EOF","Data error",
+		 "Out of memory","Obsolete (pre 0.9.5) bzip format not supported."};
+
+/* ---- Forward declarations for micro-bzip.c ---------------------------- */
+
+unsigned int get_bits(bunzip_data *bd, char bits_wanted);
+int get_next_block( bunzip_data *bd );
+int read_bunzip(bunzip_data *bd, char *outbuf, int len);
+int start_bunzip(bunzip_data **bdp, int in_fd, char *inbuf, int len);
+int read_bunzip_to_char(bunzip_data *bd, char *outbuf, int len, int* gotcount_out, char stopchar );
+
+#endif
\ No newline at end of file
diff --git a/src/cluster.c b/src/cluster.c
new file mode 100644
index 0000000..0887d85
--- /dev/null
+++ b/src/cluster.c
@@ -0,0 +1,267 @@
+/*
+    Kanwei Li, 2009
+    Inspired by previous ClusterTree
+    
+    This clustering algorithm uses a binary tree structure. Nodes correspond to 
+    non-overlapping intervals, where overlapping means that the distance between
+    two intervals is less or equal to max_dist, which is the max separation.
+    
+    The tree self-balances using rotations based on the binomial sequence. Merges
+    among nodes are performed whenever a node is changed/added that will cause other
+    nodes to form a new cluster.
+*/
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+#include "cluster.h"
+
+#define ALLOC(pt) (malloc(sizeof(pt)))
+
+static int min(int a, int b) {
+    if( a < b )
+        return a;
+    else
+        return b;
+}
+
+static int max(int a, int b) {
+    if( a > b )
+        return a;
+    else
+        return b;
+}
+
+/* Create new tree with given max_dist (max distance between intervals to be
+    considered a cluster), and min_intervals, the minimum number of intervals
+    needed for a cluster to be considered significant */
+clustertree* create_clustertree(int max_dist, int min_intervals) {
+    clustertree *tree = ALLOC(clustertree);
+    tree->max_dist = max_dist;
+    tree->min_intervals = min_intervals;
+    tree->root = NULL;
+    return tree;
+}
+
+static interval* create_interval(int start, int end, int id) {
+    interval *ival = ALLOC(interval);
+    
+    ival->start = start;
+    ival->end = end;
+    ival->id = id;
+    ival->next = NULL;
+    return ival;
+}
+
+static clusternode* create_node(int start, int end, int id) {
+    clusternode *new_node = ALLOC(clusternode);
+    
+    new_node->start     = start;
+    new_node->end       = end;
+    new_node->interval_head = create_interval(start, end, id);
+    new_node->interval_tail = new_node->interval_head;
+    new_node->num_ivals = 1;
+    new_node->left      = NULL;
+    new_node->right     = NULL;
+    
+    double uniform = ((double)rand()) / (RAND_MAX);
+    if (uniform == 1.0)
+        uniform = 0;
+    new_node->priority = (int)ceil( (-1.0 / log(.5)) * log( -1.0 / (uniform - 1)));
+    
+    return new_node;
+}
+
+static void recursively_free_intervals(interval *ival) {
+    interval *next;
+    if(ival) {
+        next = ival->next;
+        free(ival);
+        recursively_free_intervals(next);
+    }
+}
+
+static void recursively_free_nodes(clusternode *node) {
+    if(node) {
+        recursively_free_nodes(node->left);
+        recursively_free_nodes(node->right);
+        recursively_free_intervals(node->interval_head);
+        free(node);
+    }
+}
+
+void free_tree(clustertree *tree) {
+    recursively_free_nodes(tree->root);
+    free(tree);
+}
+
+void cluster_rotateright(clusternode **node) {
+    clusternode* root = (*node)->left;
+    (*node)->left = (*node)->left->right;
+    root->right = (*node);
+    *node = root;
+}
+
+void cluster_rotateleft(clusternode **node) {
+    clusternode* root = (*node)->right;
+    (*node)->right = (*node)->right->left;
+    root->left = (*node);
+    *node = root;
+}
+
+/* Go down the tree and merge nodes if necessary */
+void cluster_fixup(clustertree *tree, clusternode **ln, clusternode **rn) {
+    clusternode* local = *ln;
+    clusternode* root = *rn;
+    int maxstart = max(root->start, local->start);
+    int maxend = max(local->end, root->end);
+    int minstart = min(root->start, local->start);
+    int minend = min(root->end, local->end);
+
+    if( maxstart - minend <= tree->max_dist ) {
+        /* Have to merge this node and children */
+        root->start = minstart;
+        root->end = maxend;
+        root->interval_tail->next = local->interval_head;
+        root->interval_tail = local->interval_tail;
+        root->num_ivals += local->num_ivals;
+        if( local->right) cluster_fixup(tree, &(local->right), rn);
+        if( local->left) cluster_fixup(tree, &(local->left), rn);
+        if((local->right == NULL) && (local->left == NULL)) {
+            free(local);
+            *ln = NULL;
+        } else if(local->right) {
+            *ln = local->right;
+            free(local);
+        } else if (local->left) {
+            *ln = local->left;
+            free(local);
+        }
+        return;
+    }
+    // Even if we miss, we still have to check children
+    if(local->left) {
+        cluster_fixup(tree, &(local->left), rn);
+    }
+    if(local->right) {
+        cluster_fixup(tree, &(local->right), rn);
+    }
+}
+
+/* Pyrex "getregions" implements this. Only used for C debugging */
+void clustereach(clustertree *tree, clusternode *node) {
+    interval* ival;
+    if (node == NULL) {
+        exit(1); /* Shouldn't happen */
+    }
+    if (node->left != NULL) {
+        clustereach(tree, node->left);
+    }
+    printf("Node: %d\t%d\n", node->start, node->end);
+    ival = node->interval_head;
+    while(ival) {
+        printf("\tInterval %d: %d\t%d\n", ival->id, ival->start, ival->end);
+        ival = ival->next;
+    }
+    
+    if (node->right != NULL) {
+        clustereach(tree, node->right);
+    }
+}
+
+void clusteritr_recursive(clustertree *tree, clusternode *node, treeitr* *itr) {
+    treeitr *newitr;
+
+    if (node == NULL) {
+        return;
+    }
+    if (node->right != NULL) {
+        clusteritr_recursive(tree, node->right, itr);
+    }
+    if (node->num_ivals >= tree->min_intervals) {
+        newitr = ALLOC(treeitr);
+        newitr->next = *itr;
+        newitr->node = node;
+        *itr = newitr;
+    }
+    if (node->left != NULL) {
+        clusteritr_recursive(tree, node->left, itr);
+    }
+}
+
+/* Create an infix iterator */
+treeitr* clusteritr(clustertree *tree) {
+    treeitr *itr = NULL;
+    
+    clusteritr_recursive(tree, tree->root, &itr);
+    if (itr != NULL) {
+        return itr;
+    }
+    return NULL;
+}
+
+/* Free iterator (tail recursive) */
+void freeclusteritr(treeitr *itr) {
+    treeitr *next;
+    if (itr == NULL) {
+        return;
+    }
+    
+    next = itr->next;
+    free(itr);
+    freeclusteritr(next);
+}
+
+/* Insert based on the start position of intervals */
+clusternode* clusternode_insert(clustertree *tree, clusternode *node, int start, int end, int id) {
+    int oldstart;
+    int oldend;
+    interval* ival;
+    
+    // printf("Inserting %d %d %d\n", start, end, id);
+    if (node == NULL) {
+        node = create_node(start, end, id);
+        
+    } else if ( (start - tree->max_dist) > node->end ) { /* We're to the right of this cluster */
+        node->right = clusternode_insert(tree, node->right, start, end, id);
+        if (node->priority < node->right->priority) cluster_rotateleft(&node);
+    
+    } else if ( (end + tree->max_dist) < node->start) { /* We're to the left of this cluster */
+        node->left = clusternode_insert(tree, node->left, start, end, id);
+        if (node->priority < node->left->priority) cluster_rotateright(&node);
+                        
+    } else { /* We're in the range of this cluster */
+        /* Update the start and end to match to new values */
+        oldstart    = node->start;
+        oldend      = node->end;
+        node->start = min(start, node->start);
+        node->end   = max(end, node->end);
+        ival = create_interval(start, end, id);
+        ival->next = node->interval_head; /* Add this interval as the head of the interval list */
+        node->interval_head = ival;
+        node->num_ivals += 1;
+                
+        if ( oldstart > node->start && node->left != NULL ) { /* New interval added to the start, and there's a left child */
+            cluster_fixup(tree, &(node->left), &node);
+        }
+        if ( oldend < node->end && node->right != NULL ) { /* New interval added to the end, and there's a right child */
+            cluster_fixup(tree, &(node->right), &node);
+        }
+    }
+    return node;
+}
+
+int main() {
+    
+    // Simple test
+    clustertree* tree = create_clustertree(0, 1);
+    
+    tree->root = clusternode_insert(tree, tree->root, 3, 4, 0);
+    tree->root = clusternode_insert(tree, tree->root, 6, 7, 1);
+    tree->root = clusternode_insert(tree, tree->root, 9, 10, 2);
+    tree->root = clusternode_insert(tree, tree->root, 1, 2, 3);
+    tree->root = clusternode_insert(tree, tree->root, 3, 8, 4);
+    
+    clustereach(tree, tree->root);
+    return 0;
+    
+}
diff --git a/src/cluster.h b/src/cluster.h
new file mode 100644
index 0000000..a509ecb
--- /dev/null
+++ b/src/cluster.h
@@ -0,0 +1,39 @@
+typedef struct struct_interval {
+    int start;
+    int end;
+    int id;
+    
+    struct struct_interval *next;
+} interval;
+
+typedef struct struct_clusternode {
+    int start;
+    int end;
+    int priority;
+    
+    struct struct_interval *interval_head;
+    struct struct_interval *interval_tail;
+    int num_ivals;
+    
+    struct struct_clusternode *left;
+    struct struct_clusternode *right;
+} clusternode;
+
+typedef struct {
+    int max_dist;
+    int min_intervals;
+    
+    clusternode *root;
+} clustertree;
+
+typedef struct struct_treeitr {
+    struct struct_treeitr *next;
+    struct struct_clusternode *node;
+} treeitr;
+
+
+clusternode* clusternode_insert(clustertree *tree, clusternode *node, int start, int end, int id);
+clustertree* create_clustertree(int max_dist, int min_intervals);
+treeitr* clusteritr(clustertree *tree);
+void freeclusteritr(treeitr *itr);
+void free_tree(clustertree *tree);
diff --git a/src/kent/bits.c b/src/kent/bits.c
new file mode 100644
index 0000000..0c058cf
--- /dev/null
+++ b/src/kent/bits.c
@@ -0,0 +1,279 @@
+/* bits - handle operations on arrays of bits. 
+ *
+ * This file is copyright 2002 Jim Kent, but license is hereby
+ * granted for all use - public, private or commercial. */
+
+#include "common.h"
+#include "bits.h"
+
+static char const rcsid[] = "$Id: bits.c,v 1.20 2008/03/25 16:32:31 angie Exp $";
+
+
+static Bits oneBit[8] = { 0x80, 0x40, 0x20, 0x10, 0x8, 0x4, 0x2, 0x1};
+static Bits leftMask[8] = {0xFF, 0x7F, 0x3F, 0x1F,  0xF,  0x7,  0x3,  0x1,};
+static Bits rightMask[8] = {0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE, 0xFF,};
+int bitsInByte[256];
+
+static boolean inittedBitsInByte = FALSE;
+
+void bitsInByteInit(void)
+/* Initialize bitsInByte array. */
+{
+    int i;
+
+    if (!inittedBitsInByte)
+    {
+        inittedBitsInByte = TRUE;
+        for (i=0; i<256; ++i)
+        {
+            int count = 0;
+            if (i&1)
+                count = 1;
+            if (i&2)
+                ++count;
+            if (i&4)
+                ++count;
+            if (i&8)
+                ++count;
+            if (i&0x10)
+                ++count;
+            if (i&0x20)
+                ++count;
+            if (i&0x40)
+                ++count;
+            if (i&0x80)
+                ++count;
+            bitsInByte[i] = count;
+        }
+    }
+}
+
+Bits *bitAlloc(int bitCount)
+/* Allocate bits. */
+{
+    int byteCount = ((bitCount+7)>>3);
+    return needLargeZeroedMem(byteCount);
+}
+
+Bits *bitClone(Bits* orig, int bitCount)
+/* Clone bits. */
+{
+    int byteCount = ((bitCount+7)>>3);
+    Bits* bits = needLargeZeroedMem(byteCount);
+    if(orig!=NULL)
+        memcpy(bits, orig, byteCount);
+    return bits;
+}
+
+void bitFree(Bits **pB)
+/* Free bits. */
+{
+    freez(pB);
+}
+
+void bitSetOne(Bits *b, int bitIx)
+/* Set a single bit. */
+{
+    b[bitIx>>3] |= oneBit[bitIx&7];
+}
+
+void bitClearOne(Bits *b, int bitIx)
+/* Clear a single bit. */
+{
+    b[bitIx>>3] &= ~oneBit[bitIx&7];
+}
+
+void bitSetRange(Bits *b, int startIx, int bitCount)
+/* Set a range of bits. */
+{
+
+    int endIx = (startIx + bitCount - 1);
+    int startByte = (startIx>>3);
+    int endByte = (endIx>>3);
+    int startBits = (startIx&7);
+    int endBits = (endIx&7);
+    int i;
+
+    if (bitCount <= 0)
+        return;
+
+    if (startByte == endByte)
+    {
+        b[startByte] |= (leftMask[startBits] & rightMask[endBits]);
+        return;
+    }
+    b[startByte] |= leftMask[startBits];
+    for (i = startByte+1; i<endByte; ++i)
+        b[i] = 0xff;
+    b[endByte] |= rightMask[endBits];
+}
+
+
+boolean bitReadOne(Bits *b, int bitIx)
+/* Read a single bit. */
+{
+    return (b[bitIx>>3] & oneBit[bitIx&7]) != 0;
+}
+
+int bitCountRange(Bits *b, int startIx, int bitCount)
+/* Count number of bits set in range. */
+{
+    int endIx = (startIx + bitCount - 1);
+    int startByte = (startIx>>3);
+    int endByte = (endIx>>3);
+    int startBits = (startIx&7);
+    int endBits = (endIx&7);
+    int i;
+    int count = 0;
+
+    if (bitCount <= 0)
+        return 0;
+
+    if (!inittedBitsInByte)
+        bitsInByteInit();
+    if (startByte == endByte)
+        return bitsInByte[b[startByte] & leftMask[startBits] & rightMask[endBits]];
+    count = bitsInByte[b[startByte] & leftMask[startBits]];
+    for (i = startByte+1; i<endByte; ++i)
+        count += bitsInByte[b[i]];
+    count += bitsInByte[b[endByte] & rightMask[endBits]];
+    return count;
+}
+
+int bitFind(Bits *b, int startIx, boolean val, int bitCount)
+/* Find the index of the the next set bit. */
+{
+    unsigned char notByteVal = val ? 0 : 0xff;
+    int iBit = startIx;
+    int endByte = ((bitCount-1)>>3);
+    int iByte;
+
+/* scan initial byte */
+    while (((iBit & 7) != 0) && (iBit < bitCount))
+    {
+        if (bitReadOne(b, iBit) == val)
+            return iBit;
+        iBit++;
+    }
+
+/* scan byte at a time, if not already in last byte */
+    iByte = (iBit >> 3);
+    if (iByte < endByte)
+    {
+        while ((iByte < endByte) && (b[iByte] == notByteVal))
+            iByte++;
+        iBit = iByte << 3;
+    }
+
+/* scan last byte */
+    while (iBit < bitCount)
+    {
+        if (bitReadOne(b, iBit) == val)
+            return iBit;
+        iBit++;
+    }
+    return bitCount;  /* not found */
+}
+
+int bitFindSet(Bits *b, int startIx, int bitCount)
+/* Find the index of the the next set bit. */
+{
+    return bitFind(b, startIx, TRUE, bitCount);
+}
+
+int bitFindClear(Bits *b, int startIx, int bitCount)
+/* Find the index of the the next clear bit. */
+{
+    return bitFind(b, startIx, FALSE, bitCount);
+}
+
+void bitClear(Bits *b, int bitCount)
+/* Clear many bits (possibly up to 7 beyond bitCount). */
+{
+    int byteCount = ((bitCount+7)>>3);
+    zeroBytes(b, byteCount);
+}
+
+void bitClearRange(Bits *b, int startIx, int bitCount)
+/* Clear a range of bits. */
+{
+
+    int endIx = (startIx + bitCount - 1);
+    int startByte = (startIx>>3);
+    int endByte = (endIx>>3);
+    int startBits = (startIx&7);
+    int endBits = (endIx&7);
+    int i;
+
+    if (bitCount <= 0)
+        return;
+
+    if (startByte == endByte)
+    {
+        b[startByte] &= ~(leftMask[startBits] & rightMask[endBits]);
+        return;
+    }
+    b[startByte] &= ~leftMask[startBits];
+    for (i = startByte+1; i<endByte; ++i)
+        b[i] = 0x00;
+    b[endByte] &= ~rightMask[endBits];
+}
+
+void bitAnd(Bits *a, Bits *b, int bitCount)
+/* And two bitmaps.  Put result in a. */
+{
+    int byteCount = ((bitCount+7)>>3);
+    while (--byteCount >= 0)
+    {
+        *a = (*a & *b++);
+        a++;
+    }
+}
+
+void bitOr(Bits *a, Bits *b, int bitCount)
+/* Or two bitmaps.  Put result in a. */
+{
+    int byteCount = ((bitCount+7)>>3);
+    while (--byteCount >= 0)
+    {
+        *a = (*a | *b++);
+        a++;
+    }
+}
+
+void bitXor(Bits *a, Bits *b, int bitCount)
+{
+    int byteCount = ((bitCount+7)>>3);
+    while (--byteCount >= 0)
+    {
+        *a = (*a ^ *b++);
+        a++;
+    }
+}
+
+void bitNot(Bits *a, int bitCount)
+/* Flip all bits in a. */
+{
+    int byteCount = ((bitCount+7)>>3);
+    while (--byteCount >= 0)
+    {
+        *a = ~*a;
+        a++;
+    }
+}
+
+void bitPrint(Bits *a, int startIx, int bitCount, FILE* out)
+/* Print part or all of bit map as a string of 0s and 1s.  Mostly useful for
+* debugging */
+{
+    int i;
+    for (i = startIx; i < bitCount; i++)
+    {
+        if (bitReadOne(a, i))
+            fputc('1', out);
+        else
+            fputc('0', out);
+    }
+    fputc('\n', out);
+}
+
diff --git a/src/kent/bits.h b/src/kent/bits.h
new file mode 100644
index 0000000..7377b28
--- /dev/null
+++ b/src/kent/bits.h
@@ -0,0 +1,72 @@
+/* bits - handle operations on arrays of bits. 
+ *
+ * This file is copyright 2002 Jim Kent, but license is hereby
+ * granted for all use - public, private or commercial. */
+
+#ifndef BITS_H
+#define BITS_H
+
+#include "common.h"
+
+typedef unsigned char Bits;
+
+Bits *bitAlloc(int bitCount);
+/* Allocate bits. */
+
+Bits *bitClone(Bits* orig, int bitCount);
+/* Clone bits. */
+
+void bitFree(Bits **pB);
+/* Free bits. */
+
+void bitSetOne(Bits *b, int bitIx);
+/* Set a single bit. */
+
+void bitClearOne(Bits *b, int bitIx);
+/* Clear a single bit. */
+
+void bitSetRange(Bits *b, int startIx, int bitCount);
+/* Set a range of bits. */
+
+boolean bitReadOne(Bits *b, int bitIx);
+/* Read a single bit. */
+
+int bitCountRange(Bits *b, int startIx, int bitCount);
+/* Count number of bits set in range. */
+
+int bitFindSet(Bits *b, int startIx, int bitCount);
+/* Find the index of the the next set bit. */
+
+int bitFindClear(Bits *b, int startIx, int bitCount);
+/* Find the index of the the next clear bit. */
+
+void bitClear(Bits *b, int bitCount);
+/* Clear many bits (possibly up to 7 beyond bitCount). */
+
+void bitClearRange(Bits *b, int startIx, int bitCount);
+/* Clear a range of bits. */
+
+void bitAnd(Bits *a, Bits *b, int bitCount);
+/* And two bitmaps.  Put result in a. */
+
+void bitOr(Bits *a, Bits *b, int bitCount);
+/* Or two bitmaps.  Put result in a. */
+
+void bitXor(Bits *a, Bits *b, int bitCount);
+/* Xor two bitmaps.  Put result in a. */
+
+void bitNot(Bits *a, int bitCount);
+/* Flip all bits in a. */
+
+void bitPrint(Bits *a, int startIx, int bitCount, FILE* out);
+/* Print part or all of bit map as a string of 0s and 1s.  Mostly useful for
+ * debugging */
+
+extern int bitsInByte[256];
+/* Lookup table for how many bits are set in a byte. */
+
+void bitsInByteInit(void);
+/* Initialize bitsInByte array. */
+
+#endif /* BITS_H */
+
diff --git a/src/kent/common.c b/src/kent/common.c
new file mode 100644
index 0000000..55528f6
--- /dev/null
+++ b/src/kent/common.c
@@ -0,0 +1,62 @@
+#include "common.h"
+
+void *needMem(size_t size)
+        /* Need mem calls abort if the memory allocation fails. The memory
+         *  * is initialized to zero. */
+{
+        void *pt;
+        if ((pt = malloc(size)) == NULL)
+        {        
+                    fprintf( stderr, "Out of memory needMem - request size %llu bytes\n",
+                                                 (unsigned long long)size);
+                    exit(1);
+        }            
+        memset(pt, 0, size);
+        return pt;
+}
+
+void freeMem(void *pt)
+        /* Free memory will check for null before freeing. */
+{
+        if (pt != NULL)
+                    free(pt);
+}
+
+
+void *needLargeZeroedMem(size_t size)
+        /* Request a large block of memory and zero it. */
+{
+        void *v;
+        /*v = needLargeMem(size);*/
+        v = malloc(size);
+	/* 
+	 * If you do memset(NULL,0,size), there will be a segfault. 
+	 * So check v for NULL 
+	 */
+	if( v != NULL )
+        memset(v, 0, size);
+        return v;
+}
+
+void freez(void *vpt)
+        /* Pass address of pointer.  Will free pointer and set it 
+         *  * to NULL. */
+{
+        void **ppt = (void **)vpt;
+        void *pt = *ppt;
+        *ppt = NULL;
+        freeMem(pt);
+}
+
+/* fill a specified area of memory with zeroes 
+ * If you do zeroBytes(NULL,count), there will be a segfault. 
+ * So check pt for NULL 
+ */
+void zeroBytes(void *vpt, int count)
+{
+        char *pt = (char*)vpt;
+	if(pt != NULL ){
+        while (--count>=0)
+                    *pt++=0;
+	}
+}
diff --git a/src/kent/common.h b/src/kent/common.h
new file mode 100644
index 0000000..13d1b68
--- /dev/null
+++ b/src/kent/common.h
@@ -0,0 +1,32 @@
+#ifndef __COMMON_H__
+#define __COMMON_H__
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <math.h>
+
+/* Let's pretend C has a boolean type. */
+#define TRUE 1
+#define FALSE 0
+#define boolean int
+#define bool char
+
+#define AllocVar(pt) (pt = needMem(sizeof(*pt)))
+/* Shortcut to allocating a single variable on the heap and
+ *  * assigning pointer to it. */
+
+#define AllocArray(pt, size) (pt = needLargeZeroedMem(sizeof(*pt) * (size)))
+
+void *needMem(size_t size);
+
+void freeMem(void *pt);
+
+void *needLargeZeroedMem(size_t size);
+
+void freez(void *vpt);
+
+void zeroBytes(void *vpt, int count);
+
+#endif
diff --git a/src/pwm_utils.c b/src/pwm_utils.c
new file mode 100644
index 0000000..3303b10
--- /dev/null
+++ b/src/pwm_utils.c
@@ -0,0 +1,63 @@
+
+#include <ctype.h>
+#include <stdio.h>
+#include <strings.h>
+
+int symbol_match( char, char);
+int pattern_match( char*, char*, int);
+
+int main(int argc, char** argv) {
+    if (argc == 3) {
+        int string_size = strlen(argv[1]);
+        if (strlen(argv[2]) != string_size) {
+            fprintf(stdout, "%s != %s\n", argv[1], argv[2]);
+            return 1;
+        }
+        if ( pattern_match( argv[1], argv[2], string_size) )
+            fprintf(stdout, "%s == %s\n", argv[1], argv[2]);
+        else
+            fprintf(stdout, "%s != %s\n", argv[1], argv[2]);
+    }
+    return 0;
+}
+
+int pattern_match( char* string, char* pattern, int n){
+    int i = 0;
+    while (i<n) {
+        if (! symbol_match( string[i], pattern[i] )) return 0;
+        i++;
+    }
+    return 1;
+}
+
+int symbol_match( char s, char p ) {
+    char P = toupper(p);
+    char S = toupper(s);
+    if (P == 'N') return 1;
+    switch(P){
+        case 'A': return S=='A';
+        case 'C': return S=='C';
+        case 'G': return S=='G';
+        case 'T': return S=='T';
+        // IUPAC-UB nomenclature for two-fold degenerate symbols
+        case 'R':
+            if (S=='A' || S=='G') return 1;
+            else return 0;
+        case 'Y':
+            if (S=='C' || S=='T') return 1;
+            else return 0;
+        case 'M':
+            if (S=='A' || S=='C') return 1;
+            else return 0;
+        case 'K':
+            if (S=='G' || S=='T') return 1;
+            else return 0;
+        case 'S':
+            if (S=='G' || S=='C') return 1;
+            else return 0;
+        case 'W':
+            if (S=='A' || S=='T') return 1;
+            else return 0;
+    }
+    return 0;
+}
diff --git a/src/pwm_utils.h b/src/pwm_utils.h
new file mode 100644
index 0000000..8970aca
--- /dev/null
+++ b/src/pwm_utils.h
@@ -0,0 +1,3 @@
+
+int symbol_match( char, char);
+int pattern_match( char*, char*, int);
diff --git a/src/samtools/bgzf.c b/src/samtools/bgzf.c
new file mode 100644
index 0000000..0219cf9
--- /dev/null
+++ b/src/samtools/bgzf.c
@@ -0,0 +1,693 @@
+/* The MIT License
+
+   Copyright (c) 2008 Broad Institute / Massachusetts Institute of Technology
+
+   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.
+*/
+
+/*
+  2009-06-29 by lh3: cache recent uncompressed blocks.
+  2009-06-25 by lh3: optionally use my knetfile library to access file on a FTP.
+  2009-06-12 by lh3: support a mode string like "wu" where 'u' for uncompressed output */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include "bgzf.h"
+
+#include "khash.h"
+typedef struct {
+	int size;
+	uint8_t *block;
+	int64_t end_offset;
+} cache_t;
+KHASH_MAP_INIT_INT64(cache, cache_t)
+
+#if defined(_WIN32) || defined(_MSC_VER)
+#define ftello(fp) ftell(fp)
+#define fseeko(fp, offset, whence) fseek(fp, offset, whence)
+#else
+extern off_t ftello(FILE *stream);
+extern int fseeko(FILE *stream, off_t offset, int whence);
+#endif
+
+typedef int8_t bgzf_byte_t;
+
+static const int DEFAULT_BLOCK_SIZE = 64 * 1024;
+static const int MAX_BLOCK_SIZE = 64 * 1024;
+
+static const int BLOCK_HEADER_LENGTH = 18;
+static const int BLOCK_FOOTER_LENGTH = 8;
+
+static const int GZIP_ID1 = 31;
+static const int GZIP_ID2 = 139;
+static const int CM_DEFLATE = 8;
+static const int FLG_FEXTRA = 4;
+static const int OS_UNKNOWN = 255;
+static const int BGZF_ID1 = 66; // 'B'
+static const int BGZF_ID2 = 67; // 'C'
+static const int BGZF_LEN = 2;
+static const int BGZF_XLEN = 6; // BGZF_LEN+4
+
+static const int GZIP_WINDOW_BITS = -15; // no zlib header
+static const int Z_DEFAULT_MEM_LEVEL = 8;
+
+
+inline
+void
+packInt16(uint8_t* buffer, uint16_t value)
+{
+    buffer[0] = value;
+    buffer[1] = value >> 8;
+}
+
+inline
+int
+unpackInt16(const uint8_t* buffer)
+{
+    return (buffer[0] | (buffer[1] << 8));
+}
+
+inline
+void
+packInt32(uint8_t* buffer, uint32_t value)
+{
+    buffer[0] = value;
+    buffer[1] = value >> 8;
+    buffer[2] = value >> 16;
+    buffer[3] = value >> 24;
+}
+
+static inline
+int
+bgzf_min(int x, int y)
+{
+    return (x < y) ? x : y;
+}
+
+static
+void
+report_error(BGZF* fp, const char* message) {
+    fp->error = message;
+}
+
+static BGZF *bgzf_read_init()
+{
+	BGZF *fp;
+	fp = calloc(1, sizeof(BGZF));
+    fp->uncompressed_block_size = MAX_BLOCK_SIZE;
+    fp->uncompressed_block = malloc(MAX_BLOCK_SIZE);
+    fp->compressed_block_size = MAX_BLOCK_SIZE;
+    fp->compressed_block = malloc(MAX_BLOCK_SIZE);
+	fp->cache_size = 0;
+	fp->cache = kh_init(cache);
+	return fp;
+}
+
+static
+BGZF*
+open_read(int fd)
+{
+#ifdef _USE_KNETFILE
+    knetFile *file = knet_dopen(fd, "r");
+#else
+    FILE* file = fdopen(fd, "r");
+#endif
+    BGZF* fp;
+	if (file == 0) return 0;
+	fp = bgzf_read_init();
+    fp->file_descriptor = fd;
+    fp->open_mode = 'r';
+#ifdef _USE_KNETFILE
+    fp->x.fpr = file;
+#else
+    fp->file = file;
+#endif
+    return fp;
+}
+
+static
+BGZF*
+open_write(int fd, bool is_uncompressed)
+{
+    FILE* file = fdopen(fd, "w");
+    BGZF* fp;
+	if (file == 0) return 0;
+	fp = malloc(sizeof(BGZF));
+    fp->file_descriptor = fd;
+    fp->open_mode = 'w';
+    fp->owned_file = 0; fp->is_uncompressed = is_uncompressed;
+#ifdef _USE_KNETFILE
+    fp->x.fpw = file;
+#else
+    fp->file = file;
+#endif
+    fp->uncompressed_block_size = DEFAULT_BLOCK_SIZE;
+    fp->uncompressed_block = NULL;
+    fp->compressed_block_size = MAX_BLOCK_SIZE;
+    fp->compressed_block = malloc(MAX_BLOCK_SIZE);
+    fp->block_address = 0;
+    fp->block_offset = 0;
+    fp->block_length = 0;
+    fp->error = NULL;
+    return fp;
+}
+
+#ifdef __SUNPRO_C
+BGZF*
+bgzf_open(const char* path, const char* mode)
+#else
+BGZF*
+bgzf_open(const char* __restrict path, const char* __restrict mode)
+#endif
+{
+    BGZF* fp = NULL;
+    if (mode[0] == 'r' || mode[0] == 'R') { /* The reading mode is preferred. */
+#ifdef _USE_KNETFILE
+		knetFile *file = knet_open(path, mode);
+		if (file == 0) return 0;
+		fp = bgzf_read_init();
+		fp->file_descriptor = -1;
+		fp->open_mode = 'r';
+		fp->x.fpr = file;
+#else
+		int fd, oflag = O_RDONLY;
+#ifdef _WIN32
+		oflag |= O_BINARY;
+#endif
+		fd = open(path, oflag);
+		if (fd == -1) return 0;
+        fp = open_read(fd);
+#endif
+    } else if (mode[0] == 'w' || mode[0] == 'W') {
+		int fd, oflag = O_WRONLY | O_CREAT | O_TRUNC;
+#ifdef _WIN32
+		oflag |= O_BINARY;
+#endif
+		fd = open(path, oflag, 0666);
+		if (fd == -1) return 0;
+        fp = open_write(fd, strstr(mode, "u")? 1 : 0);
+    }
+    if (fp != NULL) {
+        fp->owned_file = 1;
+    }
+    return fp;
+}
+
+#ifdef __SUNPRO_C
+BGZF*
+bgzf_fdopen(int fd, const char * mode)
+#else
+BGZF*
+bgzf_fdopen(int fd, const char * __restrict mode)
+#endif
+{
+	if (fd == -1) return 0;
+    if (mode[0] == 'r' || mode[0] == 'R') {
+        return open_read(fd);
+    } else if (mode[0] == 'w' || mode[0] == 'W') {
+        return open_write(fd, strstr(mode, "u")? 1 : 0);
+    } else {
+        return NULL;
+    }
+}
+
+static
+int
+deflate_block(BGZF* fp, int block_length)
+{
+    // Deflate the block in fp->uncompressed_block into fp->compressed_block.
+    // Also adds an extra field that stores the compressed block length.
+
+    bgzf_byte_t* buffer = fp->compressed_block;
+    int buffer_size = fp->compressed_block_size;
+
+    // Init gzip header
+    buffer[0] = GZIP_ID1;
+    buffer[1] = GZIP_ID2;
+    buffer[2] = CM_DEFLATE;
+    buffer[3] = FLG_FEXTRA;
+    buffer[4] = 0; // mtime
+    buffer[5] = 0;
+    buffer[6] = 0;
+    buffer[7] = 0;
+    buffer[8] = 0;
+    buffer[9] = OS_UNKNOWN;
+    buffer[10] = BGZF_XLEN;
+    buffer[11] = 0;
+    buffer[12] = BGZF_ID1;
+    buffer[13] = BGZF_ID2;
+    buffer[14] = BGZF_LEN;
+    buffer[15] = 0;
+    buffer[16] = 0; // placeholder for block length
+    buffer[17] = 0;
+
+    // loop to retry for blocks that do not compress enough
+    int input_length = block_length;
+    int compressed_length = 0;
+    while (1) {
+		int compress_level = fp->is_uncompressed? 0 : Z_DEFAULT_COMPRESSION;
+        z_stream zs;
+        zs.zalloc = NULL;
+        zs.zfree = NULL;
+        zs.next_in = fp->uncompressed_block;
+        zs.avail_in = input_length;
+        zs.next_out = (void*)&buffer[BLOCK_HEADER_LENGTH];
+        zs.avail_out = buffer_size - BLOCK_HEADER_LENGTH - BLOCK_FOOTER_LENGTH;
+
+        int status = deflateInit2(&zs, compress_level, Z_DEFLATED,
+                                  GZIP_WINDOW_BITS, Z_DEFAULT_MEM_LEVEL, Z_DEFAULT_STRATEGY);
+        if (status != Z_OK) {
+            report_error(fp, "deflate init failed");
+            return -1;
+        }
+        status = deflate(&zs, Z_FINISH);
+        if (status != Z_STREAM_END) {
+            deflateEnd(&zs);
+            if (status == Z_OK) {
+                // Not enough space in buffer.
+                // Can happen in the rare case the input doesn't compress enough.
+                // Reduce the amount of input until it fits.
+                input_length -= 1024;
+                if (input_length <= 0) {
+                    // should never happen
+                    report_error(fp, "input reduction failed");
+                    return -1;
+                }
+                continue;
+            }
+            report_error(fp, "deflate failed");
+            return -1;
+        }
+        status = deflateEnd(&zs);
+        if (status != Z_OK) {
+            report_error(fp, "deflate end failed");
+            return -1;
+        }
+        compressed_length = zs.total_out;
+        compressed_length += BLOCK_HEADER_LENGTH + BLOCK_FOOTER_LENGTH;
+        if (compressed_length > MAX_BLOCK_SIZE) {
+            // should never happen
+            report_error(fp, "deflate overflow");
+            return -1;
+        }
+        break;
+    }
+
+    packInt16((uint8_t*)&buffer[16], compressed_length-1);
+    uint32_t crc = crc32(0L, NULL, 0L);
+    crc = crc32(crc, fp->uncompressed_block, input_length);
+    packInt32((uint8_t*)&buffer[compressed_length-8], crc);
+    packInt32((uint8_t*)&buffer[compressed_length-4], input_length);
+
+    int remaining = block_length - input_length;
+    if (remaining > 0) {
+        if (remaining > input_length) {
+            // should never happen (check so we can use memcpy)
+            report_error(fp, "remainder too large");
+            return -1;
+        }
+        memcpy(fp->uncompressed_block,
+               fp->uncompressed_block + input_length,
+               remaining);
+    }
+    fp->block_offset = remaining;
+    return compressed_length;
+}
+
+static
+int
+inflate_block(BGZF* fp, int block_length)
+{
+    // Inflate the block in fp->compressed_block into fp->uncompressed_block
+
+    z_stream zs;
+    zs.zalloc = NULL;
+    zs.zfree = NULL;
+    zs.next_in = fp->compressed_block + 18;
+    zs.avail_in = block_length - 16;
+    zs.next_out = fp->uncompressed_block;
+    zs.avail_out = fp->uncompressed_block_size;
+
+    int status = inflateInit2(&zs, GZIP_WINDOW_BITS);
+    if (status != Z_OK) {
+        report_error(fp, "inflate init failed");
+        return -1;
+    }
+    status = inflate(&zs, Z_FINISH);
+    if (status != Z_STREAM_END) {
+        inflateEnd(&zs);
+        report_error(fp, "inflate failed");
+        return -1;
+    }
+    status = inflateEnd(&zs);
+    if (status != Z_OK) {
+        report_error(fp, "inflate failed");
+        return -1;
+    }
+    return zs.total_out;
+}
+
+static
+int
+check_header(const bgzf_byte_t* header)
+{
+    return (header[0] == GZIP_ID1 &&
+            header[1] == (bgzf_byte_t) GZIP_ID2 &&
+            header[2] == Z_DEFLATED &&
+            (header[3] & FLG_FEXTRA) != 0 &&
+            unpackInt16((uint8_t*)&header[10]) == BGZF_XLEN &&
+            header[12] == BGZF_ID1 &&
+            header[13] == BGZF_ID2 &&
+            unpackInt16((uint8_t*)&header[14]) == BGZF_LEN);
+}
+
+static void free_cache(BGZF *fp)
+{
+	khint_t k;
+	khash_t(cache) *h = (khash_t(cache)*)fp->cache;
+	if (fp->open_mode != 'r') return;
+	for (k = kh_begin(h); k < kh_end(h); ++k)
+		if (kh_exist(h, k)) free(kh_val(h, k).block);
+	kh_destroy(cache, h);
+}
+
+static int load_block_from_cache(BGZF *fp, int64_t block_address)
+{
+	khint_t k;
+	cache_t *p;
+	khash_t(cache) *h = (khash_t(cache)*)fp->cache;
+	k = kh_get(cache, h, block_address);
+	if (k == kh_end(h)) return 0;
+	p = &kh_val(h, k);
+	if (fp->block_length != 0) fp->block_offset = 0;
+	fp->block_address = block_address;
+	fp->block_length = p->size;
+	memcpy(fp->uncompressed_block, p->block, MAX_BLOCK_SIZE);
+#ifdef _USE_KNETFILE
+	knet_seek(fp->x.fpr, p->end_offset, SEEK_SET);
+#else
+	fseeko(fp->file, p->end_offset, SEEK_SET);
+#endif
+	return p->size;
+}
+
+static void cache_block(BGZF *fp, int size)
+{
+	int ret;
+	khint_t k;
+	cache_t *p;
+	khash_t(cache) *h = (khash_t(cache)*)fp->cache;
+	if (MAX_BLOCK_SIZE >= fp->cache_size) return;
+	if ((kh_size(h) + 1) * MAX_BLOCK_SIZE > fp->cache_size) {
+		/* A better way would be to remove the oldest block in the
+		 * cache, but here we remove a random one for simplicity. This
+		 * should not have a big impact on performance. */
+		for (k = kh_begin(h); k < kh_end(h); ++k)
+			if (kh_exist(h, k)) break;
+		if (k < kh_end(h)) {
+			free(kh_val(h, k).block);
+			kh_del(cache, h, k);
+		}
+	}
+	k = kh_put(cache, h, fp->block_address, &ret);
+	if (ret == 0) return; // if this happens, a bug!
+	p = &kh_val(h, k);
+	p->size = fp->block_length;
+	p->end_offset = fp->block_address + size;
+	p->block = malloc(MAX_BLOCK_SIZE);
+	memcpy(kh_val(h, k).block, fp->uncompressed_block, MAX_BLOCK_SIZE);
+}
+
+static
+int
+read_block(BGZF* fp)
+{
+    bgzf_byte_t header[BLOCK_HEADER_LENGTH];
+	int size = 0;
+#ifdef _USE_KNETFILE
+    int64_t block_address = knet_tell(fp->x.fpr);
+	if (load_block_from_cache(fp, block_address)) return 0;
+    int count = knet_read(fp->x.fpr, header, sizeof(header));
+#else
+    int64_t block_address = ftello(fp->file);
+	if (load_block_from_cache(fp, block_address)) return 0;
+    int count = fread(header, 1, sizeof(header), fp->file);
+#endif
+    if (count == 0) {
+        fp->block_length = 0;
+        return 0;
+    }
+	size = count;
+    if (count != sizeof(header)) {
+        report_error(fp, "read failed");
+        return -1;
+    }
+    if (!check_header(header)) {
+        report_error(fp, "invalid block header");
+        return -1;
+    }
+    int block_length = unpackInt16((uint8_t*)&header[16]) + 1;
+    bgzf_byte_t* compressed_block = (bgzf_byte_t*) fp->compressed_block;
+    memcpy(compressed_block, header, BLOCK_HEADER_LENGTH);
+    int remaining = block_length - BLOCK_HEADER_LENGTH;
+#ifdef _USE_KNETFILE
+    count = knet_read(fp->x.fpr, &compressed_block[BLOCK_HEADER_LENGTH], remaining);
+#else
+    count = fread(&compressed_block[BLOCK_HEADER_LENGTH], 1, remaining, fp->file);
+#endif
+    if (count != remaining) {
+        report_error(fp, "read failed");
+        return -1;
+    }
+	size += count;
+    count = inflate_block(fp, block_length);
+    if (count < 0) {
+        return -1;
+    }
+    if (fp->block_length != 0) {
+        // Do not reset offset if this read follows a seek.
+        fp->block_offset = 0;
+    }
+    fp->block_address = block_address;
+    fp->block_length = count;
+	cache_block(fp, size);
+    return 0;
+}
+
+int
+bgzf_read(BGZF* fp, void* data, int length)
+{
+    if (length <= 0) {
+        return 0;
+    }
+    if (fp->open_mode != 'r') {
+        report_error(fp, "file not open for reading");
+        return -1;
+    }
+
+    int bytes_read = 0;
+    bgzf_byte_t* output = data;
+    while (bytes_read < length) {
+        int available = fp->block_length - fp->block_offset;
+        if (available <= 0) {
+            if (read_block(fp) != 0) {
+                return -1;
+            }
+            available = fp->block_length - fp->block_offset;
+            if (available <= 0) {
+                break;
+            }
+        }
+        int copy_length = bgzf_min(length-bytes_read, available);
+        bgzf_byte_t* buffer = fp->uncompressed_block;
+        memcpy(output, buffer + fp->block_offset, copy_length);
+        fp->block_offset += copy_length;
+        output += copy_length;
+        bytes_read += copy_length;
+    }
+    if (fp->block_offset == fp->block_length) {
+#ifdef _USE_KNETFILE
+        fp->block_address = knet_tell(fp->x.fpr);
+#else
+        fp->block_address = ftello(fp->file);
+#endif
+        fp->block_offset = 0;
+        fp->block_length = 0;
+    }
+    return bytes_read;
+}
+
+static
+int
+flush_block(BGZF* fp)
+{
+    while (fp->block_offset > 0) {
+        int block_length = deflate_block(fp, fp->block_offset);
+        if (block_length < 0) {
+            return -1;
+        }
+#ifdef _USE_KNETFILE
+        int count = fwrite(fp->compressed_block, 1, block_length, fp->x.fpw);
+#else
+        int count = fwrite(fp->compressed_block, 1, block_length, fp->file);
+#endif
+        if (count != block_length) {
+            report_error(fp, "write failed");
+            return -1;
+        }
+        fp->block_address += block_length;
+    }
+    return 0;
+}
+
+int
+bgzf_write(BGZF* fp, const void* data, int length)
+{
+    if (fp->open_mode != 'w') {
+        report_error(fp, "file not open for writing");
+        return -1;
+    }
+
+    if (fp->uncompressed_block == NULL) {
+        fp->uncompressed_block = malloc(fp->uncompressed_block_size);
+    }
+
+    const bgzf_byte_t* input = data;
+    int block_length = fp->uncompressed_block_size;
+    int bytes_written = 0;
+    while (bytes_written < length) {
+        int copy_length = bgzf_min(block_length - fp->block_offset, length - bytes_written);
+        bgzf_byte_t* buffer = fp->uncompressed_block;
+        memcpy(buffer + fp->block_offset, input, copy_length);
+        fp->block_offset += copy_length;
+        input += copy_length;
+        bytes_written += copy_length;
+        if (fp->block_offset == block_length) {
+            if (flush_block(fp) != 0) {
+                break;
+            }
+        }
+    }
+    return bytes_written;
+}
+
+int
+bgzf_close(BGZF* fp)
+{
+    if (fp->open_mode == 'w') {
+        if (flush_block(fp) != 0) {
+            return -1;
+        }
+		{ // add an empty block
+			int count, block_length = deflate_block(fp, 0);
+#ifdef _USE_KNETFILE
+			count = fwrite(fp->compressed_block, 1, block_length, fp->x.fpw);
+#else
+			count = fwrite(fp->compressed_block, 1, block_length, fp->file);
+#endif
+		}
+#ifdef _USE_KNETFILE
+        if (fflush(fp->x.fpw) != 0) {
+#else
+        if (fflush(fp->file) != 0) {
+#endif
+            report_error(fp, "flush failed");
+            return -1;
+        }
+    }
+    if (fp->owned_file) {
+#ifdef _USE_KNETFILE
+		int ret;
+		if (fp->open_mode == 'w') ret = fclose(fp->x.fpw);
+		else ret = knet_close(fp->x.fpr);
+        if (ret != 0) return -1;
+#else
+        if (fclose(fp->file) != 0) {
+            return -1;
+        }
+#endif
+    }
+    free(fp->uncompressed_block);
+    free(fp->compressed_block);
+	free_cache(fp);
+    free(fp);
+    return 0;
+}
+
+int64_t
+bgzf_tell(BGZF* fp)
+{
+    return ((fp->block_address << 16) | (fp->block_offset & 0xFFFF));
+}
+
+void bgzf_set_cache_size(BGZF *fp, int cache_size)
+{
+	if (fp) fp->cache_size = cache_size;
+}
+
+int bgzf_check_EOF(BGZF *fp)
+{
+	static uint8_t magic[28] = "\037\213\010\4\0\0\0\0\0\377\6\0\102\103\2\0\033\0\3\0\0\0\0\0\0\0\0\0";
+	uint8_t buf[28];
+	off_t offset;
+#ifdef _USE_KNETFILE
+	offset = knet_tell(fp->x.fpr);
+	if (knet_seek(fp->x.fpr, -28, SEEK_END) != 0) return -1;
+	knet_read(fp->x.fpr, buf, 28);
+	knet_seek(fp->x.fpr, offset, SEEK_SET);
+#else
+	offset = ftello(fp->file);
+	if (fseeko(fp->file, -28, SEEK_END) != 0) return -1;
+	fread(buf, 1, 28, fp->file);
+	fseeko(fp->file, offset, SEEK_SET);
+#endif
+	return (memcmp(magic, buf, 28) == 0)? 1 : 0;
+}
+
+int64_t
+bgzf_seek(BGZF* fp, int64_t pos, int where)
+{
+    if (fp->open_mode != 'r') {
+        report_error(fp, "file not open for read");
+        return -1;
+    }
+    if (where != SEEK_SET) {
+        report_error(fp, "unimplemented seek option");
+        return -1;
+    }
+    int block_offset = pos & 0xFFFF;
+    int64_t block_address = (pos >> 16) & 0xFFFFFFFFFFFFLL;
+#ifdef _USE_KNETFILE
+    if (knet_seek(fp->x.fpr, block_address, SEEK_SET) != 0) {
+#else
+    if (fseeko(fp->file, block_address, SEEK_SET) != 0) {
+#endif
+        report_error(fp, "seek failed");
+        return -1;
+    }
+    fp->block_length = 0;  // indicates current block is not loaded
+    fp->block_address = block_address;
+    fp->block_offset = block_offset;
+    return 0;
+}
diff --git a/src/samtools/bgzf.h b/src/samtools/bgzf.h
new file mode 100644
index 0000000..45f3af3
--- /dev/null
+++ b/src/samtools/bgzf.h
@@ -0,0 +1,142 @@
+/* The MIT License
+
+   Copyright (c) 2008 Broad Institute / Massachusetts Institute of Technology
+
+   Permission is hereby granted, free of charge, to any person obtaining a copy
+   of this software and associated documentation files (the "Software"), to deal
+   in the Software without restriction, including without limitation the rights
+   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+   copies of the Software, and to permit persons to whom the Software is
+   furnished to do so, subject to the following conditions:
+
+   The above copyright notice and this permission notice shall be included in
+   all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+   THE SOFTWARE.
+*/
+
+#ifndef __BGZF_H
+#define __BGZF_H
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <zlib.h>
+#ifdef _USE_KNETFILE
+#include "knetfile.h"
+#endif
+
+//typedef int8_t bool;
+
+typedef struct {
+    int file_descriptor;
+    char open_mode;  // 'r' or 'w'
+    bool owned_file, is_uncompressed;
+#ifdef _USE_KNETFILE
+	union {
+		knetFile *fpr;
+		FILE *fpw;
+	} x;
+#else
+    FILE* file;
+#endif
+    int uncompressed_block_size;
+    int compressed_block_size;
+    void* uncompressed_block;
+    void* compressed_block;
+    int64_t block_address;
+    int block_length;
+    int block_offset;
+	int cache_size;
+    const char* error;
+	void *cache; // a pointer to a hash table
+} BGZF;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Open an existing file descriptor for reading or writing.
+ * Mode must be either "r" or "w".
+ * A subsequent bgzf_close will not close the file descriptor.
+ * Returns null on error.
+ */
+#ifdef __SUNPRO_C
+BGZF* bgzf_fdopen(int fd, const char* mode);
+#else
+BGZF* bgzf_fdopen(int fd, const char* __restrict mode);
+#endif
+
+/*
+ * Open the specified file for reading or writing.
+ * Mode must be either "r" or "w".
+ * Returns null on error.
+ */
+#ifdef __SUNPRO_C
+BGZF* bgzf_open(const char* path, const char* mode);
+#else
+BGZF* bgzf_open(const char* path, const char* __restrict mode);
+#endif
+
+/*
+ * Close the BGZ file and free all associated resources.
+ * Does not close the underlying file descriptor if created with bgzf_fdopen.
+ * Returns zero on success, -1 on error.
+ */
+int bgzf_close(BGZF* fp);
+
+/*
+ * Read up to length bytes from the file storing into data.
+ * Returns the number of bytes actually read.
+ * Returns zero on end of file.
+ * Returns -1 on error.
+ */
+int bgzf_read(BGZF* fp, void* data, int length);
+
+/*
+ * Write length bytes from data to the file.
+ * Returns the number of bytes written.
+ * Returns -1 on error.
+ */
+int bgzf_write(BGZF* fp, const void* data, int length);
+
+/*
+ * Return a virtual file pointer to the current location in the file.
+ * No interpetation of the value should be made, other than a subsequent
+ * call to bgzf_seek can be used to position the file at the same point.
+ * Return value is non-negative on success.
+ * Returns -1 on error.
+ */
+int64_t bgzf_tell(BGZF* fp);
+
+/*
+ * Set the file to read from the location specified by pos, which must
+ * be a value previously returned by bgzf_tell for this file (but not
+ * necessarily one returned by this file handle).
+ * The where argument must be SEEK_SET.
+ * Seeking on a file opened for write is not supported.
+ * Returns zero on success, -1 on error.
+ */
+int64_t bgzf_seek(BGZF* fp, int64_t pos, int where);
+
+/*
+ * Set the cache size. Zero to disable. By default, caching is
+ * disabled. The recommended cache size for frequent random access is
+ * about 8M bytes.
+ */
+void bgzf_set_cache_size(BGZF *fp, int cache_size);
+
+int bgzf_check_EOF(BGZF *fp);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/samtools/khash.h b/src/samtools/khash.h
new file mode 100644
index 0000000..1d583ef
--- /dev/null
+++ b/src/samtools/khash.h
@@ -0,0 +1,486 @@
+/* The MIT License
+
+   Copyright (c) 2008 Genome Research Ltd (GRL).
+
+   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.
+*/
+
+/* Contact: Heng Li <lh3 at sanger.ac.uk> */
+
+/*
+  An example:
+
+#include "khash.h"
+KHASH_MAP_INIT_INT(32, char)
+int main() {
+	int ret, is_missing;
+	khiter_t k;
+	khash_t(32) *h = kh_init(32);
+	k = kh_put(32, h, 5, &ret);
+	if (!ret) kh_del(32, h, k);
+	kh_value(h, k) = 10;
+	k = kh_get(32, h, 10);
+	is_missing = (k == kh_end(h));
+	k = kh_get(32, h, 5);
+	kh_del(32, h, k);
+	for (k = kh_begin(h); k != kh_end(h); ++k)
+		if (kh_exist(h, k)) kh_value(h, k) = 1;
+	kh_destroy(32, h);
+	return 0;
+}
+*/
+
+/*
+  2008-09-19 (0.2.3):
+
+	* Corrected the example
+	* Improved interfaces
+
+  2008-09-11 (0.2.2):
+
+	* Improved speed a little in kh_put()
+
+  2008-09-10 (0.2.1):
+
+	* Added kh_clear()
+	* Fixed a compiling error
+
+  2008-09-02 (0.2.0):
+
+	* Changed to token concatenation which increases flexibility.
+
+  2008-08-31 (0.1.2):
+
+	* Fixed a bug in kh_get(), which has not been tested previously.
+
+  2008-08-31 (0.1.1):
+
+	* Added destructor
+*/
+
+
+#ifndef __AC_KHASH_H
+#define __AC_KHASH_H
+
+/*!
+  @header
+
+  Generic hash table library.
+
+  @copyright Heng Li
+ */
+
+#define AC_VERSION_KHASH_H "0.2.2"
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+typedef uint32_t khint_t;
+typedef khint_t khiter_t;
+
+#define __ac_HASH_PRIME_SIZE 32
+static const uint32_t __ac_prime_list[__ac_HASH_PRIME_SIZE] =
+{
+  0ul,          3ul,          11ul,         23ul,         53ul,
+  97ul,         193ul,        389ul,        769ul,        1543ul,
+  3079ul,       6151ul,       12289ul,      24593ul,      49157ul,
+  98317ul,      196613ul,     393241ul,     786433ul,     1572869ul,
+  3145739ul,    6291469ul,    12582917ul,   25165843ul,   50331653ul,
+  100663319ul,  201326611ul,  402653189ul,  805306457ul,  1610612741ul,
+  3221225473ul, 4294967291ul
+};
+
+#define __ac_isempty(flag, i) ((flag[i>>4]>>((i&0xfU)<<1))&2)
+#define __ac_isdel(flag, i) ((flag[i>>4]>>((i&0xfU)<<1))&1)
+#define __ac_iseither(flag, i) ((flag[i>>4]>>((i&0xfU)<<1))&3)
+#define __ac_set_isdel_false(flag, i) (flag[i>>4]&=~(1ul<<((i&0xfU)<<1)))
+#define __ac_set_isempty_false(flag, i) (flag[i>>4]&=~(2ul<<((i&0xfU)<<1)))
+#define __ac_set_isboth_false(flag, i) (flag[i>>4]&=~(3ul<<((i&0xfU)<<1)))
+#define __ac_set_isdel_true(flag, i) (flag[i>>4]|=1ul<<((i&0xfU)<<1))
+
+static const double __ac_HASH_UPPER = 0.77;
+
+#define KHASH_INIT(name, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal) \
+	typedef struct {													\
+		khint_t n_buckets, size, n_occupied, upper_bound;				\
+		uint32_t *flags;												\
+		khkey_t *keys;													\
+		khval_t *vals;													\
+	} kh_##name##_t;													\
+	static inline kh_##name##_t *kh_init_##name() {						\
+		return (kh_##name##_t*)calloc(1, sizeof(kh_##name##_t));		\
+	}																	\
+	static inline void kh_destroy_##name(kh_##name##_t *h)				\
+	{																	\
+		if (h) {														\
+			free(h->keys); free(h->flags);								\
+			free(h->vals);												\
+			free(h);													\
+		}																\
+	}																	\
+	static inline void kh_clear_##name(kh_##name##_t *h)				\
+	{																	\
+		if (h && h->flags) {											\
+			memset(h->flags, 0xaa, ((h->n_buckets>>4) + 1) * sizeof(uint32_t)); \
+			h->size = h->n_occupied = 0;								\
+		}																\
+	}																	\
+	static inline khint_t kh_get_##name(const kh_##name##_t *h, khkey_t key) \
+	{																	\
+		if (h->n_buckets) {												\
+			khint_t inc, k, i, last;									\
+			k = __hash_func(key); i = k % h->n_buckets;					\
+			inc = 1 + k % (h->n_buckets - 1); last = i;					\
+			while (!__ac_isempty(h->flags, i) && (__ac_isdel(h->flags, i) || !__hash_equal(h->keys[i], key))) { \
+				if (i + inc >= h->n_buckets) i = i + inc - h->n_buckets; \
+				else i += inc;											\
+				if (i == last) return h->n_buckets;						\
+			}															\
+			return __ac_iseither(h->flags, i)? h->n_buckets : i;		\
+		} else return 0;												\
+	}																	\
+	static inline void kh_resize_##name(kh_##name##_t *h, khint_t new_n_buckets) \
+	{																	\
+		uint32_t *new_flags = 0;										\
+		khint_t j = 1;													\
+		{																\
+			khint_t t = __ac_HASH_PRIME_SIZE - 1;						\
+			while (__ac_prime_list[t] > new_n_buckets) --t;				\
+			new_n_buckets = __ac_prime_list[t+1];						\
+			if (h->size >= (khint_t)(new_n_buckets * __ac_HASH_UPPER + 0.5)) j = 0;	\
+			else {														\
+				new_flags = (uint32_t*)malloc(((new_n_buckets>>4) + 1) * sizeof(uint32_t));	\
+				memset(new_flags, 0xaa, ((new_n_buckets>>4) + 1) * sizeof(uint32_t)); \
+				if (h->n_buckets < new_n_buckets) {						\
+					h->keys = (khkey_t*)realloc(h->keys, new_n_buckets * sizeof(khkey_t)); \
+					if (kh_is_map)										\
+						h->vals = (khval_t*)realloc(h->vals, new_n_buckets * sizeof(khval_t)); \
+				}														\
+			}															\
+		}																\
+		if (j) {														\
+			for (j = 0; j != h->n_buckets; ++j) {						\
+				if (__ac_iseither(h->flags, j) == 0) {					\
+					khkey_t key = h->keys[j];							\
+					khval_t val;										\
+					if (kh_is_map) val = h->vals[j];					\
+					__ac_set_isdel_true(h->flags, j);					\
+					while (1) {											\
+						khint_t inc, k, i;								\
+						k = __hash_func(key);							\
+						i = k % new_n_buckets;							\
+						inc = 1 + k % (new_n_buckets - 1);				\
+						while (!__ac_isempty(new_flags, i)) {			\
+							if (i + inc >= new_n_buckets) i = i + inc - new_n_buckets; \
+							else i += inc;								\
+						}												\
+						__ac_set_isempty_false(new_flags, i);			\
+						if (i < h->n_buckets && __ac_iseither(h->flags, i) == 0) { \
+							{ khkey_t tmp = h->keys[i]; h->keys[i] = key; key = tmp; } \
+							if (kh_is_map) { khval_t tmp = h->vals[i]; h->vals[i] = val; val = tmp; } \
+							__ac_set_isdel_true(h->flags, i);			\
+						} else {										\
+							h->keys[i] = key;							\
+							if (kh_is_map) h->vals[i] = val;			\
+							break;										\
+						}												\
+					}													\
+				}														\
+			}															\
+			if (h->n_buckets > new_n_buckets) {							\
+				h->keys = (khkey_t*)realloc(h->keys, new_n_buckets * sizeof(khkey_t)); \
+				if (kh_is_map)											\
+					h->vals = (khval_t*)realloc(h->vals, new_n_buckets * sizeof(khval_t)); \
+			}															\
+			free(h->flags);												\
+			h->flags = new_flags;										\
+			h->n_buckets = new_n_buckets;								\
+			h->n_occupied = h->size;									\
+			h->upper_bound = (khint_t)(h->n_buckets * __ac_HASH_UPPER + 0.5); \
+		}																\
+	}																	\
+	static inline khint_t kh_put_##name(kh_##name##_t *h, khkey_t key, int *ret) \
+	{																	\
+		khint_t x;														\
+		if (h->n_occupied >= h->upper_bound) {							\
+			if (h->n_buckets > (h->size<<1)) kh_resize_##name(h, h->n_buckets - 1); \
+			else kh_resize_##name(h, h->n_buckets + 1);					\
+		}																\
+		{																\
+			khint_t inc, k, i, site, last;								\
+			x = site = h->n_buckets; k = __hash_func(key); i = k % h->n_buckets; \
+			if (__ac_isempty(h->flags, i)) x = i;						\
+			else {														\
+				inc = 1 + k % (h->n_buckets - 1); last = i;				\
+				while (!__ac_isempty(h->flags, i) && (__ac_isdel(h->flags, i) || !__hash_equal(h->keys[i], key))) { \
+					if (__ac_isdel(h->flags, i)) site = i;				\
+					if (i + inc >= h->n_buckets) i = i + inc - h->n_buckets; \
+					else i += inc;										\
+					if (i == last) { x = site; break; }					\
+				}														\
+				if (x == h->n_buckets) {								\
+					if (__ac_isempty(h->flags, i) && site != h->n_buckets) x = site; \
+					else x = i;											\
+				}														\
+			}															\
+		}																\
+		if (__ac_isempty(h->flags, x)) {								\
+			h->keys[x] = key;											\
+			__ac_set_isboth_false(h->flags, x);							\
+			++h->size; ++h->n_occupied;									\
+			*ret = 1;													\
+		} else if (__ac_isdel(h->flags, x)) {							\
+			h->keys[x] = key;											\
+			__ac_set_isboth_false(h->flags, x);							\
+			++h->size;													\
+			*ret = 2;													\
+		} else *ret = 0;												\
+		return x;														\
+	}																	\
+	static inline void kh_del_##name(kh_##name##_t *h, khint_t x)		\
+	{																	\
+		if (x != h->n_buckets && !__ac_iseither(h->flags, x)) {			\
+			__ac_set_isdel_true(h->flags, x);							\
+			--h->size;													\
+		}																\
+	}
+
+/* --- BEGIN OF HASH FUNCTIONS --- */
+
+/*! @function
+  @abstract     Integer hash function
+  @param  key   The integer [uint32_t]
+  @return       The hash value [khint_t]
+ */
+#define kh_int_hash_func(key) (uint32_t)(key)
+/*! @function
+  @abstract     Integer comparison function
+ */
+#define kh_int_hash_equal(a, b) ((a) == (b))
+/*! @function
+  @abstract     64-bit integer hash function
+  @param  key   The integer [uint64_t]
+  @return       The hash value [khint_t]
+ */
+#define kh_int64_hash_func(key) (uint32_t)((key)>>33^(key)^(key)<<11)
+/*! @function
+  @abstract     64-bit integer comparison function
+ */
+#define kh_int64_hash_equal(a, b) ((a) == (b))
+/*! @function
+  @abstract     const char* hash function
+  @param  s     Pointer to a null terminated string
+  @return       The hash value
+ */
+static inline khint_t __ac_X31_hash_string(const char *s)
+{
+	khint_t h = *s;
+	if (h) for (++s ; *s; ++s) h = (h << 5) - h + *s;
+	return h;
+}
+/*! @function
+  @abstract     Another interface to const char* hash function
+  @param  key   Pointer to a null terminated string [const char*]
+  @return       The hash value [khint_t]
+ */
+#define kh_str_hash_func(key) __ac_X31_hash_string(key)
+/*! @function
+  @abstract     Const char* comparison function
+ */
+#define kh_str_hash_equal(a, b) (strcmp(a, b) == 0)
+
+/* --- END OF HASH FUNCTIONS --- */
+
+/* Other necessary macros... */
+
+/*!
+  @abstract Type of the hash table.
+  @param  name  Name of the hash table [symbol]
+ */
+#define khash_t(name) kh_##name##_t
+
+/*! @function
+  @abstract     Initiate a hash table.
+  @param  name  Name of the hash table [symbol]
+  @return       Pointer to the hash table [khash_t(name)*]
+ */
+#define kh_init(name) kh_init_##name()
+
+/*! @function
+  @abstract     Destroy a hash table.
+  @param  name  Name of the hash table [symbol]
+  @param  h     Pointer to the hash table [khash_t(name)*]
+ */
+#define kh_destroy(name, h) kh_destroy_##name(h)
+
+/*! @function
+  @abstract     Reset a hash table without deallocating memory.
+  @param  name  Name of the hash table [symbol]
+  @param  h     Pointer to the hash table [khash_t(name)*]
+ */
+#define kh_clear(name, h) kh_clear_##name(h)
+
+/*! @function
+  @abstract     Resize a hash table.
+  @param  name  Name of the hash table [symbol]
+  @param  h     Pointer to the hash table [khash_t(name)*]
+  @param  s     New size [khint_t]
+ */
+#define kh_resize(name, h, s) kh_resize_##name(h, s)
+
+/*! @function
+  @abstract     Insert a key to the hash table.
+  @param  name  Name of the hash table [symbol]
+  @param  h     Pointer to the hash table [khash_t(name)*]
+  @param  k     Key [type of keys]
+  @param  r     Extra return code: 0 if the key is present in the hash table;
+                1 if the bucket is empty (never used); 2 if the element in
+				the bucket has been deleted [int*]
+  @return       Iterator to the inserted element [khint_t]
+ */
+#define kh_put(name, h, k, r) kh_put_##name(h, k, r)
+
+/*! @function
+  @abstract     Retrieve a key from the hash table.
+  @param  name  Name of the hash table [symbol]
+  @param  h     Pointer to the hash table [khash_t(name)*]
+  @param  k     Key [type of keys]
+  @return       Iterator to the found element, or kh_end(h) is the element is absent [khint_t]
+ */
+#define kh_get(name, h, k) kh_get_##name(h, k)
+
+/*! @function
+  @abstract     Remove a key from the hash table.
+  @param  name  Name of the hash table [symbol]
+  @param  h     Pointer to the hash table [khash_t(name)*]
+  @param  k     Iterator to the element to be deleted [khint_t]
+ */
+#define kh_del(name, h, k) kh_del_##name(h, k)
+
+
+/*! @function
+  @abstract     Test whether a bucket contains data.
+  @param  h     Pointer to the hash table [khash_t(name)*]
+  @param  x     Iterator to the bucket [khint_t]
+  @return       1 if containing data; 0 otherwise [int]
+ */
+#define kh_exist(h, x) (!__ac_iseither((h)->flags, (x)))
+
+/*! @function
+  @abstract     Get key given an iterator
+  @param  h     Pointer to the hash table [khash_t(name)*]
+  @param  x     Iterator to the bucket [khint_t]
+  @return       Key [type of keys]
+ */
+#define kh_key(h, x) ((h)->keys[x])
+
+/*! @function
+  @abstract     Get value given an iterator
+  @param  h     Pointer to the hash table [khash_t(name)*]
+  @param  x     Iterator to the bucket [khint_t]
+  @return       Value [type of values]
+  @discussion   For hash sets, calling this results in segfault.
+ */
+#define kh_val(h, x) ((h)->vals[x])
+
+/*! @function
+  @abstract     Alias of kh_val()
+ */
+#define kh_value(h, x) ((h)->vals[x])
+
+/*! @function
+  @abstract     Get the start iterator
+  @param  h     Pointer to the hash table [khash_t(name)*]
+  @return       The start iterator [khint_t]
+ */
+#define kh_begin(h) (khint_t)(0)
+
+/*! @function
+  @abstract     Get the end iterator
+  @param  h     Pointer to the hash table [khash_t(name)*]
+  @return       The end iterator [khint_t]
+ */
+#define kh_end(h) ((h)->n_buckets)
+
+/*! @function
+  @abstract     Get the number of elements in the hash table
+  @param  h     Pointer to the hash table [khash_t(name)*]
+  @return       Number of elements in the hash table [khint_t]
+ */
+#define kh_size(h) ((h)->size)
+
+/*! @function
+  @abstract     Get the number of buckets in the hash table
+  @param  h     Pointer to the hash table [khash_t(name)*]
+  @return       Number of buckets in the hash table [khint_t]
+ */
+#define kh_n_buckets(h) ((h)->n_buckets)
+
+/* More conenient interfaces */
+
+/*! @function
+  @abstract     Instantiate a hash set containing integer keys
+  @param  name  Name of the hash table [symbol]
+ */
+#define KHASH_SET_INIT_INT(name)										\
+	KHASH_INIT(name, uint32_t, char, 0, kh_int_hash_func, kh_int_hash_equal)
+
+/*! @function
+  @abstract     Instantiate a hash map containing integer keys
+  @param  name  Name of the hash table [symbol]
+  @param  khval_t  Type of values [type]
+ */
+#define KHASH_MAP_INIT_INT(name, khval_t)								\
+	KHASH_INIT(name, uint32_t, khval_t, 1, kh_int_hash_func, kh_int_hash_equal)
+
+/*! @function
+  @abstract     Instantiate a hash map containing 64-bit integer keys
+  @param  name  Name of the hash table [symbol]
+ */
+#define KHASH_SET_INIT_INT64(name)										\
+	KHASH_INIT(name, uint64_t, char, 0, kh_int64_hash_func, kh_int64_hash_equal)
+
+/*! @function
+  @abstract     Instantiate a hash map containing 64-bit integer keys
+  @param  name  Name of the hash table [symbol]
+  @param  khval_t  Type of values [type]
+ */
+#define KHASH_MAP_INIT_INT64(name, khval_t)								\
+	KHASH_INIT(name, uint64_t, khval_t, 1, kh_int64_hash_func, kh_int64_hash_equal)
+
+typedef const char *kh_cstr_t;
+/*! @function
+  @abstract     Instantiate a hash map containing const char* keys
+  @param  name  Name of the hash table [symbol]
+ */
+#define KHASH_SET_INIT_STR(name)										\
+	KHASH_INIT(name, kh_cstr_t, char, 0, kh_str_hash_func, kh_str_hash_equal)
+
+/*! @function
+  @abstract     Instantiate a hash map containing const char* keys
+  @param  name  Name of the hash table [symbol]
+  @param  khval_t  Type of values [type]
+ */
+#define KHASH_MAP_INIT_STR(name, khval_t)								\
+	KHASH_INIT(name, kh_cstr_t, khval_t, 1, kh_str_hash_func, kh_str_hash_equal)
+
+#endif /* __AC_KHASH_H */
diff --git a/test_data/bbi_tests/make_expectation.sh b/test_data/bbi_tests/make_expectation.sh
new file mode 100755
index 0000000..6054885
--- /dev/null
+++ b/test_data/bbi_tests/make_expectation.sh
@@ -0,0 +1,11 @@
+#!/bin/sh
+
+BW=$1
+REGIONS=$2
+
+cat $REGIONS | while read chr start end n; do \
+    echo $chr $start $end $n mean `bigWigSummary -type=mean $BW $chr $start $end $n`;
+    echo $chr $start $end $n min `bigWigSummary -type=min $BW $chr $start $end $n`;
+    echo $chr $start $end $n max `bigWigSummary -type=max $BW $chr $start $end $n`;
+    echo $chr $start $end $n std `bigWigSummary -type=std $BW $chr $start $end $n`;
+done;
diff --git a/test_data/bbi_tests/test.bw b/test_data/bbi_tests/test.bw
new file mode 100644
index 0000000..f6d52a9
Binary files /dev/null and b/test_data/bbi_tests/test.bw differ
diff --git a/test_data/bbi_tests/test.expectation b/test_data/bbi_tests/test.expectation
new file mode 100644
index 0000000..8ad2466
--- /dev/null
+++ b/test_data/bbi_tests/test.expectation
@@ -0,0 +1,24 @@
+chr1 10000 20000 10 mean -0.175576 -0.0540093 -0.0568922 -0.0365033 0.0361129 0.0064466 0.036949 0.0766383 0.0435181 0.0155475
+chr1 10000 20000 10 min -2.525 -3.84387 -3.91 -3.735 -3.61157 -3.594 -3.666 -1.7313 -2.819 -3.099
+chr1 10000 20000 10 max 0.0508425 0.289 0.289 0.184 0.184 0.184 0.184 0.184 0.184 0.184
+chr1 10000 20000 10 std 0.700141 0.529165 0.546035 0.53675 0.441437 0.467338 0.435692 0.355528 0.410757 0.454092
+chr1 10000 12000 10 mean n/a n/a n/a n/a -0.164968 -0.194169 -0.0533029 0.00390226 -0.00226906 -0.0365958
+chr1 10000 12000 10 min n/a n/a n/a n/a -2.525 -2.45895 -2.45895 -2.525 -2.21678 -3.84387
+chr1 10000 12000 10 max n/a n/a n/a n/a 0.0508425 0.0508425 0.0508425 0.271 0.271 0.11689
+chr1 10000 12000 10 std n/a n/a n/a n/a 0.679479 0.724087 0.478575 0.410891 0.427236 0.511289
+chr1 10000 20000 100 mean n/a n/a n/a n/a n/a n/a n/a n/a n/a -0.163546 -0.272118 -0.127111 -0.116169 0.0202627 -0.0243522 0.0349913 -0.0054408 -0.00101548 -0.0307148 -0.0374406 -0.0024669 -0.034042 -0.0343892 -0.0199075 -0.0406878 -0.0322236 -0.080479 -0.235991 -0.0897865 -0.041593 0.019942 -0.0608448 0.0144338 -0.0348468 0.0195101 -0.0555526 -0.0892809 0.011672 -0.173894 -0.0849444 0.0718796 0.0608432 0.0313183 0.0439315 -0.0242363 0.03288 0.0318241 0.122005 0.0879138 0.00102565 0.0334 [...]
+chr1 10000 20000 100 min n/a n/a n/a n/a n/a n/a n/a n/a n/a -2.525 -2.45895 -2.45895 -2.45895 -2.45895 -2.34887 -2.525 -2.08469 -1.95259 -2.17275 -3.84387 -3.84387 -2.68667 -2.02541 -2.02541 -1.99235 -1.99235 -3.91 -2.25685 -1.99235 -1.99235 -1.45149 -3.735 -1.63664 -3.45728 -1.5132 -1.57492 -1.63664 -2.90183 -1.6675 -3.61157 -2.76106 -1.45214 -1.63063 -1.45214 -2.0471 -3.41551 -3.41551 -1.21416 -2.76106 -3.594 -2.82937 -3.173 -3.173 -1.42842 -1.45485 -1.45485 -1.82491 -1.45485 -1.50772 [...]
+chr1 10000 20000 100 max n/a n/a n/a n/a n/a n/a n/a n/a n/a 0.0508425 0.0508425 0.0508425 0.0508425 0.0508425 0.271 0.271 0.11689 0.11689 0.11689 0.11689 0.289 0.289 0.090622 0.090622 0.090622 0.090622 0.090622 0.090622 0.090622 0.184 0.184 0.184 0.184 0.184 0.184 0.184 0.184 0.184 0.184 0.184 0.184 0.184 0.184 0.184 0.0947559 0.184 0.184 0.184 0.184 0.184 0.184 0.184 0.184 0.184 0.184 0.184 0.184 0.184 0.184 0.184 0.184 0.184 0.184 0.184 0.184 0.184 0.184 0.184 0.184 0.184 0.184 0.184  [...]
+chr1 10000 20000 100 std n/a n/a n/a n/a n/a n/a n/a n/a n/a 0.677135 0.822194 0.62085 0.612407 0.231852 0.328151 0.491656 0.41591 0.426687 0.488369 0.496677 0.593145 0.601794 0.47278 0.437521 0.482739 0.4581 0.611283 0.727005 0.555172 0.508856 0.437795 0.651825 0.450452 0.5853 0.446921 0.533572 0.562739 0.507615 0.641553 0.631814 0.429699 0.385442 0.442343 0.39576 0.474238 0.416927 0.494794 0.257982 0.400201 0.551855 0.468543 0.482704 0.609168 0.474814 0.307805 0.433662 0.555056 0.44514 [...]
+chr1 10000 12000 100 mean n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a 0.0508425 0.0508425 -0.0768488 -0.189129 -0.439008 -0.182524 -0.304712 -0.197935 -0.462124 -0.194633 -0.2882 -0.0570346 -0.0724456 -0.301409 0.0508425 -0.0702441 -0.182524 0.0508425 0.0508425 -0.55459 0.0508425 0.0508425 0.0508425 0.0508425 0.00460946 -0.0152047 -0.0152047 -0.095562 -0 [...]
+chr1 10000 12000 100 min n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a 0.0508425 0.0508425 -2.1067 -2.525 -2.525 -2.45895 -2.43694 -2.45895 -2.45895 -2.45895 -2.43694 -2.1067 -2.41492 -2.45895 0.0508425 -2.37089 -2.45895 0.0508425 0.0508425 -2.45895 0.0508425 0.0508425 0.0508425 0.0508425 -0.0152047 -0.0152047 -0.0152047 -2.34887 -2.1067 0.0508425 -1.79848 [...]
+chr1 10000 12000 100 max n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a 0.0508425 0.0508425 0.0508425 0.0508425 0.0508425 0.0508425 0.0508425 0.0508425 0.0508425 0.0508425 0.0508425 0.0508425 0.0508425 0.0508425 0.0508425 0.0508425 0.0508425 0.0508425 0.0508425 0.0508425 0.0508425 0.0508425 0.0508425 0.0508425 0.0508425 -0.0152047 -0.0152047 0.0508425 0.050 [...]
+chr1 10000 12000 100 std n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a 0 0 0.478763 0.73063 0.99997 0.720557 0.86116 0.765755 1.01076 0.755768 0.830521 0.482441 0.551361 0.862571 0 0.541516 0.720557 0 0 1.07612 0 0 0 0 0.0310529 0 0 0.531375 0.482441 0.0585867 0.45454 0.581741 0.639311 0.533446 0.47752 0 0.0253547 0.0103511 0.643384 0.567666 0.411522 0.009 [...]
+chr1 10000 20000 1000 mean n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a 0.0508425 0.0508425 0.0508425 0.0112142 -0.164912 -0.206742 -0.171516 -0.671274 -0.206741 -0.415891 0 [...]
+chr1 10000 20000 1000 min n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a 0.0508425 0.0508425 0.0508425 -0.0152047 -2.1067 -2.525 -2.1067 -2.525 -2.45895 -2.45895 0.0508425 -2. [...]
+chr1 10000 20000 1000 max n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a 0.0508425 0.0508425 0.0508425 0.0508425 0.0508425 0.0508425 0.0508425 0.0508425 0.0508425 0.0508425 0. [...]
+chr1 10000 20000 1000 std n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a 0 0 0 0.0341066 0.682275 0.814553 0.680271 1.16809 0.791618 0.987457 0 0.95987 0.786706 0 1.04899 0.78 [...]
+chr1 10000 12000 1000 mean n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n [...]
+chr1 10000 12000 1000 min n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/ [...]
+chr1 10000 12000 1000 max n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/ [...]
+chr1 10000 12000 1000 std n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a n/ [...]
diff --git a/test_data/bbi_tests/test.regions b/test_data/bbi_tests/test.regions
new file mode 100644
index 0000000..c24cac4
--- /dev/null
+++ b/test_data/bbi_tests/test.regions
@@ -0,0 +1,6 @@
+chr1 10000 20000 10
+chr1 10000 12000 10
+chr1 10000 20000 100
+chr1 10000 12000 100
+chr1 10000 20000 1000
+chr1 10000 12000 1000
diff --git a/test_data/bbi_tests/test.wig b/test_data/bbi_tests/test.wig
new file mode 100644
index 0000000..fd0839d
--- /dev/null
+++ b/test_data/bbi_tests/test.wig
@@ -0,0 +1,9992 @@
+variableStep chrom=chr1 span=1
+10918	0.0508425
+10919	0.0508425
+10920	0.0508425
+10921	0.0508425
+10922	0.0508425
+10923	0.0508425
+10924	0.0508425
+10925	0.0508425
+10926	0.0508425
+10927	0.0508425
+10928	0.0508425
+10929	0.0508425
+10930	0.0508425
+10931	0.0508425
+10932	0.0508425
+10933	0.0508425
+10934	0.0508425
+10935	0.0508425
+10936	0.0508425
+10937	0.0508425
+10938	0.0508425
+10939	0.0508425
+10940	0.0508425
+10941	0.0508425
+10942	-0.0152047
+10943	-0.0152047
+10944	-0.0152047
+10945	-0.0152047
+10946	-0.0152047
+10947	-0.0152047
+10948	0.0508425
+10949	0.0508425
+10950	0.0508425
+10951	0.0508425
+10952	0.0508425
+10953	0.0508425
+10954	0.0508425
+10955	0.0508425
+10956	-2.1067
+10957	0.0508425
+10958	0.0508425
+10959	0.0508425
+10960	0.0508425
+10961	0.0508425
+10962	0.0508425
+10963	0.0508425
+10964	0.0508425
+10965	0.0508425
+10966	0.0508425
+10967	0.0508425
+10968	-2.525
+10969	0.0508425
+10970	0.0508425
+10971	0.0508425
+10972	0.0508425
+10973	-0.0152047
+10974	0.0508425
+10975	0.0508425
+10976	0.0508425
+10977	0.0508425
+10978	0.0508425
+10979	-2.1067
+10980	0.0508425
+10981	-2.08469
+10982	0.0508425
+10983	0.0508425
+10984	0.0508425
+10985	0.0508425
+10986	0.0508425
+10987	-2.525
+10988	0.0508425
+10989	-2.45895
+10990	0.0508425
+10991	0.0508425
+10992	0.0508425
+10993	-2.45895
+10994	0.0508425
+10995	0.0508425
+10996	0.0508425
+10997	0.0508425
+10998	0.0508425
+10999	-0.0152047
+11000	0.0508425
+11001	0.0508425
+11002	-2.45895
+11003	0.0508425
+11004	0.0508425
+11005	0.0508425
+11006	0.0508425
+11007	0.0508425
+11008	-2.1067
+11009	0.0508425
+11010	0.0508425
+11011	0.0508425
+11012	0.0508425
+11013	0.0508425
+11014	0.0508425
+11015	0.0508425
+11016	0.0508425
+11017	0.0508425
+11018	0.0508425
+11019	0.0508425
+11020	0.0508425
+11021	-2.37089
+11022	0.0508425
+11023	0.0508425
+11024	0.0508425
+11025	0.0508425
+11026	-0.0152047
+11027	0.0508425
+11028	0.0508425
+11029	-2.08469
+11030	0.0508425
+11031	0.0508425
+11032	0.0508425
+11033	-2.43694
+11034	0.0508425
+11035	0.0508425
+11036	0.0508425
+11037	0.0508425
+11038	0.0508425
+11039	0.0508425
+11040	0.0508425
+11041	0.0508425
+11042	0.0508425
+11043	0.0508425
+11044	0.0508425
+11045	0.0508425
+11046	0.0508425
+11047	0.0508425
+11048	0.0508425
+11049	0.0508425
+11050	0.0508425
+11051	0.0508425
+11052	0.0508425
+11053	0.0508425
+11054	0.0508425
+11055	-2.41492
+11056	0.0508425
+11057	0.0508425
+11058	0.0508425
+11059	-2.45895
+11060	0.0508425
+11061	-2.45895
+11062	0.0508425
+11063	0.0508425
+11064	0.0508425
+11065	0.0508425
+11066	0.0508425
+11067	0.0508425
+11068	-0.0152047
+11069	-0.0152047
+11070	-0.0152047
+11071	-0.0152047
+11072	-0.0152047
+11073	0.0508425
+11074	-2.37089
+11075	0.0508425
+11076	0.0508425
+11077	0.0508425
+11078	-2.45895
+11079	-2.43694
+11080	0.0508425
+11081	0.0508425
+11082	0.0508425
+11083	-2.45895
+11084	0.0508425
+11085	0.0508425
+11086	0.0508425
+11087	0.0508425
+11088	0.0508425
+11089	0.0508425
+11090	0.0508425
+11091	-2.34887
+11092	0.0508425
+11093	0.0508425
+11094	0.0508425
+11095	0.0508425
+11096	0.0508425
+11097	0.0508425
+11098	0.0508425
+11099	0.0508425
+11100	0.0508425
+11101	0.0508425
+11102	-2.43694
+11103	0.0508425
+11104	0.0508425
+11105	0.0508425
+11106	0.0508425
+11107	0.0508425
+11108	0.0508425
+11109	-2.1067
+11110	0.0508425
+11111	0.0508425
+11112	0.0508425
+11113	-2.08469
+11114	0.0508425
+11115	0.0508425
+11116	0.0508425
+11117	0.0508425
+11118	0.0508425
+11119	0.0508425
+11120	0.0508425
+11121	0.0508425
+11122	0.0508425
+11123	0.0508425
+11124	0.0508425
+11125	0.0508425
+11126	0.0508425
+11127	0.0508425
+11128	0.0508425
+11129	0.0508425
+11130	0.0508425
+11131	0.0508425
+11132	0.0508425
+11133	0.0508425
+11134	-2.1067
+11135	0.0508425
+11136	0.0508425
+11137	0.0508425
+11138	0.0508425
+11139	0.0508425
+11140	0.0508425
+11141	0.0508425
+11142	0.0508425
+11143	0.0508425
+11144	0.0508425
+11145	0.0508425
+11146	0.0508425
+11147	0.0508425
+11148	0.0508425
+11149	-2.41492
+11150	0.0508425
+11151	0.0508425
+11152	0.0508425
+11153	0.0508425
+11154	0.0508425
+11155	0.0508425
+11156	0.0508425
+11157	0.0508425
+11158	0.0508425
+11159	0.0508425
+11160	0.0508425
+11161	-2.45895
+11162	0.0508425
+11163	-2.34887
+11164	0.0508425
+11165	0.0508425
+11166	0.0508425
+11167	0.0508425
+11168	0.0508425
+11169	0.0508425
+11170	0.0508425
+11171	0.0508425
+11172	0.0508425
+11173	-2.08469
+11174	0.0508425
+11175	0.0508425
+11176	0.0508425
+11177	0.0508425
+11178	0.0508425
+11179	0.0508425
+11180	0.0508425
+11181	0.0508425
+11182	0.0508425
+11183	0.0508425
+11184	0.0508425
+11185	0.0508425
+11186	0.0508425
+11187	0.0508425
+11188	0.0508425
+11189	0.0508425
+11190	0.0508425
+11191	0.0508425
+11192	0.0508425
+11193	0.0508425
+11194	0.0508425
+11195	0.0508425
+11196	0.0508425
+11197	0.0508425
+11198	0.0508425
+11199	0.0508425
+11200	0.0508425
+11201	0.0508425
+11202	0.0508425
+11203	0.0508425
+11204	0.0508425
+11205	0.0508425
+11206	0.0508425
+11207	0.0508425
+11208	0.0508425
+11209	0.0508425
+11210	0.0508425
+11211	0.0508425
+11212	0.0508425
+11213	0.0508425
+11214	0.0508425
+11215	0.0508425
+11216	0.0508425
+11217	-2.37089
+11218	0.0508425
+11219	0.0508425
+11220	0.0508425
+11221	0.0508425
+11222	0.0508425
+11223	0.0508425
+11224	-2.45895
+11225	0.0508425
+11226	0.0508425
+11227	0.0508425
+11228	0.0508425
+11229	0.0508425
+11230	0.0508425
+11231	0.0508425
+11232	0.0508425
+11233	0.0508425
+11234	0.0508425
+11235	0.0508425
+11236	0.0508425
+11237	0.0508425
+11238	0.0508425
+11239	0.0508425
+11240	-2.1067
+11241	0.0508425
+11242	0.0508425
+11243	0.0508425
+11244	0.0508425
+11245	0.0508425
+11246	0.0508425
+11247	0.0508425
+11248	0.0508425
+11249	0.0508425
+11250	0.0508425
+11251	0.0508425
+11252	0.0508425
+11253	0.0508425
+11254	0.0508425
+11255	0.0508425
+11256	0.0508425
+11257	0.0508425
+11258	0.0508425
+11259	0.0508425
+11260	0.0508425
+11261	0.0508425
+11262	0.0508425
+11263	0.0508425
+11264	0.0508425
+11265	0.0508425
+11266	0.0508425
+11267	0.0508425
+11268	0.0508425
+11269	0.0508425
+11270	0.0508425
+11271	0.0508425
+11272	0.0508425
+11273	0.0508425
+11274	0.0508425
+11275	0.0508425
+11276	0.0508425
+11277	0.0508425
+11278	0.0508425
+11279	0.0508425
+11280	0.0508425
+11281	0.0508425
+11282	0.0508425
+11283	0.0508425
+11284	0.0508425
+11285	0.0508425
+11286	-2.34887
+11287	-2.34887
+11288	-2.34887
+11289	-2.34887
+11290	0.0508425
+11291	0.0508425
+11292	0.0508425
+11293	0.0508425
+11294	0.0508425
+11295	0.0508425
+11296	0.0508425
+11297	0.0508425
+11298	-2.45895
+11299	0.0508425
+11300	0.0508425
+11301	0.0508425
+11302	0.0508425
+11303	0.0508425
+11304	0.0508425
+11305	0.0508425
+11306	0.0508425
+11307	0.0508425
+11308	0.0508425
+11309	0.0508425
+11310	0.0508425
+11311	0.0508425
+11312	0.0508425
+11313	0.0508425
+11314	0.0508425
+11315	0.0508425
+11316	0.0508425
+11317	0.0508425
+11318	0.0508425
+11319	0.0508425
+11320	0.0508425
+11321	0.0508425
+11322	0.0508425
+11323	0.0508425
+11324	0.0508425
+11325	0.0508425
+11326	0.0508425
+11327	0.0508425
+11328	0.0508425
+11329	0.0508425
+11330	0.0508425
+11331	0.0508425
+11332	0.0508425
+11333	0.0508425
+11334	0.0508425
+11335	0.0508425
+11336	0.0508425
+11337	0.0508425
+11338	0.0508425
+11339	0.0508425
+11340	0.0508425
+11341	0.0508425
+11342	0.0508425
+11343	0.0508425
+11344	0.0508425
+11345	0.0508425
+11346	0.0508425
+11347	0.0508425
+11348	0.0508425
+11349	0.0508425
+11350	0.0508425
+11351	0.0508425
+11352	0.0508425
+11353	0.0508425
+11354	0.0508425
+11355	0.0508425
+11356	0.0508425
+11357	0.0508425
+11358	0.0508425
+11359	0.0508425
+11360	0.0508425
+11361	0.0508425
+11362	0.0508425
+11363	0.0508425
+11364	0.0508425
+11365	0.0508425
+11366	0.0508425
+11367	0.0508425
+11368	0.0508425
+11369	0.0508425
+11370	0.0508425
+11371	0.0508425
+11372	0.0508425
+11373	0.0508425
+11374	0.0508425
+11375	0.0508425
+11376	0.0508425
+11377	0.0508425
+11378	0.0508425
+11379	0.0508425
+11380	0.0508425
+11381	0.0508425
+11382	0.0508425
+11383	0.0508425
+11384	0.0508425
+11385	0.0508425
+11386	0.0508425
+11387	-0.0152047
+11388	-0.0152047
+11389	-0.0152047
+11390	-0.0152047
+11391	-0.0152047
+11392	-0.0152047
+11393	-0.0152047
+11394	-0.0152047
+11395	-0.0152047
+11396	-0.0152047
+11397	-0.0152047
+11398	-0.0152047
+11399	-0.0152047
+11400	-0.0152047
+11401	-0.0152047
+11402	-0.0152047
+11403	-0.0152047
+11404	-0.0152047
+11405	-0.0152047
+11406	-0.0152047
+11407	-0.0152047
+11408	-0.0152047
+11409	-0.0152047
+11410	-0.0152047
+11411	-0.0152047
+11412	-0.0152047
+11413	-0.0152047
+11414	-0.0152047
+11415	-0.0152047
+11416	-0.0152047
+11417	-0.0152047
+11418	-0.0152047
+11419	-0.0152047
+11420	-0.0152047
+11421	-0.0152047
+11422	-0.0152047
+11423	-0.0152047
+11424	-0.0152047
+11425	-0.0152047
+11426	-0.0152047
+11427	-0.0152047
+11428	-0.0152047
+11429	-0.0152047
+11430	-0.0152047
+11431	-0.0152047
+11432	-0.0152047
+11433	-0.0152047
+11434	-0.0152047
+11435	-0.0152047
+11436	-0.0152047
+11437	-0.0152047
+11438	-0.0152047
+11439	-0.0152047
+11440	-0.0152047
+11441	-0.0152047
+11442	-0.0152047
+11443	-0.0152047
+11444	-0.0152047
+11445	-0.0152047
+11446	-0.0152047
+11447	-0.0152047
+11448	-0.0152047
+11449	0.0508425
+11450	0.0508425
+11451	0.0508425
+11452	0.0508425
+11453	0.0508425
+11454	0.0508425
+11455	0.0508425
+11456	0.0508425
+11457	-2.34887
+11458	0.0508425
+11459	0.0508425
+11460	0.0508425
+11461	0.0508425
+11462	0.0508425
+11463	0.0508425
+11464	0.0508425
+11465	0.0508425
+11466	0.0508425
+11467	0.0508425
+11468	0.0508425
+11469	-2.1067
+11470	0.0508425
+11471	0.0508425
+11472	0.0508425
+11473	0.0508425
+11474	0.0508425
+11475	0.0508425
+11476	0.0508425
+11477	0.0508425
+11478	0.0508425
+11479	0.0508425
+11480	0.0508425
+11481	0.0508425
+11482	0.0508425
+11483	0.0508425
+11484	0.0508425
+11485	0.0508425
+11486	0.0508425
+11487	0.0508425
+11488	0.0508425
+11489	0.0508425
+11490	0.0508425
+11491	0.0508425
+11492	0.0508425
+11493	0.0508425
+11494	0.0508425
+11495	0.0508425
+11496	0.0508425
+11497	0.0508425
+11498	0.0508425
+11499	0.204953
+11500	0.271
+11501	0.204953
+11502	0.271
+11503	0.204953
+11504	0.271
+11505	0.204953
+11506	0.204953
+11507	0.271
+11508	-1.79848
+11509	0.271
+11510	0.204953
+11511	0.271
+11512	0.271
+11513	0.204953
+11514	0.204953
+11515	0.204953
+11516	0.204953
+11517	0.204953
+11518	0.204953
+11519	0.204953
+11520	0.271
+11521	0.271
+11522	0.271
+11523	-0.873819
+11524	0.204953
+11525	0.204953
+11526	0.271
+11527	0.271
+11528	0.204953
+11529	0.271
+11530	0.271
+11531	-1.64437
+11532	0.204953
+11533	0.204953
+11534	0.204953
+11535	0.204953
+11536	0.204953
+11537	0.204953
+11538	-1.42421
+11539	0.271
+11540	0.204953
+11541	0.0508425
+11542	-2.525
+11543	0.0508425
+11544	0.0508425
+11545	0.0508425
+11546	-0.873819
+11547	0.204953
+11548	0.204953
+11549	0.204953
+11550	0.204953
+11551	0.204953
+11552	0.204953
+11553	0.204953
+11554	0.271
+11555	0.204953
+11556	0.204953
+11557	0.204953
+11558	0.204953
+11559	0.204953
+11560	0.204953
+11561	0.204953
+11562	0.204953
+11563	0.271
+11564	0.204953
+11565	-2.21678
+11566	0.204953
+11567	0.204953
+11568	0.271
+11569	0.204953
+11570	0.271
+11571	0.0508425
+11572	0.0508425
+11573	0.0508425
+11574	0.0508425
+11575	0.0508425
+11576	0.0508425
+11577	0.0508425
+11578	0.0508425
+11579	0.0508425
+11580	0.0508425
+11581	0.0508425
+11582	0.0508425
+11583	0.0508425
+11584	0.0508425
+11585	0.0508425
+11586	0.0508425
+11587	0.0508425
+11588	0.0508425
+11589	0.0508425
+11590	0.0508425
+11591	0.0508425
+11592	0.0508425
+11593	0.0508425
+11594	0.0508425
+11595	0.0508425
+11596	0.0508425
+11597	0.0508425
+11598	0.0508425
+11599	-2.08469
+11600	0.0508425
+11601	0.0508425
+11602	0.0508425
+11603	0.0508425
+11604	0.0508425
+11605	0.0508425
+11606	0.0508425
+11607	0.0508425
+11608	0.0508425
+11609	0.0508425
+11610	0.0508425
+11611	0.0508425
+11612	0.0508425
+11613	0.0508425
+11614	0.0508425
+11615	0.0508425
+11616	0.0508425
+11617	0.0508425
+11618	0.0508425
+11619	0.0508425
+11620	0.0508425
+11621	0.0508425
+11622	0.0508425
+11623	0.0508425
+11624	0.0508425
+11625	0.0508425
+11626	0.11689
+11627	0.094874
+11628	0.094874
+11629	0.094874
+11630	0.11689
+11631	0.094874
+11632	0.11689
+11633	0.11689
+11634	0.094874
+11635	0.11689
+11636	0.094874
+11637	0.094874
+11638	0.094874
+11639	0.11689
+11640	0.094874
+11641	0.11689
+11642	0.094874
+11643	0.094874
+11644	0.094874
+11645	0.094874
+11646	0.11689
+11647	0.094874
+11648	0.094874
+11649	0.094874
+11650	0.094874
+11651	0.11689
+11652	0.11689
+11653	0.094874
+11654	0.094874
+11655	0.094874
+11656	0.094874
+11657	0.094874
+11658	0.094874
+11659	0.11689
+11660	0.11689
+11661	0.11689
+11662	-1.90856
+11663	-1.49026
+11664	0.094874
+11665	0.11689
+11666	0.094874
+11667	0.094874
+11668	0.094874
+11669	0.11689
+11670	0.094874
+11671	0.11689
+11672	0.11689
+11673	0.094874
+11674	0.11689
+11675	0.094874
+11676	0.094874
+11677	0.11689
+11678	-1.51228
+11679	0.11689
+11680	0.11689
+11681	0.094874
+11682	0.11689
+11683	0.11689
+11684	0.094874
+11685	0.11689
+11686	0.094874
+11687	0.094874
+11688	0.094874
+11689	0.11689
+11690	0.094874
+11691	0.094874
+11692	-1.90856
+11693	0.094874
+11694	0.094874
+11695	0.094874
+11696	0.11689
+11697	0.094874
+11698	0.11689
+11699	-1.55631
+11700	0.094874
+11701	0.094874
+11702	0.094874
+11703	0.11689
+11704	0.11689
+11705	0.11689
+11706	0.11689
+11707	0.094874
+11708	0.0508425
+11709	0.11689
+11710	-1.73243
+11711	0.11689
+11712	0.11689
+11713	0.11689
+11714	0.094874
+11715	0.11689
+11716	0.11689
+11717	0.11689
+11718	0.11689
+11719	0.094874
+11720	0.094874
+11721	0.11689
+11722	0.094874
+11723	0.11689
+11724	0.094874
+11725	0.094874
+11726	0.094874
+11727	0.094874
+11728	0.094874
+11729	0.094874
+11730	0.094874
+11731	0.094874
+11732	0.094874
+11733	0.094874
+11734	0.094874
+11735	0.094874
+11736	0.094874
+11737	0.094874
+11738	0.094874
+11739	0.11689
+11740	0.11689
+11741	0.094874
+11742	0.11689
+11743	0.094874
+11744	0.11689
+11745	0.094874
+11746	0.094874
+11747	0.11689
+11748	0.094874
+11749	0.094874
+11750	0.094874
+11751	0.094874
+11752	0.094874
+11753	0.11689
+11754	0.11689
+11755	0.094874
+11756	0.11689
+11757	0.11689
+11758	0.094874
+11759	0.094874
+11760	0.11689
+11761	0.11689
+11762	0.11689
+11763	0.11689
+11764	-1.49026
+11765	0.11689
+11766	-1.88654
+11767	0.11689
+11768	0.094874
+11769	0.094874
+11770	0.11689
+11771	0.094874
+11772	0.11689
+11773	0.094874
+11774	0.094874
+11775	-1.55631
+11776	0.11689
+11777	0.094874
+11778	0.11689
+11779	0.094874
+11780	0.11689
+11781	-1.95259
+11782	0.11689
+11783	0.11689
+11784	0.094874
+11785	0.094874
+11786	0.094874
+11787	0.094874
+11788	0.094874
+11789	0.094874
+11790	0.11689
+11791	0.11689
+11792	0.11689
+11793	0.11689
+11794	0.11689
+11795	0.094874
+11796	0.094874
+11797	0.094874
+11798	0.094874
+11799	0.11689
+11800	0.11689
+11801	0.094874
+11802	0.094874
+11803	0.094874
+11804	0.11689
+11805	0.11689
+11806	0.094874
+11807	0.11689
+11808	0.094874
+11809	0.094874
+11810	0.11689
+11811	0.11689
+11812	0.094874
+11813	0.11689
+11814	0.11689
+11815	0.094874
+11816	-1.55631
+11817	0.11689
+11818	0.094874
+11819	-2.17275
+11820	0.11689
+11821	0.094874
+11822	0.094874
+11823	0.094874
+11824	0.094874
+11825	0.094874
+11826	0.094874
+11827	0.11689
+11828	0.11689
+11829	0.094874
+11830	-1.84251
+11831	0.094874
+11832	0.094874
+11833	-1.55631
+11834	0.11689
+11835	0.11689
+11836	0.11689
+11837	0.094874
+11838	0.11689
+11839	0.11689
+11840	0.094874
+11841	0.11689
+11842	0.11689
+11843	0.11689
+11844	0.11689
+11845	0.11689
+11846	0.094874
+11847	0.094874
+11848	0.094874
+11849	0.11689
+11850	-1.73243
+11851	0.094874
+11852	0.094874
+11853	0.11689
+11854	0.094874
+11855	0.11689
+11856	0.11689
+11857	0.094874
+11858	0.094874
+11859	0.094874
+11860	0.094874
+11861	0.094874
+11862	0.094874
+11863	0.11689
+11864	0.094874
+11865	0.094874
+11866	0.094874
+11867	0.094874
+11868	-1.95259
+11869	0.094874
+11870	0.0728583
+11871	0.0728583
+11872	0.0728583
+11873	0.0728583
+11874	0.11689
+11875	0.094874
+11876	0.094874
+11877	0.11689
+11878	0.11689
+11879	0.11689
+11880	0.11689
+11881	0.094874
+11882	0.11689
+11883	0.094874
+11884	0.11689
+11885	0.11689
+11886	-1.51228
+11887	0.094874
+11888	0.094874
+11889	0.094874
+11890	0.094874
+11891	0.11689
+11892	0.094874
+11893	0.094874
+11894	0.094874
+11895	0.11689
+11896	0.094874
+11897	0.11689
+11898	0.11689
+11899	0.094874
+11900	-1.75445
+11901	0.094874
+11902	0.094874
+11903	0.11689
+11904	0.094874
+11905	-1.90856
+11906	0.094874
+11907	0.11689
+11908	0.094874
+11909	0.11689
+11910	0.094874
+11911	0.094874
+11912	0.11689
+11913	0.094874
+11914	0.094874
+11915	0.11689
+11916	0.094874
+11917	0.11689
+11918	0.094874
+11919	0.094874
+11920	0.094874
+11921	0.094874
+11922	0.094874
+11923	0.11689
+11924	0.11689
+11925	0.094874
+11926	0.11689
+11927	0.094874
+11928	0.11689
+11929	0.094874
+11930	-1.75445
+11931	0.094874
+11932	0.094874
+11933	0.094874
+11934	0.11689
+11935	0.11689
+11936	0.11689
+11937	0.11689
+11938	-1.55631
+11939	0.11689
+11940	0.094874
+11941	0.11689
+11942	0.090622
+11943	0.090622
+11944	0.090622
+11945	0.090622
+11946	0.090622
+11947	0.090622
+11948	0.090622
+11949	0.090622
+11950	0.090622
+11951	0.090622
+11952	0.090622
+11953	0.090622
+11954	0.090622
+11955	0.090622
+11956	0.090622
+11957	0.090622
+11958	0.090622
+11959	0.090622
+11960	0.090622
+11961	0.090622
+11962	0.090622
+11963	0.090622
+11964	0.090622
+11965	0.090622
+11966	0.090622
+11967	0.090622
+11968	0.090622
+11969	0.090622
+11970	-1.76091
+11971	0.090622
+11972	0.090622
+11973	0.090622
+11974	0.090622
+11975	-1.89316
+11976	0.090622
+11977	0.090622
+11978	0.090622
+11979	0.090622
+11980	0.090622
+11981	0.090622
+11982	0.090622
+11983	0.090622
+11984	0.090622
+11985	0.090622
+11986	0.090622
+11987	0.090622
+11988	0.090622
+11989	0.090622
+11990	0.090622
+11991	0.090622
+11992	0.090622
+11993	-1.72784
+11994	0.090622
+11995	0.090622
+11996	0.090622
+11997	0.090622
+11998	0.090622
+11999	0.090622
+12000	0.090622
+12001	-1.99235
+12002	-3.84387
+12003	0.090622
+12004	0.090622
+12005	0.090622
+12006	0.090622
+12007	0.090622
+12008	0.090622
+12009	0.090622
+12010	0.090622
+12011	0.090622
+12012	0.090622
+12013	0.090622
+12014	0.090622
+12015	0.090622
+12016	0.090622
+12017	0.090622
+12018	0.090622
+12019	0.090622
+12020	0.090622
+12021	-1.72784
+12022	0.090622
+12023	0.090622
+12024	0.090622
+12025	0.090622
+12026	0.090622
+12027	0.090622
+12028	0.090622
+12029	0.090622
+12030	0.090622
+12031	0.090622
+12032	0.090622
+12033	0.090622
+12034	0.090622
+12035	0.090622
+12036	0.090622
+12037	0.090622
+12038	0.090622
+12039	0.090622
+12040	0.090622
+12041	0.090622
+12042	0.090622
+12043	0.090622
+12044	0.090622
+12045	0.090622
+12046	0.090622
+12047	0.090622
+12048	0.090622
+12049	-1.99235
+12050	0.090622
+12051	0.090622
+12052	0.090622
+12053	0.090622
+12054	0.090622
+12055	0.090622
+12056	0.090622
+12057	0.090622
+12058	0.090622
+12059	0.090622
+12060	0.090622
+12061	0.090622
+12062	0.090622
+12063	0.090622
+12064	0.090622
+12065	0.090622
+12066	0.090622
+12067	0.090622
+12068	0.090622
+12069	0.090622
+12070	0.090622
+12071	0.090622
+12072	0.090622
+12073	0.222874
+12074	0.222874
+12075	0.289
+12076	0.289
+12077	0.222874
+12078	0.289
+12079	0.222874
+12080	0.289
+12081	0.289
+12082	0.222874
+12083	0.289
+12084	0.222874
+12085	0.289
+12086	0.289
+12087	0.222874
+12088	0.289
+12089	0.289
+12090	0.289
+12091	0.222874
+12092	0.222874
+12093	0.289
+12094	0.289
+12095	0.289
+12096	-2.7528
+12097	-0.835142
+12098	0.289
+12099	-0.835142
+12100	0.289
+12101	0.222874
+12102	0.289
+12103	0.289
+12104	0.289
+12105	0.222874
+12106	-1.59559
+12107	0.289
+12108	0.289
+12109	0.289
+12110	0.289
+12111	0.289
+12112	0.222874
+12113	-1.62865
+12114	-1.69478
+12115	0.289
+12116	0.222874
+12117	0.222874
+12118	0.289
+12119	0.222874
+12120	-1.16577
+12121	-2.68667
+12122	0.222874
+12123	0.222874
+12124	0.289
+12125	0.222874
+12126	0.289
+12127	0.289
+12128	0.289
+12129	0.289
+12130	0.289
+12131	0.090622
+12132	0.090622
+12133	0.289
+12134	0.222874
+12135	0.222874
+12136	0.289
+12137	0.222874
+12138	0.289
+12139	0.222874
+12140	0.289
+12141	0.289
+12142	0.222874
+12143	0.222874
+12144	0.289
+12145	0.222874
+12146	0.222874
+12147	0.222874
+12148	0.289
+12149	-1.79397
+12150	0.090622
+12151	-1.89316
+12152	0.090622
+12153	0.090622
+12154	0.090622
+12155	0.090622
+12156	0.090622
+12157	0.090622
+12158	0.090622
+12159	0.090622
+12160	0.090622
+12161	0.090622
+12162	0.090622
+12163	0.090622
+12164	0.090622
+12165	0.090622
+12166	0.090622
+12167	0.090622
+12168	0.0244961
+12169	-2.1246
+12170	0.0575591
+12171	0.0575591
+12172	0.0575591
+12173	0.0575591
+12174	0.0244961
+12175	0.0244961
+12176	0.0244961
+12177	0.0575591
+12178	0.0244961
+12179	-2.09154
+12180	0.0244961
+12181	0.0575591
+12182	0.0575591
+12183	0.0244961
+12184	0.0575591
+12185	0.0575591
+12186	0.0244961
+12187	0.0244961
+12188	0.0244961
+12189	0.0575591
+12190	0.0244961
+12191	0.0244961
+12192	0.0575591
+12193	0.0244961
+12194	0.0575591
+12195	0.090622
+12196	0.090622
+12197	0.090622
+12198	0.090622
+12199	0.090622
+12200	0.090622
+12201	-1.99235
+12202	0.090622
+12203	0.090622
+12204	0.090622
+12205	0.090622
+12206	0.090622
+12207	0.090622
+12208	0.090622
+12209	0.090622
+12210	0.090622
+12211	0.090622
+12212	0.090622
+12213	0.090622
+12214	-1.99235
+12215	0.090622
+12216	0.090622
+12217	0.090622
+12218	-1.92622
+12219	0.090622
+12220	0.090622
+12221	0.090622
+12222	0.090622
+12223	0.090622
+12224	0.090622
+12225	0.090622
+12226	0.090622
+12227	0.090622
+12228	0.090622
+12229	0.090622
+12230	0.090622
+12231	0.090622
+12232	0.090622
+12233	0.090622
+12234	0.090622
+12235	0.090622
+12236	0.090622
+12237	0.090622
+12238	0.090622
+12239	0.090622
+12240	0.090622
+12241	-2.02541
+12242	0.090622
+12243	0.090622
+12244	0.090622
+12245	0.090622
+12246	0.090622
+12247	0.090622
+12248	0.090622
+12249	0.090622
+12250	0.090622
+12251	0.090622
+12252	0.090622
+12253	0.090622
+12254	0.090622
+12255	0.090622
+12256	0.090622
+12257	0.090622
+12258	0.090622
+12259	0.090622
+12260	0.090622
+12261	0.090622
+12262	0.090622
+12263	0.090622
+12264	0.090622
+12265	0.090622
+12266	0.090622
+12267	-1.56253
+12268	0.090622
+12269	0.090622
+12270	0.090622
+12271	0.090622
+12272	-1.4964
+12273	0.090622
+12274	0.090622
+12275	0.090622
+12276	0.090622
+12277	0.090622
+12278	0.090622
+12279	-1.4964
+12280	0.090622
+12281	0.090622
+12282	0.090622
+12283	0.090622
+12284	0.090622
+12285	0.090622
+12286	0.090622
+12287	0.090622
+12288	0.090622
+12289	0.090622
+12290	0.090622
+12291	0.090622
+12292	0.090622
+12293	0.090622
+12294	0.090622
+12295	0.090622
+12296	0.090622
+12297	0.090622
+12298	0.090622
+12299	0.090622
+12300	0.090622
+12301	0.090622
+12302	0.090622
+12303	0.090622
+12304	0.090622
+12305	0.090622
+12306	0.090622
+12307	0.090622
+12308	0.090622
+12309	0.090622
+12310	0.090622
+12311	0.090622
+12312	0.090622
+12313	0.090622
+12314	0.090622
+12315	0.090622
+12316	0.090622
+12317	0.090622
+12318	0.090622
+12319	-1.4964
+12320	0.090622
+12321	0.090622
+12322	0.090622
+12323	0.090622
+12324	0.090622
+12325	0.090622
+12326	0.090622
+12327	0.090622
+12328	0.090622
+12329	-1.95928
+12330	0.090622
+12331	0.090622
+12332	0.090622
+12333	0.090622
+12334	0.090622
+12335	0.090622
+12336	0.090622
+12337	0.090622
+12338	0.090622
+12339	0.090622
+12340	0.090622
+12341	0.090622
+12342	0.090622
+12343	0.090622
+12344	0.090622
+12345	0.090622
+12346	0.090622
+12347	0.090622
+12348	-1.4964
+12349	0.090622
+12350	0.090622
+12351	0.090622
+12352	0.090622
+12353	0.090622
+12354	0.090622
+12355	0.090622
+12356	-1.4964
+12357	0.090622
+12358	0.090622
+12359	0.090622
+12360	0.090622
+12361	0.090622
+12362	0.090622
+12363	0.090622
+12364	0.090622
+12365	0.090622
+12366	0.090622
+12367	0.090622
+12368	0.090622
+12369	0.090622
+12370	0.090622
+12371	0.090622
+12372	0.090622
+12373	0.090622
+12374	0.090622
+12375	0.090622
+12376	0.090622
+12377	0.090622
+12378	0.090622
+12379	-2.02541
+12380	0.090622
+12381	0.090622
+12382	0.090622
+12383	0.090622
+12384	0.090622
+12385	0.090622
+12386	0.090622
+12387	0.090622
+12388	0.090622
+12389	0.090622
+12390	0.090622
+12391	0.090622
+12392	0.090622
+12393	-1.72784
+12394	0.090622
+12395	0.090622
+12396	0.090622
+12397	0.090622
+12398	0.090622
+12399	-1.95928
+12400	0.090622
+12401	0.090622
+12402	0.090622
+12403	0.090622
+12404	0.090622
+12405	0.090622
+12406	0.090622
+12407	0.090622
+12408	0.090622
+12409	0.090622
+12410	0.090622
+12411	0.090622
+12412	0.090622
+12413	0.090622
+12414	0.090622
+12415	0.090622
+12416	0.090622
+12417	0.090622
+12418	0.090622
+12419	0.090622
+12420	0.090622
+12421	0.090622
+12422	0.090622
+12423	0.090622
+12424	0.090622
+12425	0.090622
+12426	0.090622
+12427	0.090622
+12428	0.090622
+12429	0.090622
+12430	0.090622
+12431	-1.4964
+12432	-1.76091
+12433	-1.76091
+12434	0.090622
+12435	0.090622
+12436	0.090622
+12437	0.090622
+12438	0.090622
+12439	0.090622
+12440	0.090622
+12441	0.090622
+12442	0.090622
+12443	0.090622
+12444	0.090622
+12445	0.090622
+12446	-1.72784
+12447	0.090622
+12448	0.090622
+12449	0.090622
+12450	0.090622
+12451	0.090622
+12452	0.090622
+12453	0.090622
+12454	0.090622
+12455	0.090622
+12456	0.090622
+12457	0.090622
+12458	0.090622
+12459	0.090622
+12460	0.090622
+12461	0.090622
+12462	0.090622
+12463	0.090622
+12464	0.090622
+12465	0.090622
+12466	0.090622
+12467	0.090622
+12468	0.090622
+12469	0.090622
+12470	0.090622
+12471	0.090622
+12472	0.090622
+12473	-1.99235
+12474	0.090622
+12475	0.090622
+12476	0.090622
+12477	0.090622
+12478	0.090622
+12479	0.090622
+12480	0.090622
+12481	0.090622
+12482	0.090622
+12483	0.090622
+12484	0.090622
+12485	0.090622
+12486	0.090622
+12487	-1.79397
+12488	0.090622
+12489	0.090622
+12490	0.090622
+12491	0.090622
+12492	0.090622
+12493	0.090622
+12494	0.090622
+12495	0.090622
+12496	0.090622
+12497	0.090622
+12498	0.090622
+12499	0.090622
+12500	0.090622
+12501	0.090622
+12502	0.090622
+12503	0.090622
+12504	0.090622
+12505	0.090622
+12506	-1.99235
+12507	0.090622
+12508	0.090622
+12509	0.090622
+12510	0.090622
+12511	0.090622
+12512	0.090622
+12513	0.090622
+12514	0.090622
+12515	0.090622
+12516	0.090622
+12517	0.090622
+12518	0.090622
+12519	0.090622
+12520	0.090622
+12521	0.090622
+12522	-1.4964
+12523	0.090622
+12524	0.090622
+12525	0.090622
+12526	0.090622
+12527	0.090622
+12528	0.090622
+12529	0.090622
+12530	0.090622
+12531	0.090622
+12532	0.090622
+12533	0.090622
+12534	-1.89316
+12535	0.090622
+12536	0.090622
+12537	0.090622
+12538	0.090622
+12539	0.090622
+12540	0.090622
+12541	0.090622
+12542	0.090622
+12543	0.090622
+12544	0.090622
+12545	-1.76091
+12546	0.090622
+12547	0.090622
+12548	0.090622
+12549	0.090622
+12550	0.090622
+12551	0.090622
+12552	0.090622
+12553	0.090622
+12554	0.090622
+12555	0.090622
+12556	0.090622
+12557	0.090622
+12558	0.090622
+12559	0.090622
+12560	0.090622
+12561	0.090622
+12562	0.090622
+12563	0.090622
+12564	0.090622
+12565	0.090622
+12566	0.090622
+12567	0.090622
+12568	-1.4964
+12569	0.090622
+12570	0.090622
+12571	0.090622
+12572	0.090622
+12573	0.090622
+12574	0.090622
+12575	0.090622
+12576	-1.82703
+12577	0.090622
+12578	0.090622
+12579	0.090622
+12580	0.090622
+12581	-1.4964
+12582	0.090622
+12583	0.090622
+12584	0.090622
+12585	0.090622
+12586	0.090622
+12587	0.090622
+12588	0.090622
+12589	0.090622
+12590	0.090622
+12591	0.090622
+12592	0.090622
+12593	0.090622
+12594	0.090622
+12595	0.090622
+12596	0.090622
+12597	0.090622
+12598	0.090622
+12599	0.090622
+12600	0.090622
+12601	0.090622
+12602	0.090622
+12603	0.090622
+12604	0.090622
+12605	0.090622
+12606	0.090622
+12607	0.090622
+12608	0.090622
+12609	0.090622
+12610	0.090622
+12611	0.090622
+12612	0.090622
+12613	0.090622
+12614	0.090622
+12615	0.090622
+12616	0.090622
+12617	0.090622
+12618	0.090622
+12619	0.090622
+12620	0.090622
+12621	0.090622
+12622	0.090622
+12623	0.090622
+12624	0.090622
+12625	0.090622
+12626	-1.76091
+12627	0.090622
+12628	0.090622
+12629	0.090622
+12630	0.090622
+12631	0.090622
+12632	0.090622
+12633	0.090622
+12634	0.090622
+12635	0.090622
+12636	0.090622
+12637	0.090622
+12638	0.090622
+12639	0.090622
+12640	0.090622
+12641	0.090622
+12642	-1.72784
+12643	0.090622
+12644	0.090622
+12645	-1.4964
+12646	-1.4964
+12647	0.090622
+12648	0.090622
+12649	0.090622
+12650	0.090622
+12651	0.090622
+12652	0.090622
+12653	0.090622
+12654	0.090622
+12655	0.090622
+12656	0.090622
+12657	0.090622
+12658	0.090622
+12659	0.090622
+12660	0.090622
+12661	0.090622
+12662	0.090622
+12663	0.090622
+12664	0.090622
+12665	0.090622
+12666	0.090622
+12667	0.090622
+12668	0.090622
+12669	0.090622
+12670	-1.4964
+12671	0.090622
+12672	-1.76091
+12673	0.090622
+12674	0.090622
+12675	0.090622
+12676	0.090622
+12677	0.090622
+12678	0.090622
+12679	0.090622
+12680	-3.91
+12681	0.090622
+12682	0.090622
+12683	0.090622
+12684	0.090622
+12685	0.090622
+12686	0.090622
+12687	0.090622
+12688	0.090622
+12689	0.090622
+12690	0.090622
+12691	0.090622
+12692	0.090622
+12693	0.090622
+12694	0.090622
+12695	0.090622
+12696	0.090622
+12697	-2.19072
+12698	-1.72784
+12699	0.090622
+12700	0.090622
+12701	0.090622
+12702	0.090622
+12703	0.090622
+12704	0.090622
+12705	0.090622
+12706	0.090622
+12707	0.090622
+12708	0.090622
+12709	0.090622
+12710	0.090622
+12711	0.090622
+12712	0.090622
+12713	-1.72784
+12714	0.090622
+12715	0.090622
+12716	0.090622
+12717	0.090622
+12718	0.090622
+12719	0.090622
+12720	-2.19072
+12721	0.090622
+12722	0.090622
+12723	0.090622
+12724	0.090622
+12725	0.090622
+12726	0.090622
+12727	0.090622
+12728	0.090622
+12729	0.090622
+12730	0.090622
+12731	0.090622
+12732	0.090622
+12733	0.090622
+12734	0.090622
+12735	0.090622
+12736	0.090622
+12737	-1.56253
+12738	0.090622
+12739	-1.76091
+12740	0.090622
+12741	-1.56253
+12742	-1.4964
+12743	0.090622
+12744	0.090622
+12745	0.090622
+12746	0.090622
+12747	0.090622
+12748	0.090622
+12749	0.090622
+12750	0.090622
+12751	0.090622
+12752	0.090622
+12753	0.090622
+12754	0.090622
+12755	0.090622
+12756	0.090622
+12757	0.090622
+12758	-1.95928
+12759	0.090622
+12760	0.090622
+12761	0.090622
+12762	0.090622
+12763	0.090622
+12764	0.090622
+12765	0.090622
+12766	0.090622
+12767	0.090622
+12768	-1.92622
+12769	0.090622
+12770	-1.99235
+12771	0.090622
+12772	-1.76091
+12773	0.090622
+12774	-2.25685
+12775	0.090622
+12776	0.090622
+12777	0.090622
+12778	0.090622
+12779	-1.89316
+12780	-1.4964
+12781	0.090622
+12782	-1.89316
+12783	0.090622
+12784	0.090622
+12785	0.090622
+12786	0.090622
+12787	0.090622
+12788	0.090622
+12789	0.090622
+12790	0.090622
+12791	0.090622
+12792	0.090622
+12793	0.090622
+12794	0.090622
+12795	-1.89316
+12796	0.090622
+12797	-1.72784
+12798	0.090622
+12799	-1.76091
+12800	0.090622
+12801	0.090622
+12802	0.090622
+12803	0.090622
+12804	0.090622
+12805	0.090622
+12806	0.090622
+12807	-1.99235
+12808	0.090622
+12809	-1.56253
+12810	0.090622
+12811	0.090622
+12812	0.090622
+12813	0.090622
+12814	0.090622
+12815	0.090622
+12816	0.090622
+12817	0.090622
+12818	0.090622
+12819	0.090622
+12820	0.090622
+12821	0.090622
+12822	0.090622
+12823	0.090622
+12824	0.090622
+12825	0.090622
+12826	0.090622
+12827	0.0244961
+12828	0.0244961
+12829	0.090622
+12830	0.090622
+12831	0.090622
+12832	-1.89316
+12833	0.090622
+12834	0.090622
+12835	0.090622
+12836	0.090622
+12837	0.090622
+12838	0.090622
+12839	0.090622
+12840	0.090622
+12841	0.090622
+12842	0.090622
+12843	0.090622
+12844	0.090622
+12845	0.090622
+12846	0.090622
+12847	0.090622
+12848	0.090622
+12849	0.090622
+12850	0.090622
+12851	0.090622
+12852	0.090622
+12853	0.090622
+12854	0.090622
+12855	0.090622
+12856	0.090622
+12857	0.090622
+12858	0.090622
+12859	0.090622
+12860	-1.89316
+12861	0.090622
+12862	0.090622
+12863	0.090622
+12864	0.090622
+12865	0.090622
+12866	0.090622
+12867	0.090622
+12868	0.090622
+12869	0.090622
+12870	0.090622
+12871	0.090622
+12872	0.090622
+12873	0.090622
+12874	0.090622
+12875	0.090622
+12876	0.090622
+12877	-1.56253
+12878	-1.76091
+12879	0.090622
+12880	0.090622
+12881	0.090622
+12882	0.090622
+12883	-1.72784
+12884	0.090622
+12885	0.090622
+12886	0.090622
+12887	-1.92622
+12888	-1.76091
+12889	0.090622
+12890	0.090622
+12891	0.090622
+12892	0.090622
+12893	0.090622
+12894	0.090622
+12895	0.090622
+12896	0.090622
+12897	0.090622
+12898	0.090622
+12899	0.090622
+12900	0.090622
+12901	0.090622
+12902	0.090622
+12903	0.090622
+12904	0.090622
+12905	0.090622
+12906	0.090622
+12907	0.090622
+12908	0.090622
+12909	0.090622
+12910	0.090622
+12911	0.090622
+12912	0.090622
+12913	0.090622
+12914	0.090622
+12915	0.090622
+12916	0.090622
+12917	0.090622
+12918	0.090622
+12919	0.090622
+12920	0.090622
+12921	0.090622
+12922	0.090622
+12923	0.090622
+12924	0.090622
+12925	0.090622
+12926	-1.56253
+12927	0.090622
+12928	0.090622
+12929	0.090622
+12930	0.090622
+12931	0.090622
+12932	0.090622
+12933	0.090622
+12934	0.090622
+12935	0.090622
+12936	0.090622
+12937	0.090622
+12938	0.090622
+12939	-1.99235
+12940	0.090622
+12941	0.090622
+12942	0.090622
+12943	-1.4964
+12944	0.090622
+12945	0.090622
+12946	0.090622
+12947	0.090622
+12948	-1.79397
+12949	0.090622
+12950	0.090622
+12951	0.090622
+12952	0.090622
+12953	0.090622
+12954	-1.4964
+12955	0.156748
+12956	0.123685
+12957	0.156748
+12958	0.123685
+12959	0.123685
+12960	0.156748
+12961	0.156748
+12962	0.156748
+12963	0.156748
+12964	0.123685
+12965	-1.46334
+12966	0.184
+12967	0.153142
+12968	0.184
+12969	0.153142
+12970	0.184
+12971	0.184
+12972	0.184
+12973	0.153142
+12974	0.184
+12975	0.184
+12976	0.153142
+12977	0.184
+12978	-1.42063
+12979	0.184
+12980	0.153142
+12981	0.184
+12982	0.184
+12983	0.184
+12984	0.184
+12985	-1.45149
+12986	-1.11205
+12987	0.184
+12988	0.184
+12989	0.184
+12990	-1.5132
+12991	0.184
+12992	0.184
+12993	0.184
+12994	0.184
+12995	0.184
+12996	0.184
+12997	0.184
+12998	0.184
+12999	0.184
+13000	0.153142
+13001	0.153142
+13002	0.184
+13003	0.153142
+13004	0.153142
+13005	0.153142
+13006	0.184
+13007	0.184
+13008	0.184
+13009	-1.45149
+13010	0.184
+13011	0.153142
+13012	0.184
+13013	0.184
+13014	0.153142
+13015	0.184
+13016	0.184
+13017	0.153142
+13018	0.184
+13019	0.153142
+13020	0.153142
+13021	0.184
+13022	0.184
+13023	0.153142
+13024	0.184
+13025	-1.20462
+13026	0.184
+13027	0.184
+13028	0.153142
+13029	0.153142
+13030	0.184
+13031	0.153142
+13032	0.153142
+13033	0.184
+13034	0.184
+13035	0.184
+13036	0.153142
+13037	0.184
+13038	-1.20462
+13039	0.184
+13040	0.153142
+13041	0.153142
+13042	0.184
+13043	0.184
+13044	-1.20462
+13045	0.184
+13046	0.153142
+13047	0.184
+13048	0.184
+13049	0.153142
+13050	0.153142
+13051	0.153142
+13052	-1.11205
+13053	0.184
+13054	0.184
+13055	0.153142
+13056	-1.20462
+13057	0.184
+13058	0.184
+13059	0.184
+13060	0.153142
+13061	0.184
+13062	0.184
+13063	0.184
+13064	0.153142
+13065	0.184
+13066	0.184
+13067	0.184
+13068	0.153142
+13069	0.184
+13070	0.184
+13071	-1.20462
+13072	0.184
+13073	0.184
+13074	0.153142
+13075	0.184
+13076	0.184
+13077	0.184
+13078	0.153142
+13079	-1.14291
+13080	0.184
+13081	0.153142
+13082	0.184
+13083	0.153142
+13084	0.184
+13085	0.153142
+13086	0.184
+13087	-1.42063
+13088	0.184
+13089	0.184
+13090	-1.14291
+13091	0.184
+13092	-1.11205
+13093	0.153142
+13094	0.184
+13095	0.184
+13096	0.153142
+13097	0.184
+13098	0.153142
+13099	0.153142
+13100	0.184
+13101	0.184
+13102	0.184
+13103	0.184
+13104	0.153142
+13105	0.184
+13106	0.153142
+13107	0.153142
+13108	0.184
+13109	0.153142
+13110	0.184
+13111	0.184
+13112	0.153142
+13113	0.153142
+13114	0.153142
+13115	0.184
+13116	-1.14291
+13117	0.184
+13118	-3.735
+13119	0.184
+13120	0.184
+13121	-1.17376
+13122	0.153142
+13123	0.184
+13124	0.184
+13125	0.184
+13126	0.153142
+13127	0.184
+13128	0.184
+13129	0.184
+13130	0.184
+13131	0.153142
+13132	0.184
+13133	0.153142
+13134	0.184
+13135	0.153142
+13136	0.184
+13137	0.184
+13138	-2.80925
+13139	0.153142
+13140	0.184
+13141	0.184
+13142	0.153142
+13143	0.184
+13144	0.153142
+13145	0.184
+13146	0.184
+13147	0.184
+13148	0.153142
+13149	0.184
+13150	0.153142
+13151	0.184
+13152	0.184
+13153	0.153142
+13154	0.153142
+13155	0.184
+13156	0.184
+13157	-1.42063
+13158	0.184
+13159	0.153142
+13160	-1.17376
+13161	0.184
+13162	0.184
+13163	-1.11205
+13164	-1.11205
+13165	0.153142
+13166	0.153142
+13167	0.184
+13168	-1.11205
+13169	-1.20462
+13170	0.184
+13171	0.153142
+13172	0.184
+13173	0.153142
+13174	0.153142
+13175	0.184
+13176	0.184
+13177	0.184
+13178	0.184
+13179	0.153142
+13180	0.184
+13181	0.184
+13182	0.184
+13183	0.153142
+13184	0.184
+13185	0.184
+13186	0.153142
+13187	0.184
+13188	0.153142
+13189	-1.42063
+13190	0.153142
+13191	0.184
+13192	-1.38977
+13193	-1.26634
+13194	0.153142
+13195	0.153142
+13196	0.153142
+13197	0.184
+13198	0.184
+13199	0.184
+13200	-1.42063
+13201	-1.45149
+13202	-1.63664
+13203	0.184
+13204	0.184
+13205	0.184
+13206	0.153142
+13207	0.184
+13208	-1.20462
+13209	0.184
+13210	0.153142
+13211	0.153142
+13212	0.184
+13213	0.184
+13214	0.184
+13215	0.153142
+13216	0.184
+13217	-1.11205
+13218	0.153142
+13219	0.153142
+13220	0.184
+13221	0.184
+13222	0.184
+13223	0.153142
+13224	0.184
+13225	0.184
+13226	-1.11205
+13227	0.184
+13228	0.184
+13229	0.153142
+13230	0.153142
+13231	0.184
+13232	0.153142
+13233	0.184
+13234	0.184
+13235	0.184
+13236	0.153142
+13237	0.184
+13238	0.184
+13239	-1.20462
+13240	0.153142
+13241	0.153142
+13242	0.184
+13243	0.184
+13244	0.184
+13245	0.153142
+13246	0.153142
+13247	0.153142
+13248	0.184
+13249	0.153142
+13250	0.184
+13251	0.184
+13252	0.184
+13253	0.153142
+13254	0.184
+13255	0.184
+13256	0.153142
+13257	0.153142
+13258	0.153142
+13259	-1.14291
+13260	0.153142
+13261	0.184
+13262	-1.11205
+13263	0.153142
+13264	0.184
+13265	0.184
+13266	0.153142
+13267	0.184
+13268	0.184
+13269	0.153142
+13270	0.184
+13271	0.184
+13272	0.153142
+13273	0.184
+13274	0.153142
+13275	0.184
+13276	0.153142
+13277	-1.20462
+13278	0.153142
+13279	0.184
+13280	0.153142
+13281	0.184
+13282	0.184
+13283	0.184
+13284	0.184
+13285	0.184
+13286	0.0914252
+13287	0.0914252
+13288	0.184
+13289	0.184
+13290	0.184
+13291	-1.20462
+13292	0.184
+13293	0.153142
+13294	0.184
+13295	0.184
+13296	0.153142
+13297	0.184
+13298	0.184
+13299	-1.5132
+13300	0.184
+13301	0.153142
+13302	-1.45149
+13303	0.184
+13304	0.184
+13305	0.153142
+13306	0.184
+13307	-1.20462
+13308	-1.20462
+13309	-1.11205
+13310	0.184
+13311	0.184
+13312	0.184
+13313	0.153142
+13314	0.184
+13315	0.184
+13316	0.153142
+13317	0.153142
+13318	0.184
+13319	0.153142
+13320	0.184
+13321	0.153142
+13322	0.184
+13323	0.184
+13324	0.184
+13325	0.184
+13326	0.153142
+13327	-3.45728
+13328	0.184
+13329	0.153142
+13330	0.184
+13331	-1.2972
+13332	0.153142
+13333	0.184
+13334	-1.14291
+13335	0.153142
+13336	0.184
+13337	0.153142
+13338	0.153142
+13339	-1.5132
+13340	0.184
+13341	0.184
+13342	0.184
+13343	0.153142
+13344	-1.11205
+13345	0.184
+13346	0.153142
+13347	0.153142
+13348	0.153142
+13349	0.184
+13350	0.184
+13351	0.153142
+13352	0.153142
+13353	0.184
+13354	-1.45149
+13355	0.184
+13356	0.184
+13357	0.184
+13358	0.153142
+13359	-1.38977
+13360	0.153142
+13361	0.184
+13362	0.184
+13363	0.153142
+13364	0.184
+13365	0.184
+13366	0.153142
+13367	0.184
+13368	0.153142
+13369	0.184
+13370	0.153142
+13371	0.184
+13372	0.184
+13373	0.153142
+13374	0.153142
+13375	0.184
+13376	0.153142
+13377	0.153142
+13378	0.184
+13379	0.153142
+13380	-1.14291
+13381	0.153142
+13382	0.184
+13383	0.184
+13384	0.153142
+13385	0.184
+13386	0.184
+13387	0.184
+13388	0.153142
+13389	0.153142
+13390	0.153142
+13391	0.153142
+13392	0.184
+13393	0.184
+13394	0.153142
+13395	0.153142
+13396	0.153142
+13397	0.184
+13398	0.184
+13399	0.184
+13400	-1.14291
+13401	0.153142
+13402	0.184
+13403	0.153142
+13404	0.184
+13405	-1.20462
+13406	0.184
+13407	0.153142
+13408	0.184
+13409	0.184
+13410	0.153142
+13411	0.184
+13412	0.184
+13413	0.153142
+13414	0.184
+13415	0.184
+13416	0.184
+13417	0.184
+13418	0.184
+13419	0.153142
+13420	0.184
+13421	0.153142
+13422	0.153142
+13423	-1.2972
+13424	-1.17376
+13425	0.184
+13426	0.153142
+13427	-1.42063
+13428	0.153142
+13429	0.153142
+13430	0.184
+13431	0.153142
+13432	0.184
+13433	0.153142
+13434	0.184
+13435	0.153142
+13436	0.184
+13437	0.184
+13438	0.184
+13439	0.153142
+13440	0.153142
+13441	-1.20462
+13442	0.153142
+13443	0.184
+13444	0.153142
+13445	0.184
+13446	0.153142
+13447	0.184
+13448	0.184
+13449	0.184
+13450	0.184
+13451	0.153142
+13452	0.184
+13453	0.153142
+13454	0.153142
+13455	0.153142
+13456	0.184
+13457	0.153142
+13458	0.184
+13459	0.184
+13460	0.153142
+13461	0.184
+13462	0.153142
+13463	0.153142
+13464	0.184
+13465	0.153142
+13466	-1.5132
+13467	0.184
+13468	0.184
+13469	0.184
+13470	0.184
+13471	0.153142
+13472	-1.2972
+13473	0.153142
+13474	0.153142
+13475	0.184
+13476	0.184
+13477	0.153142
+13478	0.184
+13479	0.153142
+13480	0.184
+13481	-1.38977
+13482	0.184
+13483	0.184
+13484	0.184
+13485	0.153142
+13486	-1.11205
+13487	0.184
+13488	0.153142
+13489	0.184
+13490	0.184
+13491	0.153142
+13492	0.184
+13493	0.184
+13494	0.153142
+13495	0.184
+13496	0.153142
+13497	0.184
+13498	0.184
+13499	0.184
+13500	0.153142
+13501	-1.23548
+13502	0.184
+13503	-1.11205
+13504	-1.23548
+13505	0.184
+13506	0.153142
+13507	0.184
+13508	-1.17376
+13509	0.184
+13510	0.184
+13511	0.184
+13512	0.0914252
+13513	0.0914252
+13514	-1.45149
+13515	0.184
+13516	0.184
+13517	0.153142
+13518	0.153142
+13519	0.153142
+13520	-1.26634
+13521	0.184
+13522	0.153142
+13523	0.184
+13524	0.153142
+13525	0.184
+13526	0.184
+13527	0.184
+13528	0.184
+13529	-1.11205
+13530	0.184
+13531	0.153142
+13532	0.184
+13533	0.184
+13534	0.153142
+13535	0.184
+13536	0.153142
+13537	-1.23548
+13538	-1.11205
+13539	0.184
+13540	0.153142
+13541	0.184
+13542	0.153142
+13543	-1.20462
+13544	-1.57492
+13545	0.184
+13546	0.153142
+13547	0.184
+13548	0.153142
+13549	-1.57492
+13550	0.184
+13551	0.184
+13552	0.184
+13553	0.184
+13554	0.184
+13555	0.153142
+13556	0.184
+13557	0.184
+13558	0.153142
+13559	0.184
+13560	0.153142
+13561	0.184
+13562	0.184
+13563	0.153142
+13564	0.184
+13565	0.184
+13566	0.184
+13567	0.153142
+13568	0.153142
+13569	0.184
+13570	-1.2972
+13571	-1.20462
+13572	0.184
+13573	0.184
+13574	0.153142
+13575	0.153142
+13576	0.184
+13577	-1.20462
+13578	0.153142
+13579	0.153142
+13580	0.184
+13581	0.184
+13582	0.153142
+13583	0.184
+13584	0.153142
+13585	0.153142
+13586	0.153142
+13587	0.184
+13588	0.184
+13589	0.184
+13590	0.153142
+13591	0.184
+13592	0.184
+13593	0.153142
+13594	0.184
+13595	-1.5132
+13596	0.184
+13597	0.153142
+13598	0.184
+13599	0.153142
+13600	0.184
+13601	0.184
+13602	0.153142
+13603	0.184
+13604	0.153142
+13605	0.184
+13606	0.184
+13607	0.153142
+13608	0.184
+13609	0.153142
+13610	0.184
+13611	-1.38977
+13612	0.184
+13613	-1.20462
+13614	0.153142
+13615	0.184
+13616	0.184
+13617	0.184
+13618	0.153142
+13619	0.184
+13620	0.184
+13621	0.153142
+13622	0.184
+13623	0.184
+13624	0.184
+13625	0.153142
+13626	0.184
+13627	-1.11205
+13628	0.184
+13629	0.153142
+13630	0.184
+13631	0.153142
+13632	-1.11205
+13633	0.184
+13634	0.184
+13635	0.153142
+13636	0.153142
+13637	0.153142
+13638	0.153142
+13639	0.184
+13640	0.153142
+13641	0.184
+13642	0.184
+13643	0.184
+13644	0.184
+13645	-1.5132
+13646	-1.20462
+13647	0.153142
+13648	0.184
+13649	0.184
+13650	0.153142
+13651	0.184
+13652	0.153142
+13653	0.153142
+13654	0.153142
+13655	-1.20462
+13656	0.184
+13657	0.122283
+13658	-1.26634
+13659	0.184
+13660	-1.2972
+13661	0.184
+13662	-1.20462
+13663	0.153142
+13664	-1.20462
+13665	0.184
+13666	0.184
+13667	0.184
+13668	-1.14291
+13669	0.153142
+13670	0.153142
+13671	0.184
+13672	0.153142
+13673	0.153142
+13674	0.153142
+13675	0.153142
+13676	0.184
+13677	0.184
+13678	0.153142
+13679	-1.11205
+13680	-1.14291
+13681	0.184
+13682	0.153142
+13683	0.184
+13684	-1.11205
+13685	-1.45149
+13686	0.184
+13687	0.184
+13688	0.184
+13689	0.184
+13690	0.153142
+13691	0.153142
+13692	0.184
+13693	0.184
+13694	-1.60578
+13695	-1.63664
+13696	0.184
+13697	0.153142
+13698	0.184
+13699	-1.42063
+13700	0.153142
+13701	0.184
+13702	0.153142
+13703	0.153142
+13704	0.184
+13705	0.184
+13706	0.184
+13707	0.153142
+13708	0.184
+13709	0.184
+13710	-1.2972
+13711	0.184
+13712	0.153142
+13713	0.184
+13714	0.184
+13715	0.153142
+13716	0.184
+13717	0.184
+13718	0.184
+13719	0.184
+13720	0.153142
+13721	0.184
+13722	0.153142
+13723	0.184
+13724	0.153142
+13725	0.184
+13726	0.184
+13727	0.153142
+13728	0.153142
+13729	0.153142
+13730	0.184
+13731	-1.2972
+13732	0.153142
+13733	0.153142
+13734	0.153142
+13735	0.184
+13736	0.153142
+13737	-1.11205
+13738	0.153142
+13739	0.184
+13740	0.153142
+13741	0.153142
+13742	0.184
+13743	0.184
+13744	0.153142
+13745	0.153142
+13746	0.184
+13747	0.184
+13748	-1.20462
+13749	-1.11205
+13750	0.184
+13751	-1.11205
+13752	0.153142
+13753	0.184
+13754	0.184
+13755	0.184
+13756	-2.90183
+13757	-1.26634
+13758	0.153142
+13759	0.184
+13760	0.184
+13761	0.184
+13762	0.184
+13763	0.184
+13764	0.153142
+13765	0.184
+13766	0.184
+13767	0.184
+13768	0.153142
+13769	0.153142
+13770	0.184
+13771	0.153142
+13772	0.184
+13773	0.153142
+13774	0.184
+13775	0.153142
+13776	0.0914252
+13777	0.184
+13778	0.184
+13779	0.184
+13780	0.184
+13781	0.153142
+13782	0.184
+13783	0.153142
+13784	0.184
+13785	0.184
+13786	0.153142
+13787	0.184
+13788	0.184
+13789	0.153142
+13790	0.184
+13791	0.184
+13792	0.184
+13793	0.153142
+13794	0.184
+13795	0.184
+13796	0.184
+13797	-1.5132
+13798	0.153142
+13799	0.153142
+13800	0.153142
+13801	0.184
+13802	0.153142
+13803	0.184
+13804	0.184
+13805	0.153142
+13806	0.184
+13807	0.184
+13808	0.184
+13809	0.184
+13810	0.153142
+13811	-1.26634
+13812	0.184
+13813	0.153142
+13814	0.153142
+13815	0.184
+13816	0.153142
+13817	-1.45149
+13818	0.153142
+13819	0.184
+13820	0.153142
+13821	-1.42063
+13822	0.184
+13823	-1.23548
+13824	0.184
+13825	0.153142
+13826	0.184
+13827	0.153142
+13828	-1.11205
+13829	0.184
+13830	0.184
+13831	0.153142
+13832	0.184
+13833	-1.20462
+13834	0.153142
+13835	-1.14291
+13836	0.153142
+13837	0.184
+13838	-1.2972
+13839	0.184
+13840	0.153142
+13841	-1.38977
+13842	0.184
+13843	0.153142
+13844	0.184
+13845	0.184
+13846	0.153142
+13847	-1.6675
+13848	0.184
+13849	0.153142
+13850	0.184
+13851	0.184
+13852	0.184
+13853	-1.2972
+13854	0.153142
+13855	0.153142
+13856	0.153142
+13857	0.184
+13858	-1.42063
+13859	-1.38977
+13860	0.153142
+13861	-1.20462
+13862	-1.38977
+13863	-1.38977
+13864	0.153142
+13865	0.153142
+13866	-1.2972
+13867	0.153142
+13868	-1.38977
+13869	-1.45149
+13870	0.153142
+13871	0.184
+13872	0.153142
+13873	-1.20462
+13874	0.153142
+13875	0.184
+13876	0.184
+13877	0.153142
+13878	0.184
+13879	0.184
+13880	0.184
+13881	0.184
+13882	0.153142
+13883	0.184
+13884	0.184
+13885	0.153142
+13886	0.184
+13887	0.153142
+13888	0.153142
+13889	-1.57492
+13890	0.153142
+13891	0.184
+13892	0.153142
+13893	0.184
+13894	0.184
+13895	0.184
+13896	-1.5132
+13897	0.184
+13898	-1.20462
+13899	0.153142
+13900	0.184
+13901	0.153142
+13902	0.184
+13903	0.153142
+13904	0.184
+13905	-1.42063
+13906	0.153142
+13907	-1.20462
+13908	0.153142
+13909	0.153142
+13910	0.153142
+13911	-1.20462
+13912	-1.45149
+13913	-1.38977
+13914	0.153142
+13915	0.184
+13916	0.153142
+13917	0.153142
+13918	0.184
+13919	0.184
+13920	-1.2972
+13921	0.184
+13922	0.153142
+13923	0.153142
+13924	0.184
+13925	0.184
+13926	0.184
+13927	0.184
+13928	0.153142
+13929	0.184
+13930	0.153142
+13931	0.184
+13932	0.184
+13933	0.184
+13934	0.184
+13935	-1.11205
+13936	0.184
+13937	0.184
+13938	-1.20462
+13939	0.184
+13940	0.184
+13941	0.184
+13942	-1.38977
+13943	-1.23548
+13944	0.184
+13945	0.184
+13946	0.184
+13947	0.184
+13948	0.184
+13949	0.153142
+13950	0.153142
+13951	0.184
+13952	0.153142
+13953	0.184
+13954	0.153142
+13955	0.184
+13956	-1.11205
+13957	0.153142
+13958	-1.11205
+13959	0.184
+13960	0.184
+13961	0.184
+13962	0.184
+13963	0.153142
+13964	0.184
+13965	0.184
+13966	0.153142
+13967	0.153142
+13968	0.184
+13969	0.153142
+13970	0.153142
+13971	0.184
+13972	0.184
+13973	-1.38977
+13974	0.184
+13975	0.153142
+13976	0.184
+13977	0.153142
+13978	0.184
+13979	0.153142
+13980	-1.17376
+13981	0.153142
+13982	-3.61157
+13983	0.184
+13984	0.153142
+13985	0.184
+13986	0.184
+13987	0.153142
+13988	0.184
+13989	0.184
+13990	0.184
+13991	-1.39265
+13992	0.154252
+13993	0.184
+13994	0.184
+13995	0.154252
+13996	0.184
+13997	0.184
+13998	0.184
+13999	0.154252
+14000	0.154252
+14001	0.154252
+14002	0.184
+14003	0.184
+14004	0.154252
+14005	0.184
+14006	0.184
+14007	0.184
+14008	0.184
+14009	0.184
+14010	0.154252
+14011	0.184
+14012	0.154252
+14013	0.184
+14014	0.184
+14015	0.184
+14016	-1.39265
+14017	0.154252
+14018	0.184
+14019	0.184
+14020	0.184
+14021	0.154252
+14022	0.184
+14023	0.184
+14024	0.154252
+14025	0.154252
+14026	0.154252
+14027	0.154252
+14028	-1.42239
+14029	0.154252
+14030	0.154252
+14031	0.154252
+14032	0.184
+14033	0.154252
+14034	0.184
+14035	0.184
+14036	0.184
+14037	0.154252
+14038	0.184
+14039	0.184
+14040	0.184
+14041	0.154252
+14042	0.154252
+14043	0.184
+14044	0.184
+14045	0.154252
+14046	0.184
+14047	0.184
+14048	0.184
+14049	0.154252
+14050	0.184
+14051	0.154252
+14052	0.154252
+14053	0.184
+14054	0.184
+14055	0.154252
+14056	0.184
+14057	0.184
+14058	0.154252
+14059	0.154252
+14060	0.184
+14061	0.154252
+14062	-1.21416
+14063	0.184
+14064	0.154252
+14065	0.154252
+14066	0.184
+14067	0.184
+14068	0.184
+14069	0.154252
+14070	0.184
+14071	0.184
+14072	0.154252
+14073	0.184
+14074	0.184
+14075	0.184
+14076	0.154252
+14077	0.184
+14078	0.184
+14079	0.184
+14080	0.154252
+14081	0.184
+14082	0.154252
+14083	0.184
+14084	0.154252
+14085	0.154252
+14086	0.184
+14087	-2.76106
+14088	0.154252
+14089	0.184
+14090	0.154252
+14091	0.154252
+14092	0.184
+14093	0.154252
+14094	0.184
+14095	0.184
+14096	-1.45214
+14097	0.154252
+14098	0.154252
+14099	0.184
+14100	0.154252
+14101	-1.15466
+14102	-1.18441
+14103	0.154252
+14104	0.154252
+14105	0.184
+14106	0.154252
+14107	0.184
+14108	0.154252
+14109	-1.21416
+14110	0.184
+14111	0.154252
+14112	0.154252
+14113	0.184
+14114	-1.45214
+14115	0.154252
+14116	0.184
+14117	-1.12491
+14118	0.184
+14119	0.184
+14120	0.154252
+14121	0.154252
+14122	0.184
+14123	0.154252
+14124	0.184
+14125	0.184
+14126	0.154252
+14127	0.184
+14128	0.184
+14129	0.154252
+14130	0.154252
+14131	0.154252
+14132	-1.45214
+14133	0.184
+14134	0.154252
+14135	0.184
+14136	0.184
+14137	0.184
+14138	0.154252
+14139	0.154252
+14140	0.184
+14141	0.184
+14142	0.184
+14143	0.184
+14144	0.184
+14145	0.154252
+14146	0.154252
+14147	-1.39265
+14148	0.154252
+14149	0.184
+14150	0.184
+14151	0.184
+14152	0.154252
+14153	0.184
+14154	0.154252
+14155	0.184
+14156	0.154252
+14157	0.184
+14158	0.184
+14159	0.154252
+14160	0.154252
+14161	0.184
+14162	0.154252
+14163	0.184
+14164	0.154252
+14165	0.154252
+14166	0.154252
+14167	0.154252
+14168	0.154252
+14169	0.154252
+14170	0.154252
+14171	0.154252
+14172	0.184
+14173	0.154252
+14174	0.184
+14175	0.154252
+14176	0.184
+14177	0.184
+14178	0.184
+14179	0.184
+14180	0.184
+14181	0.154252
+14182	0.184
+14183	0.154252
+14184	0.184
+14185	0.154252
+14186	0.184
+14187	0.154252
+14188	0.184
+14189	0.154252
+14190	0.184
+14191	0.154252
+14192	0.184
+14193	0.154252
+14194	0.154252
+14195	0.154252
+14196	-1.27365
+14197	0.184
+14198	0.154252
+14199	0.154252
+14200	0.154252
+14201	0.154252
+14202	0.154252
+14203	-1.42239
+14204	0.184
+14205	0.154252
+14206	0.184
+14207	0.184
+14208	0.184
+14209	0.154252
+14210	0.184
+14211	0.154252
+14212	0.184
+14213	0.154252
+14214	0.154252
+14215	0.154252
+14216	0.154252
+14217	0.184
+14218	0.184
+14219	0.154252
+14220	0.184
+14221	0.184
+14222	0.184
+14223	0.154252
+14224	-1.21416
+14225	0.184
+14226	0.154252
+14227	0.184
+14228	0.184
+14229	0.154252
+14230	0.154252
+14231	0.184
+14232	0.154252
+14233	0.184
+14234	0.184
+14235	0.154252
+14236	0.184
+14237	0.184
+14238	0.184
+14239	0.184
+14240	0.184
+14241	0.154252
+14242	0.184
+14243	0.184
+14244	0.154252
+14245	0.184
+14246	0.154252
+14247	0.184
+14248	0.154252
+14249	0.184
+14250	0.184
+14251	-1.63063
+14252	0.184
+14253	-1.21416
+14254	0.154252
+14255	0.184
+14256	0.154252
+14257	0.184
+14258	0.154252
+14259	0.184
+14260	0.184
+14261	0.154252
+14262	0.184
+14263	0.184
+14264	0.184
+14265	0.154252
+14266	0.184
+14267	0.154252
+14268	-1.27365
+14269	0.154252
+14270	-1.39265
+14271	0.184
+14272	0.184
+14273	0.184
+14274	0.154252
+14275	0.184
+14276	0.154252
+14277	0.184
+14278	0.154252
+14279	0.154252
+14280	0.154252
+14281	-1.12491
+14282	-1.21416
+14283	0.184
+14284	0.184
+14285	0.154252
+14286	0.184
+14287	0.154252
+14288	0.184
+14289	0.184
+14290	0.154252
+14291	0.184
+14292	0.184
+14293	0.184
+14294	0.154252
+14295	-1.60088
+14296	0.184
+14297	0.154252
+14298	0.154252
+14299	0.184
+14300	0.154252
+14301	0.184
+14302	0.184
+14303	0.184
+14304	0.184
+14305	0.184
+14306	0.184
+14307	0.154252
+14308	-1.12491
+14309	0.154252
+14310	0.184
+14311	0.184
+14312	0.184
+14313	0.154252
+14314	0.154252
+14315	0.184
+14316	-1.21416
+14317	-1.12491
+14318	0.154252
+14319	0.184
+14320	0.184
+14321	0.154252
+14322	0.154252
+14323	0.184
+14324	0.154252
+14325	0.184
+14326	0.184
+14327	0.184
+14328	0.184
+14329	0.184
+14330	0.154252
+14331	0.184
+14332	0.184
+14333	0.154252
+14334	0.184
+14335	0.184
+14336	-1.3034
+14337	0.154252
+14338	0.184
+14339	0.154252
+14340	0.184
+14341	0.154252
+14342	0.184
+14343	0.154252
+14344	0.184
+14345	0.154252
+14346	0.184
+14347	0.184
+14348	0.184
+14349	0.184
+14350	-1.27365
+14351	0.154252
+14352	0.184
+14353	0.154252
+14354	0.184
+14355	-1.21416
+14356	0.154252
+14357	0.154252
+14358	0.154252
+14359	0.184
+14360	0.184
+14361	0.154252
+14362	0.154252
+14363	0.184
+14364	0.184
+14365	0.154252
+14366	0.184
+14367	0.184
+14368	0.154252
+14369	0.184
+14370	0.154252
+14371	0.184
+14372	0.184
+14373	-1.21416
+14374	0.154252
+14375	0.184
+14376	0.154252
+14377	0.184
+14378	-1.18441
+14379	0.154252
+14380	0.184
+14381	0.184
+14382	0.154252
+14383	0.154252
+14384	-1.45214
+14385	0.154252
+14386	0.154252
+14387	0.154252
+14388	0.154252
+14389	0.154252
+14390	0.154252
+14391	0.154252
+14392	0.184
+14393	0.0947559
+14394	0.0947559
+14395	0.0947559
+14396	0.0947559
+14397	0.0947559
+14398	0.0947559
+14399	0.0947559
+14400	0.0947559
+14401	0.0947559
+14402	0.0947559
+14403	0.0947559
+14404	0.0947559
+14405	0.0947559
+14406	0.0947559
+14407	0.0947559
+14408	0.0947559
+14409	0.0947559
+14410	0.0947559
+14411	0.0947559
+14412	0.0947559
+14413	0.0947559
+14414	0.0947559
+14415	0.0947559
+14416	0.0947559
+14417	0.0947559
+14418	0.0947559
+14419	0.0947559
+14420	0.0947559
+14421	0.0947559
+14422	0.0947559
+14423	0.0947559
+14424	0.0947559
+14425	0.0947559
+14426	0.0947559
+14427	0.0947559
+14428	-1.77937
+14429	0.0947559
+14430	0.0947559
+14431	0.0947559
+14432	0.0947559
+14433	0.0947559
+14434	0.0947559
+14435	0.0947559
+14436	-1.98761
+14437	0.0947559
+14438	0.0947559
+14439	0.0947559
+14440	0.0947559
+14441	0.0947559
+14442	0.0947559
+14443	0.0947559
+14444	0.0947559
+14445	0.0947559
+14446	0.0947559
+14447	0.0947559
+14448	0.0947559
+14449	0.0947559
+14450	0.0947559
+14451	0.0947559
+14452	0.0947559
+14453	0.0947559
+14454	0.0947559
+14455	0.0947559
+14456	0.0947559
+14457	0.0947559
+14458	0.0947559
+14459	0.0947559
+14460	0.0947559
+14461	0.0947559
+14462	0.0947559
+14463	0.0947559
+14464	0.0947559
+14465	-2.0471
+14466	0.0947559
+14467	0.0947559
+14468	0.0947559
+14469	-1.95786
+14470	0.0947559
+14471	0.0947559
+14472	0.0947559
+14473	0.0947559
+14474	0.0947559
+14475	0.0947559
+14476	0.0947559
+14477	0.0947559
+14478	0.0947559
+14479	-1.83887
+14480	0.0947559
+14481	0.0947559
+14482	0.0947559
+14483	0.0947559
+14484	0.0947559
+14485	0.0947559
+14486	-1.71987
+14487	0.0947559
+14488	0.0947559
+14489	0.0947559
+14490	0.0947559
+14491	0.0947559
+14492	0.0947559
+14493	0.0947559
+14494	0.0947559
+14495	0.0947559
+14496	0.0947559
+14497	0.0947559
+14498	0.0947559
+14499	0.0947559
+14500	0.0947559
+14501	0.0947559
+14502	0.0947559
+14503	0.0947559
+14504	0.0947559
+14505	0.0947559
+14506	0.0947559
+14507	0.0947559
+14508	0.0947559
+14509	0.0947559
+14510	0.0947559
+14511	0.0947559
+14512	0.0947559
+14513	0.0947559
+14514	0.0947559
+14515	0.0947559
+14516	0.0947559
+14517	0.0947559
+14518	0.0947559
+14519	0.0947559
+14520	0.0947559
+14521	0.0947559
+14522	0.0947559
+14523	0.0947559
+14524	0.0947559
+14525	0.0947559
+14526	0.0947559
+14527	0.0947559
+14528	0.0947559
+14529	0.0947559
+14530	0.0947559
+14531	0.184
+14532	0.154252
+14533	0.184
+14534	0.154252
+14535	0.184
+14536	0.184
+14537	0.184
+14538	0.184
+14539	0.154252
+14540	0.184
+14541	0.154252
+14542	-1.39265
+14543	0.184
+14544	0.184
+14545	0.184
+14546	0.154252
+14547	0.184
+14548	0.184
+14549	0.184
+14550	0.154252
+14551	0.154252
+14552	0.184
+14553	0.184
+14554	0.184
+14555	0.184
+14556	0.154252
+14557	0.184
+14558	0.184
+14559	0.154252
+14560	0.154252
+14561	0.184
+14562	-1.45214
+14563	0.154252
+14564	0.184
+14565	-1.27365
+14566	0.154252
+14567	0.184
+14568	0.184
+14569	0.154252
+14570	0.184
+14571	0.154252
+14572	0.184
+14573	0.184
+14574	-1.39265
+14575	0.184
+14576	0.154252
+14577	-1.21416
+14578	0.154252
+14579	0.184
+14580	0.154252
+14581	0.184
+14582	0.184
+14583	0.154252
+14584	0.184
+14585	0.184
+14586	0.154252
+14587	0.154252
+14588	0.184
+14589	0.184
+14590	-1.51164
+14591	0.154252
+14592	0.184
+14593	0.154252
+14594	0.184
+14595	0.184
+14596	0.184
+14597	-1.27365
+14598	0.184
+14599	0.154252
+14600	0.184
+14601	0.184
+14602	0.184
+14603	0.154252
+14604	-1.18441
+14605	0.184
+14606	0.184
+14607	0.154252
+14608	0.154252
+14609	0.184
+14610	-1.18441
+14611	0.154252
+14612	0.184
+14613	0.184
+14614	0.154252
+14615	0.184
+14616	0.154252
+14617	-3.41551
+14618	0.154252
+14619	0.184
+14620	0.184
+14621	-1.21416
+14622	0.184
+14623	-1.27365
+14624	0.154252
+14625	0.154252
+14626	0.184
+14627	0.154252
+14628	0.184
+14629	0.184
+14630	0.154252
+14631	0.184
+14632	0.184
+14633	0.184
+14634	0.154252
+14635	0.184
+14636	0.154252
+14637	-1.12491
+14638	0.154252
+14639	0.184
+14640	0.184
+14641	-1.42239
+14642	0.154252
+14643	0.184
+14644	0.154252
+14645	0.184
+14646	0.154252
+14647	0.184
+14648	0.154252
+14649	0.184
+14650	0.184
+14651	0.154252
+14652	0.154252
+14653	0.184
+14654	-1.12491
+14655	0.184
+14656	0.184
+14657	0.184
+14658	0.184
+14659	0.154252
+14660	0.154252
+14661	0.184
+14662	0.154252
+14663	0.184
+14664	0.154252
+14665	-1.12491
+14666	0.184
+14667	0.184
+14668	0.154252
+14669	0.184
+14670	0.154252
+14671	0.184
+14672	0.184
+14673	0.184
+14674	0.184
+14675	0.184
+14676	0.184
+14677	0.184
+14678	0.154252
+14679	0.154252
+14680	0.184
+14681	0.184
+14682	0.154252
+14683	0.184
+14684	0.154252
+14685	0.184
+14686	0.154252
+14687	0.154252
+14688	0.184
+14689	0.184
+14690	0.154252
+14691	0.184
+14692	0.184
+14693	0.184
+14694	0.184
+14695	0.184
+14696	0.184
+14697	0.154252
+14698	0.154252
+14699	-1.12491
+14700	0.184
+14701	0.154252
+14702	0.154252
+14703	0.154252
+14704	0.184
+14705	0.184
+14706	0.184
+14707	0.154252
+14708	0.184
+14709	0.154252
+14710	0.184
+14711	0.184
+14712	0.154252
+14713	0.184
+14714	0.184
+14715	0.154252
+14716	0.184
+14717	-1.15466
+14718	0.124504
+14719	0.154252
+14720	0.154252
+14721	0.154252
+14722	0.184
+14723	0.184
+14724	0.154252
+14725	0.184
+14726	0.154252
+14727	0.184
+14728	0.184
+14729	0.184
+14730	0.154252
+14731	0.184
+14732	0.154252
+14733	0.184
+14734	0.184
+14735	0.184
+14736	0.154252
+14737	0.184
+14738	0.184
+14739	0.154252
+14740	0.184
+14741	0.184
+14742	0.184
+14743	0.184
+14744	0.154252
+14745	0.184
+14746	0.184
+14747	-1.12491
+14748	0.184
+14749	0.184
+14750	0.184
+14751	0.154252
+14752	0.184
+14753	0.154252
+14754	0.184
+14755	0.184
+14756	0.154252
+14757	0.184
+14758	0.184
+14759	0.184
+14760	0.154252
+14761	0.154252
+14762	0.184
+14763	0.184
+14764	0.154252
+14765	0.184
+14766	0.154252
+14767	0.184
+14768	0.154252
+14769	0.184
+14770	0.154252
+14771	0.184
+14772	0.154252
+14773	0.184
+14774	0.184
+14775	0.184
+14776	0.184
+14777	0.184
+14778	0.184
+14779	0.184
+14780	0.154252
+14781	0.154252
+14782	0.154252
+14783	0.184
+14784	0.184
+14785	0.184
+14786	0.154252
+14787	0.184
+14788	0.184
+14789	0.154252
+14790	0.184
+14791	0.184
+14792	-1.21416
+14793	0.184
+14794	0.184
+14795	0.184
+14796	0.184
+14797	0.184
+14798	0.184
+14799	0.154252
+14800	0.184
+14801	0.154252
+14802	0.184
+14803	0.184
+14804	0.154252
+14805	0.184
+14806	0.184
+14807	0.184
+14808	0.184
+14809	0.184
+14810	-1.21416
+14811	0.184
+14812	0.184
+14813	0.154252
+14814	0.184
+14815	0.184
+14816	0.154252
+14817	0.154252
+14818	0.154252
+14819	0.184
+14820	0.184
+14821	0.184
+14822	0.154252
+14823	0.184
+14824	0.154252
+14825	0.184
+14826	0.154252
+14827	0.154252
+14828	0.184
+14829	0.184
+14830	0.184
+14831	0.154252
+14832	0.184
+14833	0.184
+14834	0.154252
+14835	0.184
+14836	0.184
+14837	0.184
+14838	0.154252
+14839	0.154252
+14840	0.154252
+14841	0.154252
+14842	0.184
+14843	0.184
+14844	0.184
+14845	0.154252
+14846	0.184
+14847	0.154252
+14848	0.184
+14849	0.154252
+14850	0.184
+14851	0.154252
+14852	0.184
+14853	0.184
+14854	0.184
+14855	0.154252
+14856	0.184
+14857	0.184
+14858	0.154252
+14859	0.154252
+14860	0.184
+14861	0.184
+14862	0.154252
+14863	0.184
+14864	0.184
+14865	0.184
+14866	0.154252
+14867	0.154252
+14868	0.154252
+14869	0.184
+14870	0.184
+14871	0.184
+14872	0.154252
+14873	0.184
+14874	-1.12491
+14875	-1.39265
+14876	0.154252
+14877	0.184
+14878	0.184
+14879	0.184
+14880	0.184
+14881	0.184
+14882	0.154252
+14883	-1.3034
+14884	0.184
+14885	0.184
+14886	0.184
+14887	0.184
+14888	0.184
+14889	-2.76106
+14890	0.184
+14891	0.154252
+14892	0.184
+14893	0.154252
+14894	0.184
+14895	0.154252
+14896	0.154252
+14897	0.154252
+14898	0.154252
+14899	0.154252
+14900	0.154252
+14901	0.154252
+14902	0.184
+14903	0.154252
+14904	0.184
+14905	0.184
+14906	0.154252
+14907	0.154252
+14908	0.184
+14909	0.154252
+14910	0.154252
+14911	0.154252
+14912	0.154252
+14913	0.154252
+14914	0.184
+14915	0.184
+14916	0.184
+14917	0.154252
+14918	0.184
+14919	0.184
+14920	0.154252
+14921	-1.42239
+14922	0.154252
+14923	-1.12491
+14924	0.154252
+14925	0.154252
+14926	0.154252
+14927	0.154252
+14928	0.154252
+14929	0.184
+14930	0.154252
+14931	0.154252
+14932	-3.594
+14933	0.184
+14934	-1.45214
+14935	0.184
+14936	0.184
+14937	-1.18441
+14938	0.184
+14939	0.184
+14940	0.184
+14941	0.184
+14942	0.184
+14943	0.154252
+14944	0.184
+14945	0.184
+14946	0.184
+14947	-1.12491
+14948	0.184
+14949	0.184
+14950	0.184
+14951	0.184
+14952	0.154252
+14953	0.184
+14954	-1.21416
+14955	0.184
+14956	0.184
+14957	-1.21416
+14958	0.184
+14959	0.184
+14960	0.154252
+14961	0.184
+14962	0.184
+14963	-1.3034
+14964	0.154252
+14965	0.184
+14966	0.184
+14967	0.154252
+14968	0.154252
+14969	0.184
+14970	0.184
+14971	-1.21416
+14972	0.154252
+14973	0.154252
+14974	0.184
+14975	0.184
+14976	0.184
+14977	0.184
+14978	0.184
+14979	0.154252
+14980	0.184
+14981	0.154252
+14982	0.154252
+14983	0.184
+14984	0.154252
+14985	0.184
+14986	0.184
+14987	0.154252
+14988	0.184
+14989	0.184
+14990	0.154252
+14991	0.154252
+14992	0.184
+14993	0.154252
+14994	0.154252
+14995	0.184
+14996	0.154252
+14997	0.154252
+14998	0.184
+14999	0.154252
+15000	0.184
+15001	0.154252
+15002	0.154252
+15003	0.184
+15004	0.184
+15005	0.184
+15006	0.154252
+15007	0.184
+15008	0.154252
+15009	0.154252
+15010	0.184
+15011	0.154252
+15012	-1.21416
+15013	0.184
+15014	0.131134
+15015	-1.13765
+15016	0.184
+15017	0.184
+15018	0.184
+15019	0.131134
+15020	0.184
+15021	0.184
+15022	0.131134
+15023	0.131134
+15024	0.184
+15025	0.184
+15026	0.184
+15027	0.131134
+15028	0.184
+15029	0.184
+15030	0.131134
+15031	0.184
+15032	0.184
+15033	0.184
+15034	0.131134
+15035	0.184
+15036	0.131134
+15037	0.184
+15038	0.131134
+15039	0.184
+15040	0.131134
+15041	0.184
+15042	0.184
+15043	0.131134
+15044	0.131134
+15045	0.184
+15046	0.184
+15047	-1.21695
+15048	0.184
+15049	0.131134
+15050	0.131134
+15051	0.131134
+15052	0.184
+15053	0.184
+15054	0.184
+15055	0.131134
+15056	-1.11122
+15057	0.131134
+15058	0.184
+15059	0.131134
+15060	0.184
+15061	0.131134
+15062	0.184
+15063	0.184
+15064	0.184
+15065	0.184
+15066	0.131134
+15067	0.184
+15068	0.131134
+15069	0.131134
+15070	0.184
+15071	0.131134
+15072	0.184
+15073	0.131134
+15074	0.131134
+15075	0.184
+15076	0.131134
+15077	0.184
+15078	0.131134
+15079	0.184
+15080	0.131134
+15081	0.184
+15082	0.131134
+15083	-1.45485
+15084	0.184
+15085	-2.82937
+15086	0.184
+15087	0.131134
+15088	0.184
+15089	0.184
+15090	-1.42842
+15091	0.184
+15092	0.131134
+15093	0.184
+15094	-1.16409
+15095	0.184
+15096	0.131134
+15097	0.184
+15098	0.184
+15099	0.184
+15100	0.131134
+15101	0.184
+15102	0.131134
+15103	0.184
+15104	0.184
+15105	0.184
+15106	0.184
+15107	0.131134
+15108	-1.87778
+15109	0.104701
+15110	0.184
+15111	0.184
+15112	0.184
+15113	-1.21695
+15114	0.131134
+15115	0.184
+15116	0.131134
+15117	0.184
+15118	0.131134
+15119	0.184
+15120	0.131134
+15121	0.184
+15122	0.184
+15123	0.184
+15124	0.184
+15125	0.131134
+15126	0.184
+15127	0.184
+15128	0.184
+15129	0.184
+15130	0.131134
+15131	0.184
+15132	0.184
+15133	0.131134
+15134	0.131134
+15135	0.184
+15136	0.184
+15137	0.184
+15138	0.184
+15139	0.131134
+15140	0.184
+15141	-1.21695
+15142	0.184
+15143	0.131134
+15144	0.184
+15145	-1.21695
+15146	0.131134
+15147	0.131134
+15148	0.184
+15149	0.184
+15150	0.184
+15151	0.131134
+15152	0.184
+15153	0.131134
+15154	0.131134
+15155	0.131134
+15156	0.184
+15157	0.184
+15158	0.131134
+15159	-1.11122
+15160	-1.21695
+15161	0.184
+15162	0.131134
+15163	0.184
+15164	0.184
+15165	0.184
+15166	0.131134
+15167	0.184
+15168	0.131134
+15169	0.184
+15170	0.131134
+15171	0.184
+15172	-1.29625
+15173	0.131134
+15174	0.131134
+15175	0.184
+15176	0.184
+15177	0.184
+15178	-1.40198
+15179	0.184
+15180	0.131134
+15181	0.184
+15182	0.184
+15183	0.184
+15184	0.131134
+15185	0.184
+15186	0.184
+15187	0.131134
+15188	0.184
+15189	-1.21695
+15190	-1.11122
+15191	0.184
+15192	0.184
+15193	0.184
+15194	-1.42842
+15195	0.184
+15196	0.131134
+15197	0.184
+15198	0.131134
+15199	0.131134
+15200	0.184
+15201	0.131134
+15202	0.184
+15203	0.131134
+15204	-3.173
+15205	0.131134
+15206	0.184
+15207	-1.11122
+15208	0.184
+15209	0.184
+15210	-1.50772
+15211	0.131134
+15212	0.184
+15213	0.131134
+15214	-1.21695
+15215	0.131134
+15216	0.184
+15217	0.131134
+15218	0.184
+15219	-1.11122
+15220	0.131134
+15221	0.184
+15222	0.184
+15223	-1.29625
+15224	-1.45485
+15225	-1.11122
+15226	0.184
+15227	0.131134
+15228	0.184
+15229	0.184
+15230	0.184
+15231	0.131134
+15232	0.184
+15233	0.184
+15234	0.184
+15235	0.131134
+15236	0.184
+15237	0.184
+15238	0.131134
+15239	-1.16409
+15240	-1.11122
+15241	0.184
+15242	0.184
+15243	0.184
+15244	-1.45485
+15245	0.184
+15246	0.131134
+15247	0.184
+15248	0.184
+15249	-1.11122
+15250	0.184
+15251	0.184
+15252	0.131134
+15253	0.184
+15254	0.184
+15255	0.184
+15256	0.131134
+15257	0.184
+15258	0.131134
+15259	0.184
+15260	0.184
+15261	0.131134
+15262	0.184
+15263	0.184
+15264	0.131134
+15265	0.184
+15266	-1.11122
+15267	-1.21695
+15268	-1.29625
+15269	-1.21695
+15270	0.184
+15271	-1.56058
+15272	0.0782677
+15273	0.104701
+15274	-1.40198
+15275	0.131134
+15276	0.131134
+15277	0.184
+15278	0.184
+15279	0.184
+15280	0.184
+15281	0.131134
+15282	0.131134
+15283	0.131134
+15284	0.184
+15285	0.131134
+15286	0.184
+15287	0.184
+15288	0.184
+15289	0.184
+15290	0.184
+15291	0.131134
+15292	0.184
+15293	0.131134
+15294	0.184
+15295	0.131134
+15296	0.184
+15297	0.184
+15298	0.131134
+15299	0.184
+15300	0.131134
+15301	0.184
+15302	0.184
+15303	0.184
+15304	0.131134
+15305	0.184
+15306	0.184
+15307	0.131134
+15308	0.131134
+15309	0.184
+15310	0.184
+15311	0.184
+15312	0.131134
+15313	0.184
+15314	-1.29625
+15315	0.184
+15316	0.184
+15317	0.131134
+15318	0.184
+15319	0.131134
+15320	0.184
+15321	0.131134
+15322	0.184
+15323	0.131134
+15324	0.184
+15325	0.184
+15326	0.131134
+15327	0.131134
+15328	0.184
+15329	0.184
+15330	0.184
+15331	0.131134
+15332	0.131134
+15333	0.131134
+15334	0.131134
+15335	0.184
+15336	0.184
+15337	0.131134
+15338	0.184
+15339	0.184
+15340	0.184
+15341	0.184
+15342	0.131134
+15343	0.184
+15344	-1.13765
+15345	0.184
+15346	0.131134
+15347	0.131134
+15348	0.184
+15349	0.131134
+15350	0.131134
+15351	0.184
+15352	0.184
+15353	0.131134
+15354	0.184
+15355	0.131134
+15356	0.131134
+15357	0.131134
+15358	0.131134
+15359	0.184
+15360	0.184
+15361	0.131134
+15362	-1.21695
+15363	0.131134
+15364	0.184
+15365	0.131134
+15366	0.184
+15367	0.184
+15368	0.184
+15369	0.184
+15370	0.131134
+15371	0.184
+15372	0.184
+15373	0.184
+15374	0.184
+15375	-1.21695
+15376	-1.16409
+15377	0.131134
+15378	0.184
+15379	0.184
+15380	-1.11122
+15381	-1.16409
+15382	0.184
+15383	-1.21695
+15384	0.184
+15385	-1.11122
+15386	0.131134
+15387	-1.42842
+15388	-1.11122
+15389	-1.21695
+15390	-1.11122
+15391	0.184
+15392	0.131134
+15393	0.184
+15394	0.184
+15395	0.184
+15396	-1.21695
+15397	0.131134
+15398	0.184
+15399	0.184
+15400	0.184
+15401	0.131134
+15402	0.131134
+15403	0.184
+15404	0.131134
+15405	0.184
+15406	0.131134
+15407	0.184
+15408	0.184
+15409	0.131134
+15410	0.184
+15411	0.131134
+15412	0.184
+15413	0.131134
+15414	0.184
+15415	0.131134
+15416	0.184
+15417	-1.29625
+15418	0.184
+15419	0.131134
+15420	0.131134
+15421	0.184
+15422	-1.21695
+15423	0.184
+15424	0.131134
+15425	0.184
+15426	0.184
+15427	0.131134
+15428	0.184
+15429	0.184
+15430	0.184
+15431	0.131134
+15432	0.131134
+15433	0.184
+15434	0.131134
+15435	0.131134
+15436	0.184
+15437	0.131134
+15438	0.184
+15439	0.131134
+15440	0.131134
+15441	0.184
+15442	0.184
+15443	0.184
+15444	0.131134
+15445	0.184
+15446	-1.45485
+15447	0.131134
+15448	0.184
+15449	0.131134
+15450	0.184
+15451	0.184
+15452	0.184
+15453	0.184
+15454	0.131134
+15455	0.184
+15456	0.131134
+15457	0.184
+15458	0.184
+15459	0.131134
+15460	0.184
+15461	0.184
+15462	0.131134
+15463	0.184
+15464	0.131134
+15465	0.184
+15466	0.131134
+15467	0.184
+15468	0.131134
+15469	0.131134
+15470	0.131134
+15471	0.131134
+15472	0.131134
+15473	0.131134
+15474	0.131134
+15475	0.131134
+15476	0.131134
+15477	0.184
+15478	0.131134
+15479	0.184
+15480	0.131134
+15481	0.184
+15482	0.184
+15483	0.131134
+15484	0.184
+15485	0.184
+15486	0.184
+15487	0.131134
+15488	0.184
+15489	0.184
+15490	0.131134
+15491	0.184
+15492	-1.45485
+15493	0.184
+15494	0.184
+15495	0.184
+15496	0.131134
+15497	0.184
+15498	0.131134
+15499	0.184
+15500	0.184
+15501	0.131134
+15502	0.131134
+15503	0.131134
+15504	0.184
+15505	0.184
+15506	0.184
+15507	0.131134
+15508	-1.21695
+15509	0.184
+15510	0.184
+15511	0.131134
+15512	0.184
+15513	-1.21695
+15514	-1.11122
+15515	0.184
+15516	0.131134
+15517	0.184
+15518	0.0782677
+15519	0.0782677
+15520	-1.11122
+15521	0.184
+15522	0.184
+15523	0.131134
+15524	0.184
+15525	0.131134
+15526	0.184
+15527	-1.21695
+15528	0.131134
+15529	0.131134
+15530	0.184
+15531	0.131134
+15532	0.131134
+15533	0.184
+15534	0.131134
+15535	0.131134
+15536	0.131134
+15537	0.184
+15538	0.131134
+15539	0.184
+15540	0.184
+15541	0.131134
+15542	0.184
+15543	0.131134
+15544	0.184
+15545	0.131134
+15546	0.184
+15547	-1.40198
+15548	0.131134
+15549	0.131134
+15550	0.184
+15551	0.131134
+15552	0.184
+15553	0.184
+15554	0.131134
+15555	0.184
+15556	0.184
+15557	0.184
+15558	0.131134
+15559	0.184
+15560	-1.45485
+15561	0.184
+15562	0.184
+15563	0.131134
+15564	0.131134
+15565	-1.40198
+15566	-1.29625
+15567	0.131134
+15568	0.184
+15569	0.131134
+15570	0.184
+15571	0.184
+15572	0.131134
+15573	-1.21695
+15574	0.131134
+15575	0.184
+15576	0.184
+15577	0.131134
+15578	0.184
+15579	0.184
+15580	0.131134
+15581	0.184
+15582	0.131134
+15583	0.131134
+15584	0.131134
+15585	0.184
+15586	0.184
+15587	0.184
+15588	0.131134
+15589	0.184
+15590	0.184
+15591	0.184
+15592	0.131134
+15593	0.131134
+15594	0.131134
+15595	0.184
+15596	0.184
+15597	0.131134
+15598	0.184
+15599	0.184
+15600	0.131134
+15601	0.131134
+15602	0.184
+15603	0.184
+15604	0.131134
+15605	0.184
+15606	0.184
+15607	0.184
+15608	0.131134
+15609	0.131134
+15610	-1.40198
+15611	-1.21695
+15612	0.184
+15613	0.184
+15614	0.184
+15615	-1.45485
+15616	0.184
+15617	0.184
+15618	0.184
+15619	-1.21695
+15620	0.184
+15621	0.184
+15622	-1.58702
+15623	0.184
+15624	0.184
+15625	0.184
+15626	0.184
+15627	0.131134
+15628	0.184
+15629	0.131134
+15630	0.184
+15631	0.184
+15632	0.131134
+15633	0.184
+15634	0.184
+15635	0.131134
+15636	0.184
+15637	0.131134
+15638	0.184
+15639	-1.29625
+15640	0.131134
+15641	0.184
+15642	0.184
+15643	0.184
+15644	-1.50772
+15645	0.184
+15646	-1.29625
+15647	0.184
+15648	0.184
+15649	0.131134
+15650	0.184
+15651	0.184
+15652	0.184
+15653	-1.13765
+15654	0.131134
+15655	0.131134
+15656	0.184
+15657	0.184
+15658	0.131134
+15659	0.184
+15660	0.184
+15661	-1.45485
+15662	0.131134
+15663	0.184
+15664	0.131134
+15665	0.184
+15666	0.184
+15667	0.184
+15668	0.184
+15669	0.131134
+15670	0.131134
+15671	0.184
+15672	0.184
+15673	-1.16409
+15674	0.184
+15675	0.131134
+15676	0.131134
+15677	0.184
+15678	0.184
+15679	0.131134
+15680	0.184
+15681	0.184
+15682	0.184
+15683	0.184
+15684	0.184
+15685	-1.11122
+15686	-1.40198
+15687	0.184
+15688	0.184
+15689	0.131134
+15690	0.184
+15691	-1.82491
+15692	0.104701
+15693	0.0782677
+15694	-1.56058
+15695	0.104701
+15696	0.0782677
+15697	0.184
+15698	0.184
+15699	0.131134
+15700	0.184
+15701	0.184
+15702	0.184
+15703	0.184
+15704	0.184
+15705	0.131134
+15706	0.184
+15707	0.184
+15708	0.184
+15709	0.184
+15710	0.131134
+15711	0.184
+15712	-1.21695
+15713	0.131134
+15714	0.131134
+15715	-1.11122
+15716	0.184
+15717	0.131134
+15718	-1.29625
+15719	0.184
+15720	0.184
+15721	-1.45485
+15722	0.184
+15723	0.131134
+15724	0.184
+15725	0.184
+15726	0.131134
+15727	0.184
+15728	0.131134
+15729	0.184
+15730	0.131134
+15731	-1.11122
+15732	0.184
+15733	0.184
+15734	0.184
+15735	0.131134
+15736	0.184
+15737	0.184
+15738	0.131134
+15739	0.184
+15740	0.184
+15741	-1.11122
+15742	-1.16409
+15743	0.131134
+15744	0.184
+15745	0.184
+15746	0.131134
+15747	0.184
+15748	0.184
+15749	0.184
+15750	-1.29625
+15751	0.131134
+15752	0.131134
+15753	0.184
+15754	0.131134
+15755	0.131134
+15756	0.184
+15757	0.184
+15758	0.184
+15759	0.184
+15760	0.131134
+15761	0.131134
+15762	0.184
+15763	-1.11122
+15764	0.184
+15765	0.184
+15766	0.184
+15767	0.131134
+15768	0.184
+15769	0.184
+15770	0.184
+15771	0.131134
+15772	0.184
+15773	-1.16409
+15774	-1.11122
+15775	0.184
+15776	0.131134
+15777	-1.16409
+15778	0.184
+15779	0.184
+15780	0.131134
+15781	0.184
+15782	0.184
+15783	0.131134
+15784	0.184
+15785	0.184
+15786	0.184
+15787	0.184
+15788	0.184
+15789	0.184
+15790	0.184
+15791	0.184
+15792	0.131134
+15793	0.184
+15794	0.131134
+15795	0.184
+15796	0.184
+15797	0.131134
+15798	0.131134
+15799	0.184
+15800	0.184
+15801	0.131134
+15802	0.184
+15803	0.184
+15804	0.131134
+15805	0.184
+15806	0.184
+15807	0.131134
+15808	0.184
+15809	0.184
+15810	0.131134
+15811	0.131134
+15812	0.184
+15813	0.131134
+15814	0.184
+15815	0.184
+15816	0.131134
+15817	-1.45485
+15818	0.184
+15819	0.131134
+15820	-1.45485
+15821	0.184
+15822	0.131134
+15823	0.131134
+15824	0.184
+15825	0.131134
+15826	0.184
+15827	0.184
+15828	0.131134
+15829	0.184
+15830	0.184
+15831	0.131134
+15832	0.131134
+15833	0.131134
+15834	0.184
+15835	0.184
+15836	0.184
+15837	0.131134
+15838	0.184
+15839	0.184
+15840	0.131134
+15841	0.131134
+15842	0.184
+15843	0.131134
+15844	-1.16409
+15845	0.184
+15846	0.184
+15847	0.131134
+15848	0.184
+15849	0.184
+15850	0.184
+15851	0.184
+15852	0.131134
+15853	0.184
+15854	-1.11122
+15855	0.131134
+15856	0.131134
+15857	0.184
+15858	0.184
+15859	0.184
+15860	0.184
+15861	0.131134
+15862	0.131134
+15863	0.184
+15864	0.184
+15865	0.184
+15866	0.184
+15867	0.131134
+15868	0.131134
+15869	0.184
+15870	0.184
+15871	0.184
+15872	0.184
+15873	0.184
+15874	0.184
+15875	-1.21695
+15876	0.184
+15877	0.184
+15878	0.131134
+15879	0.131134
+15880	0.184
+15881	0.184
+15882	0.184
+15883	0.184
+15884	0.184
+15885	0.131134
+15886	0.131134
+15887	0.184
+15888	0.184
+15889	0.131134
+15890	-1.16409
+15891	0.131134
+15892	0.184
+15893	-1.21695
+15894	0.131134
+15895	0.184
+15896	0.184
+15897	0.131134
+15898	0.184
+15899	0.131134
+15900	0.184
+15901	0.131134
+15902	0.184
+15903	0.184
+15904	0.184
+15905	0.184
+15906	-1.16409
+15907	0.184
+15908	0.184
+15909	0.184
+15910	0.131134
+15911	0.184
+15912	0.184
+15913	-1.50772
+15914	0.184
+15915	0.131134
+15916	0.184
+15917	0.184
+15918	0.184
+15919	0.184
+15920	0.131134
+15921	0.184
+15922	-1.16409
+15923	0.131134
+15924	0.184
+15925	0.184
+15926	0.131134
+15927	0.184
+15928	0.131134
+15929	0.131134
+15930	0.184
+15931	0.184
+15932	-1.11122
+15933	0.131134
+15934	0.184
+15935	0.184
+15936	0.184
+15937	0.131134
+15938	0.184
+15939	0.184
+15940	0.131134
+15941	0.184
+15942	0.184
+15943	0.184
+15944	0.131134
+15945	0.184
+15946	0.184
+15947	0.131134
+15948	0.184
+15949	0.131134
+15950	0.184
+15951	0.184
+15952	0.131134
+15953	0.184
+15954	0.184
+15955	-1.11122
+15956	0.184
+15957	0.184
+15958	0.184
+15959	0.131134
+15960	0.184
+15961	0.184
+15962	0.131134
+15963	0.184
+15964	0.184
+15965	0.184
+15966	0.184
+15967	0.131134
+15968	0.131134
+15969	0.184
+15970	-1.40198
+15971	0.184
+15972	0.184
+15973	0.184
+15974	0.184
+15975	0.131134
+15976	0.131134
+15977	0.184
+15978	0.184
+15979	0.131134
+15980	0.184
+15981	-1.11122
+15982	0.131134
+15983	0.131134
+15984	0.131134
+15985	0.184
+15986	0.184
+15987	0.184
+15988	0.131134
+15989	0.184
+15990	0.184
+15991	0.131134
+15992	0.184
+15993	0.131134
+15994	0.184
+15995	0.184
+15996	0.184
+15997	0.131134
+15998	0.184
+15999	0.184
+16000	-1.29625
+16001	0.184
+16002	0.131134
+16003	0.184
+16004	0.184
+16005	0.184
+16006	0.184
+16007	0.131134
+16008	0.131134
+16009	0.184
+16010	0.184
+16011	0.131134
+16012	0.131134
+16013	0.131134
+16014	-1.48128
+16015	0.131134
+16016	0.184
+16017	0.131134
+16018	-1.16409
+16019	0.0782677
+16020	0.184
+16021	0.184
+16022	0.131134
+16023	0.131134
+16024	0.184
+16025	0.131134
+16026	0.184
+16027	0.184
+16028	0.184
+16029	0.131134
+16030	0.184
+16031	0.184
+16032	0.131134
+16033	0.184
+16034	0.184
+16035	0.184
+16036	0.131134
+16037	0.104701
+16038	0.184
+16039	0.184
+16040	0.153685
+16041	0.153685
+16042	0.184
+16043	-1.57427
+16044	0.184
+16045	0.153685
+16046	0.184
+16047	0.184
+16048	0.153685
+16049	0.184
+16050	0.184
+16051	0.184
+16052	0.184
+16053	0.153685
+16054	0.184
+16055	0.153685
+16056	0.153685
+16057	0.153685
+16058	-1.21049
+16059	0.184
+16060	0.153685
+16061	-1.30143
+16062	-1.21049
+16063	0.153685
+16064	0.184
+16065	0.184
+16066	0.184
+16067	0.184
+16068	-1.78647
+16069	0.184
+16070	-1.51364
+16071	0.184
+16072	-1.11954
+16073	0.153685
+16074	0.184
+16075	0.184
+16076	0.184
+16077	0.184
+16078	0.153685
+16079	0.184
+16080	-1.21049
+16081	0.184
+16082	-1.11954
+16083	-1.21049
+16084	0.184
+16085	0.153685
+16086	0.184
+16087	0.184
+16088	0.153685
+16089	0.153685
+16090	0.153685
+16091	-1.27112
+16092	0.184
+16093	0.153685
+16094	0.184
+16095	0.153685
+16096	0.184
+16097	0.153685
+16098	0.184
+16099	0.153685
+16100	0.184
+16101	0.153685
+16102	0.0930551
+16103	-0.0282047
+16104	-0.0282047
+16105	-0.0282047
+16106	0.0930551
+16107	0.0930551
+16108	0.0930551
+16109	0.0930551
+16110	0.0930551
+16111	0.0930551
+16112	0.0930551
+16113	0.0930551
+16114	0.0930551
+16115	0.0930551
+16116	0.0930551
+16117	0.0930551
+16118	0.0930551
+16119	0.0930551
+16120	0.0930551
+16121	0.0930551
+16122	0.0930551
+16123	0.0930551
+16124	0.0930551
+16125	-2.11994
+16126	0.0930551
+16127	0.0930551
+16128	0.0930551
+16129	0.0930551
+16130	0.0930551
+16131	0.0930551
+16132	0.0930551
+16133	0.184
+16134	0.184
+16135	0.153685
+16136	0.184
+16137	0.153685
+16138	0.184
+16139	-1.14986
+16140	-1.11954
+16141	0.184
+16142	-1.45301
+16143	0.184
+16144	0.184
+16145	0.184
+16146	0.153685
+16147	0.153685
+16148	0.184
+16149	0.184
+16150	0.153685
+16151	0.184
+16152	0.153685
+16153	-1.21049
+16154	0.153685
+16155	0.184
+16156	0.0930551
+16157	0.153685
+16158	0.184
+16159	0.153685
+16160	-1.39238
+16161	0.153685
+16162	0.184
+16163	0.153685
+16164	0.184
+16165	0.184
+16166	0.184
+16167	0.153685
+16168	0.184
+16169	0.184
+16170	0.153685
+16171	-1.39238
+16172	0.184
+16173	0.184
+16174	0.153685
+16175	0.184
+16176	0.153685
+16177	0.184
+16178	-1.21049
+16179	0.153685
+16180	0.184
+16181	0.184
+16182	0.184
+16183	0.184
+16184	0.184
+16185	0.184
+16186	0.153685
+16187	0.184
+16188	0.184
+16189	0.184
+16190	0.153685
+16191	0.184
+16192	0.184
+16193	0.153685
+16194	0.184
+16195	0.153685
+16196	0.184
+16197	0.184
+16198	0.153685
+16199	0.184
+16200	0.0930551
+16201	0.0930551
+16202	0.0930551
+16203	0.0930551
+16204	0.0930551
+16205	0.0930551
+16206	0.0930551
+16207	0.0930551
+16208	0.0930551
+16209	0.0930551
+16210	0.0930551
+16211	0.0930551
+16212	0.0930551
+16213	0.0930551
+16214	0.0930551
+16215	0.0930551
+16216	0.0930551
+16217	0.0930551
+16218	0.0930551
+16219	0.0930551
+16220	0.0930551
+16221	0.0930551
+16222	0.0930551
+16223	0.184
+16224	0.153685
+16225	0.184
+16226	0.153685
+16227	0.184
+16228	0.153685
+16229	0.184
+16230	0.153685
+16231	0.184
+16232	0.153685
+16233	0.184
+16234	-1.21049
+16235	-3.666
+16236	0.184
+16237	0.184
+16238	0.153685
+16239	0.184
+16240	0.153685
+16241	0.184
+16242	0.153685
+16243	-1.48332
+16244	0.184
+16245	0.153685
+16246	0.184
+16247	0.184
+16248	0.184
+16249	0.153685
+16250	0.184
+16251	0.184
+16252	0.153685
+16253	0.184
+16254	0.153685
+16255	0.184
+16256	0.184
+16257	0.184
+16258	0.184
+16259	-1.21049
+16260	0.153685
+16261	0.153685
+16262	0.153685
+16263	0.184
+16264	0.153685
+16265	0.184
+16266	0.184
+16267	0.184
+16268	0.153685
+16269	0.184
+16270	0.153685
+16271	0.153685
+16272	0.184
+16273	0.153685
+16274	0.184
+16275	0.184
+16276	0.153685
+16277	0.153685
+16278	0.184
+16279	0.184
+16280	0.153685
+16281	0.153685
+16282	0.184
+16283	0.184
+16284	0.184
+16285	-1.51364
+16286	0.153685
+16287	0.153685
+16288	-1.14986
+16289	0.153685
+16290	0.184
+16291	0.153685
+16292	0.184
+16293	0.184
+16294	0.184
+16295	0.153685
+16296	0.184
+16297	0.153685
+16298	-1.48332
+16299	0.153685
+16300	-1.27112
+16301	0.153685
+16302	-1.45301
+16303	0.184
+16304	0.153685
+16305	0.184
+16306	0.153685
+16307	-1.51364
+16308	0.153685
+16309	0.153685
+16310	0.184
+16311	0.184
+16312	0.153685
+16313	0.184
+16314	0.153685
+16315	-1.42269
+16316	0.153685
+16317	-1.45301
+16318	0.184
+16319	0.153685
+16320	0.153685
+16321	0.153685
+16322	0.153685
+16323	0.153685
+16324	0.153685
+16325	0.184
+16326	0.153685
+16327	0.184
+16328	0.153685
+16329	0.153685
+16330	0.184
+16331	0.184
+16332	0.153685
+16333	0.184
+16334	0.153685
+16335	-1.39238
+16336	0.184
+16337	0.153685
+16338	0.153685
+16339	0.153685
+16340	0.184
+16341	0.153685
+16342	0.153685
+16343	0.153685
+16344	0.153685
+16345	0.153685
+16346	0.153685
+16347	0.184
+16348	0.153685
+16349	0.184
+16350	0.184
+16351	0.184
+16352	0.184
+16353	0.153685
+16354	0.153685
+16355	0.184
+16356	0.153685
+16357	0.153685
+16358	-1.39238
+16359	0.184
+16360	0.184
+16361	-1.6349
+16362	0.153685
+16363	0.153685
+16364	0.184
+16365	0.184
+16366	0.153685
+16367	0.153685
+16368	0.153685
+16369	0.153685
+16370	-1.39238
+16371	0.153685
+16372	0.153685
+16373	0.153685
+16374	0.184
+16375	0.184
+16376	0.153685
+16377	0.153685
+16378	-1.39238
+16379	-1.21049
+16380	0.184
+16381	0.184
+16382	0.184
+16383	0.153685
+16384	0.153685
+16385	0.184
+16386	0.184
+16387	0.184
+16388	0.153685
+16389	0.184
+16390	0.153685
+16391	0.184
+16392	0.184
+16393	0.184
+16394	0.153685
+16395	0.184
+16396	0.153685
+16397	0.184
+16398	0.153685
+16399	-1.6349
+16400	0.184
+16401	0.153685
+16402	0.153685
+16403	0.184
+16404	0.153685
+16405	0.184
+16406	0.184
+16407	0.184
+16408	0.153685
+16409	0.184
+16410	0.184
+16411	0.184
+16412	0.153685
+16413	-1.27112
+16414	-1.21049
+16415	0.184
+16416	0.184
+16417	-1.30143
+16418	0.184
+16419	0.153685
+16420	0.153685
+16421	0.184
+16422	0.153685
+16423	-1.39238
+16424	0.184
+16425	0.153685
+16426	0.184
+16427	0.153685
+16428	0.184
+16429	0.153685
+16430	0.153685
+16431	-1.60458
+16432	0.153685
+16433	0.184
+16434	0.184
+16435	0.153685
+16436	-1.27112
+16437	0.153685
+16438	0.184
+16439	0.184
+16440	0.153685
+16441	0.184
+16442	0.153685
+16443	0.153685
+16444	0.184
+16445	0.153685
+16446	0.184
+16447	-1.21049
+16448	0.153685
+16449	0.153685
+16450	0.184
+16451	0.153685
+16452	0.153685
+16453	0.153685
+16454	0.153685
+16455	0.184
+16456	-1.11954
+16457	0.153685
+16458	0.184
+16459	0.153685
+16460	0.153685
+16461	0.153685
+16462	0.153685
+16463	0.153685
+16464	0.153685
+16465	0.153685
+16466	0.153685
+16467	0.184
+16468	-1.21049
+16469	0.153685
+16470	0.184
+16471	0.184
+16472	0.153685
+16473	0.153685
+16474	0.184
+16475	0.153685
+16476	0.153685
+16477	0.184
+16478	0.153685
+16479	0.153685
+16480	0.184
+16481	0.153685
+16482	0.153685
+16483	0.184
+16484	0.153685
+16485	0.153685
+16486	0.153685
+16487	0.153685
+16488	0.153685
+16489	0.153685
+16490	0.184
+16491	0.153685
+16492	0.153685
+16493	0.153685
+16494	0.153685
+16495	0.184
+16496	0.184
+16497	-1.18017
+16498	0.153685
+16499	0.153685
+16500	0.184
+16501	0.153685
+16502	0.153685
+16503	0.153685
+16504	0.153685
+16505	0.184
+16506	0.153685
+16507	-1.39238
+16508	0.153685
+16509	0.153685
+16510	0.153685
+16511	0.153685
+16512	0.153685
+16513	-1.21049
+16514	0.184
+16515	0.153685
+16516	0.184
+16517	-1.21049
+16518	0.153685
+16519	0.153685
+16520	0.153685
+16521	0.153685
+16522	0.184
+16523	0.153685
+16524	0.184
+16525	0.153685
+16526	-1.11954
+16527	0.184
+16528	0.153685
+16529	0.184
+16530	0.153685
+16531	-1.45301
+16532	0.153685
+16533	0.153685
+16534	0.184
+16535	0.153685
+16536	0.153685
+16537	0.153685
+16538	0.184
+16539	0.184
+16540	0.184
+16541	-1.21049
+16542	0.184
+16543	0.153685
+16544	0.184
+16545	0.153685
+16546	0.153685
+16547	0.153685
+16548	0.153685
+16549	0.153685
+16550	-1.14986
+16551	0.184
+16552	0.153685
+16553	0.184
+16554	0.184
+16555	-1.11954
+16556	0.184
+16557	0.153685
+16558	0.184
+16559	0.153685
+16560	0.184
+16561	0.184
+16562	0.153685
+16563	0.184
+16564	-1.51364
+16565	0.184
+16566	0.153685
+16567	0.184
+16568	0.184
+16569	0.153685
+16570	0.184
+16571	-1.51364
+16572	0.184
+16573	0.184
+16574	0.153685
+16575	0.184
+16576	0.153685
+16577	0.153685
+16578	0.153685
+16579	0.153685
+16580	-1.14986
+16581	0.153685
+16582	0.184
+16583	0.184
+16584	0.153685
+16585	0.184
+16586	-1.27112
+16587	0.184
+16588	0.184
+16589	0.153685
+16590	0.184
+16591	0.153685
+16592	0.153685
+16593	0.153685
+16594	0.184
+16595	0.153685
+16596	0.184
+16597	0.184
+16598	0.153685
+16599	0.184
+16600	0.184
+16601	0.153685
+16602	0.184
+16603	0.184
+16604	0.184
+16605	0.153685
+16606	0.184
+16607	0.184
+16608	0.153685
+16609	0.184
+16610	0.153685
+16611	0.153685
+16612	0.184
+16613	0.184
+16614	0.153685
+16615	0.184
+16616	0.153685
+16617	0.184
+16618	0.184
+16619	0.184
+16620	0.0930551
+16621	0.0930551
+16622	0.0930551
+16623	0.184
+16624	0.184
+16625	0.153685
+16626	0.184
+16627	0.184
+16628	0.153685
+16629	0.184
+16630	0.184
+16631	0.153685
+16632	0.184
+16633	0.153685
+16634	-1.11954
+16635	0.184
+16636	0.153685
+16637	0.184
+16638	0.184
+16639	0.153685
+16640	0.184
+16641	0.184
+16642	0.184
+16643	0.153685
+16644	0.184
+16645	0.184
+16646	0.184
+16647	0.184
+16648	0.184
+16649	0.184
+16650	0.153685
+16651	0.153685
+16652	0.184
+16653	0.184
+16654	0.184
+16655	0.184
+16656	0.153685
+16657	0.153685
+16658	0.184
+16659	0.153685
+16660	0.184
+16661	0.184
+16662	0.184
+16663	0.184
+16664	0.184
+16665	0.184
+16666	0.184
+16667	0.184
+16668	0.184
+16669	0.184
+16670	0.153685
+16671	0.153685
+16672	0.184
+16673	0.153685
+16674	-1.27112
+16675	0.184
+16676	0.184
+16677	0.153685
+16678	0.184
+16679	0.184
+16680	0.184
+16681	0.153685
+16682	0.184
+16683	0.153685
+16684	-1.21049
+16685	0.184
+16686	0.184
+16687	0.184
+16688	0.184
+16689	0.153685
+16690	0.184
+16691	0.184
+16692	0.153685
+16693	0.184
+16694	0.153685
+16695	0.184
+16696	0.184
+16697	0.184
+16698	0.184
+16699	0.153685
+16700	0.184
+16701	0.184
+16702	0.153685
+16703	0.184
+16704	0.184
+16705	0.153685
+16706	0.184
+16707	0.153685
+16708	0.184
+16709	0.184
+16710	0.153685
+16711	0.184
+16712	0.184
+16713	0.153685
+16714	0.184
+16715	0.184
+16716	0.184
+16717	0.184
+16718	0.184
+16719	-1.51364
+16720	0.184
+16721	0.184
+16722	0.153685
+16723	0.184
+16724	0.184
+16725	0.153685
+16726	0.184
+16727	0.184
+16728	0.184
+16729	0.184
+16730	0.184
+16731	0.184
+16732	0.184
+16733	0.184
+16734	0.153685
+16735	0.184
+16736	0.184
+16737	-1.11954
+16738	0.184
+16739	0.184
+16740	0.153685
+16741	0.184
+16742	0.184
+16743	0.153685
+16744	0.184
+16745	0.153685
+16746	0.153685
+16747	0.153685
+16748	0.184
+16749	0.153685
+16750	0.153685
+16751	0.184
+16752	0.184
+16753	0.184
+16754	0.184
+16755	0.153685
+16756	0.153685
+16757	0.184
+16758	0.153685
+16759	0.153685
+16760	0.184
+16761	0.153685
+16762	0.153685
+16763	0.184
+16764	0.184
+16765	0.153685
+16766	0.184
+16767	0.153685
+16768	0.184
+16769	0.153685
+16770	0.153685
+16771	0.153685
+16772	0.184
+16773	0.153685
+16774	0.184
+16775	0.153685
+16776	0.153685
+16777	0.153685
+16778	0.184
+16779	0.153685
+16780	0.184
+16781	0.153685
+16782	0.184
+16783	0.184
+16784	0.184
+16785	0.184
+16786	0.153685
+16787	0.184
+16788	0.153685
+16789	0.184
+16790	0.153685
+16791	0.153685
+16792	0.184
+16793	0.184
+16794	-1.30143
+16795	-1.57427
+16796	0.153685
+16797	0.184
+16798	0.153685
+16799	0.153685
+16800	0.184
+16801	0.184
+16802	0.153685
+16803	-1.11954
+16804	0.153685
+16805	0.184
+16806	0.153685
+16807	0.184
+16808	0.153685
+16809	-1.14986
+16810	0.184
+16811	0.153685
+16812	0.184
+16813	0.184
+16814	0.184
+16815	0.153685
+16816	0.184
+16817	0.184
+16818	0.153685
+16819	0.184
+16820	0.184
+16821	0.184
+16822	-1.51364
+16823	-1.45301
+16824	0.184
+16825	0.184
+16826	0.184
+16827	0.184
+16828	0.153685
+16829	0.184
+16830	0.184
+16831	-1.21049
+16832	-1.21049
+16833	-1.11954
+16834	0.184
+16835	0.153685
+16836	0.153685
+16837	0.184
+16838	0.184
+16839	0.184
+16840	0.153685
+16841	0.184
+16842	0.153685
+16843	-2.81718
+16844	0.184
+16845	0.184
+16846	0.184
+16847	0.153685
+16848	0.184
+16849	0.184
+16850	0.153685
+16851	0.184
+16852	0.153685
+16853	0.184
+16854	0.184
+16855	0.153685
+16856	-1.18017
+16857	-1.11954
+16858	0.184
+16859	0.153685
+16860	0.153685
+16861	-1.21049
+16862	0.153685
+16863	0.184
+16864	0.153685
+16865	0.184
+16866	0.184
+16867	0.184
+16868	0.153685
+16869	0.184
+16870	-1.11954
+16871	0.184
+16872	0.184
+16873	0.153685
+16874	0.153685
+16875	0.184
+16876	0.184
+16877	0.153685
+16878	0.184
+16879	0.153685
+16880	0.184
+16881	0.153685
+16882	0.184
+16883	0.153685
+16884	0.184
+16885	0.184
+16886	0.153685
+16887	0.153685
+16888	0.184
+16889	0.184
+16890	0.153685
+16891	0.184
+16892	0.184
+16893	0.184
+16894	0.184
+16895	0.153685
+16896	0.184
+16897	0.153685
+16898	0.153685
+16899	0.184
+16900	0.153685
+16901	0.184
+16902	0.184
+16903	0.153685
+16904	0.153685
+16905	0.153685
+16906	0.184
+16907	0.184
+16908	0.153685
+16909	0.184
+16910	0.184
+16911	0.184
+16912	0.153685
+16913	0.184
+16914	0.184
+16915	0.184
+16916	0.184
+16917	0.184
+16918	0.153685
+16919	0.184
+16920	0.153685
+16921	0.184
+16922	0.184
+16923	0.184
+16924	0.184
+16925	0.184
+16926	0.184
+16927	0.153685
+16928	0.153685
+16929	0.153685
+16930	0.184
+16931	0.184
+16932	0.184
+16933	0.184
+16934	0.184
+16935	0.184
+16936	0.184
+16937	0.184
+16938	0.184
+16939	0.184
+16940	0.153685
+16941	0.184
+16942	0.184
+16943	0.153685
+16944	0.184
+16945	-1.21049
+16946	0.184
+16947	0.184
+16948	0.153685
+16949	-1.14986
+16950	0.153685
+16951	0.184
+16952	0.153685
+16953	0.153685
+16954	0.184
+16955	0.153685
+16956	0.153685
+16957	0.184
+16958	0.153685
+16959	0.184
+16960	0.184
+16961	0.153685
+16962	0.184
+16963	0.184
+16964	0.153685
+16965	0.153685
+16966	0.184
+16967	0.184
+16968	0.184
+16969	0.153685
+16970	0.153685
+16971	0.153685
+16972	0.184
+16973	0.184
+16974	0.184
+16975	0.184
+16976	0.184
+16977	0.184
+16978	0.184
+16979	0.153685
+16980	0.184
+16981	0.184
+16982	0.153685
+16983	0.184
+16984	0.153685
+16985	0.184
+16986	0.184
+16987	0.184
+16988	0.153685
+16989	0.184
+16990	0.184
+16991	0.153685
+16992	0.153685
+16993	0.184
+16994	0.184
+16995	0.153685
+16996	0.153685
+16997	0.184
+16998	0.184
+16999	-1.51364
+17000	0.153685
+17001	0.184
+17002	0.153685
+17003	0.153685
+17004	0.184
+17005	0.153685
+17006	0.153685
+17007	0.153685
+17008	0.184
+17009	0.153685
+17010	0.184
+17011	0.153685
+17012	0.184
+17013	0.184
+17014	0.184
+17015	0.153685
+17016	0.184
+17017	0.184
+17018	0.153685
+17019	0.184
+17020	0.184
+17021	0.184
+17022	0.184
+17023	0.184
+17024	0.153685
+17025	0.184
+17026	0.184
+17027	0.153685
+17028	0.184
+17029	0.153685
+17030	0.184
+17031	0.184
+17032	0.184
+17033	0.153685
+17034	0.184
+17035	0.153685
+17036	0.153685
+17037	0.153685
+17038	0.184
+17039	0.153685
+17040	0.153685
+17041	0.184
+17042	0.153685
+17043	0.153685
+17044	0.184
+17045	0.153685
+17046	0.153685
+17047	-1.21049
+17048	0.153685
+17049	0.184
+17050	0.153685
+17051	0.184
+17052	0.184
+17053	0.184
+17054	0.153685
+17055	0.184
+17056	0.184
+17057	0.153685
+17058	0.184
+17059	0.184
+17060	0.153685
+17061	0.153685
+17062	0.184
+17063	0.144244
+17064	0.144244
+17065	0.144244
+17066	0.144244
+17067	0.184
+17068	0.184
+17069	-1.11469
+17070	0.144244
+17071	0.184
+17072	0.184
+17073	0.184
+17074	0.144244
+17075	0.184
+17076	0.144244
+17077	0.144244
+17078	0.184
+17079	0.144244
+17080	0.184
+17081	0.144244
+17082	0.184
+17083	-1.499
+17084	0.184
+17085	0.184
+17086	0.144244
+17087	0.184
+17088	0.144244
+17089	0.184
+17090	0.144244
+17091	0.184
+17092	0.184
+17093	0.184
+17094	0.144244
+17095	0.184
+17096	0.184
+17097	0.144244
+17098	0.184
+17099	0.184
+17100	0.144244
+17101	0.184
+17102	0.184
+17103	0.184
+17104	0.184
+17105	0.184
+17106	0.144244
+17107	0.184
+17108	0.184
+17109	0.184
+17110	0.144244
+17111	0.144244
+17112	0.184
+17113	0.144244
+17114	0.144244
+17115	0.184
+17116	0.144244
+17117	0.184
+17118	0.184
+17119	0.144244
+17120	0.144244
+17121	0.184
+17122	0.144244
+17123	0.184
+17124	0.144244
+17125	0.184
+17126	0.184
+17127	0.144244
+17128	0.184
+17129	0.184
+17130	-1.37973
+17131	0.184
+17132	0.184
+17133	0.184
+17134	0.144244
+17135	0.144244
+17136	0.184
+17137	0.184
+17138	0.184
+17139	0.144244
+17140	0.184
+17141	0.184
+17142	0.144244
+17143	0.144244
+17144	0.144244
+17145	0.144244
+17146	0.144244
+17147	0.184
+17148	0.184
+17149	0.184
+17150	0.184
+17151	0.184
+17152	-1.4725
+17153	0.184
+17154	0.144244
+17155	0.144244
+17156	-1.20746
+17157	0.144244
+17158	0.184
+17159	0.184
+17160	0.184
+17161	0.144244
+17162	-1.40624
+17163	0.184
+17164	-1.499
+17165	0.184
+17166	0.144244
+17167	0.184
+17168	0.184
+17169	0.144244
+17170	0.184
+17171	0.144244
+17172	0.184
+17173	0.184
+17174	0.144244
+17175	0.184
+17176	0.184
+17177	-1.1942
+17178	0.184
+17179	0.144244
+17180	0.184
+17181	0.184
+17182	0.184
+17183	0.144244
+17184	-1.1942
+17185	0.184
+17186	0.184
+17187	0.184
+17188	0.184
+17189	0.184
+17190	-1.1942
+17191	-1.30022
+17192	0.184
+17193	0.184
+17194	0.184
+17195	0.184
+17196	0.144244
+17197	0.184
+17198	0.144244
+17199	0.184
+17200	0.184
+17201	0.144244
+17202	0.184
+17203	0.184
+17204	0.144244
+17205	0.184
+17206	0.144244
+17207	0.184
+17208	-1.37973
+17209	0.184
+17210	0.184
+17211	0.144244
+17212	0.184
+17213	0.184
+17214	-1.1942
+17215	0.184
+17216	0.144244
+17217	0.184
+17218	-1.1942
+17219	0.184
+17220	0.184
+17221	0.184
+17222	-1.1677
+17223	0.184
+17224	0.184
+17225	0.184
+17226	0.184
+17227	0.144244
+17228	0.184
+17229	0.184
+17230	0.184
+17231	0.144244
+17232	0.184
+17233	0.184
+17234	0.144244
+17235	0.184
+17236	0.184
+17237	0.144244
+17238	0.184
+17239	0.144244
+17240	0.144244
+17241	0.184
+17242	0.184
+17243	0.144244
+17244	0.184
+17245	0.184
+17246	0.144244
+17247	0.184
+17248	0.184
+17249	0.144244
+17250	0.184
+17251	0.144244
+17252	0.184
+17253	0.144244
+17254	0.184
+17255	0.144244
+17256	0.144244
+17257	0.184
+17258	0.184
+17259	0.144244
+17260	0.184
+17261	0.144244
+17262	0.144244
+17263	0.184
+17264	0.184
+17265	0.144244
+17266	0.184
+17267	0.144244
+17268	0.144244
+17269	0.184
+17270	0.184
+17271	0.184
+17272	0.184
+17273	0.184
+17274	0.184
+17275	0.144244
+17276	0.144244
+17277	0.184
+17278	0.144244
+17279	0.144244
+17280	0.144244
+17281	0.184
+17282	0.144244
+17283	0.184
+17284	0.184
+17285	0.144244
+17286	0.144244
+17287	0.184
+17288	0.144244
+17289	0.184
+17290	0.184
+17291	0.144244
+17292	0.184
+17293	0.144244
+17294	0.184
+17295	0.144244
+17296	0.184
+17297	0.144244
+17298	0.184
+17299	-1.1942
+17300	0.184
+17301	0.184
+17302	0.184
+17303	0.184
+17304	0.184
+17305	0.184
+17306	0.144244
+17307	0.184
+17308	0.184
+17309	0.144244
+17310	0.144244
+17311	0.184
+17312	0.144244
+17313	0.184
+17314	0.144244
+17315	0.144244
+17316	0.184
+17317	0.184
+17318	0.184
+17319	0.144244
+17320	0.184
+17321	0.144244
+17322	0.144244
+17323	0.144244
+17324	0.184
+17325	0.144244
+17326	0.144244
+17327	0.144244
+17328	0.184
+17329	0.144244
+17330	0.184
+17331	0.184
+17332	0.144244
+17333	0.184
+17334	0.184
+17335	0.144244
+17336	0.184
+17337	0.184
+17338	0.184
+17339	0.144244
+17340	-1.20746
+17341	0.184
+17342	0.184
+17343	0.184
+17344	0.184
+17345	0.144244
+17346	0.184
+17347	0.184
+17348	0.144244
+17349	0.184
+17350	0.184
+17351	0.144244
+17352	0.144244
+17353	0.184
+17354	0.144244
+17355	0.184
+17356	-1.1942
+17357	0.144244
+17358	0.144244
+17359	0.184
+17360	0.144244
+17361	0.144244
+17362	0.184
+17363	0.144244
+17364	0.144244
+17365	-1.12794
+17366	0.144244
+17367	0.144244
+17368	0.184
+17369	0.184
+17370	0.144244
+17371	0.144244
+17372	0.184
+17373	0.144244
+17374	0.184
+17375	-1.1677
+17376	0.184
+17377	0.184
+17378	-1.11469
+17379	0.184
+17380	0.144244
+17381	0.184
+17382	0.144244
+17383	0.144244
+17384	0.184
+17385	0.184
+17386	0.184
+17387	0.184
+17388	0.184
+17389	0.144244
+17390	0.184
+17391	0.144244
+17392	0.184
+17393	0.184
+17394	0.184
+17395	0.144244
+17396	0.144244
+17397	0.184
+17398	0.184
+17399	0.144244
+17400	0.184
+17401	0.144244
+17402	0.184
+17403	0.144244
+17404	0.184
+17405	0.184
+17406	-1.4725
+17407	0.184
+17408	0.184
+17409	0.144244
+17410	0.184
+17411	0.144244
+17412	0.184
+17413	0.184
+17414	0.144244
+17415	0.184
+17416	0.144244
+17417	0.184
+17418	0.184
+17419	0.184
+17420	0.184
+17421	0.144244
+17422	0.144244
+17423	0.184
+17424	0.144244
+17425	0.144244
+17426	0.184
+17427	0.184
+17428	0.144244
+17429	-1.11469
+17430	-1.1942
+17431	-1.11469
+17432	0.184
+17433	0.184
+17434	0.144244
+17435	0.184
+17436	0.144244
+17437	0.144244
+17438	0.184
+17439	0.144244
+17440	0.144244
+17441	0.184
+17442	0.144244
+17443	0.184
+17444	0.184
+17445	0.184
+17446	0.184
+17447	0.184
+17448	0.144244
+17449	0.184
+17450	0.144244
+17451	0.184
+17452	-1.4725
+17453	0.184
+17454	0.144244
+17455	0.184
+17456	0.184
+17457	0.144244
+17458	0.184
+17459	-1.40624
+17460	0.184
+17461	0.144244
+17462	0.184
+17463	0.184
+17464	0.184
+17465	0.184
+17466	0.144244
+17467	0.184
+17468	0.184
+17469	0.184
+17470	0.144244
+17471	0.184
+17472	0.184
+17473	0.184
+17474	0.184
+17475	0.144244
+17476	0.184
+17477	0.184
+17478	0.184
+17479	-1.11469
+17480	0.144244
+17481	0.184
+17482	0.184
+17483	0.184
+17484	-1.499
+17485	0.144244
+17486	0.184
+17487	0.184
+17488	0.184
+17489	0.144244
+17490	0.184
+17491	0.184
+17492	0.184
+17493	0.184
+17494	0.144244
+17495	0.184
+17496	0.144244
+17497	0.184
+17498	0.184
+17499	0.184
+17500	0.184
+17501	0.11774
+17502	0.0912362
+17503	0.184
+17504	0.184
+17505	0.184
+17506	0.144244
+17507	0.184
+17508	0.184
+17509	0.144244
+17510	0.184
+17511	0.184
+17512	0.184
+17513	0.184
+17514	0.144244
+17515	0.144244
+17516	0.144244
+17517	0.184
+17518	0.144244
+17519	0.184
+17520	0.184
+17521	0.144244
+17522	0.184
+17523	0.144244
+17524	0.144244
+17525	0.184
+17526	0.184
+17527	0.144244
+17528	0.184
+17529	0.144244
+17530	0.184
+17531	0.144244
+17532	0.184
+17533	0.144244
+17534	0.184
+17535	0.144244
+17536	0.144244
+17537	0.184
+17538	0.184
+17539	0.184
+17540	0.184
+17541	0.144244
+17542	0.184
+17543	0.184
+17544	0.184
+17545	0.144244
+17546	0.184
+17547	0.184
+17548	0.184
+17549	0.184
+17550	0.144244
+17551	0.184
+17552	0.144244
+17553	0.144244
+17554	0.144244
+17555	0.184
+17556	0.184
+17557	0.184
+17558	0.144244
+17559	0.184
+17560	0.184
+17561	0.184
+17562	-1.11469
+17563	0.184
+17564	0.184
+17565	0.184
+17566	0.184
+17567	0.184
+17568	0.144244
+17569	0.184
+17570	0.184
+17571	0.184
+17572	0.184
+17573	0.184
+17574	0.184
+17575	0.184
+17576	0.144244
+17577	0.184
+17578	0.144244
+17579	0.184
+17580	0.184
+17581	0.184
+17582	0.184
+17583	0.144244
+17584	0.184
+17585	0.184
+17586	0.184
+17587	0.184
+17588	0.184
+17589	0.184
+17590	0.144244
+17591	0.184
+17592	0.184
+17593	0.184
+17594	-1.4725
+17595	0.144244
+17596	0.184
+17597	0.144244
+17598	0.184
+17599	0.184
+17600	0.184
+17601	0.184
+17602	0.144244
+17603	0.144244
+17604	0.144244
+17605	0.184
+17606	0.144244
+17607	0.184
+17608	0.184
+17609	0.144244
+17610	0.144244
+17611	0.184
+17612	0.144244
+17613	0.184
+17614	0.184
+17615	0.184
+17616	0.144244
+17617	0.184
+17618	0.184
+17619	0.144244
+17620	0.184
+17621	0.144244
+17622	0.144244
+17623	0.184
+17624	0.144244
+17625	0.144244
+17626	0.184
+17627	0.144244
+17628	0.184
+17629	0.184
+17630	0.144244
+17631	0.184
+17632	0.184
+17633	0.144244
+17634	0.144244
+17635	0.184
+17636	0.184
+17637	0.144244
+17638	0.184
+17639	0.184
+17640	0.144244
+17641	0.184
+17642	0.144244
+17643	0.184
+17644	0.144244
+17645	0.184
+17646	0.144244
+17647	0.184
+17648	0.184
+17649	0.144244
+17650	0.184
+17651	0.144244
+17652	0.144244
+17653	0.184
+17654	0.144244
+17655	0.144244
+17656	0.184
+17657	0.184
+17658	0.144244
+17659	0.184
+17660	0.184
+17661	0.184
+17662	0.144244
+17663	0.144244
+17664	0.184
+17665	0.144244
+17666	0.184
+17667	0.184
+17668	0.184
+17669	0.184
+17670	0.184
+17671	0.144244
+17672	0.144244
+17673	0.184
+17674	0.144244
+17675	0.184
+17676	0.184
+17677	0.184
+17678	0.144244
+17679	0.184
+17680	0.144244
+17681	0.144244
+17682	0.184
+17683	-1.44599
+17684	0.184
+17685	0.184
+17686	-1.1942
+17687	0.144244
+17688	0.184
+17689	-1.20746
+17690	0.144244
+17691	0.184
+17692	0.184
+17693	0.144244
+17694	0.184
+17695	-1.11469
+17696	0.184
+17697	0.184
+17698	0.184
+17699	-1.40624
+17700	0.184
+17701	0.184
+17702	-1.11469
+17703	0.184
+17704	0.184
+17705	0.144244
+17706	0.144244
+17707	0.184
+17708	0.184
+17709	-1.1942
+17710	0.184
+17711	0.184
+17712	0.144244
+17713	0.184
+17714	0.144244
+17715	0.184
+17716	-1.11469
+17717	0.184
+17718	0.144244
+17719	0.184
+17720	0.144244
+17721	0.184
+17722	0.144244
+17723	0.184
+17724	0.184
+17725	0.144244
+17726	0.144244
+17727	0.144244
+17728	0.184
+17729	0.144244
+17730	-1.45924
+17731	0.184
+17732	0.144244
+17733	0.144244
+17734	0.184
+17735	0.144244
+17736	0.184
+17737	0.184
+17738	0.144244
+17739	0.144244
+17740	0.184
+17741	0.144244
+17742	0.184
+17743	0.184
+17744	0.144244
+17745	0.184
+17746	-1.1677
+17747	0.184
+17748	0.144244
+17749	0.184
+17750	0.184
+17751	0.184
+17752	0.184
+17753	0.184
+17754	0.144244
+17755	0.184
+17756	-1.1412
+17757	0.144244
+17758	0.144244
+17759	0.184
+17760	0.184
+17761	0.184
+17762	0.184
+17763	0.144244
+17764	0.144244
+17765	0.184
+17766	0.184
+17767	0.184
+17768	0.144244
+17769	0.144244
+17770	0.184
+17771	0.184
+17772	0.144244
+17773	-1.20746
+17774	0.144244
+17775	0.144244
+17776	0.144244
+17777	0.144244
+17778	0.144244
+17779	0.144244
+17780	0.144244
+17781	-1.45924
+17782	-1.27372
+17783	0.144244
+17784	0.184
+17785	0.184
+17786	-1.40624
+17787	0.184
+17788	0.184
+17789	0.184
+17790	0.184
+17791	0.184
+17792	0.144244
+17793	-1.43274
+17794	0.144244
+17795	0.144244
+17796	0.184
+17797	0.144244
+17798	0.184
+17799	0.184
+17800	0.144244
+17801	0.184
+17802	0.184
+17803	0.184
+17804	0.144244
+17805	-1.1677
+17806	0.184
+17807	0.184
+17808	0.184
+17809	0.144244
+17810	0.144244
+17811	0.184
+17812	0.184
+17813	0.184
+17814	-1.41949
+17815	0.184
+17816	0.144244
+17817	0.184
+17818	0.144244
+17819	0.184
+17820	0.184
+17821	0.184
+17822	0.144244
+17823	0.184
+17824	0.184
+17825	0.144244
+17826	0.184
+17827	0.144244
+17828	0.184
+17829	0.184
+17830	0.184
+17831	0.184
+17832	0.184
+17833	0.144244
+17834	0.184
+17835	0.144244
+17836	0.184
+17837	0.144244
+17838	0.144244
+17839	0.184
+17840	0.184
+17841	0.184
+17842	0.144244
+17843	0.144244
+17844	-1.1942
+17845	-1.11469
+17846	0.184
+17847	0.144244
+17848	0.184
+17849	0.184
+17850	0.184
+17851	0.184
+17852	0.184
+17853	0.184
+17854	0.184
+17855	0.184
+17856	0.184
+17857	0.144244
+17858	0.184
+17859	0.184
+17860	0.144244
+17861	0.184
+17862	0.184
+17863	0.184
+17864	0.184
+17865	0.144244
+17866	0.184
+17867	0.144244
+17868	0.144244
+17869	0.144244
+17870	0.184
+17871	0.184
+17872	0.144244
+17873	0.184
+17874	0.144244
+17875	0.184
+17876	0.184
+17877	0.144244
+17878	0.184
+17879	0.184
+17880	0.144244
+17881	0.184
+17882	0.184
+17883	0.144244
+17884	0.184
+17885	0.144244
+17886	0.184
+17887	-1.499
+17888	-1.27372
+17889	-1.43274
+17890	0.184
+17891	-1.1942
+17892	0.184
+17893	0.184
+17894	0.184
+17895	0.144244
+17896	0.144244
+17897	0.144244
+17898	-1.1677
+17899	0.144244
+17900	0.184
+17901	0.184
+17902	0.184
+17903	-1.499
+17904	0.184
+17905	0.184
+17906	0.184
+17907	0.184
+17908	0.144244
+17909	0.184
+17910	0.184
+17911	0.144244
+17912	0.184
+17913	0.144244
+17914	0.184
+17915	0.184
+17916	0.144244
+17917	0.184
+17918	0.184
+17919	0.144244
+17920	0.184
+17921	0.184
+17922	0.184
+17923	0.184
+17924	-1.11469
+17925	0.184
+17926	0.184
+17927	0.184
+17928	0.144244
+17929	0.184
+17930	-1.1412
+17931	0.144244
+17932	0.184
+17933	0.184
+17934	0.144244
+17935	0.184
+17936	0.184
+17937	0.184
+17938	0.184
+17939	0.184
+17940	0.184
+17941	0.184
+17942	0.184
+17943	0.144244
+17944	0.184
+17945	0.184
+17946	0.144244
+17947	0.144244
+17948	0.184
+17949	0.184
+17950	0.144244
+17951	0.184
+17952	0.144244
+17953	0.184
+17954	0.184
+17955	0.144244
+17956	0.144244
+17957	0.184
+17958	0.184
+17959	0.144244
+17960	0.184
+17961	0.144244
+17962	0.184
+17963	0.184
+17964	0.184
+17965	0.184
+17966	0.184
+17967	0.184
+17968	0.184
+17969	0.184
+17970	0.184
+17971	0.184
+17972	0.144244
+17973	0.184
+17974	0.144244
+17975	0.184
+17976	0.144244
+17977	0.184
+17978	0.184
+17979	-1.1942
+17980	0.184
+17981	0.184
+17982	0.184
+17983	0.184
+17984	0.144244
+17985	0.184
+17986	0.184
+17987	0.184
+17988	0.144244
+17989	0.184
+17990	0.184
+17991	0.144244
+17992	0.184
+17993	0.184
+17994	0.184
+17995	0.184
+17996	0.184
+17997	0.184
+17998	0.184
+17999	-1.499
+18000	0.184
+18001	0.144244
+18002	0.184
+18003	0.144244
+18004	0.144244
+18005	0.184
+18006	0.144244
+18007	0.144244
+18008	0.184
+18009	0.184
+18010	0.144244
+18011	0.184
+18012	0.184
+18013	0.184
+18014	0.144244
+18015	0.144244
+18016	0.144244
+18017	0.144244
+18018	0.144244
+18019	0.184
+18020	0.184
+18021	0.144244
+18022	0.184
+18023	0.184
+18024	0.144244
+18025	0.184
+18026	0.184
+18027	0.184
+18028	0.184
+18029	0.184
+18030	-1.4725
+18031	0.184
+18032	-1.39298
+18033	0.184
+18034	0.184
+18035	0.144244
+18036	0.184
+18037	0.184
+18038	0.144244
+18039	0.184
+18040	0.184
+18041	0.184
+18042	0.144244
+18043	0.144244
+18044	0.184
+18045	0.144244
+18046	0.144244
+18047	0.184
+18048	0.184
+18049	0.184
+18050	0.144244
+18051	0.184
+18052	0.144244
+18053	0.184
+18054	0.184
+18055	0.144244
+18056	0.184
+18057	0.144244
+18058	0.144244
+18059	0.184
+18060	0.144244
+18061	0.184
+18062	0.184
+18063	0.144244
+18064	0.184
+18065	0.144244
+18066	0.184
+18067	0.184
+18068	0.144244
+18069	0.184
+18070	0.144244
+18071	0.184
+18072	0.144244
+18073	0.184
+18074	0.184
+18075	0.184
+18076	0.144244
+18077	0.184
+18078	0.144244
+18079	0.144244
+18080	0.184
+18081	0.144244
+18082	0.184
+18083	0.144244
+18084	0.184
+18085	0.144244
+18086	0.184
+18087	0.184
+18088	0.184
+18089	0.184
+18090	-1.7313
+18091	0.184
+18092	0.184
+18093	0.184
+18094	0.184
+18095	0.136709
+18096	0.136709
+18097	0.184
+18098	0.136709
+18099	0.184
+18100	0.184
+18101	0.184
+18102	0.136709
+18103	0.184
+18104	-1.56578
+18105	0.184
+18106	-1.21109
+18107	0.184
+18108	0.184
+18109	0.184
+18110	0.184
+18111	0.136709
+18112	0.136709
+18113	0.184
+18114	0.184
+18115	0.136709
+18116	0.136709
+18117	0.136709
+18118	0.184
+18119	0.184
+18120	0.136709
+18121	0.136709
+18122	0.184
+18123	0.184
+18124	0.184
+18125	0.136709
+18126	0.184
+18127	0.184
+18128	0.136709
+18129	0.184
+18130	0.136709
+18131	0.184
+18132	0.184
+18133	0.184
+18134	0.136709
+18135	0.184
+18136	0.184
+18137	-1.21109
+18138	-1.21109
+18139	0.136709
+18140	0.136709
+18141	0.184
+18142	0.184
+18143	-1.1638
+18144	-1.21109
+18145	0.184
+18146	0.184
+18147	0.184
+18148	0.136709
+18149	0.184
+18150	0.184
+18151	0.184
+18152	0.184
+18153	-1.11651
+18154	-1.21109
+18155	0.184
+18156	0.136709
+18157	-1.21109
+18158	0.184
+18159	0.136709
+18160	0.136709
+18161	0.136709
+18162	0.184
+18163	-1.11651
+18164	-1.1638
+18165	-1.11651
+18166	0.136709
+18167	0.136709
+18168	0.184
+18169	0.184
+18170	0.136709
+18171	0.136709
+18172	-1.18745
+18173	0.136709
+18174	0.184
+18175	0.184
+18176	0.136709
+18177	0.184
+18178	0.184
+18179	-1.11651
+18180	0.184
+18181	0.136709
+18182	0.184
+18183	0.184
+18184	0.136709
+18185	-1.11651
+18186	0.184
+18187	0.184
+18188	0.184
+18189	0.136709
+18190	0.184
+18191	0.136709
+18192	0.184
+18193	0.136709
+18194	0.184
+18195	0.136709
+18196	0.184
+18197	0.184
+18198	0.184
+18199	0.184
+18200	0.136709
+18201	0.184
+18202	0.184
+18203	0.184
+18204	0.136709
+18205	0.184
+18206	0.136709
+18207	0.184
+18208	0.136709
+18209	0.184
+18210	0.184
+18211	-1.11651
+18212	0.136709
+18213	0.184
+18214	0.184
+18215	0.184
+18216	0.184
+18217	0.184
+18218	0.136709
+18219	0.136709
+18220	0.136709
+18221	0.136709
+18222	0.184
+18223	0.184
+18224	0.136709
+18225	0.184
+18226	0.184
+18227	-1.11651
+18228	0.136709
+18229	0.184
+18230	0.136709
+18231	0.184
+18232	0.184
+18233	0.184
+18234	0.184
+18235	0.136709
+18236	0.184
+18237	0.136709
+18238	0.136709
+18239	0.184
+18240	0.184
+18241	0.184
+18242	0.136709
+18243	-1.11651
+18244	0.136709
+18245	0.184
+18246	0.184
+18247	0.136709
+18248	0.184
+18249	0.136709
+18250	0.184
+18251	0.136709
+18252	0.184
+18253	0.184
+18254	0.184
+18255	0.184
+18256	-1.1638
+18257	0.136709
+18258	0.136709
+18259	0.184
+18260	0.184
+18261	0.184
+18262	0.184
+18263	-1.21109
+18264	0.184
+18265	0.136709
+18266	0.136709
+18267	0.184
+18268	0.184
+18269	0.136709
+18270	0.136709
+18271	0.184
+18272	0.136709
+18273	0.136709
+18274	0.184
+18275	0.184
+18276	0.184
+18277	0.184
+18278	0.136709
+18279	0.136709
+18280	0.184
+18281	0.136709
+18282	0.136709
+18283	0.184
+18284	0.184
+18285	0.136709
+18286	0.184
+18287	0.184
+18288	0.184
+18289	0.184
+18290	0.136709
+18291	0.136709
+18292	0.184
+18293	0.136709
+18294	0.136709
+18295	0.184
+18296	0.136709
+18297	0.136709
+18298	0.184
+18299	0.136709
+18300	0.184
+18301	0.136709
+18302	0.136709
+18303	0.136709
+18304	0.184
+18305	0.136709
+18306	0.136709
+18307	0.184
+18308	0.184
+18309	0.184
+18310	0.184
+18311	0.136709
+18312	0.184
+18313	0.184
+18314	0.184
+18315	0.184
+18316	0.184
+18317	0.136709
+18318	0.136709
+18319	0.184
+18320	0.184
+18321	0.136709
+18322	0.184
+18323	0.136709
+18324	0.184
+18325	0.184
+18326	0.136709
+18327	0.136709
+18328	0.184
+18329	0.136709
+18330	0.184
+18331	0.136709
+18332	0.184
+18333	0.184
+18334	0.136709
+18335	0.136709
+18336	0.136709
+18337	0.184
+18338	0.184
+18339	0.184
+18340	0.184
+18341	0.136709
+18342	0.184
+18343	0.184
+18344	0.136709
+18345	0.184
+18346	0.184
+18347	0.136709
+18348	0.184
+18349	0.184
+18350	-1.11651
+18351	0.136709
+18352	0.184
+18353	0.184
+18354	0.184
+18355	0.184
+18356	0.184
+18357	0.136709
+18358	0.184
+18359	0.136709
+18360	0.184
+18361	0.184
+18362	0.136709
+18363	0.184
+18364	0.136709
+18365	0.136709
+18366	0.184
+18367	0.184
+18368	-1.1638
+18369	0.184
+18370	0.184
+18371	0.136709
+18372	0.184
+18373	0.184
+18374	0.184
+18375	0.136709
+18376	0.184
+18377	0.136709
+18378	0.136709
+18379	0.184
+18380	0.184
+18381	0.136709
+18382	0.184
+18383	0.184
+18384	0.184
+18385	0.136709
+18386	-1.21109
+18387	0.184
+18388	0.184
+18389	0.136709
+18390	0.184
+18391	0.136709
+18392	0.136709
+18393	-1.30568
+18394	0.136709
+18395	0.136709
+18396	0.184
+18397	0.136709
+18398	0.184
+18399	0.136709
+18400	0.184
+18401	0.136709
+18402	0.184
+18403	0.184
+18404	0.184
+18405	0.136709
+18406	0.184
+18407	0.184
+18408	0.184
+18409	0.184
+18410	0.136709
+18411	0.184
+18412	0.184
+18413	0.136709
+18414	0.184
+18415	0.184
+18416	0.184
+18417	0.184
+18418	0.136709
+18419	0.184
+18420	0.184
+18421	0.184
+18422	-1.1638
+18423	0.184
+18424	-1.58943
+18425	0.184
+18426	0.184
+18427	0.136709
+18428	0.184
+18429	0.136709
+18430	0.184
+18431	0.184
+18432	0.136709
+18433	0.184
+18434	0.184
+18435	0.136709
+18436	0.184
+18437	0.184
+18438	0.136709
+18439	-1.1638
+18440	0.184
+18441	0.136709
+18442	0.136709
+18443	0.136709
+18444	0.184
+18445	0.136709
+18446	0.184
+18447	0.184
+18448	0.136709
+18449	0.184
+18450	-1.21109
+18451	-1.42391
+18452	0.184
+18453	0.136709
+18454	0.184
+18455	0.184
+18456	0.184
+18457	0.136709
+18458	0.184
+18459	0.184
+18460	0.184
+18461	0.184
+18462	0.136709
+18463	0.184
+18464	0.184
+18465	0.184
+18466	0.184
+18467	-1.11651
+18468	0.136709
+18469	0.184
+18470	0.136709
+18471	0.184
+18472	0.184
+18473	0.184
+18474	0.136709
+18475	0.136709
+18476	0.184
+18477	0.184
+18478	0.184
+18479	0.184
+18480	0.136709
+18481	0.184
+18482	-1.21109
+18483	-1.4712
+18484	0.136709
+18485	0.136709
+18486	0.184
+18487	0.136709
+18488	0.184
+18489	0.136709
+18490	0.184
+18491	0.184
+18492	0.184
+18493	0.136709
+18494	0.184
+18495	0.136709
+18496	0.184
+18497	0.184
+18498	0.136709
+18499	-1.1638
+18500	0.184
+18501	0.136709
+18502	0.136709
+18503	0.184
+18504	0.184
+18505	0.184
+18506	0.136709
+18507	0.184
+18508	0.184
+18509	0.184
+18510	0.184
+18511	-1.14016
+18512	-1.28203
+18513	0.136709
+18514	0.136709
+18515	0.184
+18516	0.136709
+18517	0.136709
+18518	0.184
+18519	0.184
+18520	0.136709
+18521	-1.11651
+18522	0.184
+18523	0.184
+18524	0.136709
+18525	0.136709
+18526	0.184
+18527	0.184
+18528	0.136709
+18529	-1.61307
+18530	0.184
+18531	-1.30568
+18532	0.184
+18533	0.184
+18534	0.184
+18535	0.184
+18536	0.136709
+18537	0.184
+18538	0.136709
+18539	0.136709
+18540	0.184
+18541	0.136709
+18542	0.136709
+18543	0.184
+18544	0.184
+18545	-1.40026
+18546	0.136709
+18547	0.136709
+18548	0.136709
+18549	0.136709
+18550	0.184
+18551	0.136709
+18552	0.184
+18553	0.136709
+18554	0.184
+18555	0.184
+18556	0.136709
+18557	0.184
+18558	0.184
+18559	0.136709
+18560	-1.28203
+18561	0.184
+18562	0.184
+18563	0.136709
+18564	0.184
+18565	0.184
+18566	0.136709
+18567	0.184
+18568	0.184
+18569	0.136709
+18570	0.184
+18571	-1.21109
+18572	0.136709
+18573	0.184
+18574	0.136709
+18575	-1.14016
+18576	0.184
+18577	0.184
+18578	0.136709
+18579	-1.4712
+18580	0.184
+18581	0.136709
+18582	0.184
+18583	0.136709
+18584	0.184
+18585	0.136709
+18586	0.136709
+18587	0.184
+18588	0.184
+18589	0.184
+18590	-1.21109
+18591	0.184
+18592	0.184
+18593	0.136709
+18594	0.184
+18595	0.136709
+18596	0.184
+18597	0.136709
+18598	0.184
+18599	0.136709
+18600	0.184
+18601	-1.21109
+18602	0.136709
+18603	0.184
+18604	0.184
+18605	0.184
+18606	0.136709
+18607	0.184
+18608	0.136709
+18609	0.184
+18610	-1.11651
+18611	0.184
+18612	0.184
+18613	0.184
+18614	0.136709
+18615	-1.40026
+18616	0.136709
+18617	0.184
+18618	0.184
+18619	0.136709
+18620	0.184
+18621	-1.40026
+18622	0.184
+18623	0.136709
+18624	0.184
+18625	0.184
+18626	0.136709
+18627	0.184
+18628	0.136709
+18629	0.136709
+18630	0.184
+18631	-1.21109
+18632	0.136709
+18633	0.184
+18634	0.184
+18635	0.136709
+18636	0.136709
+18637	0.136709
+18638	0.184
+18639	0.136709
+18640	0.184
+18641	0.136709
+18642	0.136709
+18643	0.184
+18644	0.184
+18645	0.136709
+18646	0.184
+18647	0.136709
+18648	0.184
+18649	0.184
+18650	0.184
+18651	0.136709
+18652	0.184
+18653	0.184
+18654	0.136709
+18655	0.184
+18656	0.184
+18657	0.184
+18658	0.184
+18659	-1.40026
+18660	0.184
+18661	0.136709
+18662	0.184
+18663	0.136709
+18664	0.184
+18665	0.136709
+18666	0.184
+18667	0.184
+18668	0.136709
+18669	0.136709
+18670	0.184
+18671	0.184
+18672	0.136709
+18673	0.136709
+18674	0.136709
+18675	0.136709
+18676	0.136709
+18677	0.136709
+18678	0.184
+18679	0.136709
+18680	0.184
+18681	0.136709
+18682	0.136709
+18683	0.184
+18684	0.184
+18685	0.136709
+18686	0.184
+18687	0.136709
+18688	0.184
+18689	0.136709
+18690	0.136709
+18691	0.184
+18692	0.184
+18693	0.184
+18694	0.136709
+18695	0.136709
+18696	-2.819
+18697	0.136709
+18698	0.184
+18699	0.136709
+18700	0.136709
+18701	0.184
+18702	0.184
+18703	0.184
+18704	0.160354
+18705	0.160354
+18706	0.113063
+18707	0.113063
+18708	0.184
+18709	0.184
+18710	0.136709
+18711	-1.4712
+18712	0.136709
+18713	0.136709
+18714	0.184
+18715	0.136709
+18716	0.184
+18717	0.136709
+18718	0.136709
+18719	0.184
+18720	0.184
+18721	0.184
+18722	0.184
+18723	0.136709
+18724	0.184
+18725	0.136709
+18726	0.136709
+18727	0.184
+18728	0.136709
+18729	0.136709
+18730	0.184
+18731	0.136709
+18732	0.184
+18733	0.184
+18734	0.136709
+18735	0.184
+18736	-1.30568
+18737	0.136709
+18738	0.184
+18739	0.184
+18740	0.136709
+18741	0.184
+18742	0.136709
+18743	-1.21109
+18744	0.136709
+18745	0.136709
+18746	-1.49484
+18747	0.184
+18748	0.136709
+18749	-1.14016
+18750	0.184
+18751	0.184
+18752	0.184
+18753	0.136709
+18754	0.184
+18755	0.136709
+18756	0.184
+18757	0.184
+18758	0.136709
+18759	0.184
+18760	0.136709
+18761	0.184
+18762	0.184
+18763	-1.21109
+18764	0.184
+18765	0.184
+18766	0.136709
+18767	0.136709
+18768	-1.4712
+18769	-1.28203
+18770	0.184
+18771	0.136709
+18772	0.184
+18773	0.136709
+18774	0.184
+18775	0.184
+18776	0.184
+18777	0.184
+18778	0.136709
+18779	0.184
+18780	0.184
+18781	0.184
+18782	0.136709
+18783	0.184
+18784	0.0894173
+18785	0.184
+18786	0.136709
+18787	0.184
+18788	0.136709
+18789	0.184
+18790	0.184
+18791	0.184
+18792	0.136709
+18793	0.136709
+18794	0.184
+18795	0.184
+18796	0.184
+18797	0.136709
+18798	0.184
+18799	0.184
+18800	0.0894173
+18801	0.113063
+18802	0.113063
+18803	0.0894173
+18804	0.113063
+18805	0.0894173
+18806	0.113063
+18807	0.0894173
+18808	0.113063
+18809	0.0894173
+18810	0.113063
+18811	-1.7313
+18812	0.0894173
+18813	0.113063
+18814	0.136709
+18815	0.184
+18816	0.184
+18817	0.136709
+18818	0.136709
+18819	0.136709
+18820	0.136709
+18821	0.136709
+18822	0.136709
+18823	0.184
+18824	0.136709
+18825	0.184
+18826	0.136709
+18827	0.184
+18828	-1.51849
+18829	0.184
+18830	0.184
+18831	0.184
+18832	0.136709
+18833	0.136709
+18834	0.184
+18835	0.136709
+18836	0.184
+18837	0.184
+18838	0.184
+18839	0.184
+18840	0.184
+18841	-1.42391
+18842	0.184
+18843	0.184
+18844	0.136709
+18845	0.184
+18846	0.0894173
+18847	0.0894173
+18848	0.136709
+18849	-1.14016
+18850	0.136709
+18851	0.184
+18852	0.136709
+18853	0.136709
+18854	0.184
+18855	0.184
+18856	0.184
+18857	0.184
+18858	0.136709
+18859	0.184
+18860	0.136709
+18861	0.184
+18862	0.136709
+18863	0.184
+18864	0.136709
+18865	0.184
+18866	0.184
+18867	0.136709
+18868	0.136709
+18869	0.136709
+18870	0.184
+18871	0.184
+18872	0.184
+18873	-1.4712
+18874	0.184
+18875	0.136709
+18876	0.184
+18877	0.136709
+18878	0.184
+18879	0.184
+18880	-1.21109
+18881	-1.14016
+18882	0.136709
+18883	0.184
+18884	0.184
+18885	0.136709
+18886	0.184
+18887	-1.28203
+18888	-1.21109
+18889	0.184
+18890	0.184
+18891	0.136709
+18892	0.184
+18893	-1.80224
+18894	0.184
+18895	0.136709
+18896	0.184
+18897	0.136709
+18898	0.184
+18899	0.184
+18900	0.136709
+18901	-1.28203
+18902	0.136709
+18903	0.136709
+18904	0.184
+18905	0.184
+18906	0.136709
+18907	0.184
+18908	0.184
+18909	0.136709
+18910	0.184
+18911	0.136709
+18912	0.184
+18913	0.184
+18914	-1.21109
+18915	-1.28203
+18916	0.184
+18917	0.136709
+18918	-1.21109
+18919	0.184
+18920	0.184
+18921	0.136709
+18922	0.136709
+18923	0.184
+18924	0.184
+18925	0.136709
+18926	0.184
+18927	0.184
+18928	0.184
+18929	0.136709
+18930	0.184
+18931	0.184
+18932	0.136709
+18933	-1.11651
+18934	0.184
+18935	-1.77859
+18936	0.184
+18937	0.184
+18938	0.184
+18939	0.136709
+18940	0.184
+18941	0.184
+18942	0.184
+18943	0.184
+18944	0.184
+18945	0.184
+18946	0.136709
+18947	0.184
+18948	0.136709
+18949	0.184
+18950	0.136709
+18951	0.136709
+18952	0.136709
+18953	-1.21109
+18954	0.184
+18955	0.136709
+18956	0.184
+18957	0.184
+18958	0.136709
+18959	0.184
+18960	0.184
+18961	0.184
+18962	0.136709
+18963	0.184
+18964	0.184
+18965	0.136709
+18966	0.184
+18967	0.136709
+18968	-1.21109
+18969	0.184
+18970	0.184
+18971	0.184
+18972	0.184
+18973	0.136709
+18974	0.184
+18975	0.136709
+18976	0.136709
+18977	0.184
+18978	0.136709
+18979	-1.11651
+18980	0.184
+18981	0.184
+18982	-1.40026
+18983	0.136709
+18984	0.184
+18985	0.136709
+18986	0.184
+18987	0.184
+18988	0.136709
+18989	0.136709
+18990	0.136709
+18991	0.184
+18992	-1.21109
+18993	0.136709
+18994	-1.14016
+18995	0.136709
+18996	0.184
+18997	0.136709
+18998	0.184
+18999	0.184
+19000	0.136709
+19001	0.136709
+19002	0.184
+19003	0.184
+19004	0.136709
+19005	0.136709
+19006	0.184
+19007	0.136709
+19008	0.184
+19009	0.136709
+19010	0.136709
+19011	0.184
+19012	0.184
+19013	0.136709
+19014	-1.21109
+19015	0.184
+19016	-2.74806
+19017	-1.21109
+19018	0.184
+19019	0.136709
+19020	0.136709
+19021	0.136709
+19022	0.136709
+19023	0.184
+19024	0.184
+19025	0.184
+19026	0.184
+19027	0.136709
+19028	0.184
+19029	0.136709
+19030	0.184
+19031	0.136709
+19032	0.136709
+19033	-1.18745
+19034	0.184
+19035	0.184
+19036	0.136709
+19037	0.184
+19038	-1.40026
+19039	0.184
+19040	0.184
+19041	0.184
+19042	0.136709
+19043	0.184
+19044	0.184
+19045	0.184
+19046	0.136709
+19047	0.184
+19048	0.184
+19049	-1.21109
+19050	0.184
+19051	-1.1638
+19052	0.136709
+19053	0.184
+19054	0.184
+19055	0.184
+19056	0.184
+19057	0.184
+19058	0.136709
+19059	0.184
+19060	0.184
+19061	0.184
+19062	0.184
+19063	0.184
+19064	-1.21109
+19065	-1.21109
+19066	-1.11651
+19067	0.136709
+19068	0.184
+19069	-1.37661
+19070	0.184
+19071	0.136709
+19072	0.184
+19073	0.136709
+19074	0.136709
+19075	0.184
+19076	0.184
+19077	0.136709
+19078	0.136709
+19079	0.136709
+19080	-1.21109
+19081	0.136709
+19082	0.184
+19083	0.184
+19084	0.184
+19085	0.136709
+19086	0.184
+19087	0.136709
+19088	-1.21109
+19089	-1.63672
+19090	0.136709
+19091	0.184
+19092	0.184
+19093	0.184
+19094	0.160354
+19095	0.113063
+19096	0.184
+19097	0.136709
+19098	0.184
+19099	0.136709
+19100	0.136709
+19101	0.184
+19102	0.184
+19103	0.136709
+19104	0.136709
+19105	0.136709
+19106	0.136709
+19107	0.184
+19108	0.184
+19109	0.136709
+19110	-1.57383
+19111	0.184
+19112	0.132299
+19113	0.132299
+19114	0.184
+19115	0.132299
+19116	0.132299
+19117	0.132299
+19118	0.184
+19119	0.184
+19120	0.184
+19121	0.184
+19122	-1.52213
+19123	0.184
+19124	0.132299
+19125	0.184
+19126	0.184
+19127	0.132299
+19128	0.132299
+19129	0.184
+19130	0.184
+19131	0.184
+19132	0.184
+19133	-1.52213
+19134	0.184
+19135	0.132299
+19136	0.184
+19137	0.132299
+19138	0.184
+19139	0.132299
+19140	0.184
+19141	0.132299
+19142	0.184
+19143	0.184
+19144	0.132299
+19145	0.132299
+19146	0.132299
+19147	0.184
+19148	0.132299
+19149	0.132299
+19150	0.132299
+19151	0.132299
+19152	0.184
+19153	0.132299
+19154	0.184
+19155	0.132299
+19156	0.184
+19157	0.132299
+19158	0.132299
+19159	0.184
+19160	-1.52213
+19161	0.184
+19162	0.132299
+19163	-1.13437
+19164	0.132299
+19165	0.184
+19166	0.132299
+19167	0.132299
+19168	0.132299
+19169	0.15815
+19170	0.132299
+19171	0.184
+19172	0.132299
+19173	0.132299
+19174	0.184
+19175	0.132299
+19176	0.132299
+19177	0.184
+19178	0.184
+19179	0.132299
+19180	0.184
+19181	0.184
+19182	0.132299
+19183	0.184
+19184	0.184
+19185	0.184
+19186	0.132299
+19187	0.184
+19188	0.132299
+19189	-1.13437
+19190	0.184
+19191	0.184
+19192	0.184
+19193	0.184
+19194	0.184
+19195	0.132299
+19196	0.184
+19197	0.132299
+19198	0.132299
+19199	0.184
+19200	0.184
+19201	0.132299
+19202	0.184
+19203	0.184
+19204	-1.28947
+19205	0.184
+19206	0.132299
+19207	0.132299
+19208	0.184
+19209	0.184
+19210	0.132299
+19211	0.184
+19212	0.184
+19213	0.132299
+19214	0.132299
+19215	-1.13437
+19216	0.132299
+19217	-1.13437
+19218	0.184
+19219	0.184
+19220	0.184
+19221	0.132299
+19222	0.184
+19223	0.184
+19224	0.184
+19225	0.184
+19226	0.132299
+19227	0.132299
+19228	0.184
+19229	0.184
+19230	0.184
+19231	0.184
+19232	0.132299
+19233	0.184
+19234	0.132299
+19235	0.184
+19236	0.184
+19237	0.184
+19238	0.184
+19239	0.184
+19240	0.132299
+19241	0.184
+19242	0.132299
+19243	0.184
+19244	0.132299
+19245	0.184
+19246	0.184
+19247	0.132299
+19248	0.184
+19249	-1.52213
+19250	0.132299
+19251	-1.59968
+19252	-1.26362
+19253	0.132299
+19254	0.184
+19255	0.132299
+19256	0.184
+19257	0.184
+19258	0.132299
+19259	0.184
+19260	0.184
+19261	0.184
+19262	0.132299
+19263	0.184
+19264	-1.57383
+19265	0.184
+19266	0.184
+19267	0.132299
+19268	-1.13437
+19269	-1.21192
+19270	0.184
+19271	0.132299
+19272	0.184
+19273	0.184
+19274	-1.59968
+19275	0.184
+19276	0.184
+19277	0.184
+19278	0.132299
+19279	0.184
+19280	0.184
+19281	-1.44457
+19282	-1.13437
+19283	0.184
+19284	0.184
+19285	0.132299
+19286	0.184
+19287	0.184
+19288	0.184
+19289	0.132299
+19290	0.184
+19291	0.132299
+19292	0.184
+19293	0.132299
+19294	0.184
+19295	-1.52213
+19296	0.132299
+19297	0.184
+19298	0.184
+19299	-1.52213
+19300	0.184
+19301	0.132299
+19302	0.184
+19303	0.184
+19304	-1.13437
+19305	0.132299
+19306	0.132299
+19307	0.184
+19308	0.132299
+19309	-1.21192
+19310	0.132299
+19311	0.132299
+19312	0.184
+19313	0.184
+19314	0.184
+19315	0.132299
+19316	0.184
+19317	0.132299
+19318	0.184
+19319	0.184
+19320	-1.21192
+19321	0.184
+19322	0.184
+19323	-1.52213
+19324	0.132299
+19325	0.184
+19326	0.132299
+19327	0.184
+19328	0.184
+19329	0.184
+19330	0.184
+19331	0.132299
+19332	0.132299
+19333	0.184
+19334	-1.41872
+19335	0.132299
+19336	0.184
+19337	0.132299
+19338	0.184
+19339	0.184
+19340	0.132299
+19341	0.132299
+19342	-1.47043
+19343	0.184
+19344	0.184
+19345	-1.52213
+19346	0.132299
+19347	0.184
+19348	0.184
+19349	0.132299
+19350	0.15815
+19351	0.15815
+19352	0.132299
+19353	0.15815
+19354	0.15815
+19355	0.054748
+19356	0.054748
+19357	0.054748
+19358	0.054748
+19359	0.054748
+19360	0.054748
+19361	0.054748
+19362	0.054748
+19363	0.054748
+19364	0.054748
+19365	0.054748
+19366	0.054748
+19367	0.054748
+19368	0.054748
+19369	0.054748
+19370	0.054748
+19371	0.054748
+19372	0.054748
+19373	0.054748
+19374	0.054748
+19375	0.054748
+19376	0.054748
+19377	0.054748
+19378	0.054748
+19379	0.054748
+19380	0.054748
+19381	0.054748
+19382	0.054748
+19383	0.054748
+19384	0.054748
+19385	0.054748
+19386	0.054748
+19387	0.054748
+19388	0.054748
+19389	0.054748
+19390	0.054748
+19391	0.054748
+19392	0.054748
+19393	0.054748
+19394	0.054748
+19395	0.054748
+19396	0.054748
+19397	0.054748
+19398	0.054748
+19399	0.054748
+19400	0.054748
+19401	0.054748
+19402	0.054748
+19403	0.054748
+19404	0.054748
+19405	0.054748
+19406	0.054748
+19407	0.054748
+19408	0.054748
+19409	0.054748
+19410	0.054748
+19411	0.054748
+19412	0.054748
+19413	0.054748
+19414	0.054748
+19415	-2.37519
+19416	0.054748
+19417	0.054748
+19418	0.054748
+19419	-2.11669
+19420	0.106449
+19421	0.106449
+19422	0.0805984
+19423	0.106449
+19424	0.106449
+19425	-1.41872
+19426	0.132299
+19427	0.184
+19428	0.132299
+19429	0.184
+19430	0.184
+19431	0.184
+19432	-1.21192
+19433	0.132299
+19434	0.184
+19435	0.184
+19436	0.132299
+19437	-1.13437
+19438	0.184
+19439	0.132299
+19440	0.184
+19441	0.184
+19442	0.184
+19443	0.184
+19444	-1.52213
+19445	0.132299
+19446	0.184
+19447	0.184
+19448	0.132299
+19449	0.184
+19450	0.132299
+19451	0.184
+19452	0.132299
+19453	0.184
+19454	0.132299
+19455	0.184
+19456	0.184
+19457	0.184
+19458	0.184
+19459	0.132299
+19460	-1.41872
+19461	0.184
+19462	0.184
+19463	0.184
+19464	0.132299
+19465	0.132299
+19466	-3.099
+19467	0.184
+19468	0.184
+19469	0.132299
+19470	0.184
+19471	0.184
+19472	0.184
+19473	-1.41872
+19474	0.132299
+19475	-1.31532
+19476	0.132299
+19477	0.184
+19478	0.132299
+19479	0.184
+19480	0.132299
+19481	0.132299
+19482	0.132299
+19483	0.132299
+19484	0.184
+19485	0.184
+19486	0.132299
+19487	0.132299
+19488	0.184
+19489	0.184
+19490	0.132299
+19491	0.132299
+19492	0.132299
+19493	0.184
+19494	0.132299
+19495	0.132299
+19496	0.132299
+19497	0.184
+19498	0.184
+19499	0.184
+19500	0.184
+19501	0.132299
+19502	0.132299
+19503	0.184
+19504	0.132299
+19505	0.132299
+19506	0.132299
+19507	-1.52213
+19508	-1.13437
+19509	0.184
+19510	0.132299
+19511	0.184
+19512	0.184
+19513	0.184
+19514	-1.49628
+19515	0.132299
+19516	-1.49628
+19517	0.132299
+19518	0.132299
+19519	0.184
+19520	0.184
+19521	0.184
+19522	0.132299
+19523	0.132299
+19524	0.132299
+19525	0.184
+19526	0.184
+19527	0.184
+19528	0.132299
+19529	0.184
+19530	-1.21192
+19531	0.132299
+19532	0.184
+19533	0.184
+19534	0.132299
+19535	0.184
+19536	0.184
+19537	0.132299
+19538	0.132299
+19539	0.184
+19540	-1.59968
+19541	0.132299
+19542	0.132299
+19543	0.132299
+19544	0.184
+19545	0.132299
+19546	0.132299
+19547	0.184
+19548	0.184
+19549	0.184
+19550	0.184
+19551	0.132299
+19552	0.132299
+19553	0.184
+19554	0.184
+19555	0.184
+19556	0.184
+19557	0.184
+19558	0.184
+19559	0.184
+19560	0.132299
+19561	0.184
+19562	0.132299
+19563	0.184
+19564	0.132299
+19565	0.184
+19566	0.184
+19567	0.184
+19568	0.132299
+19569	0.132299
+19570	0.132299
+19571	0.132299
+19572	0.132299
+19573	0.184
+19574	0.132299
+19575	0.184
+19576	0.132299
+19577	0.132299
+19578	0.132299
+19579	0.184
+19580	0.184
+19581	0.132299
+19582	0.184
+19583	-1.16022
+19584	-1.39287
+19585	0.184
+19586	0.132299
+19587	0.184
+19588	0.184
+19589	0.184
+19590	0.184
+19591	0.184
+19592	0.132299
+19593	0.184
+19594	0.184
+19595	0.184
+19596	0.184
+19597	0.132299
+19598	0.132299
+19599	0.132299
+19600	-1.65138
+19601	0.184
+19602	-1.13437
+19603	0.184
+19604	0.132299
+19605	0.184
+19606	0.132299
+19607	0.184
+19608	0.184
+19609	0.184
+19610	0.184
+19611	0.132299
+19612	0.184
+19613	0.132299
+19614	0.132299
+19615	0.132299
+19616	0.132299
+19617	0.184
+19618	0.132299
+19619	0.184
+19620	0.184
+19621	0.132299
+19622	0.184
+19623	0.184
+19624	0.184
+19625	0.132299
+19626	0.184
+19627	0.184
+19628	0.132299
+19629	-1.21192
+19630	0.184
+19631	0.132299
+19632	0.184
+19633	0.132299
+19634	0.184
+19635	0.184
+19636	0.132299
+19637	-1.13437
+19638	-1.13437
+19639	0.184
+19640	-1.28947
+19641	0.184
+19642	0.184
+19643	0.132299
+19644	-1.21192
+19645	0.132299
+19646	0.184
+19647	0.184
+19648	0.184
+19649	0.132299
+19650	0.132299
+19651	0.184
+19652	0.184
+19653	0.184
+19654	0.132299
+19655	0.184
+19656	0.184
+19657	0.184
+19658	0.184
+19659	0.132299
+19660	0.184
+19661	0.184
+19662	0.184
+19663	0.132299
+19664	0.184
+19665	0.132299
+19666	0.132299
+19667	0.184
+19668	0.184
+19669	0.132299
+19670	0.184
+19671	0.184
+19672	0.132299
+19673	-1.13437
+19674	0.184
+19675	0.184
+19676	0.132299
+19677	0.184
+19678	-1.39287
+19679	0.184
+19680	0.132299
+19681	0.132299
+19682	0.184
+19683	0.184
+19684	-1.52213
+19685	0.184
+19686	0.184
+19687	0.132299
+19688	0.132299
+19689	0.132299
+19690	0.132299
+19691	0.184
+19692	0.132299
+19693	0.184
+19694	0.132299
+19695	0.132299
+19696	0.184
+19697	0.184
+19698	0.132299
+19699	0.132299
+19700	0.184
+19701	0.132299
+19702	0.184
+19703	0.132299
+19704	0.184
+19705	0.132299
+19706	0.184
+19707	0.132299
+19708	0.184
+19709	0.184
+19710	0.132299
+19711	0.132299
+19712	0.132299
+19713	0.184
+19714	0.132299
+19715	0.132299
+19716	0.184
+19717	0.184
+19718	0.132299
+19719	0.184
+19720	0.184
+19721	0.184
+19722	0.184
+19723	0.132299
+19724	0.184
+19725	0.132299
+19726	0.132299
+19727	-1.21192
+19728	0.132299
+19729	0.184
+19730	0.132299
+19731	0.184
+19732	0.132299
+19733	0.132299
+19734	0.132299
+19735	0.184
+19736	0.132299
+19737	0.132299
+19738	0.132299
+19739	0.132299
+19740	0.132299
+19741	0.132299
+19742	0.184
+19743	0.132299
+19744	0.132299
+19745	0.184
+19746	0.132299
+19747	0.184
+19748	0.184
+19749	0.132299
+19750	0.184
+19751	0.184
+19752	0.132299
+19753	0.132299
+19754	0.184
+19755	0.132299
+19756	0.184
+19757	0.184
+19758	0.132299
+19759	0.132299
+19760	0.184
+19761	0.184
+19762	0.132299
+19763	0.184
+19764	0.132299
+19765	0.184
+19766	0.132299
+19767	0.184
+19768	-1.13437
+19769	0.132299
+19770	0.132299
+19771	0.184
+19772	-1.13437
+19773	0.184
+19774	0.184
+19775	0.184
+19776	-1.16022
+19777	0.184
+19778	0.184
+19779	0.0805984
+19780	0.184
+19781	0.184
+19782	0.132299
+19783	0.184
+19784	0.184
+19785	0.184
+19786	0.132299
+19787	0.184
+19788	0.184
+19789	0.184
+19790	0.132299
+19791	0.184
+19792	0.132299
+19793	0.184
+19794	0.184
+19795	0.132299
+19796	0.184
+19797	0.184
+19798	0.132299
+19799	0.132299
+19800	0.184
+19801	0.132299
+19802	0.132299
+19803	0.132299
+19804	0.132299
+19805	0.184
+19806	0.132299
+19807	0.184
+19808	0.184
+19809	0.184
+19810	0.132299
+19811	0.184
+19812	0.184
+19813	0.184
+19814	0.184
+19815	0.132299
+19816	0.184
+19817	0.132299
+19818	0.184
+19819	0.184
+19820	0.184
+19821	0.184
+19822	0.132299
+19823	0.132299
+19824	0.184
+19825	0.132299
+19826	0.132299
+19827	0.184
+19828	0.132299
+19829	0.184
+19830	0.184
+19831	0.132299
+19832	0.184
+19833	0.132299
+19834	-1.49628
+19835	0.132299
+19836	0.132299
+19837	0.184
+19838	0.184
+19839	0.184
+19840	0.132299
+19841	0.184
+19842	0.184
+19843	0.132299
+19844	0.184
+19845	0.184
+19846	0.132299
+19847	0.184
+19848	0.184
+19849	0.132299
+19850	0.184
+19851	0.132299
+19852	0.132299
+19853	0.184
+19854	0.184
+19855	0.132299
+19856	0.184
+19857	0.132299
+19858	-1.47043
+19859	0.132299
+19860	0.132299
+19861	0.132299
+19862	0.132299
+19863	0.132299
+19864	0.132299
+19865	-1.47043
+19866	0.132299
+19867	0.184
+19868	0.184
+19869	0.184
+19870	0.132299
+19871	0.132299
+19872	0.184
+19873	0.132299
+19874	0.132299
+19875	-1.26362
+19876	0.184
+19877	0.184
+19878	0.132299
+19879	-1.47043
+19880	0.184
+19881	0.184
+19882	0.184
+19883	0.132299
+19884	0.184
+19885	0.184
+19886	0.184
+19887	0.132299
+19888	0.184
+19889	-2.8405
+19890	0.132299
+19891	0.132299
+19892	0.184
+19893	0.132299
+19894	0.184
+19895	0.184
+19896	0.184
+19897	-1.21192
+19898	0.132299
+19899	0.184
+19900	0.184
+19901	0.184
+19902	0.132299
+19903	0.184
+19904	-1.13437
+19905	0.132299
+19906	0.184
+19907	0.132299
+19908	0.184
+19909	0.132299
+19910	-1.28947
+19911	0.184
+19912	0.132299
+19913	0.184
+19914	-1.26362
+19915	0.132299
+19916	0.132299
+19917	0.184
+19918	-1.52213
+19919	0.184
+19920	-1.49628
+19921	0.132299
+19922	0.184
+19923	-1.59968
+19924	0.132299
+19925	0.184
+19926	0.184
+19927	0.132299
+19928	0.132299
+19929	0.132299
+19930	0.132299
+19931	0.184
+19932	0.184
+19933	0.132299
+19934	0.184
+19935	0.132299
+19936	0.184
+19937	0.184
+19938	0.132299
+19939	-1.21192
+19940	0.132299
+19941	0.184
+19942	0.184
+19943	0.132299
+19944	0.184
+19945	-1.13437
+19946	0.132299
+19947	0.184
+19948	0.184
+19949	0.132299
+19950	0.184
+19951	0.132299
+19952	0.184
+19953	0.184
+19954	0.184
+19955	0.184
+19956	0.184
+19957	0.132299
+19958	0.184
+19959	0.132299
+19960	0.184
+19961	0.184
+19962	0.184
+19963	0.132299
+19964	0.184
+19965	0.184
+19966	0.184
+19967	0.132299
+19968	0.132299
+19969	0.184
+19970	0.132299
+19971	0.184
+19972	0.132299
+19973	0.184
+19974	0.132299
+19975	0.184
+19976	0.132299
+19977	0.184
+19978	0.184
+19979	0.184
+19980	0.184
+19981	0.132299
+19982	0.184
+19983	0.184
+19984	0.184
+19985	0.132299
+19986	0.184
+19987	0.132299
+19988	0.132299
+19989	0.132299
+19990	0.184
+19991	0.184
+19992	0.184
+19993	0.132299
+19994	0.184
+19995	0.184
+19996	0.132299
+19997	0.184
+19998	0.132299
+19999	0.184
+20000	0.132299
+20001	0.184
+20002	0.184
+20003	0.132299
+20004	0.184
+20005	0.184
+20006	0.132299
+20007	0.184
+20008	0.184
+20009	0.132299
+20010	0.184
+20011	0.184
+20012	0.184
+20013	0.132299
+20014	0.184
+20015	0.132299
+20016	-1.21192
+20017	0.132299
+20018	0.184
+20019	0.184
+20020	0.132299
+20021	0.184
+20022	0.132299
+20023	0.132299
+20024	0.184
+20025	0.184
+20026	0.184
+20027	0.184
+20028	0.132299
+20029	0.184
+20030	0.132299
+20031	0.132299
+20032	0.184
+20033	0.132299
+20034	0.184
+20035	0.132299
+20036	0.184
+20037	0.132299
+20038	0.132299
+20039	0.132299
+20040	0.184
+20041	0.132299
+20042	0.132299
+20043	0.184
+20044	0.184
+20045	-1.52213
+20046	0.132299
+20047	0.132299
+20048	0.184
+20049	0.132299
+20050	0.184
+20051	0.184
+20052	0.132299
+20053	0.132299
+20054	0.184
+20055	0.184
+20056	-1.21192
+20057	0.184
+20058	0.132299
+20059	0.132299
+20060	0.184
+20061	0.132299
+20062	0.132299
+20063	0.132299
+20064	0.184
+20065	0.132299
+20066	0.184
+20067	0.184
+20068	0.184
+20069	0.184
+20070	0.132299
+20071	0.184
+20072	-1.13437
+20073	0.132299
+20074	0.132299
+20075	0.132299
+20076	0.132299
+20077	0.132299
+20078	0.132299
+20079	0.132299
+20080	0.184
+20081	0.132299
+20082	0.184
+20083	-1.28947
+20084	0.132299
+20085	0.132299
+20086	0.132299
+20087	0.184
+20088	0.184
+20089	0.132299
+20090	0.132299
+20091	0.132299
+20092	0.132299
+20093	0.132299
+20094	0.132299
+20095	0.132299
+20096	-1.41872
+20097	0.132299
+20098	0.184
+20099	0.132299
+20100	0.184
+20101	0.132299
+20102	0.184
+20103	0.132299
+20104	-1.52213
+20105	0.132299
+20106	-1.21192
+20107	0.132299
+20108	0.184
+20109	0.132299
+20110	0.132299
+20111	0.132299
+20112	0.184
+20113	0.184
+20114	0.132299
+20115	0.184
+20116	0.132299
+20117	0.132299
+20118	0.132299
+20119	0.184
+20120	0.132299
+20121	0.132299
+20122	0.132299
+20123	0.132299
+20124	0.15815
+20125	0.15815
+20126	0.15815
+20127	-1.62553
+20128	0.15815
+20129	0.15815
+20130	0.15815
+20131	0.15815
+20132	0.132299
+20133	0.15815
+20134	0.130488
+20135	0.157244
+20136	0.130488
+20137	0.157244
+20138	0.157244
+20139	0.157244
+20140	0.130488
+20141	0.157244
+20142	0.184
+20143	0.184
+20144	0.184
+20145	0.184
+20146	0.184
+20147	0.130488
+20148	0.184
+20149	0.184
+20150	0.130488
+20151	0.184
+20152	-1.44811
+20153	0.184
+20154	0.184
+20155	0.130488
+20156	-1.28757
+20157	0.184
+20158	0.130488
+20159	0.130488
+20160	-1.42135
+20161	0.130488
+20162	0.184
+20163	-1.3946
+20164	0.130488
+20165	0.184
+20166	0.130488
+20167	0.184
+20168	0.184
+20169	-1.20731
+20170	0.130488
+20171	0.130488
+20172	0.130488
+20173	0.184
+20174	0.130488
+20175	0.184
+20176	0.130488
+20177	-1.20731
+20178	0.130488
+20179	0.184
+20180	0.130488
+20181	0.130488
+20182	0.130488
+20183	0.184
+20184	0.130488
+20185	0.184
+20186	0.184
+20187	-1.20731
+20188	0.130488
+20189	0.130488
+20190	0.130488
+20191	-1.42135
+20192	-3.08022
+20193	0.130488
+20194	0.184
+20195	0.184
+20196	-1.1538
+20197	0.130488
+20198	0.184
+20199	0.184
+20200	0.130488
+20201	0.184
+20202	-1.20731
+20203	-1.12704
+20204	0.184
+20205	0.184
+20206	0.184
+20207	0.184
+20208	0.184
+20209	0.184
+20210	0.184
+20211	0.130488
+20212	-1.42135
+20213	0.130488
+20214	0.130488
+20215	0.184
+20216	-3.13373
+20217	0.130488
+20218	0.184
+20219	0.184
+20220	-1.3946
+20221	0.184
+20222	0.184
+20223	0.130488
+20224	0.184
+20225	0.130488
+20226	0.184
+20227	-1.42135
+20228	-1.12704
+20229	0.184
+20230	0.130488
+20231	0.130488
+20232	0.184
+20233	-1.20731
+20234	-1.12704
+20235	-1.26082
+20236	0.130488
+20237	0.184
+20238	0.130488
+20239	0.184
+20240	0.130488
+20241	-1.26082
+20242	0.184
+20243	0.130488
+20244	0.184
+20245	0.184
+20246	0.130488
+20247	0.130488
+20248	0.130488
+20249	0.130488
+20250	-1.42135
+20251	0.184
+20252	0.130488
+20253	-1.20731
+20254	0.184
+20255	0.184
+20256	0.184
+20257	0.130488
+20258	0.130488
+20259	0.184
+20260	0.130488
+20261	0.130488
+20262	0.130488
+20263	0.184
+20264	0.130488
+20265	0.130488
+20266	0.130488
+20267	0.130488
+20268	0.130488
+20269	0.184
+20270	-1.42135
+20271	0.130488
+20272	0.184
+20273	-1.50162
+20274	0.130488
+20275	0.184
+20276	0.130488
+20277	0.184
+20278	0.130488
+20279	0.130488
+20280	0.184
+20281	0.130488
+20282	0.130488
+20283	-1.12704
+20284	0.184
+20285	0.130488
+20286	0.184
+20287	0.184
+20288	0.130488
+20289	0.130488
+20290	0.130488
+20291	0.184
+20292	0.184
+20293	0.184
+20294	0.184
+20295	0.184
+20296	0.130488
+20297	0.130488
+20298	0.184
+20299	0.184
+20300	0.130488
+20301	0.184
+20302	0.184
+20303	0.130488
+20304	0.184
+20305	0.130488
+20306	0.184
+20307	0.130488
+20308	0.130488
+20309	0.184
+20310	0.130488
+20311	-1.3946
+20312	0.130488
+20313	-1.20731
+20314	0.130488
+20315	0.184
+20316	0.184
+20317	0.130488
+20318	0.130488
+20319	0.130488
+20320	0.130488
+20321	0.130488
+20322	0.130488
+20323	0.184
+20324	0.130488
+20325	0.184
+20326	0.130488
+20327	0.184
+20328	0.184
+20329	0.184
+20330	0.130488
+20331	0.130488
+20332	0.130488
+20333	0.130488
+20334	0.184
+20335	0.130488
+20336	0.130488
+20337	0.184
+20338	0.184
+20339	0.130488
+20340	-1.12704
+20341	-1.20731
+20342	0.184
+20343	0.184
+20344	0.184
+20345	0.184
+20346	0.184
+20347	0.130488
+20348	0.130488
+20349	0.130488
+20350	0.184
+20351	0.184
+20352	0.184
+20353	0.184
+20354	0.130488
+20355	0.184
+20356	0.130488
+20357	0.184
+20358	0.130488
+20359	0.130488
+20360	0.184
+20361	-1.3946
+20362	0.130488
+20363	0.184
+20364	0.130488
+20365	0.130488
+20366	0.130488
+20367	0.184
+20368	0.184
+20369	0.130488
+20370	0.184
+20371	0.130488
+20372	0.184
+20373	0.130488
+20374	0.130488
+20375	0.130488
+20376	0.184
+20377	0.184
+20378	0.130488
+20379	0.184
+20380	0.184
+20381	0.184
+20382	0.130488
+20383	0.130488
+20384	0.184
+20385	0.184
+20386	0.130488
+20387	0.184
+20388	0.184
+20389	0.184
+20390	0.130488
+20391	0.184
+20392	0.184
+20393	0.184
+20394	0.130488
+20395	-1.20731
+20396	0.184
+20397	0.130488
+20398	0.184
+20399	0.184
+20400	0.184
+20401	0.130488
+20402	0.184
+20403	0.130488
+20404	0.184
+20405	0.130488
+20406	0.184
+20407	0.184
+20408	0.130488
+20409	0.130488
+20410	0.184
+20411	0.184
+20412	-1.42135
+20413	0.184
+20414	0.130488
+20415	0.130488
+20416	0.184
+20417	0.130488
+20418	0.130488
+20419	0.130488
+20420	0.184
+20421	0.130488
+20422	0.130488
+20423	0.184
+20424	0.130488
+20425	0.184
+20426	0.184
+20427	-1.20731
+20428	0.184
+20429	0.184
+20430	0.130488
+20431	0.130488
+20432	0.130488
+20433	0.184
+20434	0.130488
+20435	0.130488
+20436	0.130488
+20437	0.130488
+20438	0.184
+20439	0.130488
+20440	0.184
+20441	0.184
+20442	0.184
+20443	0.184
+20444	0.184
+20445	0.184
+20446	0.130488
+20447	0.184
+20448	0.157244
+20449	0.130488
+20450	0.157244
+20451	0.130488
+20452	-1.52838
+20453	0.130488
+20454	0.157244
+20455	-1.60865
+20456	0.157244
+20457	0.157244
+20458	0.130488
+20459	0.130488
+20460	0.157244
+20461	0.157244
+20462	0.157244
+20463	0.130488
+20464	0.130488
+20465	0.130488
+20466	-1.52838
+20467	0.157244
+20468	0.130488
+20469	0.157244
+20470	0.157244
+20471	0.130488
+20472	-1.26082
+20473	0.130488
+20474	0.157244
+20475	0.130488
+20476	0.130488
+20477	0.157244
+20478	0.130488
+20479	0.130488
+20480	0.157244
+20481	0.157244
+20482	0.130488
+20483	0.130488
+20484	0.130488
+20485	0.157244
+20486	0.130488
+20487	0.130488
+20488	0.157244
+20489	0.157244
+20490	0.157244
+20491	0.130488
+20492	0.157244
+20493	0.130488
+20494	0.157244
+20495	0.130488
+20496	-1.18055
+20497	0.130488
+20498	0.130488
+20499	0.130488
+20500	0.130488
+20501	0.130488
+20502	0.130488
+20503	0.130488
+20504	0.130488
+20505	0.130488
+20506	0.130488
+20507	0.157244
+20508	0.157244
+20509	0.157244
+20510	0.157244
+20511	0.130488
+20512	0.157244
+20513	0.130488
+20514	0.157244
+20515	-1.36784
+20516	0.157244
+20517	0.130488
+20518	0.130488
+20519	0.157244
+20520	0.130488
+20521	0.157244
+20522	0.130488
+20523	0.157244
+20524	0.157244
+20525	0.130488
+20526	0.130488
+20527	0.130488
+20528	0.157244
+20529	0.130488
+20530	0.157244
+20531	0.157244
+20532	0.130488
+20533	0.130488
+20534	0.157244
+20535	0.130488
+20536	-1.26082
+20537	0.157244
+20538	0.130488
+20539	0.130488
+20540	0.130488
+20541	0.130488
+20542	0.130488
+20543	0.130488
+20544	0.130488
+20545	0.157244
+20546	0.130488
+20547	0.130488
+20548	0.157244
+20549	0.157244
+20550	0.130488
+20551	0.130488
+20552	0.157244
+20553	0.130488
+20554	0.130488
+20555	0.130488
+20556	0.130488
+20557	0.130488
+20558	0.130488
+20559	0.157244
+20560	0.130488
+20561	0.130488
+20562	0.157244
+20563	0.157244
+20564	0.157244
+20565	0.157244
+20566	0.130488
+20567	0.130488
+20568	0.157244
+20569	0.130488
+20570	0.130488
+20571	-1.26082
+20572	0.130488
+20573	0.130488
+20574	0.157244
+20575	0.157244
+20576	0.130488
+20577	0.130488
+20578	0.130488
+20579	0.130488
+20580	0.130488
+20581	0.130488
+20582	0.130488
+20583	0.0769764
+20584	0.0769764
+20585	0.0769764
+20586	0.103732
+20587	0.130488
+20588	0.130488
+20589	0.157244
+20590	-1.52838
+20591	0.157244
+20592	-1.26082
+20593	0.130488
+20594	0.130488
+20595	0.130488
+20596	0.130488
+20597	0.130488
+20598	0.130488
+20599	0.130488
+20600	-1.52838
+20601	0.130488
+20602	0.157244
+20603	0.130488
+20604	0.130488
+20605	0.157244
+20606	0.157244
+20607	0.130488
+20608	0.157244
+20609	0.157244
+20610	0.130488
+20611	0.157244
+20612	0.157244
+20613	0.157244
+20614	0.130488
+20615	0.130488
+20616	0.157244
+20617	0.130488
+20618	0.130488
+20619	0.157244
+20620	-3.214
+20621	-1.52838
+20622	0.130488
+20623	0.130488
+20624	0.130488
+20625	0.157244
+20626	0.130488
+20627	0.157244
+20628	0.130488
+20629	0.157244
+20630	0.130488
+20631	0.157244
+20632	0.130488
+20633	0.130488
+20634	0.157244
+20635	0.130488
+20636	0.157244
+20637	0.157244
+20638	0.130488
+20639	0.157244
+20640	0.130488
+20641	0.130488
+20642	0.157244
+20643	0.130488
+20644	0.130488
+20645	0.130488
+20646	0.157244
+20647	0.130488
+20648	0.157244
+20649	0.157244
+20650	0.130488
+20651	0.157244
+20652	0.157244
+20653	0.130488
+20654	0.130488
+20655	-1.26082
+20656	0.157244
+20657	0.130488
+20658	0.130488
+20659	0.157244
+20660	0.130488
+20661	0.157244
+20662	0.130488
+20663	0.130488
+20664	0.130488
+20665	0.130488
+20666	0.157244
+20667	0.130488
+20668	-1.26082
+20669	0.130488
+20670	0.130488
+20671	0.130488
+20672	0.157244
+20673	0.157244
+20674	0.130488
+20675	0.157244
+20676	0.130488
+20677	0.157244
+20678	0.130488
+20679	0.130488
+20680	0.157244
+20681	0.157244
+20682	-1.18055
+20683	0.157244
+20684	0.157244
+20685	0.130488
+20686	0.130488
+20687	-1.58189
+20688	0.130488
+20689	0.130488
+20690	0.157244
+20691	0.157244
+20692	0.130488
+20693	0.130488
+20694	0.157244
+20695	0.130488
+20696	0.130488
+20697	0.130488
+20698	0.130488
+20699	0.130488
+20700	-1.18055
+20701	-1.52838
+20702	0.157244
+20703	0.157244
+20704	0.130488
+20705	0.130488
+20706	0.130488
+20707	0.130488
+20708	0.130488
+20709	0.130488
+20710	0.130488
+20711	0.157244
+20712	0.157244
+20713	0.157244
+20714	0.130488
+20715	0.130488
+20716	0.130488
+20717	0.157244
+20718	-1.58189
+20719	0.157244
+20720	0.130488
+20721	0.130488
+20722	0.157244
+20723	0.130488
+20724	0.130488
+20725	0.130488
+20726	0.157244
+20727	0.157244
+20728	0.157244
+20729	0.157244
+20730	0.130488
+20731	0.157244
+20732	0.130488
+20733	0.157244
+20734	0.130488
+20735	0.157244
+20736	0.157244
+20737	0.130488
+20738	0.157244
+20739	0.157244
+20740	0.157244
+20741	0.157244
+20742	0.157244
+20743	-1.52838
+20744	0.157244
+20745	0.157244
+20746	0.157244
+20747	0.130488
+20748	0.157244
+20749	0.130488
+20750	0.130488
+20751	0.157244
+20752	-1.26082
+20753	0.157244
+20754	-1.71567
+20755	0.157244
+20756	0.157244
+20757	0.130488
+20758	0.130488
+20759	0.157244
+20760	0.130488
+20761	0.130488
+20762	0.157244
+20763	0.157244
+20764	-2.00998
+20765	0.130488
+20766	0.157244
+20767	0.130488
+20768	0.130488
+20769	0.130488
+20770	-1.3946
+20771	0.130488
+20772	0.130488
+20773	0.130488
+20774	0.157244
+20775	0.130488
+20776	0.157244
+20777	0.157244
+20778	0.130488
+20779	0.157244
+20780	0.157244
+20781	0.157244
+20782	0.130488
+20783	0.157244
+20784	0.157244
+20785	-1.36784
+20786	0.130488
+20787	0.157244
+20788	0.157244
+20789	0.130488
+20790	0.157244
+20791	0.130488
+20792	0.157244
+20793	0.130488
+20794	0.157244
+20795	0.130488
+20796	0.130488
+20797	-1.18055
+20798	0.157244
+20799	0.130488
+20800	0.157244
+20801	-1.6354
+20802	0.157244
+20803	0.130488
+20804	0.157244
+20805	0.157244
+20806	0.130488
+20807	0.157244
+20808	0.130488
+20809	0.157244
+20810	0.130488
+20811	0.130488
+20812	0.130488
+20813	0.130488
+20814	0.157244
+20815	0.130488
+20816	0.157244
+20817	0.130488
+20818	0.157244
+20819	-0.00329134
+20820	-0.00329134
+20821	-0.00329134
+20822	-0.00329134
+20823	-0.00329134
+20824	-0.00329134
+20825	-0.00329134
+20826	-0.00329134
+20827	-0.00329134
+20828	-0.00329134
+20829	-0.00329134
+20830	-0.00329134
+20831	-0.00329134
+20832	-0.00329134
+20833	-0.00329134
+20834	-0.00329134
+20835	-0.00329134
+20836	-0.00329134
+20837	-0.00329134
+20838	-0.00329134
+20839	-0.00329134
+20840	-0.00329134
+20841	-0.00329134
+20842	-0.00329134
+20843	-0.00329134
+20844	-0.00329134
+20845	-0.00329134
+20846	-0.00329134
+20847	-0.00329134
+20848	-0.00329134
+20849	-0.00329134
+20850	-0.00329134
+20851	-0.00329134
+20852	-0.00329134
+20853	-0.00329134
+20854	-0.00329134
+20855	-0.00329134
+20856	-0.00329134
+20857	-0.00329134
+20858	-0.00329134
+20859	-0.00329134
+20860	-0.00329134
+20861	-0.00329134
+20862	-0.00329134
+20863	-0.00329134
+20864	0.130488
+20865	0.130488
+20866	0.103732
+20867	0.130488
+20868	-1.8762
+20869	0.130488
+20870	0.130488
+20871	0.157244
+20872	0.130488
+20873	0.157244
+20874	0.130488
+20875	0.130488
+20876	0.157244
+20877	0.157244
+20878	0.157244
+20879	0.157244
+20880	0.130488
+20881	0.157244
+20882	0.157244
+20883	0.130488
+20884	0.157244
+20885	0.130488
+20886	0.157244
+20887	0.130488
+20888	0.157244
+20889	0.130488
+20890	0.157244
+20891	0.157244
+20892	0.130488
+20893	0.157244
+20894	0.130488
+20895	0.157244
+20896	0.130488
+20897	0.157244
+20898	0.157244
+20899	-1.18055
+20900	-1.36784
+20901	0.157244
+20902	0.157244
+20903	0.130488
+20904	0.157244
+20905	0.157244
+20906	0.130488
+20907	0.157244
+20908	0.157244
diff --git a/test_data/bgzf_tests/test.txt b/test_data/bgzf_tests/test.txt
new file mode 100644
index 0000000..38a0e3b
--- /dev/null
+++ b/test_data/bgzf_tests/test.txt
@@ -0,0 +1,20 @@
+begin 644 -
+M7#MX8 at E/CF1L8D+5C*2$BF]//54$09RCLJZ!&JQ)#I+^_(W,9?1?NTO#^7_5
+M=B4]A-]ARI+$]?`#D`"!W>Q+8`)3.&NIL9L%"L3?QQ8=S:'7\)WU0FGB?FUG
+M&HZ4;<4I"QU=CH^U8O\_F<OT+,=U1/64`"/>2HU at FOBLYO2KV\1)TQJYS$*8
+M!*O^1\K$YK[XNZF"Q-8,MMW-GPOYD'JER=B6!WYA,WDV`3KR;/<%#K0OQ,L*
+MRZ(LM#K2EUG94WH3JL&\^M5^]67$?@FO_FS?VBY+FYJ)I"WX[G)L=X4JF0'Q
+MGDU)V]'E0ZALRY->4 at 7N)U:8N;1".+;WT#'=QE!A>AUOCJ]F/R8_<A,:MTD2
+MFVE2F^6<.(I&V!]$=^I*!S^Z&;1!80]`"!PG4JX@@&D8EKP>?L8E(_->_"9P
+M6;T>A/<7A!"0 at N6'V,AA+GHCC\Z7J3/(<=D*FGCY%HJH+UNC+M6HPVEOYQ'W
+M4.IUE2K=X0N.I\AX^O27ME>,7.*>NG-<BM+I;"V..AQQ at W_-[AZ at 4?V1.K)8
+M-+C7-]7`LCP8/MY`2.D;95A=#=FE[74GJL">T#7Q#S_++=4[EI9U3TW$S,F6
+M7K)_\I87UF*,J9D'X%*UD!IM$)3.W"/#R.`#83^Z17H5QX&/C",?%R!ACEI[
+MGY17MK$GDIA-J9$?TJJXZ'1,)*Y^3KIO(Z4G4]OB8];N^0L<8_/\C&WPT=1W
+M7OW`L6QX5A75IO&],.2XNF?+[#2\*QYX^IU<0_)@UUXA#IICLH[%MWZ0+P\I
+M^$`D]&A0A:<T!ERG/IA4XT=@.PES,C?XB!RZ\=`W"U,U()&MX_Y.CQ:!F>83
+MV!W(_NBD&.P;W9#;23CB4HT>HBF34._SJD>BD[-..6VR6\$IZ`6<?B*:O)&^
+MK!36F6L at GX&V]>[VN)0S/%KCA'ULX(SF^GPMEQ$:X0-OF`^BF\=GI45X\P3)
+ML8N62\>P6JQG,I!BIX5<6^*#K/;RF"\1=Y:`T-W`3^U<>F"P=KK<$S.3`&O1
+MWEFNXI+`BWG,"+K,J3D-)M4MED^K4!D6 at O?_70,69A8Z_27\C8&Y`;\2-GIC
+MZ?WM7&9N#"2`XA-^S,]W%6*#![A=_(DM(=&W^^5K8M$YB"7!Q623%6#J!WK:
diff --git a/test_data/bgzf_tests/test.txt.gz b/test_data/bgzf_tests/test.txt.gz
new file mode 100644
index 0000000..11f5ede
Binary files /dev/null and b/test_data/bgzf_tests/test.txt.gz differ
diff --git a/test_data/epo_tests/epo_547_hs_mm_12way_mammals_65.chain b/test_data/epo_tests/epo_547_hs_mm_12way_mammals_65.chain
new file mode 100644
index 0000000..6da76e8
--- /dev/null
+++ b/test_data/epo_tests/epo_547_hs_mm_12way_mammals_65.chain
@@ -0,0 +1,1705 @@
+chain 0 chr21 48129895 + 33431076 33445364 chr16 98319150 + 90536377 90551568 5470000000036i0
+15 1 0
+17 106 0
+9 0 3
+0 18 0
+4 3 0
+10 0 1
+11 1 0
+34 0 2
+74 0 418
+6 1 0
+14 0 1
+4 7 0
+2 7 0
+17 3 0
+10 0 1
+13 0 1
+40 0 1
+39 10 0
+17 12 0
+2 60 0
+25 0 1
+14 5 0
+30 0 1
+11 0 1
+0 16 0
+14 14 0
+9 0 3
+29 0 795
+3 0 1
+7 0 6
+23 0 35
+20 4 0
+16 0 1
+31 1 0
+2 1 0
+39 5 0
+11 1 0
+43 0 2
+8 398 0
+7 0 1
+69 5 0
+3 1 0
+9 0 5
+10 0 1
+8 0 146
+10 6 0
+4 0 2
+48 0 10
+13 0 8
+14 1 0
+56 1 0
+8 1 0
+3 20 0
+62 0 8
+28 0 1
+45 1 0
+67 16 0
+35 1 0
+4 1 0
+108 21 0
+21 0 4
+15 1 0
+15 0 3
+23 0 1
+5 317 0
+16 0 1
+2 1 0
+86 1 0
+11 1 0
+33 0 1
+15 1 0
+9 4 0
+26 0 1
+30 1 0
+42 0 1
+23 17 0
+26 0 4
+19 101 0
+11 0 1
+23 2 0
+8 146 0
+5 0 1
+2 0 1
+20 0 3
+4 0 6
+133 5 0
+14 3 0
+14 0 4
+32 27 0
+19 0 6
+5 0 3
+14 17 0
+0 0 34
+2 4 0
+40 6 0
+1 4 0
+19 1 0
+17 0 10
+18 0 1
+26 2 0
+37 1 0
+15 1 0
+34 1 0
+64 0 31
+15 3 0
+10 0 4
+6 1 0
+3 5 0
+15 4 0
+30 1 0
+42 0 9
+27 2 0
+9 2 0
+6 2 0
+7 1 0
+4 0 3
+16 7 0
+44 0 5
+10 0 249
+53 2 0
+7 3 0
+30 7 0
+0 0 7
+51 1 0
+4 70 0
+5 37 0
+0 0 14
+25 0 1
+23 4 0
+26 0 1
+81 8 0
+22 1 0
+1 0 3038
+42 1 0
+10 9 0
+0 0 38
+0 27 0
+14 0 3
+6 2 0
+1 3 0
+14 4 0
+13 3 0
+8 5 0
+65 2 0
+13 0 1
+16 5 0
+43 3 0
+17 0 4
+3 18 0
+12 2 0
+11 0 1
+0 13 0
+0 0 10
+26 3 0
+11 1 0
+4 1 0
+10 4 0
+60 1 0
+32 3 0
+9 6 0
+44 1 0
+48 2 0
+14 8 0
+10 0 1
+71 0 1
+8 0 1
+31 5 0
+37 8 0
+5 0 1
+10 0 2
+2 0 6
+8 1 0
+37 1 0
+10 20 0
+36 1 0
+12 0 1
+24 13 0
+20 8 0
+29 1 0
+31 1 0
+176 0 1
+0 1 0
+34 2 0
+76 0 11
+1 0 1
+5 0 12
+4 0 3
+5 0 4
+12 0 6
+57 1 0
+22 0 3
+27 0 9
+81 42 0
+1 4 0
+5 3 0
+9 2 0
+48 10 0
+5 4 0
+8 0 2
+21 4 0
+18 3 0
+16 0 4
+2 0 1
+8 52 0
+8 1 0
+7 0 4
+5 0 15
+63 0 1
+0 14 0
+32 0 316
+0 479 0
+0 0 13
+2 0 561
+0 12 0
+33 1 0
+11 0 3
+9 5 0
+11 2 0
+52 1 0
+42 2 0
+51 22 0
+71 0 3
+0 1 0
+5 11 0
+1 178 0
+19 1423 0
+33 0 174
+35 0 49
+6 264 0
+9 5 0
+3 2 0
+19 1 0
+4 14 0
+14 108 0
+55 0 1
+30 3 0
+34 3 0
+21 10 0
+41 1 0
+41 0 5
+4 0 1
+6 12 0
+95 3 0
+2 0 9
+4 0 3
+28 2 0
+27 0 187
+1 0 21
+15 2 0
+62 3 0
+69 1 0
+13 0 5
+10 11 0
+8 0 2
+14 0 3
+19 4 0
+33 2 0
+114 1 0
+25 1 0
+78 0 1
+6 0 7
+46 0 1
+10 0 1
+8 10 0
+23 0 6
+4 0 2
+20 1 0
+3 2 0
+40 1 0
+25 1 0
+4 1 0
+36 0 428
+15 1 0
+40 0 3
+19 3 0
+18 4 0
+16 0 4
+50 6 0
+24 4 0
+0 0 5
+20 0 5
+38 0 3
+8 0 4
+6 0 7
+10 0 1
+11 3 0
+9 1 0
+5 1 0
+3 2 0
+10 0 4
+26 0 2
+10 0 2
+10 0 250
+3 0 2
+0 2 0
+6 494 0
+45 29 0
+6 685 0
+8 0 1
+13 0 12
+1 1 0
+16 0 1
+15 3 0
+46 6 0
+4 13 0
+6 0 1
+3 8 0
+30 4 0
+17 5 0
+25 1 0
+11 1 0
+32 43 0
+1 0 20
+55 3 0
+29 0 41
+61 20 0
+0 0 28
+19 6 0
+44 2 0
+3 1 0
+17 367 0
+17 3 0
+48 0 3
+22 6 0
+13 1 0
+9 1 0
+17 2 0
+33 4 0
+7 0 1
+3 0 1
+2 2 0
+10 0 7
+34 1 0
+54 0 2
+40 1 0
+5 8 0
+1 9 0
+0 0 19
+5 1 0
+16 10 0
+3 7 0
+25 1 0
+20 1 0
+24 9 0
+59 3 0
+15 8 0
+2 1 0
+29 4 0
+2 1 0
+16 48 0
+0 0 22
+17 0 41
+92 0 2
+12 11 0
+0 0 6
+47 0 2
+24 3 0
+13 15 0
+43 2 0
+12 20 0
+12 19 0
+8 1 0
+4 20 0
+14 0 2
+58 2 0
+46
+
+chain 0 chr21 48129895 + 31729779 31746017 chr16 98319150 + 88691418 88709653 5470000000034i0
+63 1 0
+14 298 0
+82 3 0
+78 1 0
+28 0 2
+6 1 0
+11 2 0
+4 0 1
+34 0 299
+10 0 5
+34 0 113
+19 0 4
+2 0 3
+48 6 0
+16 4 0
+83 170 0
+39 3 0
+19 0 13
+8 1 0
+10 1 0
+54 1 0
+40 13 0
+10 1 0
+24 4 0
+67 0 1
+21 6 0
+12 4 0
+2 2 0
+38 2 0
+32 0 3
+9 1 0
+28 0 4
+90 1 0
+9 1 0
+26 5 0
+6 2 0
+3 0 3
+15 1 0
+23 2 0
+30 0 325
+58 1 0
+76 0 15
+26 1 0
+69 1 0
+27 909 0
+16 0 49
+14 1 0
+31 1 0
+14 4 0
+49 0 8
+12 0 370
+14 0 175
+26 3 0
+3 0 15
+26 0 2
+9 0 6
+17 0 1548
+17 7 0
+12 22 0
+33 2 0
+13 1 0
+21 0 1
+44 1 0
+6 0 2
+42 0 191
+23 1 0
+6 1 0
+35 0 1
+9 0 1
+144 1 0
+85 1 0
+112 0 1
+3 3 0
+19 0 1
+28 9 0
+37 0 2
+42 1 0
+16 2 0
+19 0 4
+20 0 83
+43 0 2
+11 0 2
+42 0 142
+0 165 0
+3 0 6
+32 5 0
+20 27 0
+11 1826 0
+21 0 3
+36 15 0
+36 16 0
+41 0 9
+92 2 0
+10 1 0
+26 3 0
+55 0 4
+102 150 0
+0 0 354
+16 0 3
+61 0 3
+32 57 0
+13 0 1
+9 0 133
+48 1 0
+56 0 1
+63 4 0
+38 2 0
+37 7 0
+12 124 0
+14 0 113
+9 0 3
+15 0 2
+45 0 2
+7 0 67
+11 0 1
+8 0 4
+10 0 5
+5 2 0
+7 2 0
+8 0 10
+25 329 0
+8 139 0
+20 0 3
+20 0 643
+4 6 0
+0 0 7
+27 0 90
+8 0 37
+2 0 3
+7 5 0
+8 0 3
+16 0 3
+28 0 127
+13 7 0
+12 0 2
+3 0 1610
+0 761 0
+14 3 0
+4 0 4
+17 0 2
+17 2 0
+26 31 0
+22 1 0
+17 22 0
+10 0 114
+0 86 0
+10 0 3
+12 5 0
+32 5 0
+18 4 0
+41 0 1
+19 13 0
+13 5 0
+7 468 0
+10 608 0
+0 0 1363
+0 169 0
+0 0 835
+0 950 0
+39 0 1544
+0 782 0
+72 0 1
+27 65 0
+15 0 4
+22 348 0
+21 412 0
+15 0 4
+16 0 387
+11 2 0
+11 1 0
+15 26 0
+13 0 1
+68 0 1
+6 2 0
+8 0 6
+13 0 6
+15 0 8
+23 0 7
+15 0 4
+23 0 1
+49 0 3
+10 2 0
+20 1 0
+21 0 224
+21 0 2
+0 2 0
+4 0 60
+23 0 14
+5 0 1
+120 1 0
+74 3 0
+8 1 0
+20 4 0
+65 70 0
+27 2 0
+21 2 0
+469 3 0
+108 3 0
+27 0 4
+22 1 0
+35 1 0
+13 1 0
+25 0 2
+8 0 1
+17 1 0
+29 2 0
+78 1 0
+9 4 0
+12 0 3
+5 3 0
+6 0 2
+16 0 3
+13 1 0
+28 2 0
+16 0 1
+20 0 3
+0 1 0
+18 15 0
+20 0 1
+12 0 11
+10 10 0
+16 1 0
+8 26 0
+112 2 0
+7 2 0
+25 16 0
+15 1 0
+3 0 110
+6 1 0
+14 13 0
+54 0 5
+9 0 1
+2 0 9
+7 0 8
+63 5 0
+8 11 0
+12 0 4
+31 4 0
+49 2 0
+1 12 0
+45 9 0
+11 1 0
+130 2 0
+29 1 0
+18 0 5
+121 1 0
+5 0 2
+16 4 0
+27
+
+chain 0 chr21 48129895 + 28174037 28186888 chr16 98319150 + 85762652 85778955 5470000000032i0
+14 0 1
+60 0 8
+53 1 0
+29 0 50
+20 1 0
+25 1 0
+17 0 8
+7 0 2
+26 4 0
+15 0 1
+17 0 1
+22 0 1
+20 0 1
+4 0 7
+18 2 0
+11 2 0
+22 0 1
+42 2 0
+46 1 0
+18 0 8
+0 30 0
+32 0 7
+28 1 0
+17 0 132
+13 0 4
+19 0 4
+6 0 3
+5 9 0
+92 1 0
+26 0 1
+16 1 0
+10 418 0
+27 4 0
+36 0 1
+46 16 0
+0 0 31
+9 0 1
+13 1 0
+50 0 3
+15 1 0
+4 5 0
+14 5 0
+12 6 0
+19 2 0
+8 30 0
+3 2 0
+11 1 0
+41 1 0
+28 0 66
+39 11 0
+0 0 10
+67 175 0
+8 1 0
+57 5 0
+15 2 0
+1 0 3
+1 2 0
+31 12 0
+16 0 2
+3 0 10
+1 0 4
+14 3 0
+4 2 0
+16 34 0
+0 0 457
+4 16 0
+12 1 0
+144 0 2
+8 371 0
+43 2 0
+10 0 2
+46 0 2
+40 0 4
+11 0 14
+6 1 0
+36 0 1
+51 0 1
+6 4 0
+27 8 0
+40 0 1
+6 0 3
+17 6 0
+23 0 2
+14 0 9
+87 2 0
+6 2 0
+3 0 1
+0 1 0
+23 0 3
+10 1 0
+54 20 0
+14 2 0
+60 0 2
+19 0 5
+2 7 0
+2 4 0
+21 0 1
+33 1 0
+24 0 4
+14 0 1
+16 0 4
+16 0 20
+5 0 118
+109 1 0
+118 3 0
+16 2 0
+5 0 1
+37 1 0
+3 3 0
+31 0 1
+8 0 1
+34 0 1
+32 1 0
+27 0 3
+5 15 0
+5 0 85
+9 0 6
+46 1 0
+17 0 1
+2 1 0
+13 1 0
+11 0 10
+77 1 0
+22 0 1
+71 0 13
+26 0 2
+8 3 0
+1 1 0
+4 2 0
+33 6 0
+22 0 5
+0 1 0
+40 0 1
+22 0 3
+16 0 329
+9 3 0
+13 7 0
+20 4 0
+19 15 0
+17 0 26
+2 0 1
+19 1 0
+35 0 2
+47 1 0
+5 7 0
+0 0 6
+11 1 0
+11 1 0
+20 5 0
+18 0 3
+7 0 7
+6 2 0
+12 0 9
+19 1 0
+71 4 0
+20 2 0
+16 0 1
+9 2 0
+18 2 0
+12 1 0
+41 3 0
+30 4 0
+24 16 0
+58 2 0
+20 2 0
+55 5 0
+34 1 0
+3 1 0
+23 1 0
+12 9 0
+14 6 0
+24 0 4
+38 0 1
+11 0 5
+9 0 3
+32 0 1
+34 14 0
+29 1 0
+7 5 0
+5 317 0
+3 3 0
+7 56 0
+19 10 0
+28 0 4
+12 0 2
+44 192 0
+0 0 78
+2 1 0
+0 0 5
+0 1 0
+10 134 0
+3 1 0
+13 0 4
+2 0 7
+12 5 0
+1 3 0
+48 0 1
+46 0 1
+5 2 0
+11 0 4
+1 0 15
+24 1 0
+7 1 0
+12 0 4
+15 1 0
+18 0 1
+30 0 2
+11 31 0
+153 18 0
+22 0 4
+60 0 3
+48 1 0
+6 0 2
+13 0 201
+1 0 23
+22 0 3
+5 4 0
+16 2 0
+19 0 109
+6 0 20
+12 0 1
+82 0 1
+28 0 1
+67 1 0
+34 3 0
+12 4 0
+44 0 7
+75 1 0
+27 0 1
+6 0 1
+67 0 1
+15 4 0
+70 0 1
+33 1 0
+50 2 0
+15 0 1
+21 0 1
+23 0 1
+32 0 3
+98 1 0
+14 0 1
+8 0 1
+84 0 6
+49 0 2
+0 3 0
+5 2 0
+14 0 1
+0 1 0
+7 0 1
+18 1 0
+6 23 0
+6 1 0
+4 4 0
+16 0 2
+13 0 2
+26 1 0
+30 4 0
+18 0 1
+2 4 0
+26 4 0
+71 1 0
+43 0 3
+20 21 0
+0 0 7
+47 5 0
+5 3 0
+7 1 0
+9 2 0
+11 0 1
+28 0 2
+20 0 592
+24 0 17
+7 1 0
+8 1 0
+38 0 1
+9 0 193
+39 0 18
+4 0 4
+19 5 0
+1 3 0
+17 2 0
+17 1 0
+22 41 0
+15 2 0
+10 0 2
+32 0 39
+6 0 4
+50 0 2
+5 0 11
+29 2 0
+39 0 1
+0 1 0
+105 4 0
+58 2 0
+138 0 3
+0 3 0
+168 0 3
+153 7 0
+19 10 0
+23 8 0
+6 0 353
+1 0 3
+71 47 0
+3 0 1
+29 1 0
+59 0 1454
+7 0 1
+22 1 0
+27 0 3
+4 1 0
+125 1 0
+22 0 7
+5 9 0
+0 0 1211
+0 102 0
+41 0 1
+48 5 0
+6 0 13
+20 4 0
+29 0 1
+10 9 0
+14 9 0
+46 1 0
+12 4 0
+57 0 2
+2 0 1
+26 1 0
+58 1 0
+46 1 0
+44 0 4
+17 0 25
+8 0 1
+47 2 0
+1 7 0
+25 0 82
+13 0 4
+2 0 6
+64 1 0
+53 10 0
+51 28 0
+43 0 1
+10 0 7
+33 3 0
+17 0 8
+7 0 2
+9 0 4
+34 0 2
+21 1 0
+5 2 0
+12 1 0
+41 4 0
+37 0 14
+15 0 2
+12 0 7
+31 0 4
+63 4 0
+6 0 2
+31 106 0
+0 0 51
+46 0 8
+14 176 0
+0 0 175
+0 283 0
+0 0 53
+0 125 0
+23 13 0
+56 5 0
+33 4 0
+10 4 0
+6 0 356
+34 0 26
+3 2 0
+5 0 5
+8 0 1
+13 3 0
+4 1 0
+20 7 0
+8 10 0
+42 1 0
+5 0 1
+11 11 0
+0 0 7
+29 0 3
+6 1 0
+40 37 0
+24 1 0
+19 12 0
+42
+
+chain 0 chr21 48129895 + 27838554 27852668 chr16 98319150 + 85453121 85465856 5470000000042i0
+68 2 0
+61 0 2
+10 6 0
+30 1 0
+82 1 0
+81 1 0
+11 2 0
+11 1 0
+48 0 4
+15 4 0
+19 2 0
+38 0 2
+48 1 0
+42 1 0
+36 3 0
+9 2 0
+44 5 0
+1 1 0
+11 1 0
+38 0 2
+20 7 0
+69 5 0
+130 3 0
+89 1 0
+14 1 0
+16 0 1
+30 6 0
+16 0 8
+23 9 0
+8 0 3
+25 23 0
+17 3 0
+1 1 0
+14 6 0
+11 3 0
+28 2 0
+28 53 0
+24 3 0
+6 0 2
+13 0 1
+106 6 0
+29 5 0
+38 15 0
+41 0 32
+27 0 15
+6 0 18
+1 0 2539
+24 1 0
+15 0 1
+90 4 0
+53 11 0
+10 1 0
+59 1 0
+85 1 0
+12 6 0
+20 1 0
+4 3 0
+4 2 0
+44 8 0
+7 0 2
+0 1 0
+230 0 1
+0 2 0
+2 1 0
+17 1 0
+2 4 0
+6 0 1
+11 1 0
+56 0 2
+66 0 3
+16 1 0
+34 9 0
+5 0 3
+8 1 0
+12 0 1
+12 0 3
+32 0 1
+19 0 1
+27 0 2
+21 0 573
+0 13 0
+1 0 23
+16 14 0
+43 0 2
+12 3 0
+14 8 0
+57 0 1
+8 2 0
+22 3 0
+27 2 0
+40 0 1
+15 43 0
+70 1 0
+4 0 1
+6 7 0
+10 0 1
+9 344 0
+59 1 0
+29 1 0
+20 2 0
+8 49 0
+44 1 0
+36 7 0
+98 105 0
+14 1 0
+25 0 2
+36 382 0
+15 1 0
+39 1 0
+40 1 0
+86 6 0
+49 36 0
+22 9 0
+56 2 0
+20 0 2
+47 2 0
+31 0 1
+18 0 15
+14 0 1
+56 1 0
+98 0 17
+20 0 6
+5 1 0
+44 0 1
+38 0 2
+41 1 0
+4 2 0
+47 5 0
+17 1 0
+17 0 2
+12 1 0
+7 3 0
+23 4 0
+17 0 1
+11 1 0
+4 0 1
+31 0 8
+15 1 0
+52 0 1
+41 0 1
+65 0 177
+74 49 0
+80 0 289
+0 3 0
+0 0 105
+7 2 0
+61 8 0
+20 0 2
+9 0 2
+16 5 0
+20 0 1
+17 0 1
+17 1 0
+22 1 0
+8 3 0
+7 0 7
+16 0 1
+11 4 0
+10 8 0
+20 0 1
+2 0 5
+20 1 0
+25 0 9
+17 7 0
+12 0 4
+4 0 1
+11 14 0
+10 1 0
+23 0 3
+1 7 0
+4 4 0
+24 0 7
+13 0 1
+14 3 0
+28 0 1
+16 16 0
+9 0 5
+12 0 2
+21 0 3
+24 0 18
+5 0 4
+7 0 12
+23 0 1
+17 2235 0
+28 2 0
+38 1 0
+48 1 0
+35 10 0
+7 0 2
+91 116 0
+1 5 0
+18 0 9
+42 1 0
+0 0 166
+8 7 0
+28 0 13
+9 1 0
+6 1 0
+6 0 2
+5 0 1
+54 18 0
+11 6 0
+14 0 1
+15 0 11
+12 3 0
+15 0 7
+1 0 913
+31 167 0
+0 0 158
+42 0 3
+28 171 0
+0 0 459
+47 690 0
+1 743 0
+7 0 1
+0 1 0
+12 2 0
+1 0 191
+13 1 0
+2 0 22
+0 368 0
+10 0 4
+11 107 0
+4 24 0
+19 0 22
+11 1 0
+11 1214 0
+5 20 0
+0 0 203
+67 1 0
+55 2 0
+53 2 0
+20 151 0
+17 1 0
+28 1 0
+86 0 4
+3 1 0
+87 12 0
+25 0 1
+0 3 0
+13 0 1
+14 1 0
+2 2 0
+10 0 2
+66 7 0
+46 0 4
+37 3 0
+66
+
+chain 0 chr21 48129895 + 31588806 31605740 chr16 98319150 - 9742397 9755312 5470000000030i0
+61 1 0
+13 0 2
+7 5 0
+20 1 0
+49 1 0
+27 0 1
+28 0 4
+24 1328 0
+49 1 0
+0 0 1
+10 8 0
+1 1 0
+2 7 0
+17 5 0
+26 2 0
+1 2 0
+29 299 0
+1 28 0
+5 4 0
+11 1 0
+12 0 8
+15 44 0
+10 0 5
+37 10 0
+6 0 1
+2 0 7
+32 6 0
+5 0 5
+5 7 0
+28 5 0
+9 1 0
+5 0 1
+30 0 1
+17 2 0
+50 2 0
+5 12 0
+16 1 0
+12 0 4
+22 7 0
+19 14 0
+18 1 0
+23 0 3
+68 18 0
+12 0 5
+16 1 0
+7 1 0
+1 7 0
+26 87 0
+17 56 0
+18 3 0
+54 0 1
+13 0 202
+9 0 2
+18 4 0
+0 0 2
+0 2 0
+18 5 0
+7 418 0
+8 2 0
+5 0 6
+0 12 0
+12 1 0
+7 0 19
+0 47 0
+1 0 2
+0 2 0
+8 0 5
+0 16 0
+28 37 0
+19 2 0
+20 0 4
+15 0 4
+14 3 0
+17 2 0
+5 5 0
+28 28 0
+77 0 9
+40 11 0
+10 0 1
+18 0 3
+15 0 1
+8 0 6
+1 68 0
+58 0 14
+24 0 3
+12 0 2
+19 0 154
+68 2 0
+33 1 0
+29 16 0
+4 1 0
+21 6 0
+9 6 0
+62 1 0
+20 3 0
+124 29 0
+1 317 0
+20 10 0
+28 0 7
+9 2 0
+23 2 0
+13 0 5
+8 8 0
+4 0 3
+1 0 2
+11 0 4
+8 1 0
+51 4 0
+2 30 0
+12 0 1
+3 0 2
+36 17 0
+3 2 0
+3 15 0
+38 6 0
+12 0 8
+10 1 0
+2 0 4
+16 9 0
+13 0 61
+15 0 6
+0 272 0
+5 0 2
+19 15 0
+5 0 2
+55 6 0
+7 15 0
+7 0 2
+9 0 8
+26 2 0
+13 3 0
+74 4 0
+28 1 0
+7 0 1
+36 0 4
+10 0 1
+7 9 0
+33 0 3
+8 0 1
+49 0 10
+4 0 3
+81 0 4
+16 0 4
+98 0 2
+23 0 4
+15 2 0
+23 1 0
+46 0 1
+2 0 2
+22 0 3
+29 1 0
+30 4 0
+16 1 0
+88 14 0
+7 1 0
+49 0 1
+8 0 1
+24 4 0
+23 351 0
+140 3 0
+29 0 34
+12 1 0
+36 0 5
+4 0 4
+45 0 1
+4 0 3
+11 0 6
+15 0 66
+17 30 0
+19 0 2
+7 0 19
+2 0 5
+21 1 0
+5 2 0
+8 459 0
+14 1 0
+32 1 0
+31 1 0
+11 2 0
+32 0 1
+87 9 0
+34 2 0
+48 0 3
+63 3 0
+43 10 0
+2 0 60
+4 82 0
+15 1 0
+15 26 0
+18 1 0
+7 0 2
+4 3 0
+21 2 0
+5 4 0
+15 3 0
+25 1 0
+41 0 2
+29 0 1
+16 5 0
+37 0 1
+25 1 0
+77 1 0
+17 0 1
+3 1 0
+33 0 1
+65 3 0
+28 0 2
+6 2 0
+1 12 0
+29 2 0
+20 1 0
+20 10 0
+25 0 2
+18 2 0
+16 15 0
+17 0 6
+6 0 5
+4 0 10
+22 1 0
+24 8 0
+24 8 0
+7 0 6
+5 0 1
+14 0 85
+46 5 0
+18 0 7
+18 1 0
+102 4 0
+11 0 3
+123 2 0
+8 0 10
+29 4 0
+26 4 0
+19 5 0
+24 3 0
+19 6 0
+7 3 0
+8 0 3
+19 0 59
+16 1 0
+23 26 0
+4 1 0
+42 0 14
+0 10 0
+2 0 1
+8 1 0
+3 1 0
+8 0 1
+10 0 9
+12 0 344
+8 1 0
+39 0 2
+34 0 4
+27 1 0
+47 8 0
+24 3 0
+8 0 3
+5 3 0
+45 6 0
+39 4 0
+17 0 5
+9 1 0
+1 3 0
+238 12 0
+31 0 1
+32 1 0
+10 7 0
+0 0 2
+20 14 0
+12 2 0
+20 4 0
+8 7 0
+44 1 0
+40 1 0
+27 1 0
+11 4 0
+12 1 0
+1 0 1
+9 0 1
+0 3 0
+49 0 1
+6 17 0
+17 14 0
+10 0 2
+5 1 0
+1 1 0
+12 1 0
+4 0 2
+32 1 0
+16 0 30
+6 1 0
+9 4 0
+10 0 1
+49 0 1
+13 0 3
+25 1 0
+18 0 3
+4 0 1
+20 0 1
+17 0 3
+24 2 0
+11 6 0
+43 0 3
+36 0 9
+13 0 1
+24 1 0
+80 0 3
+24 10 0
+22 4 0
+4 1 0
+19 3 0
+14 0 1
+26 0 2
+0 12 0
+11 0 1
+39 2 0
+23 6 0
+20 1 0
+35 3 0
+7 1 0
+11 0 117
+27 1 0
+14 16 0
+45 1 0
+32 2 0
+5 41 0
+6 2 0
+10 1 0
+27 5 0
+19 1 0
+59 0 4
+9 50 0
+1 1 0
+13 0 3
+9 1 0
+30 0 543
+6 1 0
+8 0 1
+35 0 3
+20 0 6
+0 18 0
+17 0 1
+18 2 0
+3 9 0
+69 1 0
+16 1 0
+7 13 0
+18 0 5
+6 2 0
+17 1 0
+7 1 0
+12 0 44
+31 3 0
+10 1 0
+16 40 0
+25 10 0
+27 9 0
+16 0 1
+10 3 0
+31 1 0
+21 0 4
+11 2 0
+8 2 0
+1 60 0
+16 134 0
+17 5 0
+27 1 0
+14 0 230
+14 0 5
+18 0 7
+3 0 126
+6 0 483
+24 0 126
+15 0 2
+3 0 1
+5 0 9
+6 7 0
+6 5 0
+49 6 0
+31 6 0
+3 2 0
+26 1 0
+64 1 0
+30 0 26
+0 356 0
+5 3 0
+43 1 0
+0 0 1
+22 54 0
+50 4 0
+23 1 0
+2 13 0
+27 0 2
+5 2 0
+3 1 0
+21 0 1
+50 4 0
+18 0 1
+2 0 6
+14 4 0
+63 1 0
+33 1 0
+24 0 319
+12 0 8
+1 0 6
+8 1 0
+8 1897 0
+2 4 0
+1 8 0
+79 1 0
+23 6 0
+7 0 1
+37 3 0
+21 4 0
+7 0 4
+1 0 2
+11 0 1
+31 23 0
+1 1 0
+2 1 0
+15 1 0
+32 0 2
+12 0 4
+30 1 0
+15 1 0
+12 1 0
+6 0 19
+20 1 0
+11 0 4
+19 3 0
+13 5 0
+6 0 11
+23 0 4
+20 2 0
+6 0 8
+0 1 0
+10 0 3
+34 1 0
+20 0 1
+15 0 1
+38 0 1
+38 2 0
+8 0 2
+37
+
diff --git a/test_data/epo_tests/epo_547_hs_mm_12way_mammals_65.out b/test_data/epo_tests/epo_547_hs_mm_12way_mammals_65.out
new file mode 100644
index 0000000..28bfa70
--- /dev/null
+++ b/test_data/epo_tests/epo_547_hs_mm_12way_mammals_65.out
@@ -0,0 +1,10 @@
+homo_sapiens	5470000000030	21	31588807	31605740	-1	37M2D48MD31M3D7MD15MD3MD52M3D11M11D19MD9M4D23M12D22M5D12M33D12M4D11M4D15M22D6M19D41M2D5M4D8M3D12M4D12M2D107MD6M43D5M2DM4D9M49D2M2D35MD8M2D18MD4MD14MD29M5D25M3D6M2D12M5D32M5D56M444D49MD36MD12M9D17M5D9MD5M2D28M3DM5D15M2D15M9D41MD52MD14MD4MD20M89D26M10D14MD121MD19MD113MD37M3D266MD11M95D43M18D29M4D63M217D57M38D19MD51MD25MD55M2D28M82D84M4D83MD20M52D60MD26MDMDM2D19MD50M9D8M3D6M343D10M11D43M4D2M4D28M5D3M5D56M44D7MD28MD35M4D2M6DM8D12M325D126MD14 [...]
+mus_musculus	5470000000030	16	88563839	88576753	1	47M2D70M3D27MD17MD47M4D14M2D11MD47MD6M5D11M5D2M3D7M33D27M5D14M22D31MD12MD15MD5M2D5M4D8M3D62MD15MD2MDM23D38M43D19M55D21M3D11MD8M2D23MD3M6D5MD18MD10M5D25M3D6M2D12M5D26M13DM4D2M3442D8MD6M4D184M3D91M3D97MD33MD63M5D22M22D19M4D26MD46MD3M2D34M38D2MD23M4D50M112D23MD43M3D5M381D43M2D13MD27M912D37M2D26M2D3M21D28M10D3M6D4MD38MD7M5D6M7D16M221D4M13D16M2D65MD70M4D199M3D31M11D125MD112M5D162MD7M2D290MD27M6D17M137D11M3D5M79DM2D8M96D15M7D21MD9M3DM7D3M228D18 [...]
+homo_sapiens	5470000000032	21	28174038	28186888	1	14MD60M8D74M3D9M61D3M29D44M15D17M8D5MD2M2D40M8D5MD17MD22MD20MD4M7D43M4D4M7D8M19DM20D2M5D12M3D94M9D40M5D11M2D11M7D46M148D13M4D19M4D6M3D2M8DM5DM5D5MD30M2D20M31D4M6D70MD59M4D6M3D32MD22M2D31M3D112M36D86MD57M49D10M292D18M4D62M117D10M6D7MD7M8D9M133D17MD10M2D19M31D9MD64M3D14M2D7M255D9M23D15MD11MD64MD59MDMD28M66D8MD42M10D117MD102M3D36M6D42M188D34M3D62M2D3M10DM4D73M457D177M2D79M25D249M10D23M10D67M3D5M4D3MD8M2D46M2D36M4D4M4D11M14D21M2D22MD50M286DMD [...]
+mus_musculus	5470000000032	16	85762653	85778955	1	136MD20M3D9M11D53M29D17MD25M16D30MD30M4D10M8D97M2D11M2D10M4D4M7D8M18D2M20D2M5D12M3D27M2D46MD26M31D10M5D11M2D46MD63M8D63M8D74M8DM5DM5DM10D25M2D20M31D4M6D43MD43MD10M813D27M4D19M117D10M6D15M8D9M133D17MD10M2D3M16D54MD67M2DMD4M260D5M23D9M5DMD11M7D19M2D8M31D3M2D11MD41M3D102MD31M11D77M179D8MD4M6D42M188D11M5D15M2D5M2D31M12D50M3D4M2D16M34D461M16D12MD154M416D39M3D4M6D2MD94M4D39MD14M2D73M286D8M4D27M8D47M4D20M6D24M4D88MD10M2D13M2D6M2D2MD2MD36MDMD24MD [...]
+mus_musculus	5470000000034	16	88691419	88709653	1	62MDMDM950D13M446D82M3D78MD2MD9M2D11M7D14MD11M2D13MD494M98D21MD2MD7M17DM2D37M4DM114D16M9D7M8D18MD58M172D35M203D4M6D13M1104D27MD9M5DMD30MD12M2D12MD40M13D10MD24M4D69M4D20M7DM280D11M4D2M2D24MD14M2D4M2D8M593D11M271D13MD8MD6M6D116MD9MD26M5D6M2D19M4D2MD23M2D362M4D34M2D17MD96M3D21MD6M3D25M2D10M5D2M2DM2D25MD27M1248DMDM3D77MD17MD2MD12M2D14M8D38M311D28M7D376MD212M3DM2D47MD18MD1577M7D12M30D33M2D13MD66MD6MD258MD6MD44M4D72MD6MD68MD14MD71MD116M3D48M9D1 [...]
+homo_sapiens	5470000000034	21	31729780	31746017	1	62MD3M950D25M3D111MD7M2D158M142D176MD9M2D11M7D6M2D24MD8MD26M299D10M5D34M113D7M98D12M4D2M4D2MD7M17DM2D37M4D7M108D16M2D4M3D7M8D18MD210M2D53M203D4M3D16M1104D6M13D18M5D32MD12M2D172MDM4D20MD7M280D43MD20M2D8M593D11M271D9M3DMD15M6D22M4D143M3D13M4D58M325D7M4D34M2D94M15D5M3D28M3D25M2D10M5D2M2DM2D80MD19MD145M2D79MD41M246D57MD33M14D155M10D74M10DM8D19M5D11MD15MD80M8D12M2DM2D49M23D68M3D24MDM3D14M49D32MD2MD13MD18M4D38M311D11M8D9M7D3M370D3MD11M175D30M2D [...]
+homo_sapiens	5470000000036	21	33431077	33445364	1	4744D148M3D35MD46M13D2M2D61MD11M426D3M2D12MD6MD50MD13MD5M3D32MD3MD29M7D2MD134MD4MD14M3D12M6D19MD2MD9MD53M3D29M796D3MD7M6D14MD8M13DM35D3MD24MD13MD35MD99M2D80MD256MD34M788D43MD6M320D12M3D37M1027D24M3DMD7M5D6M2D4MD8M264D20M2D48M10D5M3D8M8D12M233D58MD20M81D71MD5M8D28MD90M3D41M233D48MD118MD4M3D19M4D31M3D3M9D20MD40M5D151M14D93MD54MD22M73D65MD24MD22MD2MD10M2D10M9D35MD73MD30MD36M4D40M864D6MD46M13D6M6D33MD53M4D13MD118MD2MD15M12D3M207D2M3D2MDM7DM6D [...]
+mus_musculus	5470000000036	16	90533789	90551568	1	70M98D34M9D64MD16M12D3MD25M39D238M14D78M3D57M408D78MD70MD3M302D94M4D60M94D86MD6M2D2M2D100MD19M47D62MD27M343D230MD40M5D26M198D18M210D39M9D89M6D56MD16M111D13M3D18M2D104M4DM4D3MD11M2DMDMD24M2D167M37D31M7D54M13D32M153D438MD17M106D12M18D4M3D22MD36M11D2M2D61MD35M2D170M6D227M2D3MD8MD11M7D2M7D17M3D30M3D32MD33M7D2MD8M10D17M12D2M60D30MD10M8D11M6D22MD10M16D14M14D157MD710MD8M13D39MD17M4D3MD45MD2M2D39M5D11MD53M1188D14M320D12M3D37M1027D14M5D3MDM3DMD18M [...]
+mus_musculus	5470000000042	16	85453122	85465856	1	40M2D28M2D73M6D23MD7MD8MD63MD11MD2M2D7M6D72MD10MDM2D11M3D10MD9MD48M4D19M2D88MD32M4D10MD14M2D22M3D9M2D44M5DMD11MD60M7D31M213D9MD29M5D60M13D8M260D49M5165D13M3D25MD4MD4MD23M2D16M269D17MD14MD47M6D9MD38M9D19M2D11M12D6M23D11MD2M5D2MD2M3DMD14M6D11M3D26M15D2M2D28M53D4MD20M9DM3D8M2D72MD47M6D21MD8M5D38M15D34M2D7M59D80M4D29M4D142M5D67MD486M19D408M5D25M386D150M7D96M4D137M4D74M6D93MD23M3D98M2D27MD384M12D24M9D70MD174M3D9M2D66M23D61MD24MD21M4D53M11D10MD [...]
+homo_sapiens	5470000000042	21	27838555	27852668	1	40M2D91M2D39MD16MD63MD14M2D7M6D83MD14M2D11MD9MD29M4D78M2D81M4D25M2D137M2D58M213D9MD94M13D8M260D49M5165D41MD4MD4MD23M2D16M269D49MD45MD7M8D40M3D8M2D11M12D40MD2M5D2MD67M15D89MD20M6D4M3D5M2DM2D12MD59MD74MD100M2D7M91D27M15D6M22DM3014D24M22D16MD45MD24MD183M220D63MD39MD9M5D41MD22M5D8M12D221M13D2MD35MD45M479D21M34D2M2D66M3D65M3D4M3D5M7D9MD3MD12M3D11M4D16MD5MD7MD7M4D3MD2MD27M2DMD8M3DM421D11M641D11M2D3M23D12M11D51M2DM2D9M2D67MD16MD4MD4M2D3MD3MD51MD [...]
diff --git a/test_data/epo_tests/hg19.chrom.sizes b/test_data/epo_tests/hg19.chrom.sizes
new file mode 100644
index 0000000..050d5c6
--- /dev/null
+++ b/test_data/epo_tests/hg19.chrom.sizes
@@ -0,0 +1,93 @@
+chr1	249250621
+chr2	243199373
+chr3	198022430
+chr4	191154276
+chr5	180915260
+chr6	171115067
+chr7	159138663
+chrX	155270560
+chr8	146364022
+chr9	141213431
+chr10	135534747
+chr11	135006516
+chr12	133851895
+chr13	115169878
+chr14	107349540
+chr15	102531392
+chr16	90354753
+chr17	81195210
+chr18	78077248
+chr20	63025520
+chrY	59373566
+chr19	59128983
+chr22	51304566
+chr21	48129895
+chr6_ssto_hap7	4928567
+chr6_mcf_hap5	4833398
+chr6_cox_hap2	4795371
+chr6_mann_hap4	4683263
+chr6_apd_hap1	4622290
+chr6_qbl_hap6	4611984
+chr6_dbb_hap3	4610396
+chr17_ctg5_hap1	1680828
+chr4_ctg9_hap1	590426
+chr1_gl000192_random	547496
+chrUn_gl000225	211173
+chr4_gl000194_random	191469
+chr4_gl000193_random	189789
+chr9_gl000200_random	187035
+chrUn_gl000222	186861
+chrUn_gl000212	186858
+chr7_gl000195_random	182896
+chrUn_gl000223	180455
+chrUn_gl000224	179693
+chrUn_gl000219	179198
+chr17_gl000205_random	174588
+chrUn_gl000215	172545
+chrUn_gl000216	172294
+chrUn_gl000217	172149
+chr9_gl000199_random	169874
+chrUn_gl000211	166566
+chrUn_gl000213	164239
+chrUn_gl000220	161802
+chrUn_gl000218	161147
+chr19_gl000209_random	159169
+chrUn_gl000221	155397
+chrUn_gl000214	137718
+chrUn_gl000228	129120
+chrUn_gl000227	128374
+chr1_gl000191_random	106433
+chr19_gl000208_random	92689
+chr9_gl000198_random	90085
+chr17_gl000204_random	81310
+chrUn_gl000233	45941
+chrUn_gl000237	45867
+chrUn_gl000230	43691
+chrUn_gl000242	43523
+chrUn_gl000243	43341
+chrUn_gl000241	42152
+chrUn_gl000236	41934
+chrUn_gl000240	41933
+chr17_gl000206_random	41001
+chrUn_gl000232	40652
+chrUn_gl000234	40531
+chr11_gl000202_random	40103
+chrUn_gl000238	39939
+chrUn_gl000244	39929
+chrUn_gl000248	39786
+chr8_gl000196_random	38914
+chrUn_gl000249	38502
+chrUn_gl000246	38154
+chr17_gl000203_random	37498
+chr8_gl000197_random	37175
+chrUn_gl000245	36651
+chrUn_gl000247	36422
+chr9_gl000201_random	36148
+chrUn_gl000235	34474
+chrUn_gl000239	33824
+chr21_gl000210_random	27682
+chrUn_gl000231	27386
+chrUn_gl000229	19913
+chrM	16571
+chrUn_gl000226	15008
+chr18_gl000207_random	4262
diff --git a/test_data/epo_tests/hg19.mm9.rBest.chain.gz b/test_data/epo_tests/hg19.mm9.rBest.chain.gz
new file mode 100644
index 0000000..f3d675a
Binary files /dev/null and b/test_data/epo_tests/hg19.mm9.rBest.chain.gz differ
diff --git a/test_data/epo_tests/hg19_one_peak.bed b/test_data/epo_tests/hg19_one_peak.bed
new file mode 100644
index 0000000..525472c
--- /dev/null
+++ b/test_data/epo_tests/hg19_one_peak.bed
@@ -0,0 +1 @@
+chr16	72821045	72821349	1
diff --git a/test_data/epo_tests/hg19_one_peak.mapped.bed b/test_data/epo_tests/hg19_one_peak.mapped.bed
new file mode 100644
index 0000000..2e23407
--- /dev/null
+++ b/test_data/epo_tests/hg19_one_peak.mapped.bed
@@ -0,0 +1 @@
+chr8	111480715	111481019	1
diff --git a/test_data/epo_tests/hpeaks.bed b/test_data/epo_tests/hpeaks.bed
new file mode 100644
index 0000000..44deff2
--- /dev/null
+++ b/test_data/epo_tests/hpeaks.bed
@@ -0,0 +1,5 @@
+chr21	27838555	27838629	peak1
+chr21	27839679	27839785	peak2
+chr21	27839723	27839727	peak3
+chr21	31588807	31588855	peak4
+chr21	27852660	28174039	peak5
diff --git a/test_data/epo_tests/hpeaks.mapped.bed12 b/test_data/epo_tests/hpeaks.mapped.bed12
new file mode 100644
index 0000000..993df26
--- /dev/null
+++ b/test_data/epo_tests/hpeaks.mapped.bed12
@@ -0,0 +1,3 @@
+chr16	85453122	85453194	peak1	1000	+	85453122	85453194	0,0,0	1	72	0
+chr16	85454203	85454286	peak2	1000	+	85454203	85454286	0,0,0	3	16,31,25	0,24,58
+chr16	88576704	88576752	peak4	1000	+	88576704	88576752	0,0,0	1	48	0
diff --git a/test_data/epo_tests/hpeaks.mapped.bed4 b/test_data/epo_tests/hpeaks.mapped.bed4
new file mode 100644
index 0000000..e1a6fb1
--- /dev/null
+++ b/test_data/epo_tests/hpeaks.mapped.bed4
@@ -0,0 +1,5 @@
+chr16	85453122	85453194	peak1
+chr16	85454203	85454219	peak2
+chr16	85454227	85454258	peak2
+chr16	85454261	85454286	peak2
+chr16	88576704	88576752	peak4
diff --git a/test_data/epo_tests/hpeaks.mapped.nopeak2.bed4 b/test_data/epo_tests/hpeaks.mapped.nopeak2.bed4
new file mode 100644
index 0000000..000a05b
--- /dev/null
+++ b/test_data/epo_tests/hpeaks.mapped.nopeak2.bed4
@@ -0,0 +1,2 @@
+chr16	85453122	85453194	peak1
+chr16	88576704	88576752	peak4
diff --git a/test_data/epo_tests/mm9.chrom.sizes b/test_data/epo_tests/mm9.chrom.sizes
new file mode 100644
index 0000000..3555580
--- /dev/null
+++ b/test_data/epo_tests/mm9.chrom.sizes
@@ -0,0 +1,35 @@
+chr1	197195432
+chr2	181748087
+chrX	166650296
+chr3	159599783
+chr4	155630120
+chr5	152537259
+chr7	152524553
+chr6	149517037
+chr8	131738871
+chr10	129993255
+chr14	125194864
+chr9	124076172
+chr11	121843856
+chr12	121257530
+chr13	120284312
+chr15	103494974
+chr16	98319150
+chr17	95272651
+chr18	90772031
+chr19	61342430
+chrY_random	58682461
+chrY	15902555
+chrUn_random	5900358
+chrX_random	1785075
+chr1_random	1231697
+chr8_random	849593
+chr17_random	628739
+chr9_random	449403
+chr13_random	400311
+chr7_random	362490
+chr5_random	357350
+chr4_random	160594
+chr3_random	41899
+chrM	16299
+chr16_random	3994
diff --git a/test_data/lav_tests/apple.fa b/test_data/lav_tests/apple.fa
new file mode 100644
index 0000000..9e6268a
--- /dev/null
+++ b/test_data/lav_tests/apple.fa
@@ -0,0 +1,10 @@
+> apple
+GGCGCTGCGATAAGGTTGCGACAACACGGACCTTCTTTTGCCTACCTCTG
+CCTGCATATCGACTATTACAGCCACGCGAGTTACATTCCTCTTTTTTTTT
+GCTGGCGTCCGGCCGGCTGAGAGCTACAATACACATGCACGCAGTTTGGC
+CACTCACATTAAGTATATGAGGAAGGGTTAGCATGAGTTGTACTATAAGG
+CAGCGGATAGCAGGTTGTGGAAAAATATCCTCCCGATTCAAATCCCCAGG
+TGCCTAAAGTAGGGCCGGTAGTTGAATGCTTGCCTGTCAGACTGGATGAC
+CAAGTTCAGTATCAACACAATATAGTGCCAGGAGCTAATTGTTCCCCAGC
+AGCGTGACCGGGATACCACCCCAGATACTACTGCACCGCCCGGCGGACTG
+TTCTTGGCACG
diff --git a/test_data/lav_tests/apple_orange.lav b/test_data/lav_tests/apple_orange.lav
new file mode 100644
index 0000000..7de3c0c
--- /dev/null
+++ b/test_data/lav_tests/apple_orange.lav
@@ -0,0 +1,55 @@
+#:lav
+d {
+  "blastz.v0(256) test_data/lav_tests/apple.fa[51,361] test_data/lav_tests/orange.nib K=2000
+     A    C    G    T
+    91 -114  -31 -123
+  -114  100 -125  -31
+   -31 -125  100 -114
+  -123  -31 -114   91
+   O = 400, E = 30, K = 2000, L = 2000, M = 0"
+}
+#:lav
+s {
+  "test_data/lav_tests/apple.fa" 51 361 0 1
+  "test_data/lav_tests/orange.nib" 1 361 0 1
+}
+h {
+  "> apple"
+  "test_data/lav_tests/orange.nib:1-361"
+}
+a {
+  s 10286
+  b 57 54
+  e 308 305
+  l 57 54 161 158 88
+  l 165 159 171 165 71
+  l 180 166 194 180 53
+  l 199 181 208 190 60
+  l 209 207 224 222 56
+  l 226 223 308 305 76
+}
+x {
+  n 0
+}
+#:lav
+s {
+  "test_data/lav_tests/apple.fa" 51 361 0 1
+  "test_data/lav_tests/orange.nib-" 1 361 1 1
+}
+h {
+  "> apple"
+  "test_data/lav_tests/orange.nib:1-361 (reverse complement)"
+}
+a {
+  s 3586
+  b 3 3
+  e 74 74
+  l 3 3 74 74 72
+}
+x {
+  n 0
+}
+m {
+  n 0
+}
+#:eof
diff --git a/test_data/lav_tests/orange.fa b/test_data/lav_tests/orange.fa
new file mode 100644
index 0000000..5a42afb
--- /dev/null
+++ b/test_data/lav_tests/orange.fa
@@ -0,0 +1,9 @@
+> orange
+CGTGCCGAGAACAGAAAATACGCCGGGCGGTGCAGTAGTATCTTGGTATC
+CCGGTCCGGCCGGCTGTGTGCTACAATACACGTTCACGCAGTTTGGCCAA
+TCACTTTAAGTATATACGAAATGGTTACCATGAGTTGTACTGTAAGGCAG
+CGGAAAGCTTGTTAACTCCTGGGCGACATTGGGGCTGCAACATCGTTTAT
+CCTCCTCTACAACCAATAGCTGTTGCTTCTTGGTTCAAGTATATCCCATG
+GATTAGTATCAACACGATATAGTGTCAGGAGCTAATTGTTCCCCAGCAGC
+GTGACGTCAGCAAGAGGAATGGGGGGGGTAACTCGAGAGGCTGTACTAGT
+CGATATGCAGG
diff --git a/test_data/lav_tests/orange.nib b/test_data/lav_tests/orange.nib
new file mode 100644
index 0000000..73885f7
Binary files /dev/null and b/test_data/lav_tests/orange.nib differ
diff --git a/test_data/maf_tests/dcking_ghp074.bed b/test_data/maf_tests/dcking_ghp074.bed
new file mode 100644
index 0000000..834bc66
--- /dev/null
+++ b/test_data/maf_tests/dcking_ghp074.bed
@@ -0,0 +1 @@
+chr7 80082367 80083066 GHP074.Cib1
diff --git a/test_data/maf_tests/dcking_ghp074.maf b/test_data/maf_tests/dcking_ghp074.maf
new file mode 100644
index 0000000..95d2a66
--- /dev/null
+++ b/test_data/maf_tests/dcking_ghp074.maf
@@ -0,0 +1,64 @@
+##maf version=1
+a score=-33148.0
+s mm8.chr7                 80082368 103 + 145134094 TGAGAGGGCATGCT-GTGAAGGGACTGTGCT---CAGTTCAAGGCATAGTCCACTTCC--------CTTCCCTTGGTCATTCTGTTCGGTGTGTTTCCAGCAGATATGGAGAGT-------------------------------------C---- 
+s rn4.chr1                136011819  86 + 267910886 TGAGAGGGCATGTT-ATGAAGGCACTGTGCT--------------------CACTTTC--------CATCCCATGGTCATTCTGTTGAGTGTGTTCCCAGCAGATACGGAAAGT-------------------------------------C---- 
+s oryCun1.scaffold_199771     14064  74 -     75077 TAGGACTGCCTGGTGGGGGGGGCCCTGCACC--------------------TACTTCTGCAAGGCACGTCCCGCG----------TCTGTGCCTTCGCCGCA-----------T-------------------------------------C---- 
+s hg18.chr15               88557607 128 + 100338915 GGGGAAAGCCTGGT-TAAGGGGCCCTTCACCCCCCTCTCCAAGGCACATTCCCCTTTC--------TGTCCCTTTGTCGTTTCATTCACTCTACTCCCAGCATGGCTGGAGGGC---TTGTGG---CTGGCTCGTTTGG---------AGGC---- 
+s panTro2.chr15            87959864 116 + 100063422 GGGGAAAGCCTGGT-TAAGGGGCCCTTCACCCCCCTCTCCAAGGCACATTCCCCTTTC--------TGTCCCTTTGTCGTTTCATTCACTA------------GGCTAGAGGGC---TTGTGG---CTGGCTCGTTTGG---------AGGC---- 
+s rheMac2.chr7             69864742 107 + 169801366 GGAGAAAGCCTGGT-TAAGGGGCCCTTCA-----CTCTCCAAGGCACATTCCACTTTC--------TGTCCCTTTGTCATTCCATTCACTCTACTCCCCGCATGGCTAGAGGGC----------------------TGG---------AGGC---- 
+s canFam2.chr3             56030609 103 +  94715083 AGGGAATGCATGGTGTATGGGGGCCCCCGTC--------------------CACTTC---------TGTCCCGTTGCTATTTCCTTGACCATACTTCCAGTATGACTGGGGGAG---GTGCGG---TGGAGCAGGTTC------------------ 
+s loxAfr1.scaffold_8298       30302 144 +     78952 --TGGATGCCTGGT-TTAAGGATCC-GCTCACCCACTTCTGAGTCACGTTACACTTTC--------TGCCCCTTTGCCATTTCATTTATGGTACTCCCAACACCGGGGGAGGGTGCGCTTTGGTTCTTGAGCAGTTTGTGTATATAGGGGGCTGAG 
+s echTel1.scaffold_304651       631  67 -     10007 --TGGAGGGCTACT-TTAAGAAACC----CTCCCGTTTCTCAG-------------CC--------TGCTTC---------------------------------------------CTTTGGGTTTGAGGTACTTTGT----------------G 
+
+a score=87527.0
+s mm8.chr7                 80082471 121 + 145134094 CTG-AGC---------------CGCTGGCCCCTGGGCTTCCCCTCCAGCCTGGCTTGACTTTGTCTGAGGGACCCTGGGCAGC-TTGCCATCCA---------CCCAGGCTGAAGTGGAGGGGGTGTTGAGCTGCCACCTGGGACTT 
+s rn4.chr1                136011905 121 + 267910886 TCG-GAC---------------CGCTGGCACCCAGGCTTCCCCTCCAGCCTGGCCTGACTCTGTCTGAGGGACCCTGGGCAGC-TTGCCATCCA---------CGCAGGCAAAAGTGGAGGGGATGTTGAGCTGCCACCTGGAACTT 
+s oryCun1.scaffold_199771     14138 103 -     75077 CCGCAGT---------------GGATCCCACCTCGGCTGTAGCAGTAGGCCAACCAGG----GCCCGACAGGCGCCCGGCTGTGCTGGCTTCCA-CACCCTCTCCCAGGC---------------------CTGCCACCCAGGC--- 
+s hg18.chr15               88557735 127 + 100338915 CTG-GGCTGAACCAGGGACT--GGCTGGTCTATAGGTTTCCCCTCCAGCC-GGCTGCACTCTG----TAGTGCCCGAGGCAGG-TTTCCACCCC-----TTCTCCCAGGCGTAAGTGGG------ATTGAGTTGCCACCTGGGACTG 
+s panTro2.chr15            87959980 127 + 100063422 CTG-GGCTGAACCAGGGACT--GGCTGGTCTATAGGTTTCCCCTCCAGCC-GGCTGCACTCTG----TAGTGCCCGTGGCAGG-TTTCCACCCC-----TTCTCCCAGGCGTAAGTGGG------ATTGAGTTGCCACCTGGGACTG 
+s rheMac2.chr7             69864849 116 + 169801366 CTG-GGCTGAACCAGGGGCT--GGCTGGTCTGCAG----------------GGCTGCACTCTGTCTATAGTGCCCGAGGCAGG-TTTCCACCCC-----TTCTTCCAGTCGTAAGTGGG------GTTGAGCTGCCACCTGGGACTG 
+s bosTau2.scaffold2397        93191 110 +    117874 CTG-GGC---------------AGCTGGCGCCTCGGCTGCCCCTCCCACCTGGCT-------------GTGACCCTTGGCAAG-TCTCCCCGCCCCCCATGCCCCCAGGCCTGAGCAAG------GCTGAGCTGCCACCT-GGACTA 
+s canFam2.chr3             56030712 116 +  94715083 TCT-AGC---------------AGCTGGCGCCCCAGCTGTCCTTCCAACCTGGCTGTGCTCTGTCTACGTGACCTTTGGCAGA-TTGCCACTCC-------CTCCCAGGCCCGAGCAGG------GCCAAGCTGCCACCT-GGATGG 
+s loxAfr1.scaffold_8298       30446 129 +     78952 CTG-AAC-----CAGGGACTGCAGCTAGTGCCTGGGCCACCGCTCCAGCCTGGCTGTGCTCTGTCTACAGGACGCATGGCAAG-TTGCCACCCC----CCTCTCCCAGG-CTAGGTGGG------GCTAAGCTGCCACTTGAAACTT 
+s echTel1.scaffold_304651       698 101 -     10007 CTG-GAC-----CAGGAACTGCAGCT---------GCTGCCCCTCTAGCCTACCTGTGC---------------CTTGGCAGG-TTGCCAGCCC-------CTCCCAGGCCTAGGTGGG------GTGACGCTGCCTCCTGGGAC-- 
+
+a score=185399.0
+s mm8.chr7                 80082592 121 + 145134094 GTGCTTATCTCGGACTCTTGGCATTTCTGTTTCTGGACAGAACCCAAGGGTGGCTTCCCGCTTAGAGCTGTAGGTCCC----ACCCAGGTGGAAATG--CCCTCCGGTGCAGGCAGATAAGCTCTGG 
+s rn4.chr1                136012026 121 + 267910886 GTGCTTATCTTGGCCTCTTGGCATTTCTGTATCTGGACAGAATCCAAGGGTGGCTTCCCGCTTAGAGCTGTAGGTCCC----ACCCAGGTGGAAATG--CCCTCCGGAGCAGGCAGATAAGCTCTGG 
+s oryCun1.scaffold_199771     14241 119 -     75077 ---CTTATCTCCGACTGCTGGCATTGCTGTGTCTGGGCAGAGGCCAAGGGCGGCCTCCCGCACAGACACTCGGGGCCC----GCCCAGGTAGAAGTG-CCCCTCCTGTGCAGGCAGATAAGCGCTGG 
+s hg18.chr15               88557862 119 + 100338915 AGGCTTATCTCTGACTCTTGGCATTTCTTTGTCTGGACAGATTCCAAGGGCGGTCTGCTGCCCAGACTTACAGGGCCT----GCCCAGGTGGAAACG--CTCTTT--TGCAGGTAGATAAGCACGGG 
+s panTro2.chr15            87960107 119 + 100063422 AGGCTTATCTCTGACTCTTGGCATTTCTTTGTCTGGACAGATTCCAAGGGCGGTCTGCTGCCCAGACTTACAGGGCCT----GCCCAGGTGGAAACG--CTCTTT--TGCAGGTAGATAAGCACGGG 
+s rheMac2.chr7             69864965 114 + 169801366 AGGCTTATCTCTGATCCTTGGCATTTCTGTGTCTGGACAGATTCCAAGGGCGGTCTGCTGCCCAGACTTACAGGGCCC----GCCCAGGTG-----G--CTCTTC--TGCAGGTAGATAAGCATGGG 
+s bosTau2.scaffold2397        93301 123 +    117874 AAGCTTATCTCTGACCTTTGGCATTCCTGTGTGTGGACAGATTGCAAGAGCAGCCTCT-GCCCAGGCTTACGGGGACCTGCTGCCTCGGTAGAAATG-CGCCTCCTCTGTAGGCAGATAAGCCCT-- 
+s canFam2.chr3             56030828 121 +  94715083 CAACTTATCTTTGACCTTCGGCATTTCTATATCTGGATGGATCCTAAGTGCAGCCTCCAGCCTAGACTTCCAGGACCC----ACCCTGGGA-AGATG-CCCCTCCTGTGTGGGCAGATAAATGTTGG 
+s echTel1.scaffold_304651       799 118 -     10007 ATGACAATCT--GACCTTTGACATT--TGTTTTAGGATAGGTTCCAAGTGAAGCCTCCTGCCTAGACTTCCTGATTCT-----CCCAGATAGAAGCGCCCCCTTCTTGGAAGACAGATAAGCGATAA 
+
+a score=30120.0
+s mm8.chr7                 80082713 54 + 145134094 CAA-------ACCAAAGGCAGCCTGT-GCTTCCAGAAAACCTT-GAGGGGTGCAAGAGATAAA 
+s rn4.chr1                136012147 54 + 267910886 CAA-------ACCAGAGGCAGCCTAC-GTTTCCAGAAAACCTT-GAGGGGTACAAGAGATAAA 
+s hg18.chr15               88557981 62 + 100338915 CAACCAGCTTATCTGAACCAGCCCTT-GCTTCCAGAGAACTATGGAAAAATCCAAAAGATAAG 
+s panTro2.chr15            87960226 62 + 100063422 CAACCAGCTTATCTGAACCAGCCCTT-GCTTCCAGAGAACTATGGAAAAATCCAAAAGATAAG 
+s rheMac2.chr7             69865079 62 + 169801366 CAACCAGCTTATCTGAACCAGCCCTC-GTTTCCAGGTAACTCTGGAAAAATCCAAAAGATGAG 
+s canFam2.chr3             56030949 40 +  94715083 -------CATATTTGACCCAGCCCTTGGCTTTCAGAAAACC------------ACAA----AG 
+s echTel1.scaffold_304651       917 55 -     10007 CAA-------ATTCCATCCCACCCTT-CGTTCTGGACGGGCTGGGAGGGGTACAAAAGATAAA 
+
+a score=58255.0
+s mm8.chr7              80082767 128 + 145134094 GGGGTGCAGGAGCTGTG----TGTCTTGATCTCCCAGA----GTCTTCGTGAGCCT-----------CACTTTTTGTCTTATCCCT---GTGATACACACAGG-AAGCCACAGTGAATTCAGTGGGTGTCAT---------ACAGAAGGGCCTCC-TGGAG- 
+s rn4.chr1             136012201 139 + 267910886 GGGGTACAGGAGCTGTG----TG-CTTGATGTCGCTGA----GCCTTCGTGAGGCTCCTGTGAGCTGCACTTTTTGTCTCGTCCCT---GTGATAGACACAAG-AAGCCACAGTGAATTCAGTGGGTATCAT---------ATGGAAGGGCCTCCTTGGAC- 
+s hg18.chr15            88558043 143 + 100338915 AAGGGACCGCAG-TGTC----TGTCTTGGTCTCAC--------TCCTCTTGAGACTCCTGTGAT---CTTTATATGTCTCATTCCTCCCGTGACATGTATGAG-AAACTGCAGCTCATTGAGACGATGTCTCTGCTGCCTGACAGAAGGGCCTAC-TTGAG- 
+s panTro2.chr15         87960288 143 + 100063422 AAGGGACCGCAG-TGTC----TGTCTTGGTCTCAC--------TCCTCTTGAGACTCCTGTGAT---CTTTATATGTCTCATTCCTCCCGTGACATGTATGAG-AAACTGCAGCTCATTGAGACGATGTCTCTGCTGCCTGACAGAAGGGCCTAC-TTGAG- 
+s rheMac2.chr7          69865141 147 + 169801366 GAGGGACCACAG-TGTCTGTTTGTCCTGGTCTCAC--------TCCTCATGAGACTCCTGTGAT---CTTTGTATGTCTCATTCCTCCTGTGACATGTATGAG-AATGTACAGCTCAGTGAGATGATGTCTCTGCTGCCTGACAGAAGTGCCTAC-TTGAG- 
+s bosTau2.scaffold2397     93775 133 +    117874 GGACTGCAGTGGCCATT----TGCTCTGGCCTCACTGA----CTCCTTGTGAGCCCGCTGTGAG---TTTTGTTT---TCATTATCCCCAT------TATGAGAAAACTCCAGTTTGGTGAGATGGCATCTACCCTGCCCT--------ACAAAC-ATGgtg 
+s canFam2.chr3          56030989 153 +  94715083 GGGATGTGGAAGACGTT----TGCCCTCGTCTCACAGACTCCCTCCTTGTAAGGCTGCTGGGAG---TCATATTTTGCTCATTATCCCTGCGGTATGTATGAG-AAGCCAAAGGTCAGTGAGCTGGAGTTTGCACTGCCCTCCAGAGGGACCGAC-ATGgtg 
+
+a score=2607.0
+s mm8.chr7              80082895 114 + 145134094 CTTCTCAGAGTGTAGT-----------CCTTGGGCTACC-TCCTCCTAAGTCACTGGG-----------------------AGCTGGTCA-AGAGG------CTCAGACCAGCAGTTTCAGAATCTCTTGGGAGGGCCT--------GGAGTCCGGGTGATGTT 
+s rn4.chr1             136012340 112 + 267910886 CTTCTCAGA--GTAGT-----------CCTTGGGCCACC-TCCTTCTAAGTTACTGAG-----------------------AGCTGGTCA-AGAGG------CTCAGACCAGCAGTTTCAGAATCTCTTGGGAGGGCCT--------GGAGTCAAGGTACTGTT 
+s rheMac2.chr7          69865323 119 + 169801366 CTTCTTGTTGACTAGTGTCACCCCCACCCGAGGGCTTCCTTCCTCATTTGCTGCCAGGTGTAAAGCTGAGCTTC-------agctgggcgcagtgg------ctcacacccataatcctagca--ttttgggag------------------------------ 
+s bosTau2.scaffold2397     93908 136 +    117874 cttctcaaagtgtgct-----------ccatgagcctcc-tacttcagaatcccctgg---------gagattcaaaaccttgcatgttc-tcaggccccatcacgggccagcatcgtcagagtcttcagggtcagctcgtggatctagagtgtaggt------ 
+s canFam2.chr3          56031142 126 +  94715083 cttttcagagggtggt-----------ccctgggcctcc-cactttggaattgcctgg---------gag-ctcatagaattgcccgttg-tcagg--ccatcccagggcagtggcagcag-gcctctagggcaggcct------------ttcaggtgacttt 
+
+a score=8132.0
+s mm8.chr7  80083009 57 + 145134094 TAGGGAGGTTGGCATTGGTGCTGGAACTTTCCTTGGCCCCCCAATTTATCGAAGTAC 
+s rn4.chr1 136012452 56 + 267910886 TAGGGAGATTGGGATTGGTACTGGAACTTTCCTTGGCCTCCCAGTGTATT-CAGTAC 
+
diff --git a/test_data/maf_tests/mm8_chr7_tiny.maf b/test_data/maf_tests/mm8_chr7_tiny.maf
new file mode 100644
index 0000000..d21c567
--- /dev/null
+++ b/test_data/maf_tests/mm8_chr7_tiny.maf
@@ -0,0 +1,76 @@
+##maf version=1
+a score=10542.0
+s mm8.chr7                 80082334 34 + 145134094 GGGCTGAGGGC--AGGGATGG---AGGGCGGTCC--------------CAGCA- 
+s rn4.chr1                136011785 34 + 267910886 GGGCTGAGGGC--AGGGACGG---AGGGCGGTCC--------------CAGCA- 
+s oryCun1.scaffold_199771     14021 43 -     75077 -----ATGGGC--AAGCGTGG---AGGGGAACCTCTCCTCCCCTCCGACAAAG- 
+s hg18.chr15               88557580 27 + 100338915 --------GGC--AAGTGTGGA--AGGGAAGCCC--------------CAGAA- 
+s panTro2.chr15            87959837 27 + 100063422 --------GGC--AAGTGTGGA--AGGGAAGCCC--------------CAGAA- 
+s rheMac2.chr7             69864714 28 + 169801366 -------GGGC--AAGTATGGA--AGGGAAGCCC--------------CAGAA- 
+s canFam2.chr3             56030570 39 +  94715083 AGGTTTAGGGCAGAGGGATGAAGGAGGAGAATCC--------------CTATG- 
+s dasNov1.scaffold_106893      7435 34 +      9831 GGAACGAGGGC--ATGTGTGG---AGGGGGCTGC--------------CCACA- 
+s loxAfr1.scaffold_8298       30264 38 +     78952 ATGATGAGGGG--AAGCGTGGAGGAGGGGAACCC--------------CTAGGA 
+s echTel1.scaffold_304651       594 37 -     10007 -TGCTATGGCT--TTGTGTCTAGGAGGGGAATCC--------------CCAGGA 
+
+a score=-33148.0
+s mm8.chr7                 80082368 103 + 145134094 TGAGAGGGCATGCT-GTGAAGGGACTGTGCT---CAGTTCAAGGCATAGTCCACTTCC--------CTTCCCTTGGTCATTCTGTTCGGTGTGTTTCCAGCAGATATGGAGAGT-------------------------------------C---- 
+s rn4.chr1                136011819  86 + 267910886 TGAGAGGGCATGTT-ATGAAGGCACTGTGCT--------------------CACTTTC--------CATCCCATGGTCATTCTGTTGAGTGTGTTCCCAGCAGATACGGAAAGT-------------------------------------C---- 
+s oryCun1.scaffold_199771     14064  74 -     75077 TAGGACTGCCTGGTGGGGGGGGCCCTGCACC--------------------TACTTCTGCAAGGCACGTCCCGCG----------TCTGTGCCTTCGCCGCA-----------T-------------------------------------C---- 
+s hg18.chr15               88557607 128 + 100338915 GGGGAAAGCCTGGT-TAAGGGGCCCTTCACCCCCCTCTCCAAGGCACATTCCCCTTTC--------TGTCCCTTTGTCGTTTCATTCACTCTACTCCCAGCATGGCTGGAGGGC---TTGTGG---CTGGCTCGTTTGG---------AGGC---- 
+s panTro2.chr15            87959864 116 + 100063422 GGGGAAAGCCTGGT-TAAGGGGCCCTTCACCCCCCTCTCCAAGGCACATTCCCCTTTC--------TGTCCCTTTGTCGTTTCATTCACTA------------GGCTAGAGGGC---TTGTGG---CTGGCTCGTTTGG---------AGGC---- 
+s rheMac2.chr7             69864742 107 + 169801366 GGAGAAAGCCTGGT-TAAGGGGCCCTTCA-----CTCTCCAAGGCACATTCCACTTTC--------TGTCCCTTTGTCATTCCATTCACTCTACTCCCCGCATGGCTAGAGGGC----------------------TGG---------AGGC---- 
+s canFam2.chr3             56030609 103 +  94715083 AGGGAATGCATGGTGTATGGGGGCCCCCGTC--------------------CACTTC---------TGTCCCGTTGCTATTTCCTTGACCATACTTCCAGTATGACTGGGGGAG---GTGCGG---TGGAGCAGGTTC------------------ 
+s loxAfr1.scaffold_8298       30302 144 +     78952 --TGGATGCCTGGT-TTAAGGATCC-GCTCACCCACTTCTGAGTCACGTTACACTTTC--------TGCCCCTTTGCCATTTCATTTATGGTACTCCCAACACCGGGGGAGGGTGCGCTTTGGTTCTTGAGCAGTTTGTGTATATAGGGGGCTGAG 
+s echTel1.scaffold_304651       631  67 -     10007 --TGGAGGGCTACT-TTAAGAAACC----CTCCCGTTTCTCAG-------------CC--------TGCTTC---------------------------------------------CTTTGGGTTTGAGGTACTTTGT----------------G 
+
+a score=87527.0
+s mm8.chr7                 80082471 121 + 145134094 CTG-AGC---------------CGCTGGCCCCTGGGCTTCCCCTCCAGCCTGGCTTGACTTTGTCTGAGGGACCCTGGGCAGC-TTGCCATCCA---------CCCAGGCTGAAGTGGAGGGGGTGTTGAGCTGCCACCTGGGACTT 
+s rn4.chr1                136011905 121 + 267910886 TCG-GAC---------------CGCTGGCACCCAGGCTTCCCCTCCAGCCTGGCCTGACTCTGTCTGAGGGACCCTGGGCAGC-TTGCCATCCA---------CGCAGGCAAAAGTGGAGGGGATGTTGAGCTGCCACCTGGAACTT 
+s oryCun1.scaffold_199771     14138 103 -     75077 CCGCAGT---------------GGATCCCACCTCGGCTGTAGCAGTAGGCCAACCAGG----GCCCGACAGGCGCCCGGCTGTGCTGGCTTCCA-CACCCTCTCCCAGGC---------------------CTGCCACCCAGGC--- 
+s hg18.chr15               88557735 127 + 100338915 CTG-GGCTGAACCAGGGACT--GGCTGGTCTATAGGTTTCCCCTCCAGCC-GGCTGCACTCTG----TAGTGCCCGAGGCAGG-TTTCCACCCC-----TTCTCCCAGGCGTAAGTGGG------ATTGAGTTGCCACCTGGGACTG 
+s panTro2.chr15            87959980 127 + 100063422 CTG-GGCTGAACCAGGGACT--GGCTGGTCTATAGGTTTCCCCTCCAGCC-GGCTGCACTCTG----TAGTGCCCGTGGCAGG-TTTCCACCCC-----TTCTCCCAGGCGTAAGTGGG------ATTGAGTTGCCACCTGGGACTG 
+s rheMac2.chr7             69864849 116 + 169801366 CTG-GGCTGAACCAGGGGCT--GGCTGGTCTGCAG----------------GGCTGCACTCTGTCTATAGTGCCCGAGGCAGG-TTTCCACCCC-----TTCTTCCAGTCGTAAGTGGG------GTTGAGCTGCCACCTGGGACTG 
+s bosTau2.scaffold2397        93191 110 +    117874 CTG-GGC---------------AGCTGGCGCCTCGGCTGCCCCTCCCACCTGGCT-------------GTGACCCTTGGCAAG-TCTCCCCGCCCCCCATGCCCCCAGGCCTGAGCAAG------GCTGAGCTGCCACCT-GGACTA 
+s canFam2.chr3             56030712 116 +  94715083 TCT-AGC---------------AGCTGGCGCCCCAGCTGTCCTTCCAACCTGGCTGTGCTCTGTCTACGTGACCTTTGGCAGA-TTGCCACTCC-------CTCCCAGGCCCGAGCAGG------GCCAAGCTGCCACCT-GGATGG 
+s loxAfr1.scaffold_8298       30446 129 +     78952 CTG-AAC-----CAGGGACTGCAGCTAGTGCCTGGGCCACCGCTCCAGCCTGGCTGTGCTCTGTCTACAGGACGCATGGCAAG-TTGCCACCCC----CCTCTCCCAGG-CTAGGTGGG------GCTAAGCTGCCACTTGAAACTT 
+s echTel1.scaffold_304651       698 101 -     10007 CTG-GAC-----CAGGAACTGCAGCT---------GCTGCCCCTCTAGCCTACCTGTGC---------------CTTGGCAGG-TTGCCAGCCC-------CTCCCAGGCCTAGGTGGG------GTGACGCTGCCTCCTGGGAC-- 
+
+a score=185399.0
+s mm8.chr7                 80082592 121 + 145134094 GTGCTTATCTCGGACTCTTGGCATTTCTGTTTCTGGACAGAACCCAAGGGTGGCTTCCCGCTTAGAGCTGTAGGTCCC----ACCCAGGTGGAAATG--CCCTCCGGTGCAGGCAGATAAGCTCTGG 
+s rn4.chr1                136012026 121 + 267910886 GTGCTTATCTTGGCCTCTTGGCATTTCTGTATCTGGACAGAATCCAAGGGTGGCTTCCCGCTTAGAGCTGTAGGTCCC----ACCCAGGTGGAAATG--CCCTCCGGAGCAGGCAGATAAGCTCTGG 
+s oryCun1.scaffold_199771     14241 119 -     75077 ---CTTATCTCCGACTGCTGGCATTGCTGTGTCTGGGCAGAGGCCAAGGGCGGCCTCCCGCACAGACACTCGGGGCCC----GCCCAGGTAGAAGTG-CCCCTCCTGTGCAGGCAGATAAGCGCTGG 
+s hg18.chr15               88557862 119 + 100338915 AGGCTTATCTCTGACTCTTGGCATTTCTTTGTCTGGACAGATTCCAAGGGCGGTCTGCTGCCCAGACTTACAGGGCCT----GCCCAGGTGGAAACG--CTCTTT--TGCAGGTAGATAAGCACGGG 
+s panTro2.chr15            87960107 119 + 100063422 AGGCTTATCTCTGACTCTTGGCATTTCTTTGTCTGGACAGATTCCAAGGGCGGTCTGCTGCCCAGACTTACAGGGCCT----GCCCAGGTGGAAACG--CTCTTT--TGCAGGTAGATAAGCACGGG 
+s rheMac2.chr7             69864965 114 + 169801366 AGGCTTATCTCTGATCCTTGGCATTTCTGTGTCTGGACAGATTCCAAGGGCGGTCTGCTGCCCAGACTTACAGGGCCC----GCCCAGGTG-----G--CTCTTC--TGCAGGTAGATAAGCATGGG 
+s bosTau2.scaffold2397        93301 123 +    117874 AAGCTTATCTCTGACCTTTGGCATTCCTGTGTGTGGACAGATTGCAAGAGCAGCCTCT-GCCCAGGCTTACGGGGACCTGCTGCCTCGGTAGAAATG-CGCCTCCTCTGTAGGCAGATAAGCCCT-- 
+s canFam2.chr3             56030828 121 +  94715083 CAACTTATCTTTGACCTTCGGCATTTCTATATCTGGATGGATCCTAAGTGCAGCCTCCAGCCTAGACTTCCAGGACCC----ACCCTGGGA-AGATG-CCCCTCCTGTGTGGGCAGATAAATGTTGG 
+s echTel1.scaffold_304651       799 118 -     10007 ATGACAATCT--GACCTTTGACATT--TGTTTTAGGATAGGTTCCAAGTGAAGCCTCCTGCCTAGACTTCCTGATTCT-----CCCAGATAGAAGCGCCCCCTTCTTGGAAGACAGATAAGCGATAA 
+
+a score=30120.0
+s mm8.chr7                 80082713 54 + 145134094 CAA-------ACCAAAGGCAGCCTGT-GCTTCCAGAAAACCTT-GAGGGGTGCAAGAGATAAA 
+s rn4.chr1                136012147 54 + 267910886 CAA-------ACCAGAGGCAGCCTAC-GTTTCCAGAAAACCTT-GAGGGGTACAAGAGATAAA 
+s hg18.chr15               88557981 62 + 100338915 CAACCAGCTTATCTGAACCAGCCCTT-GCTTCCAGAGAACTATGGAAAAATCCAAAAGATAAG 
+s panTro2.chr15            87960226 62 + 100063422 CAACCAGCTTATCTGAACCAGCCCTT-GCTTCCAGAGAACTATGGAAAAATCCAAAAGATAAG 
+s rheMac2.chr7             69865079 62 + 169801366 CAACCAGCTTATCTGAACCAGCCCTC-GTTTCCAGGTAACTCTGGAAAAATCCAAAAGATGAG 
+s canFam2.chr3             56030949 40 +  94715083 -------CATATTTGACCCAGCCCTTGGCTTTCAGAAAACC------------ACAA----AG 
+s echTel1.scaffold_304651       917 55 -     10007 CAA-------ATTCCATCCCACCCTT-CGTTCTGGACGGGCTGGGAGGGGTACAAAAGATAAA 
+
+a score=58255.0
+s mm8.chr7              80082767 128 + 145134094 GGGGTGCAGGAGCTGTG----TGTCTTGATCTCCCAGA----GTCTTCGTGAGCCT-----------CACTTTTTGTCTTATCCCT---GTGATACACACAGG-AAGCCACAGTGAATTCAGTGGGTGTCAT---------ACAGAAGGGCCTCC-TGGAG- 
+s rn4.chr1             136012201 139 + 267910886 GGGGTACAGGAGCTGTG----TG-CTTGATGTCGCTGA----GCCTTCGTGAGGCTCCTGTGAGCTGCACTTTTTGTCTCGTCCCT---GTGATAGACACAAG-AAGCCACAGTGAATTCAGTGGGTATCAT---------ATGGAAGGGCCTCCTTGGAC- 
+s hg18.chr15            88558043 143 + 100338915 AAGGGACCGCAG-TGTC----TGTCTTGGTCTCAC--------TCCTCTTGAGACTCCTGTGAT---CTTTATATGTCTCATTCCTCCCGTGACATGTATGAG-AAACTGCAGCTCATTGAGACGATGTCTCTGCTGCCTGACAGAAGGGCCTAC-TTGAG- 
+s panTro2.chr15         87960288 143 + 100063422 AAGGGACCGCAG-TGTC----TGTCTTGGTCTCAC--------TCCTCTTGAGACTCCTGTGAT---CTTTATATGTCTCATTCCTCCCGTGACATGTATGAG-AAACTGCAGCTCATTGAGACGATGTCTCTGCTGCCTGACAGAAGGGCCTAC-TTGAG- 
+s rheMac2.chr7          69865141 147 + 169801366 GAGGGACCACAG-TGTCTGTTTGTCCTGGTCTCAC--------TCCTCATGAGACTCCTGTGAT---CTTTGTATGTCTCATTCCTCCTGTGACATGTATGAG-AATGTACAGCTCAGTGAGATGATGTCTCTGCTGCCTGACAGAAGTGCCTAC-TTGAG- 
+s bosTau2.scaffold2397     93775 133 +    117874 GGACTGCAGTGGCCATT----TGCTCTGGCCTCACTGA----CTCCTTGTGAGCCCGCTGTGAG---TTTTGTTT---TCATTATCCCCAT------TATGAGAAAACTCCAGTTTGGTGAGATGGCATCTACCCTGCCCT--------ACAAAC-ATGgtg 
+s canFam2.chr3          56030989 153 +  94715083 GGGATGTGGAAGACGTT----TGCCCTCGTCTCACAGACTCCCTCCTTGTAAGGCTGCTGGGAG---TCATATTTTGCTCATTATCCCTGCGGTATGTATGAG-AAGCCAAAGGTCAGTGAGCTGGAGTTTGCACTGCCCTCCAGAGGGACCGAC-ATGgtg 
+
+a score=2607.0
+s mm8.chr7              80082895 114 + 145134094 CTTCTCAGAGTGTAGT-----------CCTTGGGCTACC-TCCTCCTAAGTCACTGGG-----------------------AGCTGGTCA-AGAGG------CTCAGACCAGCAGTTTCAGAATCTCTTGGGAGGGCCT--------GGAGTCCGGGTGATGTT 
+s rn4.chr1             136012340 112 + 267910886 CTTCTCAGA--GTAGT-----------CCTTGGGCCACC-TCCTTCTAAGTTACTGAG-----------------------AGCTGGTCA-AGAGG------CTCAGACCAGCAGTTTCAGAATCTCTTGGGAGGGCCT--------GGAGTCAAGGTACTGTT 
+s rheMac2.chr7          69865323 119 + 169801366 CTTCTTGTTGACTAGTGTCACCCCCACCCGAGGGCTTCCTTCCTCATTTGCTGCCAGGTGTAAAGCTGAGCTTC-------agctgggcgcagtgg------ctcacacccataatcctagca--ttttgggag------------------------------ 
+s bosTau2.scaffold2397     93908 136 +    117874 cttctcaaagtgtgct-----------ccatgagcctcc-tacttcagaatcccctgg---------gagattcaaaaccttgcatgttc-tcaggccccatcacgggccagcatcgtcagagtcttcagggtcagctcgtggatctagagtgtaggt------ 
+s canFam2.chr3          56031142 126 +  94715083 cttttcagagggtggt-----------ccctgggcctcc-cactttggaattgcctgg---------gag-ctcatagaattgcccgttg-tcagg--ccatcccagggcagtggcagcag-gcctctagggcaggcct------------ttcaggtgacttt 
+
+a score=8132.0
+s mm8.chr7  80083009 147 + 145134094 TAGGGAGGTTGGCATTGGTGCTGGAACTTTCCTTGGCCCCCCAATTTATCGAAGTACTAAGGGTTGGAAGTCTCTGGAGCTGCAGGAGTT--GAGTTTGAGAAAAGGCTCTTGGTGGTTTAAAGAGA----------------GGTTTCAACTGC--------------------------CTCTGGCCTC 
+s rn4.chr1 136012452 190 + 267910886 TAGGGAGATTGGGATTGGTACTGGAACTTTCCTTGGCCTCCCAGTGTATT-CAGTACTAAGGGTTGGAAGTCTCGGGTGCTACAAGAATTAAGAGTTTGAGAAGAGGCTCTTGGTAGTTTAGAAAGAGAGAAGGACATCTTTGGGTTTCGACTACCTGTGGTGGCAGTGTCAGAATTCAGGCTCTGGCCTC 
+
diff --git a/test_data/maf_tests/mm8_chr7_tiny.maf.index b/test_data/maf_tests/mm8_chr7_tiny.maf.index
new file mode 100644
index 0000000..fd8b0ea
Binary files /dev/null and b/test_data/maf_tests/mm8_chr7_tiny.maf.index differ
diff --git a/test_data/seq_tests/test.2bit b/test_data/seq_tests/test.2bit
new file mode 100644
index 0000000..eaa55b6
Binary files /dev/null and b/test_data/seq_tests/test.2bit differ
diff --git a/test_data/seq_tests/test.fa b/test_data/seq_tests/test.fa
new file mode 100644
index 0000000..c175944
--- /dev/null
+++ b/test_data/seq_tests/test.fa
@@ -0,0 +1,11 @@
+>mule
+TGGAG GCATT TGTGA TTCAA TAGAT GCAGA AAGAA ACCTT CCTAG AGCTG GCGTT CTCTA ACTAA
+AAGTG GAAAG TTCTG 
+      AGGAA TGAGG ACTGT TATAA ATCCC ACCCC ACACC GCACC TTCTC CAGGG AAGTT TCATG 
+GCCGT GAAGA GGACA GAAAG 
+TGAGA ACCAA GATgg aactg aataa acaag cttca cactg ttagt ttccc cat   
+atgct tacct tccca cagat gccaa ccttg gaggc ctaag aggcc tagaa tatta tcctt
+tgtct gatca tttct ctaca 
+aattt attgt tcttt gttaa gatgc tacat aagcc caaat tctaa ccacc
+ccttt gagtt accca tcatc aagtt tc   
+tccca tgtg
diff --git a/test_data/seq_tests/test.nib b/test_data/seq_tests/test.nib
new file mode 100644
index 0000000..972aca3
Binary files /dev/null and b/test_data/seq_tests/test.nib differ
diff --git a/test_data/seq_tests/test.qdna b/test_data/seq_tests/test.qdna
new file mode 100644
index 0000000..4604a62
Binary files /dev/null and b/test_data/seq_tests/test.qdna differ
diff --git a/test_data/seq_tests/test2.fa b/test_data/seq_tests/test2.fa
new file mode 100644
index 0000000..4d4d4d3
--- /dev/null
+++ b/test_data/seq_tests/test2.fa
@@ -0,0 +1,9 @@
+> apple
+GGCGCTGCGATAAGGTTGCGACAACACGGACCTTCTTTTGCCTACCTCTG
+TTCTTGGCACG
+> orange
+CGTGCCGAGAACAGAAAATACGCCGGGCGGTGCAGTAGTATCTTGGTATC
+CGATATGCAGG
+> grapefruit
+CCTGCATATCGACTAGTACACCCTCCCGAGGTACCCCACCCATCCCTCTT
+TTCTCGGCGCG
diff --git a/test_data/seq_tests/testMask.2bit b/test_data/seq_tests/testMask.2bit
new file mode 100644
index 0000000..4b8a03c
Binary files /dev/null and b/test_data/seq_tests/testMask.2bit differ
diff --git a/test_data/seq_tests/testMask.fa b/test_data/seq_tests/testMask.fa
new file mode 100644
index 0000000..1fc92cb
--- /dev/null
+++ b/test_data/seq_tests/testMask.fa
@@ -0,0 +1,10 @@
+>startLower
+aaacagtaaAAAACCC
+>endLower
+AAAACCCaaacagtaa
+>manyLower
+aaCCggTTaCgT
+>allLower
+taaaacaaaaag
+>noLower
+ACGTTTACT
diff --git a/test_data/seq_tests/testN.2bit b/test_data/seq_tests/testN.2bit
new file mode 100644
index 0000000..63db13c
Binary files /dev/null and b/test_data/seq_tests/testN.2bit differ
diff --git a/test_data/seq_tests/testN.fa b/test_data/seq_tests/testN.fa
new file mode 100644
index 0000000..56c7d64
--- /dev/null
+++ b/test_data/seq_tests/testN.fa
@@ -0,0 +1,4 @@
+>startN
+NANNAANNNAAA
+>startNonN
+ANAANNAAANNN

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-med/python-bx.git



More information about the debian-med-commit mailing list